Repository navigation
fix(specs): three ported specs were Zig and Python, and the gate reported the oldest problem instead - #4562
Merged
Conversation
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
PR DashboardGenerated at: 2026-09-21 15:27:33 UTC
Summary
Seal Status
|
specs/port/tools/jtag/link_relay.t27 landed in #4533 today with Zig bodies in a file named .t27: ?struct{} at line 104, 23 @intcast(x as T), 14 try std.testing.expect, m.tms(&[...]), while (i < n) : (i += 1), .{ .role = r }, null/.unwrap()/.or(0). It failed on gen-c, gen-rust, gen-verilog and gen. Rewritten against read_user1.t27 -- its neighbour in the same directory and the same JTAG/MPSSE domain, and a spec that does generate. t27c check now reports 0 errors and 0 warnings and all four backends exit 0. The optional is kept rather than dropped: DrWord { ok, value } preserves the distinction the Python drew with None, so a caller that ignores ok reads a zero instead of a word the hardware never sent. The chain-IR loop, written out four times between xfer and request, is one chain_ir(idx, chain, sel). One of the seven dead tests asserted 0x1F3DF where the arithmetic gives 0x1F39F. A test that cannot compile cannot be wrong out loud. adamw.t27 was fixed by #4540 and left in the baseline. check_specs_generate.py short-circuits on "baseline now generates" and never reaches "newly does not generate", so every run stopped at adamw and never looked at link_relay. The stale line is pruned here; that is what made this visible. Fixes #4559
…ed the oldest problem instead Fixes #4560 specs/port/tools/run_conformance_vvp.t27 and check_fix_carries_source.t27 landed on 2026-09-21 and have never compiled on any backend. The first is transliterated Python, the second 565 lines of Zig with `let` against a 284 line source. The transliteration also changed the verdict. The emitted testbench increments `fails` and reports success on `if (folds == 0)`, a name declared nowhere, so the pass line is unreachable. `vvp_path` is bound to the compiled output and then rebound to the simulator binary, and the run becomes `vvp vvp`. Neither is a parse error. Both rewritten as specs: 0 errors, 0 warnings, four backends exit 0. check_fix_carries_source.t27 states the verdict lattice and the is_prose inversion but deliberately does not restate SOURCE_SCOPES or PROSE_EXT -- those have one definition in cli/tri/src/hooks.rs and the Python parses it rather than copying it. tools/check_specs_generate.py had four `return 1`s in a row, so the first class found was the only one reported, and the mildest was checked three lines before the most serious. One stale adamw ledger line left by #4540 blinded it for the whole window in which #4533, #4553 and #4556 landed. All four classes now report and the exit is taken once. The stale-ledger branch had no self-check case -- the only verdict in main() nothing executed -- and now has one, with a case that plants a stale line and a new break together.
Refs #4560 `tri types ratchet` read 81 conflicted names against a ledger of 80. `Context` was mine. The rewritten check_fix_carries_source.t27 named its pull-request record `Context`, a name specs/neural/forward_pass.t27 and specs/queen/lotus.t27 had already given to two other things. Renamed to `PrEvent`, which is what it is; `context_incomplete` moved with it to `pr_event_incomplete` across 10 call sites. `Edge` came from check_graph_law8.t27 -- the same porting campaign, landed the same day. specs/tri/graph/bellman_ford.t27 has declared `Edge` as from/to/weight since long before it; the port's is from/to/kind. Two concepts, one name, and nothing for a cross-spec resolver to break the tie with. The newcomer takes the narrower name: `DepEdge`. Ratchet now reads `ledger 80, observed 80 -- CLEAN`. All four backends (gen-c, gen-rust, gen-js, gen-ts) exit 0 on both files. This is also how the ratchet is meant to be read. Resolving `Mpsse` while introducing `Context` left the count unchanged; only the identity-keyed list showed that two separate things had happened.
gHashTag
force-pushed
the
fix/link-relay-t27-port
branch
from
September 21, 2026 15:28
65a07fd to
81b5dac
Compare
Contributor
PR DashboardGenerated at: 2026-09-21 15:28:56 UTC
Summary
Seal Status
|
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
4 tasks
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.
Three specs under
specs/port/tools/were not t27 and had never compiled on any backend. All three landed on 2026-09-21 from the same porting campaign, and the gate that exists to catch exactly this reported a different, older problem every time it ran.Closes #4559. Closes #4560.
The specs
link_relay.t27(#4533)run_conformance_vvp.t27(#4553)check_fix_carries_source.t27(#4556)let, 565 lines against a 284-line source?struct{...}, 23@intCast(x as T), 14try std.testing.expectlet, 4try,+string concatenationstd.*, 30catch, 27x += 1, 25'\n' as u8, 6error.*Each was rewritten against a neighbour that actually generates, not patched until the parser stopped complaining.
link_relay.t27— the optional is gone rather than papered over:DrWord { ok, value }keeps the distinction the Python made withNone, so a caller that ignoresokreads a zero instead of a word the hardware never sent. The two IR loops, spelled four times betweenxferandrequest, are onechain_ir(idx, chain, sel). One of its seven dead tests asserted0x1F3DFwhere the arithmetic gives0x1F39F; a test that cannot compile cannot be wrong out loud. The rewrite's constants were checked against an independent computation of the same loop.run_conformance_vvp.t27— the transliteration did not only fail to parse, it changed what the tool decides:integer fails = 0and incrementsfails, and the one line that reports success readsif (folds == 0).foldsis declared nowhere, so the pass line is unreachable.vvp_pathis bound to the compiled output (line 76), then rebound to the simulator binary (line 94), then passed twice:vvp vvp. The Python's literal"vvp"became awhichlookup that overwrote the variable it was meant to sit beside.Neither is a parse error. A port that only fixed the syntax would have kept both. The rewrite keeps the decidable part — the prescaler encoding, the two-condition pass rule, T117 (absent is not failed), T67 (zero executed cases is a failure however clean the run) — and stubs the OS.
check_fix_carries_source.t27— states the verdict lattice, the inversion inis_prose, and the rule that a guard which cannot read its own definition reports could-not-run rather than passing. It deliberately does not restateSOURCE_SCOPESorPROSE_EXT: those have one definition incli/tri/src/hooks.rs, and the Python parses it rather than copying it — "two readers with two copies of a list is how a rule drifts into two rules." A third copy here would be the defect that tool exists to catch, so every predicate takes the answer to a lookup rather than the table.The gate
tools/check_specs_generate.pyhad fourreturn 1s in a row, so the first class it found was the only class it reported — andfixed, the mildest, was checked three lines beforenew, the most serious.specs/ml/optimizer/adamw.t27was repaired by #4540 and its ledger line was left behind. From then on every run printed "1 spec(s) in the baseline now generate" and returned before scanning for anything newly broken. All three specs above landed inside that window.return 1inmain()that nothing ever executed, and the one that caused this. It has one now.The ordering case was measured against the defect rather than asserted: restoring the
return 1makesa stale line does not hide a new breakreportCONTROL FAILED, while the two branch cases correctly survive it.python3 tools/check_specs_generate.pynow exits 0 —1027 specs, 952 generate, 75 known-broken.Границы
Found while doing this, filed rather than folded in:
gentoday and are counted as Working; 35 of those emit the invented name into their generated C. Arity and argument types are unchecked for the 28 real builtins too. This is whycheck_fix_carries_source.t27could not simply call@startsWithand@split— three shipped specs do, and that string library does not exist.undefinedlowers to{0};, which is not valid C.read_user1.t27, classed Working, failsccwith 6 errors for the same reason. A backend defect across every spec that stubs a body, and not introduced here.gen-cexits 0 on specs every backend rejects, which is why the gate has to shell out four times.specs/port/, of which 8 never compiled — the 5 still in the baseline plus these 3.emit-bitexacttriggers onpull_requestonly, so master accumulates reds that first surface on an unrelated branch.