From 58054af34ec874e9ccc9fb9a386db879dd989926 Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Fri, 4 Sep 2026 07:11:48 +0700 Subject: [PATCH 1/3] docs: four justifications whose subjects are gone Closes #3082 PIN_COVERAGE.md lists xdc_qmtech_minimal() and xdc_qmtech_full() as "Rust pin definitions". grep says 0 definitions in the tree: added 1911edc80 (2026-04-09) with the gen-xdc command, removed 692ba5263 (2026-04-14), and the subcommand went with them. CORPUS-RATCHET.md justifies excluding specs/scratch/ as "606,113,688 of 612,924,235 bytes (98.89%)". That directory has been out of the tree since 2255e4c32 -- 0 files in the index, absent from disk -- so the exclusion excludes nothing and the saving it claims was banked by the untracking, not by the filter. The untracking commit puts the same exclusion at 64.5% where this line puts it at 98.89%: two numbers for one subject, and neither re-takable now. The filter is kept; it costs nothing and makes the exclusion explicit if the directory returns. NUMERIC_FORMATS_83_METRICS.md cites gen/numeric/formats_catalog.json (77 formats) as a data source. That file was deleted by aa01dd4f1 -- "untrack stale gen/numeric catalog artifacts (drift 77 vs SSOT 83)". It was removed FOR being 77 against 83, and the document still publishes 77 and points at it. The re-takable source is the catalog itself, at 109 records today. SYNTH_REPORT.md declares every figure measured with yosys 0.65; `yosys -V` on the bench reports 0.68+post, and the file was last touched 2026-08-06 with no date of its own. Not re-measured here -- that needs a run, not an edit -- but a resource figure is a reading of an instrument, and the instrument is named beside the numbers now. Two measurements that produced no code, recorded because they cost the same either way. Extending the new status-table check from paths to code SYMBOLS: declined. 8 rows name a `fn()`, 5 "missing", 62% -- and the population is contaminated, since uart_tx_ready is a .t27 function that exists and quantize_groups is an RFC proposal. And the exclusion of docs/reports/** from that check, which I made by argument last pass: confirmed by measurement, 1566 of 1569 name a wave, ring or date. My first attempt at that measurement said 63 undated and was wrong, because `W\d{3}` does not match `WAVE_LOOP_170`. --- docs/CORPUS-RATCHET.md | 16 ++++++--- docs/SYNTH_REPORT.md | 11 ++++++- docs/fpga/PIN_COVERAGE.md | 4 +-- docs/metrics/NUMERIC_FORMATS_83_METRICS.md | 12 +++++++ ...stifications-for-subjects-that-are-gone.md | 33 +++++++++++++++++++ 5 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 docs/now/2026-09-04-two-justifications-for-subjects-that-are-gone.md diff --git a/docs/CORPUS-RATCHET.md b/docs/CORPUS-RATCHET.md index ecd5efc6f..ca355807e 100644 --- a/docs/CORPUS-RATCHET.md +++ b/docs/CORPUS-RATCHET.md @@ -96,10 +96,18 @@ PY Read this before trusting a green run. -- **Only the hand-written corpus.** `specs/scratch/` is excluded — 606,113,688 - of 612,924,235 bytes (98.89%), generator output the ledger does not gate on. - That exclusion is what makes the check 314 s instead of 4057 s with a - bit-identical verdict. +- **Only the hand-written corpus.** `specs/scratch/` is excluded — and since + `2255e4c32` (*"chore(specs): untrack specs/scratch — 455 files, 578 MB, 64.5% + of the tree"*, #2283) **that directory is not in the tree at all**: 0 files in + the index, absent from disk. The exclusion excludes nothing today, and the + saving it was written to justify — "314 s instead of 4057 s" — was banked by + the untracking, not by the filter. The corpus the ratchet walks is **650 files + / 7,030,194 bytes** as of this note; the 606,113,688-of-612,924,235 figure + described a tree that no longer exists. Note also that the untracking commit + puts the same exclusion at **64.5%** where this line put it at **98.89%** — + two numbers for one subject, and neither is re-takable now. + The filter itself is kept: it costs nothing and it is what makes the + exclusion explicit if the directory ever comes back. - **Only the phases `suite` runs**: `parse`, `parse-no-discard`, `typecheck`, `gen-zig`, `gen-rust`, `gen-verilog`, `gen-c`, `seal-verify`, plus the smoke gates. `lex-dropped` is not among them. diff --git a/docs/SYNTH_REPORT.md b/docs/SYNTH_REPORT.md index 659eb26f4..a3279dfa6 100644 --- a/docs/SYNTH_REPORT.md +++ b/docs/SYNTH_REPORT.md @@ -1,11 +1,20 @@ # Spec-first ternary stack — synthesis report (Artix-7) Real FPGA resource cost of the spec-first ternary hardware designs, measured with -**yosys 0.65 `synth_xilinx`** (the AX7203 / Artix-7 XC7A200T family — the same +**yosys 0.65 `synth_xilinx`** *(the instrument as measured; the bench now runs +0.68+post — see the note below)* (the AX7203 / Artix-7 XC7A200T family — the same flow openXC7 uses, no Vivado). Every design is generated from a `.t27` spec by `t27c gen-verilog` — no hand-written RTL — and is functionally cross-checked in iverilog against an independent reference (see `bootstrap/tests/*.rs`). +> **THE INSTRUMENT HAS MOVED SINCE THESE NUMBERS WERE TAKEN.** Every figure in +> this report was produced by **yosys 0.65**; `yosys -V` on the bench today +> reports **0.68+post**. This document was last touched 2026-08-06 and carries no +> date of its own, so it reads as current. It is not being re-measured here -- +> that needs a run, not an edit -- but a resource figure is a reading of an +> instrument, and the instrument is named now rather than implied. Anyone +> quoting a LUT count from this file should say "yosys 0.65" beside it. + ## Why this report exists Until this was measured, the stack was only ever **simulated** (iverilog). But diff --git a/docs/fpga/PIN_COVERAGE.md b/docs/fpga/PIN_COVERAGE.md index 59933419b..f1816eb5e 100644 --- a/docs/fpga/PIN_COVERAGE.md +++ b/docs/fpga/PIN_COVERAGE.md @@ -131,8 +131,8 @@ Option A is recommended: reduces MISSING pins from 35 to 28 while preserving har | `specs/fpga/constraints/arty_a7.xdc` | Arty A7 XDC constraints | | `specs/pins/ir.t27` | Pins IR data model | | `specs/pins/emitter_xdc.t27` | XDC emitter from Pins IR | -| `bootstrap/src/main.rs` `xdc_qmtech_minimal()` | Rust pin definitions (minimal) | -| `bootstrap/src/main.rs` `xdc_qmtech_full()` | Rust pin definitions (full) | +| ~~`bootstrap/src/main.rs` `xdc_qmtech_minimal()`~~ | **GONE.** Added `1911edc80` (2026-04-09, `gen-xdc`), removed `692ba5263` (2026-04-14). | +| ~~`bootstrap/src/main.rs` `xdc_qmtech_full()`~~ | **GONE**, same two commits. `grep -rn 'fn xdc_qmtech' --include='*.rs'` is 0, and the `gen-xdc` subcommand went with them. | ## Tracking diff --git a/docs/metrics/NUMERIC_FORMATS_83_METRICS.md b/docs/metrics/NUMERIC_FORMATS_83_METRICS.md index 21737ce3d..dae42ef34 100644 --- a/docs/metrics/NUMERIC_FORMATS_83_METRICS.md +++ b/docs/metrics/NUMERIC_FORMATS_83_METRICS.md @@ -4,6 +4,18 @@ Дата сборки: 28.06.2026. Источники данных: - Метрики (биты, S/E/M, bias, кластер, статус, назначение): `gen/numeric/formats_catalog.json` (77 форматов) + `specs/numeric/gf{10,14,48,96,512,1024}.t27` (6 GF-форматов, отсутствующих в JSON-каталоге). + +> **ИСТОЧНИК НЕДОСТУПЕН, И УДАЛЁН ИМЕННО ЗА ЭТУ ЦИФРУ.** +> `gen/numeric/formats_catalog.json` убран коммитом `aa01dd4f1` — +> *"fix(gen): untrack stale gen/numeric catalog artifacts (**drift 77 vs SSOT +> 83**) (Closes #1120)"*. То есть файл выкинули за расхождение 77 против 83, а +> этот документ до сих пор ссылается на него как на источник и печатает **77**. +> `gen/` в `.gitignore`, файл не восстанавливается из рабочего дерева. Цифру 77 нельзя +> перевзять по названному источнику. Первоисточник, который МОЖНО перевзять без +> сборки, — сам каталог: `grep -c 'CATALOG:' specs/numeric/formats_catalog.t27` +> даёт **109** записей сегодня (83 на момент W602, 92 после `08adcc39f`, 109 +> после `b92872507`). Таблица ниже — снимок 28.06.2026 и читается как запись, а +> не как текущее состояние. - SW-conformance (kind, n_vectors): `conformance/vectors/INDEX_all_formats.json`. - HW-статус: реальные прогоны на плате AX7203 (XC7A200T) в сессии 28.06.2026. - Якорь тождества: φ² + φ⁻² = 3. Препринт: arXiv:2606.05017. diff --git a/docs/now/2026-09-04-two-justifications-for-subjects-that-are-gone.md b/docs/now/2026-09-04-two-justifications-for-subjects-that-are-gone.md new file mode 100644 index 000000000..80f9e5b8a --- /dev/null +++ b/docs/now/2026-09-04-two-justifications-for-subjects-that-are-gone.md @@ -0,0 +1,33 @@ +# NOW -- Four justifications for subjects that are gone (2026-09-04) + +## Each names something the tree no longer has + +- `docs/fpga/PIN_COVERAGE.md` lists `xdc_qmtech_minimal()` and + `xdc_qmtech_full()` as "Rust pin definitions". **0 definitions in the tree** -- + added `1911edc80` (2026-04-09) with the `gen-xdc` command, removed + `692ba5263` (2026-04-14). The subcommand went with them. +- `docs/CORPUS-RATCHET.md` justifies excluding `specs/scratch/` as "606,113,688 + of 612,924,235 bytes (98.89%)". That directory has been **out of the tree + since `2255e4c32`** -- 0 files in the index, absent from disk. The exclusion + excludes nothing, and the saving it claims was banked by the untracking. The + untracking commit puts the same exclusion at **64.5%** where the doc says + **98.89%**: two numbers for one subject, neither re-takable. +- `docs/metrics/NUMERIC_FORMATS_83_METRICS.md` cites + `gen/numeric/formats_catalog.json` (**77 formats**) as a data source. That file + was deleted by `aa01dd4f1` -- *"untrack stale gen/numeric catalog artifacts + (**drift 77 vs SSOT 83**)"*. **It was removed for being 77 against 83, and the + doc still publishes 77 and points at it.** The re-takable source is the catalog + itself: `grep -c 'CATALOG:'` = **109**. +- `docs/SYNTH_REPORT.md` declares every figure measured with **yosys 0.65**; the + bench reports **0.68+post**. Not re-measured here -- that needs a run, not an + edit -- but the instrument is named beside the numbers now. +- Measured and DECLINED: extending the status-table check from paths to code + symbols. 8 table rows name a `fn()`, 5 "missing" -- 62% -- and the population + is contaminated: `uart_tx_ready` is a `.t27` function that exists, + `quantize_groups` is an RFC proposal. Eight heterogeneous rows do not support + a detector. The finding survives; the tool does not. +- Measured and CONFIRMED: excluding `docs/reports/**` from the status check. + **1566 of 1569** name a wave, ring or date; the three that do not are a + reported-upstream note, an open question, and a PR body -- none a status claim. + My first measurement of my own exclusion said 63 undated, and was wrong: + `W\d{3}` does not match `WAVE_LOOP_170`. From 4e2db63e157fb22ffb5b5065870688e3bcd7d98d Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Fri, 4 Sep 2026 07:13:30 +0700 Subject: [PATCH 2/3] skill: the matcher that verifies your matcher is a matcher Refs #3082 I excluded docs/reports/** by argument. Measuring it said 63 of 1569 undated -- and all 63 are WAVE_LOOP_NNN files, because my pattern was \bW\d{3}\b, which does not match WAVE_LOOP_170. Corrected: 1566 of 1569, exclusion justified. The check of an exclusion made to avoid a matcher describing its input was itself a matcher describing its input. Printing the members rather than the count is what caught it in one look. With the pass that produced no code: extending the check from paths to symbols measured 8 rows, 5 'missing', 62%, and the population spans three languages and an RFC proposal. Declined. --- .claude/skills/ci-gates/SKILL.md | 41 ++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/.claude/skills/ci-gates/SKILL.md b/.claude/skills/ci-gates/SKILL.md index 4f55dddb0..fa67dd6af 100644 --- a/.claude/skills/ci-gates/SKILL.md +++ b/.claude/skills/ci-gates/SKILL.md @@ -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. From 2c70e4c60d8bc26c4bb2075d0a72327eefd86acd Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Fri, 4 Sep 2026 07:25:18 +0700 Subject: [PATCH 3/3] docs: a seal that names a hash the file no longer holds Closes #3082 NUMERICS_VALIDATION.md states its measured 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 is the present tense: the sentence asserted a current fact about a file, and a re-run of `nmse_gf16.py --seal` today seals against 9b8875f1... and is therefore a NEW reading rather than a reproduction of the table it sits above. That is now said. PUBLICATION_AUDIT.md cites TNF_ARTICLE_RU.md:305 and :309. The Yosys 0.65 / nextpnr line is at :340 today, the post-route rows at :354, and :309 is blank. Both citations carry their old value beside the new one, because an audit that silently re-points is harder to check than one that shows the move. TWO TOOLS MEASURED AND DECLINED, which cost the same as building them would have. A FILE:LINE checker for docs: 43 citations outside the dated reports, 0 with a missing file, 1 with a 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, inside a record, is not a population. The "print the members, not the total" rule I proposed last pass: the repository already keeps 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 two gft demos, run_conformance_vvp. Not one is a check. That second number is the uncomfortable one and it belongs in the record. 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. The rule I was about to propose to the repository is one the repository already keeps and I do not. --- docs/NUMERICS_VALIDATION.md | 18 ++++++++++++- docs/PUBLICATION_AUDIT.md | 4 +-- ...t-names-a-hash-the-file-no-longer-holds.md | 27 +++++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 docs/now/2026-09-04-a-seal-that-names-a-hash-the-file-no-longer-holds.md diff --git a/docs/NUMERICS_VALIDATION.md b/docs/NUMERICS_VALIDATION.md index 856039709..c0d4e7de4 100644 --- a/docs/NUMERICS_VALIDATION.md +++ b/docs/NUMERICS_VALIDATION.md @@ -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 | |--------|--------|-----------|--------|------------------|-------------|-----------------|-------|----------| diff --git a/docs/PUBLICATION_AUDIT.md b/docs/PUBLICATION_AUDIT.md index 456d50a33..84c598052 100644 --- a/docs/PUBLICATION_AUDIT.md +++ b/docs/PUBLICATION_AUDIT.md @@ -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 @@ -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. diff --git a/docs/now/2026-09-04-a-seal-that-names-a-hash-the-file-no-longer-holds.md b/docs/now/2026-09-04-a-seal-that-names-a-hash-the-file-no-longer-holds.md new file mode 100644 index 000000000..c052cad10 --- /dev/null +++ b/docs/now/2026-09-04-a-seal-that-names-a-hash-the-file-no-longer-holds.md @@ -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.