Skip to content

Commit 5d3d0bc

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix-issue4614
2 parents c2369d5 + 1083d20 commit 5d3d0bc

32 files changed

Lines changed: 1822 additions & 125 deletions

DEVELOPER_GUIDE.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2654,10 +2654,11 @@ Contract guarantees that callers and operators can rely on:
26542654

26552655
Contract guarantees that downstream consumers can rely on:
26562656

2657-
- **Field stability.** `timestamp`, `tool`, `arg_keys`, `arg_lengths`, `elapsed_ms`, `error_code` are emitted on every record. `caller`, `caller_version`, `request_id`, `request_id_type`, `request_id_length`, `request_id_truncated`, `arg_key_lengths`, `arg_keys_truncated`, `arg_key_truncation_reasons`, `arg_values`, `arg_values_redacted`, `arg_values_truncated`, `arg_values_truncation_reasons`, `arg_values_serialized_bytes`, `arg_values_max_bytes`, `result_count`, `error` are emitted only when non-null or true; renaming or repurposing any published field is a breaking change, the same policy as the CLI `--metrics` schema.
2657+
- **Field stability.** `timestamp`, `tool`, `arg_keys`, `arg_lengths`, `elapsed_ms`, `error_code` are emitted on every record. `caller`, `caller_version`, `request_id`, `request_id_type`, `request_id_length`, `request_id_truncated`, `arg_key_lengths`, `arg_keys_truncated`, `arg_key_truncation_reasons`, `arg_values`, `arg_values_redacted`, `arg_values_truncated`, `arg_values_truncation_reasons`, `arg_values_serialized_bytes`, `arg_values_max_bytes`, `result_count`, `checked_root_identity`, `error` are emitted only when non-null or true; renaming or repurposing any published field is a breaking change, the same policy as the CLI `--metrics` schema.
26582658
- **Request-id privacy.** `request_id` is the process-salted fixed-length token described above, never the JSON-RPC wire value. A present token is accompanied by `request_id_type` and the decoded-value `request_id_length`; the legacy truncation guard is normally absent because the token is already bounded.
26592659
- **Error code semantics.** `0` = success, `1` = MCP tool error (`isError: true`), negative = the verbatim JSON-RPC error code (e.g. `-32602` for invalid params, `-32603` for internal error). The companion `error` string is one of `jsonrpc_error`, `tool_error`, `missing_tool_name`, or the sanitized exception type name (`McpServer.BuildSanitizedToolErrorMessage` keeps `ex.Message` out of the wire and out of the audit, #1530).
26602660
- **Result count.** `ExtractResultCount` prefers `structuredContent.count` over `structuredContent.results.length`; tool errors and JSON-RPC errors omit the field. Tools that return no count-shaped payload (e.g. `ping`) leave `result_count` absent rather than emitting `0`.
2661+
- **MCP index root identity.** `index` resolves the requested root canonically, captures its platform filesystem identity, and retains a no-follow directory handle for the run. Directory enumeration is handle-relative on Linux, macOS, and Windows; the authorized filesystem seam compares each directory/file's pre-open identity, opened-handle identity, and post-open canonical containment before consuming content. Language-map and pattern sidecars are confined to the authorized project tree, opened through that seam, and cached in an authorization-scoped snapshot that excludes wider user configuration and executable workspace plugins. A root, ancestor, link, or entry identity change raises a bounded `permission_denied` tool error with `authorization_failure_reason`; successful/dry-run structured output and every post-authorization audit record carry the same fixed-length opaque `checked_root_identity`, even when the response was built by an error path. A containing repository root is used for ignore rules only when it remains authorized; otherwise discovery is confined to the requested project root.
26612662
- **Argument privacy.** `arg_keys` and `arg_lengths` are always recorded so query *shape* is recoverable, but argument-key count and displayed key length are capped and marked with `arg_keys_truncated`. `arg_values` is gated behind `--audit-log-include-values` because cdidx queries can carry literal source snippets or secret-shaped strings. The echo is a sanitized, budgeted clone: secret-like keys classified by the shared diagnostic/audit taxonomy and known token patterns are replaced with `[REDACTED]`, and depth, object-property, array-item, total-node, string-length, serialized-byte, and event-byte limits can mark `arg_values_truncated` before values are written.
26622663
- **Caller identity.** The published initialize snapshot captures the bounded client name/version from every successful `initialize.clientInfo` and replaces them on successful reconnection within the same session, so a long-running MCP loop with multiple accepted `initialize` handshakes attributes records to the *currently connected* client rather than the first one. Failed protocol negotiation never overwrites audit attribution or other session state (#4540).
26632664
- **Rotation.** Writes go through an open-append-close cycle so external `tail -F` consumers follow rotations and so the file is closed during the rename. When `_bytesWritten >= MaxBytes`, `RotateLocked` drops `<path>.(RotationKeep-1)` (currently `<path>.2`), cascades surviving slots up by one, and moves `<path>` to `<path>.1`. `RotationKeep = 3`, so `<path>.3` is never created — exercised by `AuditLogSinkTests.Record_KeepsAtMostThreeFiles_DropsOldestOnRotationOverflow`.
@@ -4950,10 +4951,11 @@ caller と operator が依存できる契約:
49504951

49514952
下流コンシューマが依存できる契約:
49524953

4953-
- **フィールドの安定性。** `timestamp`、`tool`、`arg_keys`、`arg_lengths`、`elapsed_ms`、`error_code` は全レコードで出力する。`caller`、`caller_version`、`request_id`、`request_id_type`、`request_id_length`、`request_id_truncated`、`arg_key_lengths`、`arg_keys_truncated`、`arg_key_truncation_reasons`、`arg_values`、`arg_values_redacted`、`arg_values_truncated`、`arg_values_truncation_reasons`、`arg_values_serialized_bytes`、`arg_values_max_bytes`、`result_count`、`error` は値が non-null または true のときだけ含める。既存フィールドの改名や流用は破壊的変更扱い(CLI `--metrics` と同じ運用)。
4954+
- **フィールドの安定性。** `timestamp`、`tool`、`arg_keys`、`arg_lengths`、`elapsed_ms`、`error_code` は全レコードで出力する。`caller`、`caller_version`、`request_id`、`request_id_type`、`request_id_length`、`request_id_truncated`、`arg_key_lengths`、`arg_keys_truncated`、`arg_key_truncation_reasons`、`arg_values`、`arg_values_redacted`、`arg_values_truncated`、`arg_values_truncation_reasons`、`arg_values_serialized_bytes`、`arg_values_max_bytes`、`result_count`、`checked_root_identity`、`error` は値が non-null または true のときだけ含める。既存フィールドの改名や流用は破壊的変更扱い(CLI `--metrics` と同じ運用)。
49544955
- **request id のプライバシー。** `request_id` は前述の process-salted な固定長 token で、JSON-RPC wire の値ではない。token がある場合は `request_id_type` と decode 後の値長を示す `request_id_length` を同伴する。token 自体がすでに bounded なため、legacy の truncation guard は通常付かない。
49554956
- **エラーコード意味論。** `0`=成功、`1`=MCP ツールエラー (`isError: true`)、負値=JSON-RPC エラーコードそのまま(例: invalid params なら `-32602`、internal error なら `-32603`)。同伴する `error` 文字列は `jsonrpc_error` / `tool_error` / `missing_tool_name` / サニタイズ済み例外型名のいずれか。`McpServer.BuildSanitizedToolErrorMessage` が `ex.Message` をワイヤーと audit から除外している(#1530)。
49564957
- **result count。** `ExtractResultCount` は `structuredContent.count` を優先し、無ければ `structuredContent.results.length`、いずれも無ければ省略する。ツールエラー / JSON-RPC エラー時も省略する(`0` ではなく欠落)。
4958+
- **MCP index の root identity。** `index` は要求された root を canonical に解決して platform filesystem identity を取得し、run 中は no-follow の directory handle を保持します。directory enumeration は Linux / macOS / Windows のすべてで handle-relative に行い、認可済み filesystem seam は各 directory / file の open 前 identity、実際に開いた handle identity、open 後の canonical containment を内容の利用前に照合します。language-map / pattern sidecar は認可済み project tree 内に限定して同じ seam から開き、より広い user 設定と executable workspace plugin を含まない authorization-scoped snapshot に cache します。root、ancestor、link、entry identity の変化時は上限付きの `permission_denied` tool error と `authorization_failure_reason` を返し、成功時/dry-run の structured output と、response が error path で生成された場合を含む認可後の全 audit record は同じ固定長 opaque `checked_root_identity` を保持します。包含 repository root は認可範囲内の場合だけ ignore rule に使い、範囲外なら discovery を要求 project root 内に限定します。
49574959
- **引数のプライバシー。** `arg_keys` / `arg_lengths` は常に記録するので呼び出しの *形状* は復元できるが、引数キー数と表示キー長は capped され `arg_keys_truncated` で明示される。`arg_values` は `--audit-log-include-values` に gated(cdidx クエリにはソース片や secret 風文字列が混入しうる)。echo は sanitize と budget を適用した clone として作り、diagnostic / audit 共有 taxonomy で分類された secret 風キーや既知 token pattern は `[REDACTED]` に置換し、depth / object property / array item / total node / string length / serialized byte / event byte の上限に達した場合は値を書き出す前に `arg_values_truncated` を記録する。
49584960
- **呼び出し元の特定。** 公開済み initialize snapshot は、成功した `initialize.clientInfo` の bounded な client name/version を保持し、同一セッション内で再 `initialize` が成功すれば置き換える。複数の受理済み handshake が走る長寿命 MCP ループでも、*現在接続中の*クライアントに対して記録が紐付く。protocol 交渉に失敗した initialize は audit attribution や他の session state を上書きしない(#4540)。
49594961
- **ローテーション。** 1 レコードごとに open-append-close する。外部 `tail -F` の追従と rename 時の close-state 維持のため。`_bytesWritten >= MaxBytes` を超えた時点で `RotateLocked` が `<path>.(RotationKeep-1)`(現在は `<path>.2`)を破棄し、生存スロットを 1 つ古い側へ寄せ、`<path>` を `<path>.1` へ移す。`RotationKeep = 3` なので `<path>.3` は決して生成されない(`AuditLogSinkTests.Record_KeepsAtMostThreeFiles_DropsOldestOnRotationOverflow` で常時検証)。

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,20 @@ rotation degrade MCP ping/health. Shutdown-only abandonment and deadline state
240240
are returned by the sink shutdown result and emitted in the bounded stderr
241241
diagnostic; they are not advertised as live MCP status after the server stops.
242242

243+
MCP `index` binds authorization to the canonical directory and filesystem
244+
identity captured before traversal and keeps a no-follow root handle for the
245+
run. Directory listings are performed relative to the retained directory handle
246+
on Linux, macOS, and Windows; file reads compare the pre-open identity, the opened
247+
handle identity, and post-open canonical containment. A link or identity change
248+
stops the run with a `permission_denied` tool error before content is read.
249+
Language-map and pattern sidecars are confined to the authorized project tree,
250+
opened through the same identity-bound seam, and cached separately from wider
251+
CLI/user configuration. Executable workspace plugins are not discovered by MCP
252+
indexing. Successful and dry-run structured results, and audit JSONL records for
253+
post-authorization failures, expose the same opaque `checked_root_identity` token.
254+
If a containing Git repository is outside the authorized roots, ignore-rule
255+
discovery stays at the requested project root instead of reading its parent.
256+
243257
When MCP rate limiting is enabled, every direct `tools/call` first consumes one
244258
caller-wide coarse bucket before detailed tool-name, enablement, and argument
245259
validation. Canonical known tool names additionally retain secondary per-tool
@@ -588,6 +602,18 @@ rotation degradation は MCP ping / health を degraded にします。shutdown
588602
abandoned count と deadline 状態は sink の shutdown result と上限付き stderr
589603
diagnostic で報告し、server 停止後に live MCP status として公開しません。
590604

605+
MCP `index` は走査前に取得した canonical directory と filesystem identity に
606+
認可を結び付け、run 中は no-follow の root handle を保持します。directory listing は
607+
Linux / macOS / Windows のすべてで保持中の directory handle を基準に行い、file read では
608+
open 前の identity、実際に開いた handle の identity、open 後の canonical containment を
609+
照合します。link または identity が変化した場合は内容を読む前に `permission_denied`
610+
tool error で処理を停止します。language-map / pattern sidecar は認可済み project tree 内に
611+
限定して同じ identity-bound seam から開き、より広い CLI / user 設定とは別 snapshot に
612+
cache します。MCP indexing では executable workspace plugin を探索しません。成功時と
613+
dry-run の structured result、および認可後に失敗した場合の audit JSONL record は、同じ
614+
opaque な `checked_root_identity` token を公開します。包含する Git repository が認可 root 外の
615+
場合、ignore-rule discovery は親を読まず、要求された project root 内に留まります。
616+
591617
MCP rate limiting が有効な場合、direct な `tools/call` request はすべて tool 名、
592618
enablement、argument の詳細検証前に caller-wide の coarse bucket を 1 つ消費します。
593619
canonical な既知 tool 名は secondary per-tool bucket も維持し、missing、malformed、

0 commit comments

Comments
 (0)