Fix: two spec-discovery defects that understate coverage and invent drift - #19
Merged
Merged
Conversation
β¦rift `load_specs` applied `SKIP_DIRS` below the `specs/` root. That list holds build and vendor directory *names*, and a spec module is named after what it governs, so `specs/out/`, `specs/build/`, `specs/target/` and `specs/coverage/` were all undiscoverable: the spec was never parsed and every file it governed was reported as an orphan. Found on a project whose `specs/out/out.spec.md` was invisible, understating its coverage by 1,252 lines and putting "write a spec for src/out.rs" at the top of its action plan. The walk now carries an `in_specs` flag and prunes only dot-directories below that point; a `.spec.md` a build copied into `out/` is still skipped, so the list is scoped rather than disabled. `enrich_drift` scraped verdicts out of the report's raw text: find the first `"<module>"` anywhere in the document, take the next 240 bytes, report the first verdict word in them. Three things were wrong with that. The name matched inside any string, so the window often described a different spec. The window ran past the end of the entry, so the *last* spec in `specs` picked up the following top-level key β `"stale": []` marked it stale, a needs-review flag on a spec that is in sync. And `out[pos..pos + 240]` panics outright when the cut lands inside a multi-byte character. It now parses the JSON and matches a module by its `specs` entry or by name in `stale`. Seven regression tests, and the engine spec's Public API table, invariant 4 and a new invariant 4a record both rules. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5 tasks done
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.
Summary
Two defects in
crates/atlas-cli/src/main.rs, both found while taking a real project from a reported 64% to 100%. Between them they understated that project's coverage by 1,252 lines and put a spec that already existed at the top of its action plan.load_specsappliedSKIP_DIRSbelow thespecs/root. That list holds build and vendor directory names, and a spec module is named after what it governs β sospecs/out/,specs/build/,specs/target/andspecs/coverage/were never parsed, and every file they governed was reported as an orphan. The walk now carries anin_specsflag and prunes only dot-directories below that point. The list is scoped, not disabled: a.spec.mda build copied intoout/is still skipped.enrich_driftscraped verdicts out of the report's raw text. It found the first"<module>"anywhere in the document, took the next 240 bytes, and reported the first verdict word in them. The name matched inside any string, so the window often described a different spec; the window ran past the end of the entry, so the last spec inspecspicked up the following top-level key and"stale": []marked it stale β a needs-review flag on a spec that is in sync; andout[pos..pos + 240]panics outright when the cut lands inside a multi-byte character. It now parses the JSON and matches a module by itsspecsentry or by name instale.The WASM engine already collected
.spec.mdfrom anywhere without the skip list, so this narrows a pre-existing divergence between the two engines rather than creating one.specs/engine/engine.spec.mdrecords both rules: theload_specsrow in the Public API table, an extension to invariant 4, and a new invariant 4a for reading drift as JSON.Test Plan
fledge lanes run verifyβ fmt, lint, test, build, wasm-test, wasm-build, all greenatlas-cli, 26 inatlas-core, 0 failures)load_specs_finds_a_module_named_after_a_build_directoryβout,build,dist,target,coverageand a control module are all discoveredload_specs_still_skips_a_build_tree_outside_specsβ a.spec.mdunderout/,node_modules/ortarget/is not adoptedthe_last_spec_in_a_report_is_not_made_stale_by_the_next_keyβ the false positive that started thisa_module_named_in_the_stale_list_is_staleβ bare name,{name}object, and{path}objectan_explicit_verdict_on_the_module_s_own_entry_is_reporteda_module_name_appearing_in_another_spec_s_entry_is_not_its_verdicta_report_carrying_multibyte_text_does_not_panicβ the old slice would have panickeda_report_that_is_not_json_is_ignored_rather_than_guessed_at64%/ 4 orphans / one falseneeds_reviewto100%/ 0 orphans / 0needs_review; this repo stayshealthywith no new review flagsπ€ Generated with Claude Code