Report pins a branch drops and modules it leaves unsealed, without refusing either - #436
Merged
Merged
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Base automatically changed from
surface/416-pin-admission-and-egress
to
master
September 16, 2026 09:01
This was referenced Sep 16, 2026
Closed
lamemustafa
force-pushed
the
surface/416-coverage-report
branch
from
September 16, 2026 09:21
69ccd46 to
1e4b776
Compare
…ither bridge#416's second decision: report, and let a person decide. Rebuilt on master after #434's squash, and after two reviews. scripts/surface_coverage_report.py runs after every successful reseal.sh (not --verify) and never fails it. Against the merge-base with origin/master it lists a dropped pin, and a module declared directly by a pinned module and newly left unpinned -- a new file, a newly attached file, or one pinned at the base. What it does not check is stated where it will be read: in its all-clear line, its docstring, docs/release-process.md and the reseal.sh comment. Review showed the first wording ("code moved between existing files") named one blind spot and implied it was the only one. It also misses a new module under an unpinned parent even when carved out of a pinned file, deeper descendants, a pinned file that stops being compiled, a test-only or feature-gated module becoming production, and a new crate root. Module resolution follows rustc, walked from crate roots: a bare `mod` resolves beside a file that owns its directory (crate root, mod.rs, or declaring file. Review compared file sets, not just counts, with rustc's dep-info for every crate here and found them identical. The docstring lists the forms it does not handle, none of which occurs in the repo. Relative --surface paths now resolve against the caller's directory, and paths are compared as real paths: on macOS /tmp and /var are symlinks, and the first version reported a surface under a symlinked root as outside the repository. 32 tests, run against 34 mutations -- the 19 from the first version, and 15 more including every survivor review found -- and all 34 fail a test. Six needed the tests strengthened first: #[path] in an ordinary file (the shape agent.rs uses for nearly every agent_*.rs), inheritance of test-only and feature gates through a file, restricted visibility with a cfg, the new-file and pinned-at-base report clauses, a relative surface from a subdirectory, and an escaped quote in a char literal. docs/module-decomposition.md now points at the report and says what it does not catch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Inner #![cfg] does occur here, in five test files; none of them declares a module, which is the case the resolver does not handle. And the test file now says file sets, matching what the review compared, not counts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lamemustafa
force-pushed
the
surface/416-coverage-report
branch
from
September 16, 2026 09:30
8d2df85 to
ab5bde0
Compare
lamemustafa
added a commit
that referenced
this pull request
Sep 16, 2026
docs/proposed-rust-module-conventions.md item 2: extract inline test modules first -- mechanical, no production change. These were the two largest remaining inline test blocks among pinned production files: 1,951 lines in runtime.rs and 1,848 in connection.rs. Production lines are unchanged; the files drop to 3,490 and 2,024 lines. Each block moves to <stem>_tests.rs beside its parent, kept as the same child module (`#[cfg(test)] #[path = "..."] mod tests;`), so private access and test paths are unchanged, and relative include_str!/include_bytes! paths still resolve from the same directory. Checked, not asserted: - The moved bodies differ from the removed blocks only by four columns of indentation, compared against HEAD line by line. The eight multi-line string literals were left byte-identical rather than dedented, since their whitespace can be test data. - rustfmt then re-wrapped lines using the freed columns. Its only non-whitespace changes are four trailing commas; all 1,057 string literals are identical before and after. - Test names are identical before and after: 99 under default features, 110 with voucher-scan, which gates 11 of them. All pass under both. - cargo clippy --lib --tests -D warnings is clean. - Resealing changed exactly two pinned hashes, and the #436 coverage report counts exactly two newly unsealed test-only modules, listing nothing else. Unpinned test modules are the repository norm. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lamemustafa
added a commit
that referenced
this pull request
Sep 16, 2026
…ot by name #440, #441 and #442 moved inline `#[cfg(test)] mod tests { ... }` blocks into sibling files loaded by `#[cfg(test)] #[path = "..."] mod tests;`. check-tally-request-builder-hazards.mjs skipped only the inline form, so it began reading those files as production code. Results did not change, but a test that builds a hazard-shaped string as an expectation would have raised a false alarm. Skipping any file named *_tests.rs was rejected: a safety scanner must not exempt production code for its file name. Instead a file is skipped only when it is actually loaded as a test module: - Edges: a brace-depth-0 out-of-line `mod name;` whose attribute group has a cfg implying test (cfg(test), or test as an argument of cfg(all(...))), with #[path] or bare in a crate root or mod.rs; plus any such declaration made by a file already test-only, iterated to a fixed point. - Vetoes, from every .rs file in the repository and matched by basename case-insensitively: any other `mod name;` at any depth (including macro bodies and inline modules), any `path = "..."` or include!-family string not part of an edge (covering cfg_attr), and every Cargo crate root. - Files whose braces underflow or do not end balanced contribute no edges. - Everything unhandled -- cfg(any(...)), #[path] inside an inline module, r#name -- leaves the file scanned, so an error is a false alarm, never a missed hazard. The design was critiqued before implementation. The critique found four ways the first draft could skip a production file -- a non-test declaration it did not recognise, a Cargo target, a declaration outside the scan roots, case variants -- and that it would still have scanned 24 of the 74 extracted files: 22 declared by other test files, one under cfg(all(test, ...)), one bare in a mod.rs. The veto set, the fixed point and those two cfg/bare shapes are the response. Checked, not asserted: on this repository the skipped set is exactly the 74 files the rustc-validated module graph from #436 marks test-only, path for path; the 10 pinned violations are unchanged. The skipped count is now pinned too, so a lexer regression that quarantines too much fails the gate. Main now runs under `import.meta.main` so the functions can be imported; a test runs the real script as a child process so a main that silently does nothing cannot pass. 15 fixture tests; 15 mutations of the scanner (trust file names, accept any cfg mentioning test, drop each veto, trust unbalanced files, accept nested declarations, drop propagation, drop the crate-root veto, case-sensitive veto, #[path] under the stem, main never running, no bare-mod detection, strings or comments not skipped, only the first attribute, no raw-string path) each fail a named test. One of those first survived because a fixture's production declaration masked the lexer; the fixture was fixed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #416's second decision — report, don't refuse. Now a single commit on
master(after #434's squash and #437); nothing stacked.What it reports
scripts/surface_coverage_report.pyruns after every successfulreseal.sh(not--verify) and always exits 0. Against the merge-base withorigin/masterit lists:What it does not check — stated where it is read
In its all-clear line, docstring,
docs/release-process.mdand thereseal.shcomment: code moved between existing files; a new module under an unpinned parent, even one carved out of a pinned file; deeper descendants; a pinned file that stops being compiled; a test-only or feature-gated module becoming production; a new crate root. A clean report is not evidence nothing left the seal. The all-clear line says so.(The previous version named only the first blind spot, which implied it was the only one. Review found the rest.)
Module resolution
Follows rustc, walked from crate roots: a bare
modresolves beside a file that owns its directory (crate root,mod.rs,#[path]-loaded) and under<stem>/otherwise;#[path]resolves beside the declaring file. Review compared file sets — not only counts — with rustc's dep-info for every crate in the repo and found them identical. The docstring lists forms it does not handle (cfg_attrpath,r#names,include!, macro-generated modules, …); none occurs here.Tests: 32, against 34 mutations — all caught
The 19 from the first version plus 15 more, including every survivor review found. Six needed the tests strengthened before they failed:
#[path]in an ordinary file — the shapeagent.rsuses for nearly everyagent_*.rs;pub(crate)/pub(in …)with acfg;--surfacefrom a subdirectory;'\"'), which would otherwise open a string to end of file.Writing that last test exposed a real bug, fixed: on macOS
/tmpand/varare symlinks, and a surface under a symlinked root was reported as outside the repository.Verified locally
surface_coverage_report.test.py32/32 ·reseal.sh --verifyexit 0 ·reseal.test.mjs3 pass, 0 skipped ·check-ci-workflow-consistency.mjsexit 0 · hook's first real run: clean.Doesn't touch
MAX_SURFACE_FILESor the pin guard, so against #438 only the surface/matrix hashes need resealing, whichever lands second.🤖 Generated with Claude Code