Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .claude/skills/ci-gates/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12872,3 +12872,44 @@ What the check found is worth the file it took: four deliverables marked
2026-04-19, unnoticed for four and a half months. The rows now say *DELIVERED,
then removed in `91653d2b9`* rather than disappearing -- a dashboard that quietly
drops a deliverable is worse than one that says where it went.


## 482. The matcher was wrong inside the check of an exclusion made to avoid that

Last pass I excluded `docs/reports/**` from a new status-table check, and I did
it on an ARGUMENT: those are dated records of past waves, and a path that
existed then and not now is not a defect in a log. Good reasoning, no number.

This pass I went to measure it. First reading:

docs/reports/*.md 1569
carry a date or a wave tag in name or first lines 1506
carry NEITHER 63

Sixty-three undated reports would have meant the exclusion was hiding a real
population. It did not. **All 63 are named `WAVE_LOOP_NNN_*.md`** -- they name
their wave in the filename, and my pattern was `\bW\d{3}\b`, which does not match
`WAVE_LOOP_170`. Corrected: **1566 of 1569**, and the three exceptions are a
reported-upstream note, an open question, and a PR body -- none a status claim.

So the exclusion was right, and the check of it was wrong, in the way the check
existed to prevent. That is the whole entry: **the matcher that verifies your
matcher is a matcher.** There is no level at which the question stops being "what
does this pattern actually match" -- and the cheapest guard is the one that
worked here, printing the members rather than the count. Sixty-three filenames
all starting `WAVE_LOOP_` is instantly wrong to a reader and invisible in a
total.

Same hour, the other half of the discipline, and it produced no code. Extending
that status check from paths to code SYMBOLS looked obvious -- `PIN_COVERAGE.md`
names two Rust functions with zero definitions in the tree. Measured before
building: **8 table rows name a `fn()`, 5 "missing", 62%**. Reading the five,
`uart_tx_ready` is a `.t27` function that does exist and `quantize_groups` is an
RFC proposal. Eight rows spanning three languages and one proposal is not a
population. **The finding survives; the tool does not** -- and the 62% was the
signal, the same shape that had just been wrong twice.

Both numbers cost one command each. The argument they replaced cost nothing and
was worth nothing: one of the two turned out right and the other turned out to be
a detector nobody should build, and no amount of reasoning would have separated
them.
18 changes: 17 additions & 1 deletion docs/NUMERICS_VALIDATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,23 @@ Until filled, treat numeric behavior as **implementation-defined** outside confo

## 5. Differential oracle — skeleton results table

*Measured runs (host, sealed against the frozen codec revision `49e55df6` in `bootstrap/stage0/FROZEN_HASH`). Reference oracle = f64 round-trip `real -> format -> real`. Seed 2718281, 2,000,000 samples/distribution. Reproduce: `python repro/numerics/nmse_gf16.py --seal`.*
*Measured runs (host, sealed against codec revision `49e55df6`).*

> **`bootstrap/stage0/FROZEN_HASH` NO LONGER HOLDS `49e55df6`.** It holds
> `9b8875f1…` today, last changed 2026-09-03 by #3026. The seal above is the
> record of what was measured and stays as one; what was wrong is the present
> tense — the sentence asserted a current fact about that file. Re-running
> `python repro/numerics/nmse_gf16.py --seal` today seals against `9b8875f1…`,
> so a re-run is a NEW reading and not a reproduction of the table below.
> `repro/numerics/nmse_manifest.json` carries its own seal, `87e5cbd3…`, stamped
> 2026-07-16; three identifiers, and none of them is the one in FROZEN_HASH now.

*Reference oracle = f64 round-trip `real -> format -> real`. Seed 2718281,
2,000,000 samples/distribution. Reproduce:
`python repro/numerics/nmse_gf16.py --seal` — and see the note above about what
that reproduces.*

*Reference oracle = f64 round-trip `real -> format -> real`. Seed 2718281, 2,000,000 samples/distribution. Reproduce: `python repro/numerics/nmse_gf16.py --seal`.*

| Run ID | Format | Operation | Corpus | Reference oracle | Max abs err | ULP-like metric | Pass? | Artifact |
|--------|--------|-----------|--------|------------------|-------------|-----------------|-------|----------|
Expand Down
4 changes: 2 additions & 2 deletions docs/PUBLICATION_AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ theorem ids** (T482 highest; the results file runs to T628a).

### Blocker 1 — the silicon table is a single-placement measurement [high]

`TNF_ARTICLE_RU.md:309` publishes six post-route rows with $F_{\max}$ to two
`TNF_ARTICLE_RU.md:354` *(cited as :309; the file has moved -- the post-route rows are at :354 today)* publishes six post-route rows with $F_{\max}$ to two
decimals (161.11 / 153.23 / 131.73 / 83.27 / 53.26 / 33.23 MHz), plus 81.35 vs
147.32 MHz for the pipeline cut and 136.44 vs 131.73 for the $M{=}11$ choice.
The section says *"один стенд на всю линейку, чтобы строки были сопоставимы"* and
Expand All @@ -84,7 +84,7 @@ table reports a range or a median with the seed set named.

### Blocker 2 — the declared toolchain is not the bench's toolchain [high]

`TNF_ARTICLE_RU.md:305` declares **Yosys 0.65** and **nextpnr-xilinx 1743d0f**.
`TNF_ARTICLE_RU.md:340` *(cited as :305; the file has moved -- the Yosys 0.65 / nextpnr line is at :340 today)* declares **Yosys 0.65** and **nextpnr-xilinx 1743d0f**.
Measured on this bench 2026-08-18: **Yosys 0.63** (`70a11c6b`) and nextpnr
**c32135b0**. A reader following the article's own method on this repository gets
neither version.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# NOW -- A seal that names a hash the file no longer holds (2026-09-04)

## Two more from the docs sweep, and two tools measured and declined

- `docs/NUMERICS_VALIDATION.md` says its runs are *"sealed against the frozen
codec revision `49e55df6` in `bootstrap/stage0/FROZEN_HASH`"*. That file holds
**`9b8875f1…`** today, last changed **2026-09-03 by #3026** -- one of this
session's own PRs. Three identifiers are in play: the cited `49e55df6`, the
live `9b8875f1…`, and the manifest's own seal `87e5cbd3…` stamped 2026-07-16.
The seal stays as the record of what was measured; what was wrong was the
present tense asserting a current fact about the file.
- `docs/PUBLICATION_AUDIT.md` cites `TNF_ARTICLE_RU.md:305` and `:309`. The
Yosys line is at **:340**, the post-route rows at **:354**, and :309 is blank.
Line numbers as anchors, off by 35 and 45.
- **Measured and declined, first:** a `FILE:LINE` checker for docs. **43
citations, 0 missing files, 1 line past end-of-file** -- and that one is in
`docs/NOW.md`, which the pre-commit hook itself calls a frozen archive. One
hit in 43, in a record. No tool.
- **Measured and declined, second:** the "print the members, not the total" rule
I proposed last pass. The repository already does it: **39 python checks print
a count, 33 also print their members, and the six that do not are generators
and demos** -- `fuzz_trainer`, `gen_formats_catalog`, the `gft_*_demo` pair,
`run_conformance_vvp`. Not one is a check.
- That second number is the uncomfortable one. The three times a total hid a
matcher error this session -- 153 of 232, 63 of 1569, 5 of 8 -- were all in
**my own ad-hoc probes**, not in the repository's tools. The rule I was about
to propose to the repository is one the repository already keeps and I do not.
Loading