The emitted-artifact check had no subject; now it has one - #2796
Merged
Conversation
…has one W702. `check_emitted` is the most thorough thing this gate does -- it compares every SSOT record against the emitted artifact, field by field. It has never run. `gen/` is in .gitignore, and aa01dd4 untracked those artifacts on purpose after they drifted (77 against an SSOT of 83). That left the check with nothing to read on every run since. It set r.emitted = Some("absent: gen/numeric/formats_catalog.json not generated") which is NOT a finding -- and the suite prints findings only. Measured: ZERO occurrences of "emitted artifacts" in the output of the command that gates master. A check that could not run said so where no one was looking. WHAT CHANGED. The generator is pure-stdlib Python, deterministic, and takes an output directory. When the artifact is absent the gate runs it into a temp dir and compares against that. A generator that cannot be found or that exits non-zero is a FINDING (`emitted-unreadable`), not a shrug. NOT A TAUTOLOGY, WHICH IS THE FIRST THING I CHECKED. Generating the thing you then compare against the source is usually comparing a file to itself. It is not here: `parse_records()` in this gate and `CATALOG_LINE` in the generator are two independent parsers of the same text. The comparison is two accounts of one source, which is the only reason it can disagree. SEEN FAILING, ON PURPOSE. Patching a COPY of the generator to write bits=999 for one record: [emitted-agrees] gf10: SSOT bits=10 but emitted bits=999 emitted artifacts: absent: ... not generated (before) emitted artifacts: 109 records, 436 numeric fields compared (after) Four hundred and thirty-six numeric fields, compared for the first time. The generator is found by walking UP from the catalog, not by counting directory levels: my first version computed `specs/tools/gen_formats_catalog.py` from `.parent().parent()` and reported a missing generator that was there all along. GATE FAILURES stays 2 -- the comparison passes. What changed is that it now runs. cargo test --no-fail-fast 2437 passed, 0 failed suite --ratchet RATCHET: CLEAN, exit 0 check_catalog_integrity.py exit 0 check_catalog_count.py exit 0 check_seal_coverage.py exit 0 check_specs_generate.py exit 0 check_elab_ratchet.py exit 0 check_withdrawn_live.py exit 0 Refs #2762 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
PR DashboardGenerated at: 2026-08-29 10:42:13 UTC
Summary
Seal Status
|
This was referenced Aug 29, 2026
W702, second half. Measured before: `t27c catalog-gate; echo $?` prints
`FINDINGS 3` and gives EXIT=0. The function's only terminator was `Ok(())`.
The CLI is where a human runs this gate by hand, and it was telling every one of
them that a run with three findings had succeeded. It now exits non-zero with the
same arithmetic the suite uses:
Error: 2 unexpected catalog finding(s) (1 allowed as debt)
The allowlist moved from a private const in suite.rs to `catalog_gate::ALLOWED`,
so the CLI and the suite cannot drift into disagreeing about which findings are
debt. One list, one meaning, read by both.
And its own `--help` said "whose 83 records live in structured comments". The
live number is 109 and has been since the three families were added -- a ruler
describing a smaller catalog than the one it measures.
Nothing in CI invokes this command, so the change cannot turn a workflow red; it
changes what a person at a terminal is told.
t27c catalog-gate exit 0 -> exit 1 (unchanged findings)
suite --ratchet RATCHET: CLEAN, GATE FAILURES 2 -- unmoved
cargo test --no-fail-fast 2437 passed, 0 failed
Refs #2762
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
PR DashboardGenerated at: 2026-08-29 10:57:58 UTC
Summary
Seal Status
|
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
PR DashboardGenerated at: 2026-08-29 11:15:10 UTC
Summary
Seal Status
|
Merged
This was referenced Aug 29, 2026
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.
Refs #2762
check_emittedis the most thorough thing the catalog gate does — it compares every SSOT record against the emitted artifact, field by field. It has never run.gen/is in.gitignore, andaa01dd4f1untracked those artifacts on purpose after they drifted (77 against an SSOT of 83). That left the check with nothing to read on every run since:which is not a finding — and the suite prints findings only. Measured: zero occurrences of
emitted artifactsin the output of the command that gates master. A check that could not run said so where no one was looking.What changed
The generator is pure-stdlib Python, deterministic, and takes an output directory. When the artifact is absent the gate runs it into a temp dir and compares against that. A generator that cannot be found, or that exits non-zero, is a finding (
emitted-unreadable), not a shrug.Not a tautology, which is the first thing I checked
Generating the thing you then compare against the source is usually comparing a file to itself. It is not here:
parse_records()in the gate andCATALOG_LINEin the generator are two independent parsers of the same text. The comparison is two accounts of one source, which is the only reason it can disagree.Seen failing, on purpose
Patching a copy of the generator to write
bits=999for one record:emitted artifacts: absent: … not generatedemitted artifacts: 109 records, 436 numeric fields comparedFour hundred and thirty-six numeric fields, compared for the first time.
The generator is found by walking up from the catalog, not by counting directory levels — my first version computed
specs/tools/gen_formats_catalog.pyfrom.parent().parent()and reported a missing generator that was there all along.GATE FAILURESstays 2: the comparison passes. What changed is that it runs.🤖 Generated with Claude Code