Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,23 @@ Usage: <command shape>

When an error code is available, the first line is `Error [<code>]: <message>`. Use `CommandErrorWriter` for new CLI parse, validation, and filesystem preflight errors so `ProgramRunner`, `IndexCommandRunner`, and query runners keep the same format. JSON error payloads continue to use `CommandErrorJsonResult`.

For JSON mode, recoverable non-database failures use the same versioned
`CommandErrorJsonResult` envelope. It requires `api_version`, `status`,
`message`, `hint`, `error_code`, `category`, `command`, `exit_code`, and
`usage`; command-specific fields may be merged only after paths, warnings, and
previews are sanitized and bounded. JSON failures write the envelope to stdout
and leave stderr empty. Human failures write the matching coded `Error`,
`Hint`, and `Usage` lines to stderr and leave stdout empty.

| Failure class | Exit code | Error code | Category |
|---|---:|---|---|
| Usage / invalid arguments | 1 or 7 | `E010_USAGE_ERROR` | `usage` |
| Missing outline path | 2 | `E019_FILE_NOT_FOUND` | `not_found` |
| Invalid configuration | 1 | `E024_CONFIG_INVALID` | `configuration` |
| Hook platform or filesystem failure | 9 | `E025_HOOK_OPERATION_FAILED` | `platform` |
| Hooks outside a Git repository | 2 | `E026_NOT_GIT_REPOSITORY` | `not_found` |
| Other recoverable command failure | command-specific | `E023_COMMAND_FAILED` | stable writer classification |

### Process launch policy

All production subprocess launch sites must use `ProcessStartInfo.ArgumentList` and must leave `UseShellExecute` disabled. Start-info construction belongs in `ProcessLaunchPolicy` or a nearby purpose-specific helper that calls it, so git, isolated workers, hook callbacks, installer dispatch, and other subprocesses share the same argument, encoding, and no-shell defaults.
Expand Down Expand Up @@ -3557,6 +3574,23 @@ validation、filesystem preflight error は `CommandErrorWriter` を使い、`Pr
`IndexCommandRunner`、query runner の形式を揃えてください。JSON error payload は
`CommandErrorJsonResult` を使い続けます。

JSON mode の回復可能な非データベース系失敗も、共通のバージョン付き
`CommandErrorJsonResult` envelope を使います。`api_version`、`status`、
`message`、`hint`、`error_code`、`category`、`command`、`exit_code`、
`usage` は必須です。command 固有 field を加える場合は、path、warning、preview を
sanitization し、上限を適用してから merge します。JSON の失敗は envelope を stdout に
出し、stderr を空に保ちます。human の失敗は対応する code 付き `Error`、`Hint`、
`Usage` を stderr に出し、stdout を空に保ちます。

| failure class | exit code | error code | category |
|---|---:|---|---|
| usage / 不正な引数 | 1 または 7 | `E010_USAGE_ERROR` | `usage` |
| outline path が見つからない | 2 | `E019_FILE_NOT_FOUND` | `not_found` |
| 不正な設定 | 1 | `E024_CONFIG_INVALID` | `configuration` |
| hook の platform / filesystem failure | 9 | `E025_HOOK_OPERATION_FAILED` | `platform` |
| Git repository 外での hooks 実行 | 2 | `E026_NOT_GIT_REPOSITORY` | `not_found` |
| その他の回復可能な command failure | command ごと | `E023_COMMAND_FAILED` | writer による安定した分類 |

### プロセス起動ポリシー

本番の subprocess 起動箇所はすべて `ProcessStartInfo.ArgumentList` を使い、`UseShellExecute` を無効のままにしてください。start-info の構築は `ProcessLaunchPolicy` またはそれを呼ぶ用途別 helper に置き、git、isolated worker、hook callback、installer dispatch、その他の subprocess が同じ argument、encoding、no-shell default を共有できるようにします。
Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,17 @@ versioned surfaces are the `cdidx` CLI, CLI JSON output, and `cdidx mcp`
JSON-RPC interface. There is no public library / SDK API. See
[INTEGRATION_POLICY.md](INTEGRATION_POLICY.md#api-surface-and-library-use).

## CLI JSON Error Contract

Recoverable non-database failures from commands such as `outline`, `hooks`,
`doctor`, and `validate-config` use one versioned JSON envelope. The envelope
includes `api_version`, `status`, `message`, `hint`, `error_code`, `category`,
`command`, `exit_code`, and `usage`, plus only sanitized optional context such
as `path`. JSON mode writes that envelope to stdout without human prose on
stderr. Human mode keeps the corresponding `Error`, `Hint`, and `Usage` lines.
See the [Developer Guide](DEVELOPER_GUIDE.md#cli-recoverable-error-format) for
the stable code/category mapping.

## Status JSON Contract

`cdidx status --json` exposes trust, freshness, compatibility, and remediation
Expand Down Expand Up @@ -612,6 +623,18 @@ commit し、構造化 `file_errors` を返して partial-result 終了コード
JSON-RPC interface です。公開 library / SDK API は提供していません。詳細は
[INTEGRATION_POLICY.md](INTEGRATION_POLICY.md#api-surface-and-library-use) を参照してください。

## CLI JSON エラー契約

`outline`、`hooks`、`doctor`、`validate-config` などの回復可能な
非データベース系失敗は、共通のバージョン付き JSON envelope を使います。
envelope には `api_version`、`status`、`message`、`hint`、`error_code`、
`category`、`command`、`exit_code`、`usage` を含め、`path` などの任意の
context は sanitization 済みの値だけを追加します。JSON mode は human 向け
prose を stderr に混ぜず、envelope を stdout に出力します。human mode は
対応する `Error`、`Hint`、`Usage` の各行を維持します。安定した code /
category 対応は
[開発者ガイド](DEVELOPER_GUIDE.md#cli-の回復可能エラー形式) を参照してください。

## Status JSON 契約

`cdidx status --json` は script、MCP client、release check 向けに trust、
Expand Down
4 changes: 4 additions & 0 deletions TESTING_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,8 @@ Use `docs/test-doc-maintenance-plan.md` before moving oversized suites or adding
Request-lifetime coverage keeps body-idle and correlated total-timeout configuration in that matrix. Use gated body streams for idle deadlines and bounded real TCP disconnects for queued and executing requests; assert queue removal, tool/DB cancellation, response closure, semaphore/body-budget cleanup, and health counters without fixed sleeps. Probe coverage must also keep chunked leading whitespace JSON-parseable after session establishment, prove the initial headerless `initialize` does not probe or commit headers before returning `Mcp-Session-Id`, and prove notifications retain `204 No Content` without starting a probe. Signal-gated non-cooperative output tests must prove probe shutdown and caller-cancelled SSE delivery keep their serialization gate until the started write settles, while a probe write timeout terminally cancels and cleans the queued request. Retained-resource coverage keeps a completed HTTP response's byte reservation charged until its supplied drain task finishes and proves a saturated replacement request is rejected in the interim.
- `McpServer*Tests.cs` request-lifetime cancellation coverage
Keep `maxConcurrency: 1` and signal-gated cancellation-ignoring isolated actions in both the sequential transport and concurrent stdio loops. The paired cancellation response may complete promptly, but the next normal request must not enter its delay hook until the detached action exits; the sequential probe transport must also observe the same incomplete completion task through `RetainCurrentRequestResourcesUntil` before the paired write.
- `CliNonDatabaseErrorContractTests.cs`
Table-driven empty, not-found, invalid-argument, invalid-config, and hook-platform failures. Keep JSON assertions focused on the stable versioned envelope and sanitized optional context, pair every scenario with its coded human `Error` / `Hint` / `Usage` form, and restore current-directory and hook filesystem seams after each case.
- `GitHelperTests.cs`, `GitProcessRunnerTests.cs`, `HookCommandRunnerTests.cs`
Git-specific behavior, including worktrees, commit-based updates, direct git process runner diagnostics, cancellation of git subprocesses, portable absolute executable overrides, and fail-closed metadata-write boundaries. Hook install coverage keeps `installed`, `updated`, and `already_installed` distinct, proves an exact executable UTF-8/no-BOM rerun preserves the hook write time, repairs non-executable and differently encoded managed hooks, and exercises dry-run create, managed replacement, custom-hook chain, blocked, and no-op plans without creating the missing hooks directory or changing either hook file. Keep executable-override fixtures owner-only-writable, owned by the current test user, under trusted ancestors (including an explicit root-owned sticky `/tmp` case), and able to return `git version` from `--version` unless the test is asserting a rejection reason. Symlinked `.git` directory/file, intermediate metadata components, hard-linked metadata files, worktree target, `commondir`, `info`, `exclude`, `hooks`, and hook-file coverage must prove resolution is rejected before metadata is written outside the project boundary. Tests that create real repositories or launch real/fake git subprocesses use `ExternalProcessFactAttribute` / `ExternalProcessTheoryAttribute` and run only on the `net8.0` test target; keep pure `.git` metadata parsing, trust diagnostics, and trusted-candidate enumeration cross-target. Timeout and cancellation wall-clock assertions should stay below the fake git scripts' natural completion while leaving room for macOS CI scheduling and process-cleanup overhead. Fake git scripts that run after commit-ref validation should echo the verified commit argument for `rev-parse --verify <ref>^{commit}` so timeout tests reach the intended git command.
- `WorkspaceMetadataEnricherTests.cs`
Expand Down Expand Up @@ -1459,6 +1461,8 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"
request-lifetime coverage では body-idle と相関する total-timeout 設定を同じ matrix に含めてください。idle deadline には gated body stream、queued / executing request には bounded な実 TCP disconnect を使い、固定 sleep に依存せず queue removal、tool / DB cancellation、response close、semaphore / body-budget cleanup、health counter を検証してください。probe coverage では session 確立後の chunked response が先頭空白を含めて JSON parse 可能なこと、最初の headerless `initialize` が probe や早期 header commit を行わず `Mcp-Session-Id` を返すこと、および notification が probe を開始せず `204 No Content` を維持することも確認してください。signal-gated な non-cooperative output test では、probe shutdown と caller-cancel 済み SSE delivery が開始済み write の終了まで serialization gate を保持し、probe write timeout が queued request を terminal に cancel して cleanup することを証明してください。retained-resource coverage では、完了済み HTTP response の byte reservation を supplied drain task の完了まで計上し続け、その間の replacement request が budget 飽和として拒否されることを確認してください。
- `McpServer*Tests.cs` の request-lifetime cancellation coverage
sequential transport と concurrent stdio loop の双方で `maxConcurrency: 1` と signal-gated な cancellation-ignoring isolated action を維持してください。対応する cancellation response は速やかに完了しても、detached action が終了するまで次の normal request が delay hook へ入ってはなりません。sequential probe transport は、対応 write より前に同じ未完了 completion task を `RetainCurrentRequestResourcesUntil` で観測することも検証してください。
- `CliNonDatabaseErrorContractTests.cs`
empty、not-found、不正な引数、不正な設定、hook platform failure を表駆動で検証します。JSON assertion は安定したバージョン付き envelope と sanitization 済みの任意 context に集中させ、各 scenario で code 付き human `Error` / `Hint` / `Usage` も対にして検証し、current directory と hook filesystem seam を各 case の後に復元してください。
- `GitHelperTests.cs`、`GitProcessRunnerTests.cs`、`HookCommandRunnerTests.cs`
worktree、commit ベース更新、direct git process runner diagnostics、git subprocess cancellation、portable な absolute executable override、fail-closed な metadata-write boundary を含む Git まわりのテスト。hook install coverage では `installed`、`updated`、`already_installed` を区別し、同一かつ実行可能な UTF-8/no-BOM の内容での再実行が hook の write time を維持すること、実行不可または異なる encoding の managed hook を修復すること、および dry-run の create、managed replacement、custom-hook chain、blocked、no-op plan が存在しない hooks directory を作成せず、どちらの hook file も変更しないことを検証します。executable override fixture は rejection reason 自体を検証する場合を除き owner-only-writable、test user 所有、trusted ancestor 配下(root 所有の sticky `/tmp` case を明示的に含む)とし、`--version` で `git version` を返せるようにします。symlinked `.git` directory / file、中間 metadata component、hard-linked metadata file、worktree target、`commondir`、`info`、`exclude`、`hooks`、hook file の coverage は、project boundary 外へ metadata を書く前に解決が拒否されることを証明してください。実 repo を作る、または real/fake git subprocess を起動するテストは `ExternalProcessFactAttribute` / `ExternalProcessTheoryAttribute` を使い、`net8.0` test target だけで実行します。純粋な `.git` metadata parsing、trust diagnostics、trusted-candidate enumeration は cross-target のままにしてください。Timeout と cancellation の wall-clock assertion は fake git script の自然完了より短く保ちつつ、macOS CI の scheduling や process cleanup の遅れを許容する余裕を持たせます。commit-ref validation 後に使う fake git script は `rev-parse --verify <ref>^{commit}` の検証対象 commit 引数を返し、timeout テストが意図した git command まで到達するようにします。
- `WorkspaceMetadataEnricherTests.cs`
Expand Down
Loading
Loading