v0.41.51: bounded text arguments, truthful path and startup answers, review grading by effective visibility #580

Merged
buildagent merged 31 commits from integration-1112 into master 2026-11-12 20:47:07 +01:00
Member

Release train for v0.41.51. Four lanes, each reviewed from its diff and re-run by the lead, integrated on integration-1112.

What changes for a user

  • Text arguments are bounded (#575). Every string argument and every entry of a string list is limited to 8,192 characters; longer is refused with invalid_argument_value before any work. This removes the quadratic FTS5 cost of a very long search_text literal. A measured inventory of every text argument up to 1,048,576 characters found no other superlinear path.
  • No internal_error from caller text. The name-token fallback of search_symbols considers at most 512 tokens and discloses the rest; long path_glob/lang values and unrepresentable paths get structured answers. A test walks every string argument of the published tool list at the limit (113 arguments, 464 calls, no skips).
  • Missing paths (#578). read_code on a missing file in a missing directory answers file_not_readable (was path_outside_root). Containment is decided on the deepest existing ancestor after symlink resolution; .. and absolute components are refused lexically before that.
  • Review grading (#573). A deleted member is graded by the least visible of itself and its enclosing types; modules never lower a grade. summary.changed_files under path_glob counts the matched files, so the paging invariant holds with and without a filter.
  • Startup remedies (#576). index_coverage and three other replies advise a retry while the index is starting; restart advice remains for a degraded index.
  • Documentation (#527). docs/configuration.md (every .code-index.toml key and every environment variable the release binaries read, with a two-way key test); 32 false statements corrected in README.md, CONTRIBUTING.md and docs/.

Behaviour changes to call out

  • A string argument longer than 8,192 characters is refused. whole_word_needle_unsupported can no longer be reached through MCP.
  • review_diff with path_glob: summary.changed_files is the matched-file count.
  • A deleted row's visibility in changed_symbols/review_diff is the effective visibility.
  • read_code on a dangling symbolic link answers path_outside_root (the last release answered file_not_readable for a dangling last component).

Lead review

  • r25 changed a deleted row's wire visibility to the member's own value; restored to the effective value the release reports for locals and destructors, extended to the new rule (d507b67b, mutation run red).
  • r24's first batch semantics (per-entry refusal) became a whole-call refusal with the generic rule; accepted as a schema violation of the argument, with the entry index added.
  • The path rewrite was read for traversal: lexical refusal of ../absolute/prefix components precedes the ancestor walk, an existing leaf is fully canonicalized, and the symlink cases have tests with a lexical-only mutation.
  • #577 (file-level #[test] graded as untested production) was investigated and is not fixable in the host: packages do not emit attributes. Left open with the analysis.

Qualification

One full gate run on the integrated tree (5d31f4d9, 44 steps, 15:33–18:27): formatting, fast gates, clippy for the host and for x86_64-pc-windows-gnu, rustdoc with warnings denied, the workspace suite and its timing profile, doctests, the MCP suite on the daemon leg and its timing profile, precision_gate (7/7, populations printed), the corpus suites as CI runs them, the eleven package legs, scale and tier-3 corpus, the packages-only and shipped-shape acceptance runs, and the nightly-only cost and benchmark steps.

  • 42 steps passed. No record moved: tests/corpus/*.json, tests/bench/ratchet.json and the package parity files are unchanged.
  • 2 steps failed, both on tests added in this train, both fixed in their own commits and re-run green:
    • every_wall_clock_bound_runs_alone (fast gates and workspace): the new length-refusal test asserts a wall-clock bound and was missing from the nextest timing profile (8c2c374b). Re-run: the registry test passes, the default profile lists 15 fewer MCP tests, and the test passes under the timing profile on both legs.
    • no_resolved_edge_crosses_an_undeclared_crate_boundary (workspace): the new configuration reference test used a type parameter V, and V::Value was bound to a function-local struct V in crates/mcp-server/src/server.rs. This is a resolver defect the last release already has, filed as #579. The test's type parameter is renamed (5c2c347a); the resolver is unchanged. Re-run: the layering test passes.
  • After the gate, the push security review flagged the rewritten safe_resolve: it skipped any component canonicalize reported as missing or unrepresentable, which includes a dangling link and a link chain that musl or macOS realpath refuses to expand while the kernel follows it. It now skips only components that symlink_metadata proves absent (fb6f6026). Not reproducible with this machine's glibc; fixed because the release ships a musl build. Tests: 4 unit and 152 e2e on each leg, clippy for both targets, mutation red on the unit test and on working_tree_symlink_escapes_stay_private.
  • Windows behaviour is covered by CI only.

Not in this train

  • #577 (needs a per-symbol test marker from the language packages).
  • #579: a generic parameter used as a qualifier can bind to a function-local type elsewhere (found by this gate; needs a bind account).
  • #570: six no-effect configuration keys and six test timing hooks read by release binaries (documented, not changed).
  • The resolver and extraction themes (#531, #535, #536, #538, #540, #543, #545 guest side, #566 residual).

🤖 Generated with Claude Code

https://claude.ai/code/session_014XLNPtTbPwnHBYfKMb3f1W

Release train for v0.41.51. Four lanes, each reviewed from its diff and re-run by the lead, integrated on `integration-1112`. ## What changes for a user - **Text arguments are bounded (#575).** Every string argument and every entry of a string list is limited to 8,192 characters; longer is refused with `invalid_argument_value` before any work. This removes the quadratic FTS5 cost of a very long `search_text` literal. A measured inventory of every text argument up to 1,048,576 characters found no other superlinear path. - **No `internal_error` from caller text.** The name-token fallback of `search_symbols` considers at most 512 tokens and discloses the rest; long `path_glob`/`lang` values and unrepresentable paths get structured answers. A test walks every string argument of the published tool list at the limit (113 arguments, 464 calls, no skips). - **Missing paths (#578).** `read_code` on a missing file in a missing directory answers `file_not_readable` (was `path_outside_root`). Containment is decided on the deepest existing ancestor after symlink resolution; `..` and absolute components are refused lexically before that. - **Review grading (#573).** A deleted member is graded by the least visible of itself and its enclosing types; modules never lower a grade. `summary.changed_files` under `path_glob` counts the matched files, so the paging invariant holds with and without a filter. - **Startup remedies (#576).** `index_coverage` and three other replies advise a retry while the index is starting; restart advice remains for a degraded index. - **Documentation (#527).** `docs/configuration.md` (every `.code-index.toml` key and every environment variable the release binaries read, with a two-way key test); 32 false statements corrected in `README.md`, `CONTRIBUTING.md` and `docs/`. ## Behaviour changes to call out - A string argument longer than 8,192 characters is refused. `whole_word_needle_unsupported` can no longer be reached through MCP. - `review_diff` with `path_glob`: `summary.changed_files` is the matched-file count. - A deleted row's `visibility` in `changed_symbols`/`review_diff` is the effective visibility. - `read_code` on a dangling symbolic link answers `path_outside_root` (the last release answered `file_not_readable` for a dangling last component). ## Lead review - r25 changed a deleted row's wire `visibility` to the member's own value; restored to the effective value the release reports for locals and destructors, extended to the new rule (`d507b67b`, mutation run red). - r24's first batch semantics (per-entry refusal) became a whole-call refusal with the generic rule; accepted as a schema violation of the argument, with the entry index added. - The path rewrite was read for traversal: lexical refusal of `..`/absolute/prefix components precedes the ancestor walk, an existing leaf is fully canonicalized, and the symlink cases have tests with a lexical-only mutation. - #577 (file-level `#[test]` graded as untested production) was investigated and is not fixable in the host: packages do not emit attributes. Left open with the analysis. ## Qualification One full gate run on the integrated tree (`5d31f4d9`, 44 steps, 15:33–18:27): formatting, fast gates, clippy for the host and for `x86_64-pc-windows-gnu`, rustdoc with warnings denied, the workspace suite and its timing profile, doctests, the MCP suite on the daemon leg and its timing profile, `precision_gate` (7/7, populations printed), the corpus suites as CI runs them, the eleven package legs, scale and tier-3 corpus, the packages-only and shipped-shape acceptance runs, and the nightly-only cost and benchmark steps. - 42 steps passed. No record moved: `tests/corpus/*.json`, `tests/bench/ratchet.json` and the package parity files are unchanged. - 2 steps failed, both on tests added in this train, both fixed in their own commits and re-run green: - `every_wall_clock_bound_runs_alone` (fast gates and workspace): the new length-refusal test asserts a wall-clock bound and was missing from the nextest timing profile (`8c2c374b`). Re-run: the registry test passes, the default profile lists 15 fewer MCP tests, and the test passes under the timing profile on both legs. - `no_resolved_edge_crosses_an_undeclared_crate_boundary` (workspace): the new configuration reference test used a type parameter `V`, and `V::Value` was bound to a function-local `struct V` in `crates/mcp-server/src/server.rs`. This is a resolver defect the last release already has, filed as #579. The test's type parameter is renamed (`5c2c347a`); the resolver is unchanged. Re-run: the layering test passes. - After the gate, the push security review flagged the rewritten `safe_resolve`: it skipped any component `canonicalize` reported as missing or unrepresentable, which includes a dangling link and a link chain that musl or macOS `realpath` refuses to expand while the kernel follows it. It now skips only components that `symlink_metadata` proves absent (`fb6f6026`). Not reproducible with this machine's glibc; fixed because the release ships a musl build. Tests: 4 unit and 152 e2e on each leg, clippy for both targets, mutation red on the unit test and on `working_tree_symlink_escapes_stay_private`. - Windows behaviour is covered by CI only. ## Not in this train - #577 (needs a per-symbol test marker from the language packages). - #579: a generic parameter used as a qualifier can bind to a function-local type elsewhere (found by this gate; needs a bind account). - #570: six no-effect configuration keys and six test timing hooks read by release binaries (documented, not changed). - The resolver and extraction themes (#531, #535, #536, #538, #540, #543, #545 guest side, #566 residual). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_014XLNPtTbPwnHBYfKMb3f1W
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014XLNPtTbPwnHBYfKMb3f1W
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014XLNPtTbPwnHBYfKMb3f1W
changed_symbols reported the member's own visibility for a deleted
symbol while review_diff graded it by the least visible enclosing type,
and the release's file-visible value for locals and destructors was
lost. The row now carries the effective value in both cases.

Mutation run: reporting the member's own visibility fails
deleted_members_obey_type_visibility and
deleted_container_visibility_uses_recorded_rows.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014XLNPtTbPwnHBYfKMb3f1W
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014XLNPtTbPwnHBYfKMb3f1W
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014XLNPtTbPwnHBYfKMb3f1W
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014XLNPtTbPwnHBYfKMb3f1W
text_query_length_refusal_is_bounded_before_dispatch asserts a wall-clock
bound, so every_wall_clock_bound_runs_alone requires it in the ci-timing
profile and out of the default ci run.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014XLNPtTbPwnHBYfKMb3f1W
test: rename a type parameter that the resolver bound across crates
Some checks failed
Package CI / package-corpus (rust) (pull_request) Successful in 3s
Package CI / package-corpus (php) (pull_request) Successful in 5s
Package CI / package-corpus (vue) (pull_request) Successful in 3s
Package CI / package-corpus (javascript) (pull_request) Successful in 5s
Package CI / package-corpus (svelte) (pull_request) Successful in 3s
Package CI / package-corpus (typescript) (pull_request) Successful in 3s
Package CI / package-corpus (timeline) (pull_request) Successful in 3s
Package CI / package-corpus (python) (pull_request) Successful in 5s
Package CI / package-corpus (xaml) (pull_request) Successful in 2s
Package CI / package overhead budgets (nightly, one package at a time) (pull_request) Has been skipped
CI / cargo fmt (pull_request) Successful in 31s
CI / OSS corpus tier-3 scale (nightly) (pull_request) Has been skipped
CI / Grammar rebuild from source (nightly) (pull_request) Has been skipped
Pilot plugin compatibility / Fetch the pinned runtime once (pull_request) Successful in 18s
Pilot plugin compatibility / Pilot compatibility (csharp) (pull_request) Successful in 26s
CI / guest crates (fmt, clippy, doc) (pull_request) Successful in 33s
Pilot plugin compatibility / Pilot compatibility (timeline) (pull_request) Successful in 32s
Pilot plugin compatibility / Pilot compatibility result (pull_request) Successful in 1s
CI / CI lane wall-clock headroom (pull_request) Successful in 1m0s
CI / cargo doc (intra-doc links) (pull_request) Successful in 5m23s
CI / cargo deny (pull_request) Successful in 5m57s
CI / cargo clippy (pull_request) Successful in 6m42s
CI / cargo check (MSRV 1.99.1) (pull_request) Successful in 8m21s
CI / cargo check (windows-gnu) (pull_request) Successful in 8m42s
CI / cargo test (abi, 32-bit + wasm32) (pull_request) Successful in 8m48s
CI (Windows) / fmt + clippy + build + test (windows) (pull_request) Has been cancelled
CI / cargo test (daemon transport) (pull_request) Has been cancelled
CI / Plugin path cost + pool throughput (nightly) (pull_request) Has been cancelled
CI / cargo test (pull_request) Has been cancelled
CI / OSS corpus (tier 1) (pull_request) Has been cancelled
5c2c347ae2
`V::Value` in the configuration reference test resolved to the
function-local `struct V` in crates/mcp-server/src/server.rs (tier1q),
which no_resolved_edge_crosses_an_undeclared_crate_boundary reports as two
phantom edges. The resolver defect is tracked in #579; the test no longer
triggers it.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014XLNPtTbPwnHBYfKMb3f1W
fix(read_code): skip only path components proven absent
All checks were successful
Package CI / package-corpus (python) (pull_request) Successful in 3s
Package CI / package-corpus (php) (pull_request) Successful in 4s
Package CI / package-corpus (ruby) (pull_request) Successful in 5s
Package CI / package-corpus (timeline) (pull_request) Successful in 3s
Package CI / package-corpus (rust) (pull_request) Successful in 6s
Package CI / package-corpus (typescript) (pull_request) Successful in 5s
Package CI / package-corpus (svelte) (pull_request) Successful in 6s
Package CI / package-corpus (vue) (pull_request) Successful in 3s
Package CI / package-corpus (xaml) (pull_request) Successful in 3s
Package CI / package overhead budgets (nightly, one package at a time) (pull_request) Has been skipped
CI / cargo fmt (pull_request) Successful in 50s
CI / OSS corpus tier-3 scale (nightly) (pull_request) Has been skipped
CI / Grammar rebuild from source (nightly) (pull_request) Has been skipped
Pilot plugin compatibility / Fetch the pinned runtime once (pull_request) Successful in 29s
Pilot plugin compatibility / Pilot compatibility (csharp) (pull_request) Successful in 32s
Pilot plugin compatibility / Pilot compatibility (timeline) (pull_request) Successful in 39s
Pilot plugin compatibility / Pilot compatibility result (pull_request) Successful in 1s
CI / guest crates (fmt, clippy, doc) (pull_request) Successful in 54s
CI / CI lane wall-clock headroom (pull_request) Successful in 1m7s
CI / cargo doc (intra-doc links) (pull_request) Successful in 7m40s
CI / cargo deny (pull_request) Successful in 8m32s
CI / cargo clippy (pull_request) Successful in 9m11s
CI / cargo check (MSRV 1.99.1) (pull_request) Successful in 11m51s
CI / cargo test (abi, 32-bit + wasm32) (pull_request) Successful in 11m55s
CI / cargo check (windows-gnu) (pull_request) Successful in 12m21s
CI / OSS corpus (tier 1) (pull_request) Successful in 1h2m36s
CI (Windows) / fmt + clippy + build + test (windows) (pull_request) Successful in 1h10m34s
CI / cargo test (pull_request) Successful in 1h22m28s
CI / cargo test (daemon transport) (pull_request) Successful in 10m55s
CI / Plugin path cost + pool throughput (nightly) (pull_request) Has been skipped
fb6f60261c
safe_resolve walked up to the parent whenever canonicalize reported a
component as missing or unrepresentable. An entry that exists but does not
canonicalize is not missing: a dangling link, or a link chain the C library
refuses to expand (musl and macOS bound realpath by PATH_MAX) while the
kernel would still follow it on open. Such a path was then returned as
contained. A component is now skipped only when symlink_metadata proves
nothing is there; anything else is refused.

A dangling link inside the root therefore answers path_outside_root; the
last release answered file_not_readable for a dangling leaf.

Found by the push security review of this branch. Mutation (skip every
uncanonicalizable entry) fails
safe_resolve_refuses_an_existing_entry_it_cannot_canonicalize and
working_tree_symlink_escapes_stay_private.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014XLNPtTbPwnHBYfKMb3f1W
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
h-dv/code-index!580
No description provided.