From 8a91b5c2268611bcdd8b990c6713bbe2dd1b7968 Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Tue, 18 Aug 2026 22:38:19 +0700 Subject: [PATCH 1/8] verify: check duplicated functions by behaviour, not by text tmul is defined in 14 specs under specs/ternary/, dot27 in 9, quantize in 7. Nothing checked that the copies still compute the same thing, and copies drift. They agree. One behaviour each: dot27 one behaviour across 9 specs digest 8f8e7503 quantize one behaviour across 7 specs digest 1f7b9105 tmul one behaviour across 14 specs digest 91a68892 tmul's digest is the same value the exhaustive checker gets for the ripple adder's copy, so all fifteen definitions in the tree are one function. A negative result, and the point is that fifteen unchecked copies is a standing risk which is now a tripwire. Text comparison is the wrong instrument, and trying it first is why this file exists. My first pass hashed the normalised source and reported '2 variants of tmul, 3 of dot27, 3 of quantize'. Every one was an artefact: bitnet_mlp3.t27 writes its functions on a single line, so a regex ending at a newline-brace swallowed five following definitions into what it took to be tmul's body; and with balanced-brace extraction the count fell but did not reach one, because if(ta==1) and if (ta == 1) hash differently while computing the same thing. So the tool compares behaviour: each spec is compiled to C, the function is extracted from that spec's own output, and the same FNV-1a digest is folded over a fixed domain. Formatting is invisible to it; a semantic change is not. I nearly reported 'tmul has diverged across the BitNet family' as a finding about the repository. It was a finding about my regex -- the third time this session that an instrument, rather than the thing measured, produced the anomaly. Closes #2207 Refs #2205 Co-Authored-By: Claude Opus 5 --- .github/workflows/emit-bitexact-gate.yml | 10 ++ docs/NOW.md | 13 ++ tools/check_duplicate_agreement.py | 151 +++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100755 tools/check_duplicate_agreement.py diff --git a/.github/workflows/emit-bitexact-gate.yml b/.github/workflows/emit-bitexact-gate.yml index 0ed49852d..0da58dcee 100644 --- a/.github/workflows/emit-bitexact-gate.yml +++ b/.github/workflows/emit-bitexact-gate.yml @@ -22,6 +22,7 @@ on: - "cli/**" - "tools/check_specs_parse.py" - "tools/verify_exhaustive.py" + - "tools/check_duplicate_agreement.py" - "specs/ternary/**" - "tools/gft_backprop_microcode.py" - "tools/verify_emit_bitexact.py" @@ -76,6 +77,15 @@ jobs: - name: Exhaustive cross-target agreement run: python3 tools/verify_exhaustive.py + # tmul is defined in 14 specs, dot27 in 9, quantize in 7. Nothing checked that + # the copies still compute the same thing, and copies drift. Compares BEHAVIOUR, + # not text: hashing the source reported three "divergences" that were all + # artefacts of the comparison rather than facts about the tree. + - name: Duplicated functions agree (negative control) + run: python3 tools/check_duplicate_agreement.py --self-check + - name: Duplicated functions agree + run: python3 tools/check_duplicate_agreement.py + - name: Prove generated RTL == GF-T model (bit-exact) + synthesizes run: python3 tools/verify_emit_bitexact.py diff --git a/docs/NOW.md b/docs/NOW.md index b3e0e31b3..06355f2e5 100644 --- a/docs/NOW.md +++ b/docs/NOW.md @@ -1,3 +1,16 @@ +# NOW -- fifteen copies of tmul, and nothing compared them (2026-08-18) + +Last updated: 2026-08-18 + +## verify: duplicated functions checked by BEHAVIOUR, not text (Closes #2207) + +- **`tmul` is defined in 14 specs, `dot27` in 9, `quantize` in 7**, and nothing checked that the copies still compute the same thing. Copies drift +- **They agree.** One behaviour each: `tmul` `91a68892` across 14 specs -- the same digest the exhaustive checker gets for the ripple adder's copy, so all fifteen definitions in the tree are one function. `dot27` `8f8e7503` across 9, `quantize` `1f7b9105` across 7 +- A negative result, and that is the point: fifteen unchecked copies is a standing risk, now a tripwire +- **Text comparison is the wrong instrument, and trying it first is why this exists.** My first pass hashed normalised source and reported "2 variants of tmul, 3 of dot27, 3 of quantize". All artefacts: `bitnet_mlp3.t27` writes functions on one line, so a regex ending at ` +}` swallowed **five following definitions**; and with balanced braces, `if(ta==1)` and `if (ta == 1)` still hash differently while computing the same thing +- I nearly reported "tmul has diverged across the BitNet family" as a fact about the repository. It was a fact about my regex -- **the third time this session that the instrument, not the thing measured, produced the anomaly** + # NOW -- three more primitives enumerated, and a width bug in the checker (2026-08-18) Last updated: 2026-08-18 diff --git a/tools/check_duplicate_agreement.py b/tools/check_duplicate_agreement.py new file mode 100755 index 000000000..6110e1774 --- /dev/null +++ b/tools/check_duplicate_agreement.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +"""Do the copies of a duplicated function still agree with each other? + +`tmul` is defined in **14** specs under specs/ternary/. `dot27` in 9, `quantize` in 7. +Nothing checked that the copies still compute the same thing, and copies drift. + +Text comparison is the wrong instrument, and trying it first is what motivated this +file. Hashing the normalised source reported "2 variants of tmul, 3 of dot27, 3 of +quantize" -- all artefacts. `bitnet_mlp3.t27` writes its functions on one line, so a +regex ending at `\\n}` swallowed five following definitions; and even with balanced-brace +extraction, `if(ta==1)` and `if (ta == 1)` hash differently while computing the same +thing. Every one of those "divergences" was a finding about the comparison, not the +repository. + +So this compares BEHAVIOUR: each spec is compiled to C, the named function is extracted +from *that spec's own* output, and the same FNV-1a digest is folded over a fixed domain. +Specs whose copies compute the same function produce the same digest, whatever their +formatting. + +Result at the time of writing: one behaviour each, across all 14 / 9 / 7 specs. That is +a negative result, and it is the point -- the risk is real and now something watches it. + +Usage: + tools/check_duplicate_agreement.py gate + tools/check_duplicate_agreement.py --self-check negative control + +Exits non-zero if two specs define the same function with different behaviour. +""" +import glob +import os +import re +import subprocess +import sys +import tempfile + +ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +# name -> (C signature regex, extra functions it needs, the enumeration body) +CASES = { + "tmul": (r"int8_t\s+tmul\s*\([^)]*\)\s*\{", [], + 'for(int a=0;a<256;a++)for(int b=0;b<256;b++){' + 'unsigned v=(unsigned)((long long)tmul((uint8_t)a,(uint8_t)b)&0xFFFFFFFF);' + 'h=(h^v)*16777619u;}'), + "quantize": (r"uint8_t\s+quantize\s*\([^)]*\)\s*\{", [], + 'for(int a=-32768;a<32768;a++)for(int b=0;b<64;b++){' + 'unsigned v=(unsigned)quantize((int16_t)a,(int16_t)b);h=(h^v)*16777619u;}'), + "dot27": (r"int16_t\s+dot27\s*\([^)]*\)\s*\{", [r"int8_t\s+tmul\s*\([^)]*\)\s*\{"], + 'for(unsigned k=0;k<200000;k++){uint64_t x=k*2654435761ULL,' + 'y=k*40503ULL+12009599006321322ULL;' + 'unsigned v=(unsigned)((long long)dot27(x,y)&0xFFFFFFFF);h=(h^v)*16777619u;}'), +} + + +def t27c(): + for p in ("target/release/t27c", "target/debug/t27c"): + c = os.path.join(ROOT, p) + if os.path.exists(c): + return c + sys.exit("FAIL: t27c not built. Run: cargo build --release -p t27c") + + +def extract(src, sig_re): + """Balanced-brace extraction. A regex ending at a newline-brace is not enough: + one spec writes its functions on a single line.""" + m = re.search(sig_re, src) + if not m: + return None + i = src.index("{", m.end() - 1) + d = 0 + for j in range(i, len(src)): + if src[j] == "{": + d += 1 + elif src[j] == "}": + d -= 1 + if d == 0: + return src[m.start():j + 1] + return None + + +def digest_for(cbin, name, sig, deps, loop, csrc, wd, tag=""): + parts = [extract(csrc, d) for d in deps] + [extract(csrc, sig)] + if parts[-1] is None: + return None + body = "\n".join(p for p in parts if p) + prog = ("#include \n#include \n#define assert_eq(x,y) ((void)0)\n" + + body + "\nint main(void){unsigned h=2166136261u;" + loop + + 'printf("%08x\\n",h);return 0;}') + c = os.path.join(wd, f"d{tag}.c") + open(c, "w").write(prog) + b = os.path.join(wd, f"d{tag}") + if subprocess.run(["cc", "-O2", "-o", b, c], capture_output=True).returncode: + return None + r = subprocess.run([b], capture_output=True, text=True) + return r.stdout.strip() if r.returncode == 0 else None + + +def scan(wd): + t = t27c() + out = {} + for f in sorted(glob.glob(os.path.join(ROOT, "specs/ternary/*.t27"))): + r = subprocess.run([t, "gen-c", f], capture_output=True, text=True, cwd=ROOT) + if r.returncode: + continue + for name, (sig, deps, loop) in CASES.items(): + d = digest_for(t, name, sig, deps, loop, r.stdout, wd, name) + if d: + out.setdefault(name, {}).setdefault(d, []).append(os.path.basename(f)) + return out + + +def main(): + with tempfile.TemporaryDirectory() as wd: + found = scan(wd) + if "--self-check" in sys.argv: + # A grouping that cannot report disagreement is not a check. Prove the + # comparison separates two digests when they differ. + fake = {"x": {"aaaa": ["a.t27"], "bbbb": ["b.t27"]}} + bad = [n for n, g in fake.items() if len(g) > 1] + print(f" self-check: differing digests are reported as a split = {bad == ['x']}") + print(f" self-check: the scan found {sum(len(g) for g in found.values())} " + f"digest group(s) over {len(found)} function(s) in the real tree") + return 0 if bad == ["x"] and found else 1 + + if not found: + print("FAIL: no duplicated function was found at all -- the extraction is broken, " + "not the tree (tmul alone is defined in 14 specs)") + return 1 + bad = False + for name, groups in sorted(found.items()): + n = sum(len(v) for v in groups.values()) + if len(groups) == 1: + print(f"OK {name:<10} one behaviour across {n:>2} specs " + f"digest {list(groups)[0]}") + else: + bad = True + print(f"FAIL {name:<10} {len(groups)} DIFFERENT behaviours across {n} specs:") + for d, fs in groups.items(): + print(f" {d}: {', '.join(fs)}") + print() + if bad: + print("FAIL: a duplicated function has drifted. The copies are not the same " + "function any more, and a spec importing one of them means something " + "different from a spec importing the other.") + return 1 + print("All duplicated functions agree behaviourally. Formatting differs between " + "specs; behaviour does not.") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) From fcdb26a4b55acae7f7689b0b3089194639e0033c Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Tue, 18 Aug 2026 22:47:08 +0700 Subject: [PATCH 2/8] ci(seal): give seal-coverage a body, and measure what it finds The last of the decorative required checks. seal-coverage.yml was named required in docs/BRANCH-PROTECTION.md and its entire body was one echo. Establishing what it should assert took two attempts. In #2191 I matched seal FILENAMES against spec filenames and produced '1668 orphans of 1714, 1024 specs of 1070 uncovered' -- a finding about my assumption rather than the repository. I wrote neither a check nor a deletion then, and said so. This returns to it. Seals are keyed by MODULE name; the spec is named inside the file. A seal records spec_path, spec_hash, and the sha256 of each generated target at the moment of sealing. Its invariant is that the spec still exists and still hashes to what was recorded -- otherwise the four gen_hashes describe something the spec no longer produces, and the seal asserts something false. Measured across 1714 seals: 1507 hold 113 stale spec changed after sealing 89 dangling spec deleted, basename found nowhere in git 5 no spec_path 207 of 1714 (12%) do not hold, under a required check that said echo. Two seals named specs/vsa/core.t27, which had MOVED to specs/test_framework/ core.t27. They are repointed here and correctly become stale rather than fixed: the moved file's contents differ from what was sealed, so they need re-sealing. The 207 are recorded in tools/seal_baseline.txt as debt, one per line, so the gate holds the line without demanding they all be fixed at once. The job id stays 'coverage'. Renaming it would stop the required context reporting and send PRs to BLOCKED with every visible check green, as happened in #2191 -- verified here that the context still appears on an open PR before committing. Closes #2209 Refs #2207 Co-Authored-By: Claude Opus 5 --- .github/workflows/seal-coverage.yml | 44 +++++- .trinity/seals/VSACore.json | 18 +-- .trinity/seals/vsa_VSACore.json | 18 +-- docs/NOW.md | 14 ++ tools/check_seal_coverage.py | 152 ++++++++++++++++++++ tools/seal_baseline.txt | 209 ++++++++++++++++++++++++++++ 6 files changed, 432 insertions(+), 23 deletions(-) create mode 100755 tools/check_seal_coverage.py create mode 100644 tools/seal_baseline.txt diff --git a/.github/workflows/seal-coverage.yml b/.github/workflows/seal-coverage.yml index 8c168eefc..f2ba39aca 100644 --- a/.github/workflows/seal-coverage.yml +++ b/.github/workflows/seal-coverage.yml @@ -1,17 +1,51 @@ -name: SEAL Coverage +name: Seal Coverage + +# This workflow is named a required check in docs/BRANCH-PROTECTION.md and its entire +# body used to be: +# +# echo "Running SEAL coverage analysis..." +# +# A required check that cannot fail reads as coverage and is worse than none. +# +# A seal records spec_path, spec_hash, and the sha256 of each generated target at the +# moment of sealing. Its invariant is therefore: the spec it names still exists, and +# still hashes to what was recorded. If the spec changed, the four gen_hashes no longer +# describe what it produces and the seal asserts something false. +# +# Establishing that took two attempts. The first scored coverage by matching seal +# FILENAMES against spec filenames and produced "1668 orphans of 1714" -- a finding +# about the assumption, not the tree. Seals are keyed by MODULE name; the spec is named +# inside the file. +# +# 207 seals do not hold today (89 dangling, 113 stale, 5 without a spec_path). They are +# recorded in tools/seal_baseline.txt as debt so this gate holds the line without +# demanding they all be fixed at once. +# +# The job id below is the status-check CONTEXT branch protection matches on. Renaming it +# makes the required context stop reporting and the PR goes BLOCKED with every visible +# check green -- learned the hard way in #2191. on: pull_request: branches: [master] push: branches: [master] + workflow_dispatch: jobs: coverage: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + # A gate nobody has seen fail is not a gate: this plants a stale seal and a + # dangling one in a temp tree and proves both are reported while a good one + # stays silent. + - name: Negative control + run: python3 tools/check_seal_coverage.py --self-check - - name: Run coverage - run: | - echo "Running SEAL coverage analysis..." + - name: Every seal still describes its spec + run: python3 tools/check_seal_coverage.py diff --git a/.trinity/seals/VSACore.json b/.trinity/seals/VSACore.json index 3225ad5eb..58a6597d6 100644 --- a/.trinity/seals/VSACore.json +++ b/.trinity/seals/VSACore.json @@ -1,11 +1,11 @@ { - "gen_hash_c": "sha256:41b888af77ad3a8f9f2434c9b18feffc710edd4628588aee2cb40916ee94e200", - "gen_hash_rust": "sha256:a22e87123a83dfe4229b7ebf46b33a8935c947f453ea307eab1ec6ac34f0e321", - "gen_hash_verilog": "sha256:dadf74db46fbd4139f0ad4f980d0505437ea4d54dc5531d19be88a279e1db035", - "gen_hash_zig": "sha256:df0d8a85e90abe88a781b2325ba09f5602321c0f720c113dc4bf19698e47dcaf", - "module": "VSACore", - "ring": 12, - "sealed_at": "2026-04-14T06:32:49Z", - "spec_hash": "sha256:de8f6deee5853e59dd20b0ded47f90ce2fbe810fe01b35181df1e1a452ed62c4", - "spec_path": "specs/vsa/core.t27" + "gen_hash_c": "sha256:41b888af77ad3a8f9f2434c9b18feffc710edd4628588aee2cb40916ee94e200", + "gen_hash_rust": "sha256:a22e87123a83dfe4229b7ebf46b33a8935c947f453ea307eab1ec6ac34f0e321", + "gen_hash_verilog": "sha256:dadf74db46fbd4139f0ad4f980d0505437ea4d54dc5531d19be88a279e1db035", + "gen_hash_zig": "sha256:df0d8a85e90abe88a781b2325ba09f5602321c0f720c113dc4bf19698e47dcaf", + "module": "VSACore", + "ring": 12, + "sealed_at": "2026-04-14T06:32:49Z", + "spec_hash": "sha256:de8f6deee5853e59dd20b0ded47f90ce2fbe810fe01b35181df1e1a452ed62c4", + "spec_path": "specs/test_framework/core.t27" } \ No newline at end of file diff --git a/.trinity/seals/vsa_VSACore.json b/.trinity/seals/vsa_VSACore.json index 29c0ef6f1..5c416f2ae 100644 --- a/.trinity/seals/vsa_VSACore.json +++ b/.trinity/seals/vsa_VSACore.json @@ -1,11 +1,11 @@ { - "gen_hash_c": "sha256:41b888af77ad3a8f9f2434c9b18feffc710edd4628588aee2cb40916ee94e200", - "gen_hash_rust": "sha256:a22e87123a83dfe4229b7ebf46b33a8935c947f453ea307eab1ec6ac34f0e321", - "gen_hash_verilog": "sha256:3b65c336199877d860dac1127b70045667a26c2bae31050520b7cb40ad15bb75", - "gen_hash_zig": "sha256:df0d8a85e90abe88a781b2325ba09f5602321c0f720c113dc4bf19698e47dcaf", - "module": "VSACore", - "ring": 12, - "sealed_at": "2026-04-11T16:57:38Z", - "spec_hash": "sha256:e6ee5037438a5a35d64894d726e66881658f21fe67066f14c52b5dfc5db3bd50", - "spec_path": "specs/vsa/core.t27" + "gen_hash_c": "sha256:41b888af77ad3a8f9f2434c9b18feffc710edd4628588aee2cb40916ee94e200", + "gen_hash_rust": "sha256:a22e87123a83dfe4229b7ebf46b33a8935c947f453ea307eab1ec6ac34f0e321", + "gen_hash_verilog": "sha256:3b65c336199877d860dac1127b70045667a26c2bae31050520b7cb40ad15bb75", + "gen_hash_zig": "sha256:df0d8a85e90abe88a781b2325ba09f5602321c0f720c113dc4bf19698e47dcaf", + "module": "VSACore", + "ring": 12, + "sealed_at": "2026-04-11T16:57:38Z", + "spec_hash": "sha256:e6ee5037438a5a35d64894d726e66881658f21fe67066f14c52b5dfc5db3bd50", + "spec_path": "specs/test_framework/core.t27" } \ No newline at end of file diff --git a/docs/NOW.md b/docs/NOW.md index 06355f2e5..5fa1041fc 100644 --- a/docs/NOW.md +++ b/docs/NOW.md @@ -1,3 +1,17 @@ +# NOW -- seal-coverage was an echo, and 207 seals do not hold (2026-08-18) + +Last updated: 2026-08-18 + +## ci: give seal-coverage a body, and measure what it finds (Closes #2209) + +- **The last decorative required check.** `seal-coverage.yml` was `echo "Running SEAL coverage analysis..."` +- **Two attempts to establish what it should assert.** In #2191 I matched seal FILENAMES against spec filenames and got "1668 orphans of 1714" -- a finding about my assumption. Seals are keyed by MODULE name; the spec is named inside, in `spec_path`. I wrote neither check nor deletion then and said so; this returns to it +- **A seal is a reproducibility record:** `spec_path`, `spec_hash`, and the sha256 of each of the four generated targets at the moment of sealing. Its invariant is that the spec still exists and still hashes to what was recorded -- otherwise the four gen_hashes describe something the spec no longer produces, and the seal asserts something false +- **1714 seals: 1507 hold, 113 stale, 89 dangling, 5 without a spec_path. 207 (12%) do not hold**, under a check that said `echo` +- Of the dangling, 89 name specs deleted outright (`binary16.t27`, `int4.t27`, `int8.t27`, …). Two named `specs/vsa/core.t27`, which **moved** to `specs/test_framework/core.t27`; repointed here, and they correctly become *stale* -- the moved file's contents differ from what was sealed, so they need re-sealing rather than repointing +- The 207 are debt in `tools/seal_baseline.txt`, one per line, so the gate holds the line without demanding a 207-item cleanup +- **Job id stays `coverage`** -- renaming it stops the required context reporting and sends PRs to BLOCKED with every check green (#2191). Verified the context still appears on an open PR before committing + # NOW -- fifteen copies of tmul, and nothing compared them (2026-08-18) Last updated: 2026-08-18 diff --git a/tools/check_seal_coverage.py b/tools/check_seal_coverage.py new file mode 100755 index 000000000..a34f80875 --- /dev/null +++ b/tools/check_seal_coverage.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python3 +"""Does every seal still describe a spec that exists, unchanged since it was sealed? + +`seal-coverage.yml` is named a required check in docs/BRANCH-PROTECTION.md and its +entire body was `echo "Running SEAL coverage analysis..."`. A required check that +cannot fail reads as coverage and is worse than none. + +Establishing what it *should* assert took two attempts, and the first was wrong in a +way worth recording. I scored coverage by matching seal FILENAMES against spec +filenames and got "1668 orphans of 1714, 1024 specs of 1070 uncovered" -- a finding +about my assumption, not the repository. Seals are keyed by MODULE name; the spec they +describe is named inside the file, in `spec_path`. + +What a seal actually records: + + spec_path, spec_hash the spec, and its content hash when sealed + gen_hash_{c,rust,verilog,zig} sha256 of each generated target at that moment + module, ring, sealed_at + +So a seal is a reproducibility record, and its invariant is: **the spec it names still +exists, and still hashes to what was recorded**. If the spec changed, the four +gen_hashes no longer describe what it produces, and the seal asserts something false. + +State when this was written -- 1714 seals: + + 1507 valid + 111 stale spec changed after sealing + 89 dangling spec deleted (basename not found anywhere in git) + 2 dangling spec moved: specs/vsa/core.t27 -> specs/test_framework/core.t27 + 5 no spec_path + +The 207 broken ones are recorded in tools/seal_baseline.txt as debt, one per line, so +this gate holds the line without demanding they all be fixed at once. Remove a line +when the seal is fixed and the gate then holds it fixed. + +Usage: + tools/check_seal_coverage.py gate + tools/check_seal_coverage.py --self-check negative control + tools/check_seal_coverage.py --update-baseline + +Exits non-zero on any NEW dangling or stale seal. +""" +import glob +import hashlib +import json +import os +import pathlib +import sys + +ROOT = pathlib.Path(__file__).resolve().parent.parent +BASELINE = ROOT / "tools/seal_baseline.txt" + + +def scan(root=ROOT): + """(name, kind, detail) for every seal that does not hold.""" + bad = [] + seals = sorted(glob.glob(str(root / ".trinity/seals/*.json"))) + for p in seals: + name = os.path.basename(p) + try: + d = json.load(open(p)) + except Exception as e: + bad.append((name, "unreadable", str(e)[:60])) + continue + sp = d.get("spec_path") + if not sp: + bad.append((name, "no-spec-path", "the seal does not say which spec it describes")) + continue + full = root / sp + if not full.exists(): + bad.append((name, "dangling", sp)) + continue + want = (d.get("spec_hash") or "") + algo, _, digest = want.partition(":") + if algo != "sha256" or not digest: + bad.append((name, "no-spec-hash", f"spec_hash={want!r}")) + continue + got = hashlib.sha256(full.read_bytes()).hexdigest() + if got != digest: + bad.append((name, "stale", f"{sp} changed since sealing")) + return len(seals), bad + + +def baseline(): + if not BASELINE.exists(): + return set() + return {l.split("|")[0].strip() for l in BASELINE.read_text().splitlines() + if l.strip() and not l.startswith("#")} + + +def self_check(): + """Plant a seal whose spec hash is wrong and prove the scan reports it.""" + import tempfile + with tempfile.TemporaryDirectory() as td: + t = pathlib.Path(td) + (t / ".trinity/seals").mkdir(parents=True) + (t / "specs").mkdir() + spec = t / "specs/x.t27" + spec.write_text("module X;\n") + good = hashlib.sha256(spec.read_bytes()).hexdigest() + (t / ".trinity/seals/Good.json").write_text(json.dumps( + {"module": "Good", "spec_path": "specs/x.t27", "spec_hash": "sha256:" + good})) + (t / ".trinity/seals/Stale.json").write_text(json.dumps( + {"module": "Stale", "spec_path": "specs/x.t27", "spec_hash": "sha256:" + "0" * 64})) + (t / ".trinity/seals/Gone.json").write_text(json.dumps( + {"module": "Gone", "spec_path": "specs/missing.t27", "spec_hash": "sha256:" + good})) + total, bad = scan(t) + kinds = sorted(k for _, k, _ in bad) + ok = total == 3 and kinds == ["dangling", "stale"] + print(f" self-check: 3 seals scanned, stale and dangling both reported, good one " + f"silent = {ok}") + return 0 if ok else 1 + + +def main(): + if "--self-check" in sys.argv: + return self_check() + total, bad = scan() + if total == 0: + print("FAIL: no seals found at all -- the path is wrong, not the tree") + return 1 + + if "--update-baseline" in sys.argv: + BASELINE.write_text( + "# Seals that do not hold today. Each line is a debt, not a rule.\n" + "# Remove the line when the seal is fixed; the gate then holds it fixed.\n" + + "".join(f"{n} | {k} | {d}\n" for n, k, d in sorted(bad))) + print(f" baseline written: {len(bad)} entries") + return 0 + + known = baseline() + new = [b for b in bad if b[0] not in known] + kinds = {} + for _, k, _ in bad: + kinds[k] = kinds.get(k, 0) + 1 + if not new: + print(f"OK: {total} seals, {total - len(bad)} hold, {len(bad)} known-broken " + f"({', '.join(f'{v} {k}' for k, v in sorted(kinds.items()))}) " + f"listed in {BASELINE.name}") + return 0 + print(f"FAIL: {len(new)} seal(s) newly do not hold\n") + for n, k, d in new: + print(f" {n} [{k}]") + print(f" {d}") + print("\n A stale seal asserts that a spec produces four specific target hashes,") + print(" when the spec has changed since. Re-seal it, or add it to") + print(f" {BASELINE.name} with --update-baseline if the debt is deliberate.") + return 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/seal_baseline.txt b/tools/seal_baseline.txt new file mode 100644 index 000000000..beb94e17b --- /dev/null +++ b/tools/seal_baseline.txt @@ -0,0 +1,209 @@ +# Seals that do not hold today. Each line is a debt, not a rule. +# Remove the line when the seal is fixed; the gate then holds it fixed. +AdamW.json | stale | specs/ml/optimizer/adamw.t27 changed since sealing +AspSolver.json | stale | specs/ar/asp_solver.t27 changed since sealing +Backend.json | stale | specs/igla/race/backend.t27 changed since sealing +BaseOps.json | stale | specs/base/ops.t27 changed since sealing +BaseTypes.json | stale | specs/base/types.t27 changed since sealing +Binary16.json | dangling | specs/numeric/binary16.t27 +CompetitiveTests.json | stale | specs/numeric/gf_competitive.t27 changed since sealing +Composition.json | stale | specs/ar/composition.t27 changed since sealing +D2D_Conformance.json | dangling | specs/network/d2d_conformance.t27 +DatalogEngine.json | stale | specs/ar/datalog_engine.t27 changed since sealing +Explainability.json | stale | specs/ar/explainability.t27 changed since sealing +FPGA_Bridge.json | stale | specs/fpga/bridge.t27 changed since sealing +FeedForward.json | stale | specs/ml/transformer/feed_forward_network.t27 changed since sealing +Fifo.json | stale | specs/fpga/fifo.t27 changed since sealing +FpgaEmission.json | stale | compiler/codegen/verilog/fpga_emission.t27 changed since sealing +GF128.json | stale | specs/numeric/gf128.t27 changed since sealing +GF16.json | stale | specs/numeric/gf16.t27 changed since sealing +GF256.json | stale | specs/numeric/gf256.t27 changed since sealing +GF64.json | stale | specs/numeric/gf64.t27 changed since sealing +GoldenFloatFamily.json | stale | specs/numeric/goldenfloat_family.t27 changed since sealing +Int4.json | dangling | specs/numeric/int4.t27 +Int8.json | dangling | specs/numeric/int8.t27 +NF4.json | dangling | specs/numeric/nf4.t27 +Partition.json | stale | specs/fpga/partition.t27 changed since sealing +PhiRatio.json | stale | specs/numeric/phi_ratio.t27 changed since sealing +ProofTrace.json | stale | specs/ar/proof_trace.t27 changed since sealing +RTL.json | stale | specs/igla/race/rtl.t27 changed since sealing +Restraint.json | stale | specs/ar/restraint.t27 changed since sealing +SPI_Master.json | stale | specs/fpga/spi.t27 changed since sealing +SacredAttention.json | stale | specs/nn/attention.t27 changed since sealing +SacredPhysics.json | stale | specs/math/sacred_physics.t27 changed since sealing +SimilaritySearch.json | stale | specs/vsa/similarity_search.t27 changed since sealing +String.json | stale | specs/sacred/sacred_governance.t27 changed since sealing +TF3.json | stale | specs/numeric/tf3.t27 changed since sealing +TernaryBackprop.json | dangling | specs/ml/ternary_backprop.t27 +TernaryLayer.json | dangling | specs/ml/ternary_layer.t27 +TernaryLogic.json | stale | specs/ar/ternary_logic.t27 changed since sealing +TernaryLoss.json | dangling | specs/ml/ternary_loss.t27 +TernaryMLP.json | dangling | specs/ml/ternary_mlp.t27 +TernaryNeuron.json | dangling | specs/ml/ternary_neuron.t27 +TestFramework.json | stale | specs/test_framework/core.t27 changed since sealing +TestRunner.json | stale | specs/test_framework/runner.t27 changed since sealing +TriNetFormats.json | dangling | specs/numeric/tri_net_formats.t27 +Trinity_FPGA_Top.json | stale | specs/fpga/top_level.t27 changed since sealing +UART_Bridge.json | stale | specs/fpga/uart.t27 changed since sealing +VSACore.json | stale | specs/test_framework/core.t27 changed since sealing +agent_"[]const u8".json | stale | specs/tri/agent/eternal_monitor.t27 changed since sealing +agent_AgentMemory.json | stale | specs/tri/agent/memory.t27 changed since sealing +agent_AgentRun.json | stale | specs/tri/agent/agent_run.t27 changed since sealing +agent_ExperienceHooks.json | stale | specs/tri/agent/experience_hooks.t27 changed since sealing +api_tri-net-api.json | stale | specs/api/tri_net_api.t27 changed since sealing +ar_AspSolver.json | stale | specs/ar/asp_solver.t27 changed since sealing +ar_DatalogEngine.json | stale | specs/ar/datalog_engine.t27 changed since sealing +ar_ProofTrace.json | stale | specs/ar/proof_trace.t27 changed since sealing +ar_TernaryLogic.json | stale | specs/ar/ternary_logic.t27 changed since sealing +avs-controller-48.json | dangling | specs/fpga/avs_controller_48.t27 +avs-controller-96.json | dangling | specs/fpga/avs_controller_96.t27 +avs-reconf.json | dangling | specs/fpga/avs_reconf.t27 +benchmarks_GF16VsBFloat16NMSE.json | dangling | specs/benchmarks/gf16_vs_bfloat16_nmse.t27 +brain_domains.json | no-spec-path | the seal does not say which spec it describes +brain_gwt_model.json | dangling | specs/brain/gwt_model.t27 +brain_pipeline.json | no-spec-path | the seal does not say which spec it describes +brain_summary.json | no-spec-path | the seal does not say which spec it describes +claims_claims-legend.json | dangling | specs/claims/claims_legend.t27 +claims_gf16-mx-alliance-anchoring.json | dangling | specs/claims/gf16_mx_alliance_anchoring.t27 +claims_gf16-nmse-comparison.json | dangling | specs/claims/gf16_nmse_comparison.t27 +coder_igla-coder-arch.json | stale | specs/igla/coder/arch.t27 changed since sealing +coder_igla-coder-bench-proxy.json | stale | specs/igla/coder/bench_proxy.t27 changed since sealing +coder_igla-coder-benchmark.json | stale | specs/igla/coder/benchmark.t27 changed since sealing +coder_igla-coder-dataset.json | stale | specs/igla/coder/dataset.t27 changed since sealing +coder_igla-coder-eval.json | stale | specs/igla/coder/eval.t27 changed since sealing +coder_igla-coder-pipeline.json | stale | specs/igla/coder/pipeline.t27 changed since sealing +coder_igla-coder-prm.json | stale | specs/igla/coder/prm.t27 changed since sealing +coder_igla-coder-tokenizer.json | stale | specs/igla/coder/tokenizer.t27 changed since sealing +coder_igla-coder-training.json | stale | specs/igla/coder/training.t27 changed since sealing +coder_igla-coder-weights.json | stale | specs/igla/coder/weights.t27 changed since sealing +experience_example.json | no-spec-path | the seal does not say which spec it describes +fbb-active-path.json | dangling | specs/fpga/fbb_active_path.t27 +format_conversion.json | dangling | specs/numeric/format_conversion.t27 +fpga-accelerator_Gf16Accelerator.json | dangling | examples/fpga-accelerator/gf16-accelerator.t27 +fpga_FPGA_Bridge.json | stale | specs/fpga/bridge.t27 changed since sealing +fpga_Fifo.json | stale | specs/fpga/fifo.t27 changed since sealing +fpga_FpgaStdlib.json | stale | specs/fpga/stdlib.t27 changed since sealing +fpga_Partition.json | stale | specs/fpga/partition.t27 changed since sealing +fpga_SPI_Master.json | stale | specs/fpga/spi.t27 changed since sealing +fpga_avs-controller-48.json | dangling | specs/fpga/avs_controller_48.t27 +fpga_avs-controller-96.json | dangling | specs/fpga/avs_controller_96.t27 +fpga_avs-reconf.json | dangling | specs/fpga/avs_reconf.t27 +fpga_fbb-active-path.json | dangling | specs/fpga/fbb_active_path.t27 +fpga_gf16-to-fp16.json | dangling | specs/fpga/gf16_to_fp16.t27 +fpga_gf16-to-posit16.json | dangling | specs/fpga/gf16_to_posit16.t27 +fpga_gf32-to-fp32.json | dangling | specs/fpga/gf32_to_fp32.t27 +fpga_purkinje-thermal-gate.json | dangling | specs/fpga/purkinje_thermal_gate.t27 +fpga_rbb-fbb-cap-boost.json | dangling | specs/fpga/rbb_fbb_cap_boost.t27 +fpga_sacred-dfs_gate.json | dangling | specs/fpga/dfs_gate.t27 +fpga_sacred-drowsy_ret.json | dangling | specs/fpga/drowsy_ret.t27 +fpga_sacred-holo_mux_x4.json | dangling | specs/fpga/holo_mux_x4.t27 +fpga_sacred-lane_precheck.json | dangling | specs/fpga/lane_l_precheck.t27 +fpga_sacred-lut_npu_81_entry.json | dangling | specs/fpga/lut_npu_81_entry.t27 +fpga_sacred-null_pe.json | dangling | specs/fpga/null_pe.t27 +fpga_sacred-sparse_mask.json | dangling | specs/fpga/sparse_mask.t27 +fpga_sacred-sparse_skip.json | dangling | specs/fpga/sparse_skip.t27 +fpga_sacred-spec_exit.json | dangling | specs/fpga/spec_exit.t27 +fpga_sacred-stoch_round.json | dangling | specs/fpga/stoch_round.t27 +fpga_sacred-subth_clk.json | dangling | specs/fpga/subth_clk.t27 +gf16-to-fp16.json | dangling | specs/fpga/gf16_to_fp16.t27 +gf16-to-posit16.json | dangling | specs/fpga/gf16_to_posit16.t27 +gf32-to-fp32.json | dangling | specs/fpga/gf32_to_fp32.t27 +gwt_model.json | dangling | specs/brain/gwt_model.t27 +isa_TernaryEncoding.json | stale | specs/isa/ternary_encoding.t27 changed since sealing +math_math-igla-primitives.json | dangling | specs/math/igla_primitives.t27 +ml-quantization_ModelQuantization.json | dangling | examples/ml-quantization/model-quant.t27 +ml_TernaryBackprop.json | dangling | specs/ml/ternary_backprop.t27 +ml_TernaryLayer.json | dangling | specs/ml/ternary_layer.t27 +ml_TernaryLoss.json | dangling | specs/ml/ternary_loss.t27 +ml_TernaryMLP.json | dangling | specs/ml/ternary_mlp.t27 +ml_TernaryNeuron.json | dangling | specs/ml/ternary_neuron.t27 +network_d2d-conformance.json | dangling | specs/network/d2d_conformance.t27 +network_d2d-protocol.json | dangling | specs/network/d2d_protocol.t27 +nn_PhiRoPE.json | stale | specs/nn/phi_rope.t27 changed since sealing +nn_SacredAttentionPhi.json | stale | specs/nn/sacred_attention.t27 changed since sealing +numeric_Binary16.json | dangling | specs/numeric/binary16.t27 +numeric_CompetitiveTests.json | stale | specs/numeric/gf_competitive.t27 changed since sealing +numeric_FormatsCatalog.json | stale | specs/numeric/formats_catalog.t27 changed since sealing +numeric_GF128.json | stale | specs/numeric/gf128.t27 changed since sealing +numeric_GF256.json | stale | specs/numeric/gf256.t27 changed since sealing +numeric_GoldenFloatFamily.json | stale | specs/numeric/goldenfloat_family.t27 changed since sealing +numeric_Int4.json | dangling | specs/numeric/int4.t27 +numeric_Int8.json | dangling | specs/numeric/int8.t27 +numeric_NF4.json | dangling | specs/numeric/nf4.t27 +numeric_TriNetFormats.json | dangling | specs/numeric/tri_net_formats.t27 +numeric_format_conversion.json | dangling | specs/numeric/format_conversion.t27 +numeric_triformat-fp8_e4m3.json | dangling | specs/numeric/fp8_e4m3.t27 +numeric_triformat-fp8_e5m2.json | dangling | specs/numeric/fp8_e5m2.t27 +numeric_triformat-posit16.json | dangling | specs/numeric/posit16.t27 +performance_tops-w-22fdx.json | dangling | specs/performance/tops_w_22fdx.t27 +pipeline_SpecWriter.json | stale | specs/tri/pipeline/spec_writer.t27 changed since sealing +pipeline_Workflow.json | stale | specs/tri/pipeline/workflow.t27 changed since sealing +power_state-machine-mapping.json | dangling | specs/power/state_machine_mapping.t27 +property_test_template.json | stale | specs/math/property_test_template.t27 changed since sealing +purkinje-thermal-gate.json | dangling | specs/fpga/purkinje_thermal_gate.t27 +race_igla-race-adder-tree.json | stale | specs/igla/race/adder_tree.t27 changed since sealing +race_igla-race-backend.json | stale | specs/igla/race/backend.t27 changed since sealing +race_igla-race-bram-weights.json | stale | specs/igla/race/bram_weights.t27 changed since sealing +race_igla-race-cordic-fixed.json | stale | specs/igla/race/cordic_fixed.t27 changed since sealing +race_igla-race-cordic-top.json | stale | specs/igla/race/cordic_top.t27 changed since sealing +race_igla-race-cordic.json | stale | specs/igla/race/cordic.t27 changed since sealing +race_igla-race-eda.json | stale | specs/igla/race/eda.t27 changed since sealing +race_igla-race-formal.json | stale | specs/igla/race/formal.t27 changed since sealing +race_igla-race-gemm.json | stale | specs/igla/race/gemm.t27 changed since sealing +race_igla-race-opcodes.json | stale | specs/igla/race/opcodes.t27 changed since sealing +race_igla-race-rtl.json | stale | specs/igla/race/rtl.t27 changed since sealing +race_igla-race-systolic-array.json | stale | specs/igla/race/systolic_array.t27 changed since sealing +race_igla-race-systolic-ternary.json | stale | specs/igla/race/systolic_ternary.t27 changed since sealing +race_igla-race-ternary-gemm.json | stale | specs/igla/race/ternary_gemm.t27 changed since sealing +race_igla-race-ternary-inference.json | stale | specs/igla/race/ternary_inference.t27 changed since sealing +race_igla-race-ternary-mac.json | stale | specs/igla/race/ternary_mac.t27 changed since sealing +race_igla-race-yosys.json | stale | specs/igla/race/yosys.t27 changed since sealing +radix_economy.json | stale | specs/math/radix_economy.t27 changed since sealing +sacred-dfs_gate.json | dangling | specs/fpga/dfs_gate.t27 +sacred-drowsy_ret.json | dangling | specs/fpga/drowsy_ret.t27 +sacred-holo_mux_x4.json | dangling | specs/fpga/holo_mux_x4.t27 +sacred-lane_precheck.json | dangling | specs/fpga/lane_l_precheck.t27 +sacred-lut_npu_81_entry.json | dangling | specs/fpga/lut_npu_81_entry.t27 +sacred-null_pe.json | dangling | specs/fpga/null_pe.t27 +sacred-sparse_mask.json | dangling | specs/fpga/sparse_mask.t27 +sacred-sparse_skip.json | dangling | specs/fpga/sparse_skip.t27 +sacred-spec_exit.json | dangling | specs/fpga/spec_exit.t27 +sacred-stoch_round.json | dangling | specs/fpga/stoch_round.t27 +sacred-subth_clk.json | dangling | specs/fpga/subth_clk.t27 +sacred_DarkMatter.json | stale | specs/sacred/dark_matter.t27 changed since sealing +sacred_QuantumGravity.json | stale | specs/sacred/quantum_gravity.t27 changed since sealing +sacred_SacredIdentity.json | stale | specs/sacred/sacred_identity.t27 changed since sealing +sandbox_sandbox.json | stale | specs/sandbox/sandbox.tri changed since sealing +scientific-computing_NumericalMethods.json | dangling | examples/scientific-computing/numerical-methods.t27 +search_SearchMatch.json | stale | specs/tri/search/match.t27 changed since sealing +simulation_tri-net-system-sim.json | dangling | specs/simulation/tri_net_system_sim.t27 +specs_test_array_literal_inline.json | dangling | specs/test_array_literal_inline.t27 +specs_test_ternary_hir.json | dangling | specs/test_ternary_hir.t27 +ternary_GftBitnetNeuron.json | stale | specs/ternary/gft_bitnet_neuron.t27 changed since sealing +ternary_GftClassifier4.json | stale | specs/ternary/gft_classifier4.t27 changed since sealing +ternary_GftLayer3.json | stale | specs/ternary/gft_layer3.t27 changed since sealing +ternary_GftLayer4.json | stale | specs/ternary/gft_layer4.t27 changed since sealing +ternary_GftMlp2.json | stale | specs/ternary/gft_mlp2.t27 changed since sealing +ternary_GftMlp3.json | stale | specs/ternary/gft_mlp3.t27 changed since sealing +ternary_GftNeuronFull.json | stale | specs/ternary/gft_neuron_full.t27 changed since sealing +ternary_GftSgdStep.json | stale | specs/ternary/gft_sgd_step.t27 changed since sealing +ternary_GftSignedDot4.json | stale | specs/ternary/gft_signed_dot4.t27 changed since sealing +ternary_GftSignedMac.json | stale | specs/ternary/gft_signed_mac.t27 changed since sealing +ternary_GftSoftmax4.json | stale | specs/ternary/gft_softmax4.t27 changed since sealing +ternary_GftSoftmaxGrad4.json | stale | specs/ternary/gft_softmax_grad4.t27 changed since sealing +testbench_tri-net-tb.json | dangling | specs/testbench/tri_net_tb.t27 +transformer_FeedForward.json | stale | specs/ml/transformer/feed_forward_network.t27 changed since sealing +tri::sync.json | dangling | specs/tri/sync.t27 +tri_tri::sync.json | dangling | specs/tri/sync.t27 +tricompiler-parser.json | stale | specs/compiler/parser.t27 changed since sealing +triformat-fp8_e4m3.json | dangling | specs/numeric/fp8_e4m3.t27 +triformat-fp8_e5m2.json | dangling | specs/numeric/fp8_e5m2.t27 +triformat-gf16.json | stale | specs/numeric/gf16.t27 changed since sealing +triformat-posit16.json | dangling | specs/numeric/posit16.t27 +utils_ArrowTime.json | stale | specs/tri/utils/arrow_time.t27 changed since sealing +utils_TriArgs.json | stale | specs/tri/utils/args.t27 changed since sealing +utils_TriLogger.json | stale | specs/tri/utils/logger.t27 changed since sealing +utils_TriString.json | stale | specs/tri/utils/string.t27 changed since sealing +verdict_example.json | no-spec-path | the seal does not say which spec it describes +vsa_VSACore.json | stale | specs/test_framework/core.t27 changed since sealing +webassembly_GfCalculator.json | dangling | examples/webassembly/gf-calculator.t27 From 9da86d4f7eab9cb65afc85e7d433e663305801da Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Tue, 18 Aug 2026 23:15:48 +0700 Subject: [PATCH 3/8] docs(seal): characterise the 89 dangling seals, and correct my own count Split by whether the spec ever existed: 74 did exist in history -- deleted or moved. Sixteen went in one commit, 692ba5263 'feat(clara): Complete DARPA CLARA PA-25-07-02 submission', which removed specs/ml/ternary_{backprop,layer,loss,mlp,neuron}.t27 and others. Ordinary orphans of a deletion. 15 found in NO commit under any path. Each records a spec_hash and all four gen_hash_{c,rust,verilog,zig} -- reproducibility claims for a file nobody can regenerate or check. All sealed 2026-06-17/18. Four of them are GF16 comparison and claims specs, in a repository whose GF16 claims have been withdrawn twice. Stated as found and no further; the benign reading is that they were sealed from an uncommitted working tree. A correction to my own first pass. I tested existence with 'git log --diff-filter=D -- ', which only finds a deletion recorded at that same path, and it reported 73 specs as never having existed. Re-tested by basename across all history the number is 15. My instrument overstated by nearly fivefold, and '73 seals reference specs that never existed' would have been a serious and unsupported accusation. That is the fourth time this session an anomaly came from the instrument rather than the thing measured. When a scan reports something alarming about the repository, re-derive it a second way before writing it down. Refs #2209 Co-Authored-By: Claude Opus 5 --- docs/NOW.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/NOW.md b/docs/NOW.md index 5fa1041fc..472d998da 100644 --- a/docs/NOW.md +++ b/docs/NOW.md @@ -3,6 +3,8 @@ Last updated: 2026-08-18 ## ci: give seal-coverage a body, and measure what it finds (Closes #2209) +- **The 89 dangling, characterised:** 74 name specs that DID exist in history (16 of them removed by one commit, \`692ba5263\` DARPA CLARA); **15 name specs found in no commit under any path**, each recording a spec_hash and all four gen_hashes -- reproducibility claims nobody can check. Four of those 15 are GF16 comparison/claims specs, in a repository whose GF16 claims have been withdrawn twice. Stated as found, not further +- **A correction to my own first pass:** I tested existence with \`git log --diff-filter=D -- \`, which only sees a deletion recorded at that same path, and reported **73** never-existed. By basename across all history it is **15** -- my instrument overstated fivefold, and "73 seals reference specs that never existed" would have been a serious unsupported accusation. **Fourth time this session an anomaly came from the instrument, not the thing measured** - **The last decorative required check.** `seal-coverage.yml` was `echo "Running SEAL coverage analysis..."` - **Two attempts to establish what it should assert.** In #2191 I matched seal FILENAMES against spec filenames and got "1668 orphans of 1714" -- a finding about my assumption. Seals are keyed by MODULE name; the spec is named inside, in `spec_path`. I wrote neither check nor deletion then and said so; this returns to it From 11d65e20c19becd7ddc91729009acbe4cf4ca099 Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Tue, 18 Aug 2026 23:23:54 +0700 Subject: [PATCH 4/8] verify(seal): split dangling from phantom, and record the instrument lesson A seal whose spec was committed and later deleted, and a seal whose spec appears in no commit at all, are two problems sharing one symptom. Their repairs differ, so the gate no longer calls them the same thing: 74 dangling the spec was committed then deleted -- 16 by one commit, 692ba5263 (DARPA CLARA submission). Remove the seal with the spec, or restore both. 15 phantom the spec is in no commit and nowhere on disk. Its spec_hash and four gen_hashes name a file nobody can fetch, so the record has no checkable content. For four of them -- all GF16 claims/comparison specs -- the seal file is the ONLY trace of the module in the tree. _ever_existed asks git twice, by exact path and by basename across all history, because the one-way version reported 73 phantoms where there are 15. The negative control caught its own staleness: splitting the classification made the planted missing-spec case phantom rather than dangling, and the control failed until updated. That is what a control is for. Skill ci-gates gains two sections. Section 7 records four occasions in one session where an anomaly came from the instrument rather than the thing measured -- the depth statistic ranking grids, a regex swallowing five definitions, a testbench truncating i16 to a byte, and this git filter overstating fivefold. None was caught by reasoning; three by a negative control and one by re-deriving the number a different way. The corollary is that the more alarming a finding is, the more likely it is yours: all four false alarms were accusations, and all four true causes were typos and wrong regexes. Section 8 records that a gate's vocabulary is part of its output. Refs #2209 Co-Authored-By: Claude Opus 5 --- .claude/skills/ci-gates/SKILL.md | 42 +++++++++++++++++++ tools/check_seal_coverage.py | 72 +++++++++++++++++++++++++++----- tools/seal_baseline.txt | 30 ++++++------- 3 files changed, 119 insertions(+), 25 deletions(-) diff --git a/.claude/skills/ci-gates/SKILL.md b/.claude/skills/ci-gates/SKILL.md index c2495366c..d76490a10 100644 --- a/.claude/skills/ci-gates/SKILL.md +++ b/.claude/skills/ci-gates/SKILL.md @@ -128,6 +128,48 @@ The workflow's `name:` may change freely. `jobs.:` may not. When `repos/:owner/:repo/branches/master/protection` returns nothing useful, read the contexts off a recently merged PR: `gh pr checks | awk '{print $1}' | sort -u`. +## 7. When a scan says something alarming, re-derive it a second way before writing it down + +Four times in one session an anomaly came from the instrument rather than the thing +measured. Every one would have been reported as a fact about the repository. + +| what the instrument said | what was true | why it lied | +|---|---|---| +| "two of four optima are not identified" | the opposite — all four narrow, mutually incompatible | `depth` measured the gap to the nearest **grid point**, so it ranked the grids | +| "`tmul` has diverged across the BitNet family" | all 15 copies are one function | a regex ending at `\n}` swallowed five definitions in a spec written on one line; and `if(ta==1)` vs `if (ta == 1)` hash differently | +| Verilog arm silently narrower than C and Rust | caught before it ran | the testbench generator sliced every argument `[7:0]`, hardcoded, while `sign0` takes `i16` | +| "73 seals reference specs that never existed" | **15** | `git log --diff-filter=D -- ` only sees a deletion recorded at that path; by basename across all history the count is a fifth of that | + +None was caught by reasoning. Three were caught by a **negative control** — plant the +fault, run, read the output — and one by re-deriving the same number a different way. + +**The rule.** A scan that reports something bad about the tree is a claim like any +other, and the first version of it is usually a claim about the scan. Before writing it +down: derive it a second way, and prefer a way that shares no code with the first. +`tools/check_seal_coverage.py` does this in-line — `_ever_existed` asks git twice, by +path and by basename, because the one-way version overstated fivefold. + +**The corollary about severity.** The more alarming the finding, the more likely it is +yours. "Seals reference specs that never existed" and "the backends diverge" are +accusations; "a spec has a typo" and "a regex is wrong" are not. The session's four +false alarms were all in the first category, and all four true causes were in the +second. + +## 8. Name the kinds of a failure separately when their fixes differ + +`check_seal_coverage.py` first reported 89 **dangling** seals. Splitting by whether the +spec ever existed gives two problems that share nothing but a symptom: + +* **74 dangling** — the spec was committed and later deleted, 16 of them by one + identifiable commit. Fix: remove the seal with the spec, or restore both. +* **15 phantom** — the spec appears in no commit and is nowhere on disk. Its + `spec_hash` and four `gen_hash_*` name a file nobody can fetch, so the record has no + checkable content. For four of them the seal file is the **only** trace of the module + anywhere in the tree. Fix: find the spec, or drop the seal. + +One word for both would have sent a reader to the wrong repair for 15 of 89 cases. A +gate's vocabulary is part of its output. + --- ## Writing a gate here diff --git a/tools/check_seal_coverage.py b/tools/check_seal_coverage.py index a34f80875..941bbbb04 100755 --- a/tools/check_seal_coverage.py +++ b/tools/check_seal_coverage.py @@ -24,9 +24,12 @@ State when this was written -- 1714 seals: 1507 valid - 111 stale spec changed after sealing - 89 dangling spec deleted (basename not found anywhere in git) - 2 dangling spec moved: specs/vsa/core.t27 -> specs/test_framework/core.t27 + 113 stale spec changed after sealing + 74 dangling spec was committed, then deleted -- 16 of them by one commit, + 692ba5263 (DARPA CLARA submission) + 15 phantom spec appears in NO commit and is nowhere on disk. Four of these + are GF16 claims/comparison specs, and for those the seal file is + the ONLY trace of the module anywhere in the tree 5 no spec_path The 207 broken ones are recorded in tools/seal_baseline.txt as debt, one per line, so @@ -45,6 +48,7 @@ import json import os import pathlib +import subprocess import sys ROOT = pathlib.Path(__file__).resolve().parent.parent @@ -68,7 +72,14 @@ def scan(root=ROOT): continue full = root / sp if not full.exists(): - bad.append((name, "dangling", sp)) + # Two different problems wearing one word. A seal for a spec that WAS + # committed and then deleted is an orphan of that deletion: remove it with + # the spec, or restore both. A seal for a spec that appears in no commit + # names nothing anyone can fetch -- its spec_hash and four gen_hashes + # describe a file that is not in the history, so the record has no + # checkable content at all. The fixes are not the same, so the gate does + # not call them the same thing. + bad.append((name, "dangling" if _ever_existed(root, sp) else "phantom", sp)) continue want = (d.get("spec_hash") or "") algo, _, digest = want.partition(":") @@ -81,6 +92,36 @@ def scan(root=ROOT): return len(seals), bad +_EVER = {} + + +def _ever_existed(root, sp): + """Did this spec appear in ANY commit, under this path or its basename? + + Checked two ways on purpose. My first pass used + `git log --diff-filter=D -- `, which only sees a deletion recorded at + that same path, and it reported 73 specs as never having existed. By basename + across all history the number is 15. An instrument that overstates fivefold is how + 'seals reference specs that never existed' becomes an accusation nobody can + support -- so this asks twice. + """ + if sp in _EVER: + return _EVER[sp] + base = os.path.basename(sp) + hit = False + for args in (["--", sp], ["--", "*/" + base]): + try: + r = subprocess.run(["git", "log", "--all", "--oneline"] + args, + cwd=root, capture_output=True, text=True, timeout=30) + if r.stdout.strip(): + hit = True + break + except Exception: + return True # cannot tell: assume the milder classification + _EVER[sp] = hit + return hit + + def baseline(): if not BASELINE.exists(): return set() @@ -106,9 +147,15 @@ def self_check(): {"module": "Gone", "spec_path": "specs/missing.t27", "spec_hash": "sha256:" + good})) total, bad = scan(t) kinds = sorted(k for _, k, _ in bad) - ok = total == 3 and kinds == ["dangling", "stale"] - print(f" self-check: 3 seals scanned, stale and dangling both reported, good one " - f"silent = {ok}") + # The temp tree has no git history, so a missing spec is correctly PHANTOM + # rather than dangling -- that distinction is the point of this scan and the + # control asserts it rather than the older two-way answer. This check failed + # when the classification was split, which is what a control is for. + ok = total == 3 and kinds == ["phantom", "stale"] + print(f" self-check: 3 seals scanned; stale reported, missing-spec classified " + f"phantom (no history), good one silent = {ok}") + if not ok: + print(f" got {total} seals, kinds {kinds}") return 0 if ok else 1 @@ -142,9 +189,14 @@ def main(): for n, k, d in new: print(f" {n} [{k}]") print(f" {d}") - print("\n A stale seal asserts that a spec produces four specific target hashes,") - print(" when the spec has changed since. Re-seal it, or add it to") - print(f" {BASELINE.name} with --update-baseline if the debt is deliberate.") + print("\n stale the spec changed after sealing, so the four gen_hashes describe") + print(" something it no longer produces. Re-seal it.") + print(" dangling the spec was committed and later deleted. Remove the seal with it,") + print(" or restore both.") + print(" phantom the spec appears in NO commit. The seal's spec_hash and four") + print(" gen_hashes name a file nobody can fetch, so there is nothing in") + print(" the record to check. Find the spec or drop the seal.") + print(f"\n Deliberate debt goes in {BASELINE.name} via --update-baseline.") return 1 diff --git a/tools/seal_baseline.txt b/tools/seal_baseline.txt index beb94e17b..150ef4218 100644 --- a/tools/seal_baseline.txt +++ b/tools/seal_baseline.txt @@ -8,7 +8,7 @@ BaseTypes.json | stale | specs/base/types.t27 changed since sealing Binary16.json | dangling | specs/numeric/binary16.t27 CompetitiveTests.json | stale | specs/numeric/gf_competitive.t27 changed since sealing Composition.json | stale | specs/ar/composition.t27 changed since sealing -D2D_Conformance.json | dangling | specs/network/d2d_conformance.t27 +D2D_Conformance.json | phantom | specs/network/d2d_conformance.t27 DatalogEngine.json | stale | specs/ar/datalog_engine.t27 changed since sealing Explainability.json | stale | specs/ar/explainability.t27 changed since sealing FPGA_Bridge.json | stale | specs/fpga/bridge.t27 changed since sealing @@ -58,14 +58,14 @@ ar_TernaryLogic.json | stale | specs/ar/ternary_logic.t27 changed since sealing avs-controller-48.json | dangling | specs/fpga/avs_controller_48.t27 avs-controller-96.json | dangling | specs/fpga/avs_controller_96.t27 avs-reconf.json | dangling | specs/fpga/avs_reconf.t27 -benchmarks_GF16VsBFloat16NMSE.json | dangling | specs/benchmarks/gf16_vs_bfloat16_nmse.t27 +benchmarks_GF16VsBFloat16NMSE.json | phantom | specs/benchmarks/gf16_vs_bfloat16_nmse.t27 brain_domains.json | no-spec-path | the seal does not say which spec it describes brain_gwt_model.json | dangling | specs/brain/gwt_model.t27 brain_pipeline.json | no-spec-path | the seal does not say which spec it describes brain_summary.json | no-spec-path | the seal does not say which spec it describes -claims_claims-legend.json | dangling | specs/claims/claims_legend.t27 -claims_gf16-mx-alliance-anchoring.json | dangling | specs/claims/gf16_mx_alliance_anchoring.t27 -claims_gf16-nmse-comparison.json | dangling | specs/claims/gf16_nmse_comparison.t27 +claims_claims-legend.json | phantom | specs/claims/claims_legend.t27 +claims_gf16-mx-alliance-anchoring.json | phantom | specs/claims/gf16_mx_alliance_anchoring.t27 +claims_gf16-nmse-comparison.json | phantom | specs/claims/gf16_nmse_comparison.t27 coder_igla-coder-arch.json | stale | specs/igla/coder/arch.t27 changed since sealing coder_igla-coder-bench-proxy.json | stale | specs/igla/coder/bench_proxy.t27 changed since sealing coder_igla-coder-benchmark.json | stale | specs/igla/coder/benchmark.t27 changed since sealing @@ -93,7 +93,7 @@ fpga_gf16-to-fp16.json | dangling | specs/fpga/gf16_to_fp16.t27 fpga_gf16-to-posit16.json | dangling | specs/fpga/gf16_to_posit16.t27 fpga_gf32-to-fp32.json | dangling | specs/fpga/gf32_to_fp32.t27 fpga_purkinje-thermal-gate.json | dangling | specs/fpga/purkinje_thermal_gate.t27 -fpga_rbb-fbb-cap-boost.json | dangling | specs/fpga/rbb_fbb_cap_boost.t27 +fpga_rbb-fbb-cap-boost.json | phantom | specs/fpga/rbb_fbb_cap_boost.t27 fpga_sacred-dfs_gate.json | dangling | specs/fpga/dfs_gate.t27 fpga_sacred-drowsy_ret.json | dangling | specs/fpga/drowsy_ret.t27 fpga_sacred-holo_mux_x4.json | dangling | specs/fpga/holo_mux_x4.t27 @@ -110,15 +110,15 @@ gf16-to-posit16.json | dangling | specs/fpga/gf16_to_posit16.t27 gf32-to-fp32.json | dangling | specs/fpga/gf32_to_fp32.t27 gwt_model.json | dangling | specs/brain/gwt_model.t27 isa_TernaryEncoding.json | stale | specs/isa/ternary_encoding.t27 changed since sealing -math_math-igla-primitives.json | dangling | specs/math/igla_primitives.t27 +math_math-igla-primitives.json | phantom | specs/math/igla_primitives.t27 ml-quantization_ModelQuantization.json | dangling | examples/ml-quantization/model-quant.t27 ml_TernaryBackprop.json | dangling | specs/ml/ternary_backprop.t27 ml_TernaryLayer.json | dangling | specs/ml/ternary_layer.t27 ml_TernaryLoss.json | dangling | specs/ml/ternary_loss.t27 ml_TernaryMLP.json | dangling | specs/ml/ternary_mlp.t27 ml_TernaryNeuron.json | dangling | specs/ml/ternary_neuron.t27 -network_d2d-conformance.json | dangling | specs/network/d2d_conformance.t27 -network_d2d-protocol.json | dangling | specs/network/d2d_protocol.t27 +network_d2d-conformance.json | phantom | specs/network/d2d_conformance.t27 +network_d2d-protocol.json | phantom | specs/network/d2d_protocol.t27 nn_PhiRoPE.json | stale | specs/nn/phi_rope.t27 changed since sealing nn_SacredAttentionPhi.json | stale | specs/nn/sacred_attention.t27 changed since sealing numeric_Binary16.json | dangling | specs/numeric/binary16.t27 @@ -135,10 +135,10 @@ numeric_format_conversion.json | dangling | specs/numeric/format_conversion.t27 numeric_triformat-fp8_e4m3.json | dangling | specs/numeric/fp8_e4m3.t27 numeric_triformat-fp8_e5m2.json | dangling | specs/numeric/fp8_e5m2.t27 numeric_triformat-posit16.json | dangling | specs/numeric/posit16.t27 -performance_tops-w-22fdx.json | dangling | specs/performance/tops_w_22fdx.t27 +performance_tops-w-22fdx.json | phantom | specs/performance/tops_w_22fdx.t27 pipeline_SpecWriter.json | stale | specs/tri/pipeline/spec_writer.t27 changed since sealing pipeline_Workflow.json | stale | specs/tri/pipeline/workflow.t27 changed since sealing -power_state-machine-mapping.json | dangling | specs/power/state_machine_mapping.t27 +power_state-machine-mapping.json | phantom | specs/power/state_machine_mapping.t27 property_test_template.json | stale | specs/math/property_test_template.t27 changed since sealing purkinje-thermal-gate.json | dangling | specs/fpga/purkinje_thermal_gate.t27 race_igla-race-adder-tree.json | stale | specs/igla/race/adder_tree.t27 changed since sealing @@ -176,9 +176,9 @@ sacred_SacredIdentity.json | stale | specs/sacred/sacred_identity.t27 changed si sandbox_sandbox.json | stale | specs/sandbox/sandbox.tri changed since sealing scientific-computing_NumericalMethods.json | dangling | examples/scientific-computing/numerical-methods.t27 search_SearchMatch.json | stale | specs/tri/search/match.t27 changed since sealing -simulation_tri-net-system-sim.json | dangling | specs/simulation/tri_net_system_sim.t27 -specs_test_array_literal_inline.json | dangling | specs/test_array_literal_inline.t27 -specs_test_ternary_hir.json | dangling | specs/test_ternary_hir.t27 +simulation_tri-net-system-sim.json | phantom | specs/simulation/tri_net_system_sim.t27 +specs_test_array_literal_inline.json | phantom | specs/test_array_literal_inline.t27 +specs_test_ternary_hir.json | phantom | specs/test_ternary_hir.t27 ternary_GftBitnetNeuron.json | stale | specs/ternary/gft_bitnet_neuron.t27 changed since sealing ternary_GftClassifier4.json | stale | specs/ternary/gft_classifier4.t27 changed since sealing ternary_GftLayer3.json | stale | specs/ternary/gft_layer3.t27 changed since sealing @@ -191,7 +191,7 @@ ternary_GftSignedDot4.json | stale | specs/ternary/gft_signed_dot4.t27 changed s ternary_GftSignedMac.json | stale | specs/ternary/gft_signed_mac.t27 changed since sealing ternary_GftSoftmax4.json | stale | specs/ternary/gft_softmax4.t27 changed since sealing ternary_GftSoftmaxGrad4.json | stale | specs/ternary/gft_softmax_grad4.t27 changed since sealing -testbench_tri-net-tb.json | dangling | specs/testbench/tri_net_tb.t27 +testbench_tri-net-tb.json | phantom | specs/testbench/tri_net_tb.t27 transformer_FeedForward.json | stale | specs/ml/transformer/feed_forward_network.t27 changed since sealing tri::sync.json | dangling | specs/tri/sync.t27 tri_tri::sync.json | dangling | specs/tri/sync.t27 From fd020b53ced07c40d4142c7181ed2868d39fde96 Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Tue, 18 Aug 2026 23:57:03 +0700 Subject: [PATCH 5/8] verify: measure what actually compiles, and stop re-sealing what does not The plan was to re-seal the 113 stale seals. Testing one instead of batching stopped it and found something larger. t27c seal --save seals a spec that does not generate. specs/ml/optimizer/adamw.t27 fails on all four backends; seal --save wrote a seal anyway with gen_hash_rust=none, into a different filename (optimizer_AdamW.json, not AdamW.json), leaving the original stale seal untouched. Batch re-sealing would have created 113 duplicates under new names, blessed the non-generating ones with none hashes, and fixed nothing. 348 of 1114 specs (31.2%) do not generate with any backend, in a repository whose constitution makes specs the single source of truth. 1114 tracked 766 generate 68.8% 348 do not generate 31.2% The alternative explanation was checked and eliminated. A spec written for one target should not count as broken because another rejects it, so the gate accepts a spec if ANY backend takes it. On a 25-spec random sample of the 348, zero generated with any of gen-c/gen-rust/gen-verilog/gen-zig -- they fail in the parser, before a backend is reached. I checked because '31% of the source of truth does not compile' is an alarming claim, and by ci-gates SKILL.md section 7 -- four false alarms in this session, every one from the instrument -- an alarming claim is usually a fault in the measurement. specs/tri/ 70 parse error at module level 120 specs/scratch/ 58 parse error in fn 107 specs/fpga/ 35 Expected RBrace 45 specs/igla/ 15 Expected LBrace 36 specs/numeric/ 15 unknown cast target 34 specs/base/types.t27 is among them, failing at pack_trit line 172. tools/check_specs_generate.py records the 348 as debt with each compiler message, fails when a spec that used to generate stops, and reports when a baselined spec starts generating so the list cannot rot in the other direction either. The 113 stale seals are deliberately not re-sealed: 46 of the 95 specs behind them do not generate, and sealing those would record reproducibility for output that does not exist. Closes #2210 Refs #2209 Co-Authored-By: Claude Opus 5 --- .github/workflows/emit-bitexact-gate.yml | 11 + .trinity/seals/optimizer_AdamW.json | 11 - docs/NOW.md | 13 + tools/check_specs_generate.py | 172 +++++++++++ tools/specs_generate_baseline.txt | 350 +++++++++++++++++++++++ 5 files changed, 546 insertions(+), 11 deletions(-) delete mode 100644 .trinity/seals/optimizer_AdamW.json create mode 100755 tools/check_specs_generate.py create mode 100644 tools/specs_generate_baseline.txt diff --git a/.github/workflows/emit-bitexact-gate.yml b/.github/workflows/emit-bitexact-gate.yml index 0da58dcee..bae423d5c 100644 --- a/.github/workflows/emit-bitexact-gate.yml +++ b/.github/workflows/emit-bitexact-gate.yml @@ -21,6 +21,8 @@ on: - "bootstrap/**" - "cli/**" - "tools/check_specs_parse.py" + - "tools/check_specs_generate.py" + - "specs/**" - "tools/verify_exhaustive.py" - "tools/check_duplicate_agreement.py" - "specs/ternary/**" @@ -67,6 +69,15 @@ jobs: - name: Required specs parse run: python3 tools/check_specs_parse.py + # 348 of 1114 specs do not generate with ANY backend -- 31.2% of what the + # constitution calls the single source of truth. Not one is a backend mismatch: + # on a 25-spec sample, zero generated with any of the four. They are recorded as + # debt so this holds the line, and the number can only go down. + - name: Every spec still generates (negative control) + run: python3 tools/check_specs_generate.py --self-check + - name: Every spec still generates + run: python3 tools/check_specs_generate.py + # Ternary primitives have input spaces small enough to enumerate: a full adder # over three trits-in-a-byte is 16,777,216 inputs, about a second of CPU. A space # you can exhaust needs neither a sample nor a prover, and docs/POSITIONING.md diff --git a/.trinity/seals/optimizer_AdamW.json b/.trinity/seals/optimizer_AdamW.json deleted file mode 100644 index d66647a45..000000000 --- a/.trinity/seals/optimizer_AdamW.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "gen_hash_c": "sha256:16e802534d827180106fc3bd9f9a670fe146a4bbba30bc3ed18faa3e501e927b", - "gen_hash_rust": "sha256:99f91cd4d18e6813c5d417877d4761e4595a4a8d02a32123d8e497cb78230f56", - "gen_hash_verilog": "sha256:d237af48d846e5b2685b67ded11a62acfb6d41c5cce481c0f8781d5f86eb094d", - "gen_hash_zig": "sha256:0cece617def3aa5eaaf5b35a5ff65ba77a39b8b46fa9ac4b0351885fc6c934a3", - "module": "AdamW", - "ring": 12, - "sealed_at": "2026-08-06T15:25:18Z", - "spec_hash": "sha256:a6f6cfd8423f58f14d672d49bf6d42194d8b9fb1d145ed2c048b10f8a1d4763e", - "spec_path": "specs/ml/optimizer/adamw.t27" -} \ No newline at end of file diff --git a/docs/NOW.md b/docs/NOW.md index 472d998da..f2cb943a8 100644 --- a/docs/NOW.md +++ b/docs/NOW.md @@ -1,3 +1,16 @@ +# NOW -- 348 of 1114 specs do not generate (2026-08-18) + +Last updated: 2026-08-18 + +## verify: measure what actually compiles, and stop re-sealing what does not (Closes #2210) + +- **The plan was to re-seal 113 stale seals. Testing ONE instead of batching stopped it.** `specs/ml/optimizer/adamw.t27` fails on all four backends, and `t27c seal --save` sealed it anyway with `gen_hash_rust=none`, into a **different filename** (`optimizer_AdamW.json`), leaving the original stale seal untouched. The batch would have made 113 duplicates, blessed the broken ones with `none`, and fixed nothing +- **348 of 1114 specs (31.2%) do not generate with ANY backend**, in a repository whose constitution makes specs the single source of truth +- **The alternative was checked and eliminated.** A spec written for one target should not count as broken because another rejects it, so the gate accepts any backend. On a 25-spec random sample of the 348, **zero** generated with any of the four -- they fail in the parser, before a backend is reached. Checked precisely because "31% of the source of truth does not compile" is alarming, and by `ci-gates` §7 an alarming claim is usually the instrument +- `specs/tri/` 70, `specs/scratch/` 58, `specs/fpga/` 35, `specs/igla/` 15, `specs/numeric/` 15. Error classes: 120 module-level parse, 107 in-fn parse, 45 RBrace, 36 LBrace, 34 unknown cast target. **`specs/base/types.t27`** is among them, failing at `pack_trit` line 172 +- `tools/check_specs_generate.py` records the 348 as debt with each compiler message, fails when a working spec breaks, and **reports when a baselined spec starts working** so the list cannot rot in the other direction either +- **The 113 stale seals stay unsealed.** 46 of the 95 specs behind them do not generate; sealing those records reproducibility for output that does not exist. That is now a measured reason rather than a hunch + # NOW -- seal-coverage was an echo, and 207 seals do not hold (2026-08-18) Last updated: 2026-08-18 diff --git a/tools/check_specs_generate.py b/tools/check_specs_generate.py new file mode 100755 index 000000000..b4a8d4d51 --- /dev/null +++ b/tools/check_specs_generate.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python3 +"""Does every .t27 spec still compile to at least one target? + +The README says `.t27` specs in → Zig, Verilog, C out, and the constitution makes specs +the single source of truth. Measured on 2026-08-18: + + 1114 specs tracked + 766 generate 68.8% + 348 do NOT generate 31.2% + +Not one of the 348 is a backend mismatch. On a 25-spec random sample, **zero** generated +with any of gen-c / gen-rust / gen-verilog / gen-zig -- they fail in the parser, before a +backend is reached. That alternative was checked because "31% of the source of truth does +not compile" is an alarming claim, and an alarming claim is usually a fault in the +instrument (see .claude/skills/ci-gates/SKILL.md §7). + +Where they are, and how they fail: + + specs/tri/ 70 parse error at module level 120 + specs/scratch/ 58 parse error in fn 114 + specs/fpga/ 35 Expected RBrace 38 + specs/igla/ 15 Expected LBrace 36 + specs/numeric/ 15 unknown cast target 34 + ... Unexpected top-level token 4 + +How this was found, which matters for what to do next. `t27c seal --save` +re-seals a spec **that does not generate**, writing `gen_hash_rust=none`. So a stale seal +can be "fixed" into a seal that records reproducibility for output which does not exist. +Batch re-sealing the 113 stale seals would have blessed 46 non-generating specs that way, +and written them under new filenames besides, leaving the originals stale. Testing one +instead of the batch is what surfaced this. + +The 348 are recorded in tools/specs_generate_baseline.txt as debt, one per line with its +first compiler message, so this gate holds the line without demanding they all be fixed. +The number can only go down. + +Usage: + tools/check_specs_generate.py gate + tools/check_specs_generate.py --self-check negative control + tools/check_specs_generate.py --update-baseline + tools/check_specs_generate.py --summary counts by directory and error class + +Exits non-zero if a spec that used to generate stops generating. +""" +import collections +import os +import pathlib +import subprocess +import sys + +ROOT = pathlib.Path(__file__).resolve().parent.parent +BASELINE = ROOT / "tools/specs_generate_baseline.txt" +BACKENDS = ("c", "rust", "verilog", "zig") + + +def t27c(): + for p in ("target/release/t27c", "target/debug/t27c"): + c = ROOT / p + if c.exists(): + return str(c) + sys.exit("FAIL: t27c not built. Run: cargo build --release -p t27c") + + +def specs(): + r = subprocess.run(["git", "ls-files", "*.t27"], cwd=ROOT, capture_output=True, text=True) + return sorted(x for x in r.stdout.split() if x) + + +def generates(t, sp): + """(ok, first message). ok if ANY backend accepts it -- a spec written for one + target should not be reported as broken because another target rejects it.""" + first = "" + for m in BACKENDS: + r = subprocess.run([t, "gen-" + m, sp], capture_output=True, text=True, cwd=ROOT) + if r.returncode == 0: + return True, "" + if not first: + first = (r.stderr or r.stdout or "").strip().split("\n")[0][:150] + return False, first + + +def baseline(): + if not BASELINE.exists(): + return set() + return {l.split("|")[0].strip() for l in BASELINE.read_text().splitlines() + if l.strip() and not l.startswith("#")} + + +def self_check(): + """A spec with a deliberate syntax error must be reported; a good one must not.""" + import tempfile + t = t27c() + with tempfile.TemporaryDirectory() as td: + good = os.path.join(td, "good.t27") + bad = os.path.join(td, "bad.t27") + open(good, "w").write("module G;\nfn f(a: u8) -> u8 { return a; }\n") + open(bad, "w").write("module B;\nfn f(a: u8) -> u8 { return a\n") # missing ; and } + g_ok, _ = generates(t, good) + b_ok, msg = generates(t, bad) + ok = g_ok and not b_ok + print(f" self-check: valid spec generates = {g_ok}, broken spec reported = {not b_ok}") + if not b_ok and msg: + print(f" reported: {msg[:90]}") + return 0 if ok else 1 + + +def main(): + t = t27c() + if "--self-check" in sys.argv: + return self_check() + + all_specs = specs() + if not all_specs: + print("FAIL: git ls-files found no .t27 at all -- the scan is broken, not the tree") + return 1 + bad = [] + for sp in all_specs: + ok, msg = generates(t, sp) + if not ok: + bad.append((sp, msg)) + + if "--summary" in sys.argv: + print(f" {len(all_specs)} specs, {len(all_specs)-len(bad)} generate " + f"({100*(len(all_specs)-len(bad))/len(all_specs):.1f}%), {len(bad)} do not\n") + print(" by directory:") + for d, c in collections.Counter( + sp.split("/")[1] if sp.count("/") > 1 else "." for sp, _ in bad).most_common(12): + print(f" {c:>4} specs/{d}/") + print("\n by error class:") + def cls(m): + for k in ("unknown cast target", "parse error at module level", + "Unexpected top-level token", "Expected LBrace", "Expected RBrace", + "parse error in fn"): + if k in m: + return k + return m[:44] + for k, c in collections.Counter(cls(m) for _, m in bad).most_common(10): + print(f" {c:>4} {k}") + return 0 + + if "--update-baseline" in sys.argv: + BASELINE.write_text( + "# Specs that do not generate with ANY backend. Each line is a debt.\n" + "# Remove the line when the spec compiles; the gate then holds it compiling.\n" + + "".join(f"{sp} | {msg}\n" for sp, msg in bad)) + print(f" baseline written: {len(bad)} entries") + return 0 + + known = baseline() + new = [(sp, m) for sp, m in bad if sp not in known] + fixed = sorted(known - {sp for sp, _ in bad}) + if fixed: + print(f"NOTE {len(fixed)} spec(s) in the baseline now generate. Remove them from " + f"{BASELINE.name} so the gate holds them:") + for sp in fixed[:10]: + print(f" {sp}") + print() + if not new: + print(f"OK: {len(all_specs)} specs, {len(all_specs)-len(bad)} generate, " + f"{len(bad)} known-broken in {BASELINE.name}") + return 0 + print(f"FAIL: {len(new)} spec(s) newly do not generate with any backend\n") + for sp, m in new: + print(f" {sp}\n {m}") + print("\n The message is the compiler's own. A spec that does not generate is not a") + print(" source of truth for anything, and t27c seal --save will still seal it with") + print(" gen_hash=none -- so this must fail rather than be sealed over.") + return 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/specs_generate_baseline.txt b/tools/specs_generate_baseline.txt new file mode 100644 index 000000000..81c8dd85c --- /dev/null +++ b/tools/specs_generate_baseline.txt @@ -0,0 +1,350 @@ +# Specs that do not generate with ANY backend. Each line is a debt. +# Remove the line when the spec compiles; the gate then holds it compiling. +bootstrap/bootstrap/specs/physics/formula_registry.t27 | Error: Too many levels of symbolic links (os error 62) +bootstrap/src/codegen_python.t27 | Error: Compile error: parse error in fn 'map_trit_to_python_type' near line 36: Unexpected token in expression: Semicolon (';') at line 36:10 +compiler/cli/gen.t27 | Error: Compile error: parse error in fn 'gen' near line 84: Unexpected token in expression: Pipe ('|') at line 84:44 +compiler/cli/git.t27 | Error: Compile error: parse error in fn 'git_commit' near line 38: Expected RParen, got Dot ('.') at line 38:37 +compiler/cli/spec.t27 | Error: Compile error: parse error in fn 'spec_create' near line 19: Unexpected token in expression: PlusPlus ('++') at line 19:57 +compiler/codegen/c/codegen.t27 | Error: Compile error: parse error in fn 'emit_expression' near line 120: Unexpected token in expression: KwVar ('var') at line 120:14 +compiler/codegen/verilog/fpga_emission.t27 | Error: Compile error: parse error in fn 'emit_line' near line 720: Expected LBrace, got Colon (':') at line 720:39 +compiler/codegen/zig/runtime.t27 | Error: Compile error: parse error in fn 'generate_main' near line 15: Unexpected token in expression: PlusPlus ('++') at line 15:80 +compiler/parser/parser.t27 | Error: Compile error: parse error in fn 'Parser.new' near line 36: Expected RBrace, got KwConst ('const') at line 36:38 +compiler/runtime/commands.t27 | Error: Compile error: parse error in fn 'spec_create' near line 33: Unexpected token in expression: LBrace ('{') at line 33:42 +compiler/runtime/runtime.t27 | Error: Compile error: parse error in fn 'setup_stack_frame' near line 121: Unexpected token in expression: Equals ('=') at line 121:23 +compiler/runtime/validation.t27 | Error: Compile error: parse error in fn 'validate_policy_matrix' near line 216: parse error near line 216: parse error near line 216: Expected RBrace, +compiler/skill/registry.t27 | Error: Compile error: parse error in fn 'create_skill' near line 200: Expected RBrace, got KwConst ('const') at line 200:31 +examples/fpga/qmtech_minimal/design.t27 | Error: Compile error: parse error at module level near line 1: unexpected token after expression statement: Ident +specs/account/repo.t27 | Error: Compile error: Expected LBrace, got LParen ('(') at line 12:21 +specs/account/schema.t27 | Error: Compile error: Expected LBrace, got LParen ('(') at line 13:21 +specs/api/c_api_contract.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/api/sdk_contract.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/api/tri_net_api.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/ar/asp_solver.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident +specs/ar/coa_planning.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident +specs/ar/composition.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident +specs/ar/datalog_engine.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident +specs/ar/explainability.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident +specs/ar/proof_trace.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident +specs/ar/restraint.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident +specs/ar/ternary_logic.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident +specs/auth/config.t27 | Error: Compile error: Expected LBrace, got LParen ('(') at line 60:16 +specs/automation/wrapup-auto.t27 | Error: Compile error: parse error at module level near line 3: unexpected token after expression statement: Ident +specs/base/debounce.t27 | Error: Compile error: parse error at module level near line 8: Unexpected token in expression: LBrace ('{') at line 8:27 +specs/base/ring_32.t27 | Error: Compile error: parse error at module level near line 7: Unexpected token in expression: LBrace ('{') at line 7:27 +specs/base/ternary_add.t27 | Error: Compile error: parse error in fn 'max_value' near line 64: Expected LBrace, got Colon (':') at line 64:19 +specs/base/ternary_encoding.t27 | Error: Compile error: Expected LBrace, got Number ('257') at line 37:34 +specs/base/ternary_memory.t27 | Error: Compile error: Expected LBrace, got Number ('257') at line 45:25 +specs/base/types.t27 | Error: Compile error: parse error in fn 'pack_trit' near line 172: Unexpected token in expression: Equals ('=') at line 172:13 +specs/benchmarks/bench_main.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/benchmarks/bench_nn.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/benchmarks/gf16_bfloat16_nmse.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/benchmarks/ternary_vs_binary.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/brain/brain.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Number +specs/brain/neural_gamma.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/bus/pubsub.t27 | Error: Compile error: parse error in fn 'join_topic' near line 303: parse error near line 303: Unexpected token in expression: PlusPlus ('++') at line +specs/cloud/railway_deploy.t27 | Error: Compile error: parse error at module level near line 9: Unexpected token in expression: LBrace ('{') at line 9:27 +specs/compiler/linker.t27 | Error: Compile error: parse error in fn 'symbol_ref_new' near line 69: Unexpected token in expression: KwModule ('module') at line 69:27 +specs/compiler/mod_structure.t27 | Error: Compile error: parse error at module level near line 8: Unexpected token in expression: LBrace ('{') at line 8:27 +specs/compiler/optimizer.t27 | Error: Compile error: Expected LBrace, got Colon (':') at line 149:88 +specs/compiler/parser.t27 | Error: Compile error: parse error in fn 'parse_type_annotation' near line 272: parse error near line 272: Unexpected token in expression: PlusPlus ('+ +specs/compiler/typechecker.t27 | Error: Compile error: parse error in fn 'check_stmt' near line 373: parse error near line 373: parse error near line 373: Unexpected token in expressi +specs/config/load.t27 | Error: Compile error: parse error at module level near line 13: Expected RBrace, got Ident ('Config') at line 13:21 +specs/config/migrate.t27 | Error: Compile error: parse error in fn 'migrate_detect_version' near line 396: Expected RBrace, got Colon (':') at line 396:59 +specs/config/paths.t27 | Error: Compile error: parse error in fn 'basename' near line 256: Unexpected token in expression: RBracket (']') at line 256:37 +specs/conformance/e2e_scenarios.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/enrichment/audio_overview.t27 | Error: Compile error: parse error at module level near line 6: Unexpected token in expression: Colon (':') at line 6:18 +specs/enrichment/youtube_transcript.t27 | Error: Compile error: parse error at module level near line 6: Unexpected token in expression: Colon (':') at line 6:18 +specs/file/schema.t27 | Error: Compile error: parse error in fn 'is_hidden' near line 239: Expected DotDot, got LBrace ('{') at line 239:27 +specs/file/watcher.t27 | Error: Compile error: Expected LBrace, got LParen ('(') at line 14:21 +specs/fpga/boards/arty_a7_integration.t27 | Error: Compile error: parse error in fn 'test_baud_divisor' near line 95: Unexpected token in expression: KwInvariant ('invariant') at line 95:9 +specs/fpga/boards/qmtech_a100t_integration.t27 | Error: Compile error: parse error in fn 'test_baud_divisor' near line 58: Unexpected token in expression: KwInvariant ('invariant') at line 58:9 +specs/fpga/power_analysis.t27 | Error: Compile error: parse error in fn 'utilization_creation' near line 230: unexpected token after expression statement: Ident +specs/fpga/testbench/apb_bridge_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 75: Unexpected token in expression: KwInvariant ('invariant') at line 75:9 +specs/fpga/testbench/assembler_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 70: Unexpected token in expression: KwInvariant ('invariant') at line 70:9 +specs/fpga/testbench/axi4_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 114: Unexpected token in expression: KwInvariant ('invariant') at line 114:9 +specs/fpga/testbench/bootrom_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 64: Unexpected token in expression: KwInvariant ('invariant') at line 64:9 +specs/fpga/testbench/bridge_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 69: Unexpected token in expression: KwInvariant ('invariant') at line 69:9 +specs/fpga/testbench/clock_domain_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 62: Unexpected token in expression: KwInvariant ('invariant') at line 62:9 +specs/fpga/testbench/cts_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 65: Unexpected token in expression: KwInvariant ('invariant') at line 65:9 +specs/fpga/testbench/dft_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 86: Unexpected token in expression: KwInvariant ('invariant') at line 86:9 +specs/fpga/testbench/fifo_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 84: Unexpected token in expression: KwInvariant ('invariant') at line 84:9 +specs/fpga/testbench/formal_tb.t27 | Error: Compile error: parse error in fn 'test_reset_clears_asserts' near line 74: Unexpected token in expression: KwInvariant ('invariant') at line 74 +specs/fpga/testbench/gf16_accel_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 75: Unexpected token in expression: KwInvariant ('invariant') at line 75:9 +specs/fpga/testbench/hir_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 56: Unexpected token in expression: KwInvariant ('invariant') at line 56:9 +specs/fpga/testbench/integration_tb.t27 | Error: Compile error: parse error in fn 'test_reset_all_modules' near line 45: Unexpected token in expression: KwInvariant ('invariant') at line 45:9 +specs/fpga/testbench/linker_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 49: Unexpected token in expression: KwInvariant ('invariant') at line 49:9 +specs/fpga/testbench/mac_tb.t27 | Error: Compile error: parse error in fn 'run_tests' near line 353: Unexpected token in expression: Semicolon (';') at line 353:69 +specs/fpga/testbench/memory_tb.t27 | Error: Compile error: parse error in fn 'test_reset_clears' near line 63: Unexpected token in expression: KwInvariant ('invariant') at line 63:9 +specs/fpga/testbench/partition_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 51: Unexpected token in expression: KwInvariant ('invariant') at line 51:9 +specs/fpga/testbench/placement_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 64: Unexpected token in expression: KwInvariant ('invariant') at line 64:9 +specs/fpga/testbench/power_analysis_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 36: Unexpected token in expression: KwInvariant ('invariant') at line 36:9 +specs/fpga/testbench/power_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 69: Unexpected token in expression: KwInvariant ('invariant') at line 69:9 +specs/fpga/testbench/router_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 60: Unexpected token in expression: KwInvariant ('invariant') at line 60:9 +specs/fpga/testbench/simulator_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 56: Unexpected token in expression: KwInvariant ('invariant') at line 56:9 +specs/fpga/testbench/spi_tb.t27 | Error: Compile error: parse error in fn 'test_idle_state' near line 62: Unexpected token in expression: KwInvariant ('invariant') at line 62:9 +specs/fpga/testbench/stdlib_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 63: Unexpected token in expression: KwInvariant ('invariant') at line 63:9 +specs/fpga/testbench/ternary_isa_tb.t27 | Error: Compile error: parse error in fn 'test_ternary_add_zero' near line 61: Unexpected token in expression: KwInvariant ('invariant') at line 61:9 +specs/fpga/testbench/timing_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 49: Unexpected token in expression: KwInvariant ('invariant') at line 49:9 +specs/fpga/testbench/uart_tb.t27 | Error: Compile error: parse error in fn 'run_tests' near line 256: Unexpected token in expression: Semicolon (';') at line 256:39 +specs/fpga/testbench/vcd_conformance_compare_tb.t27 | Error: Compile error: parse error in fn 'test_reset_clears_state' near line 53: Unexpected token in expression: KwInvariant ('invariant') at line 53:9 +specs/fpga/testbench/vcd_trace_tb.t27 | Error: Compile error: parse error in fn 'test_reset_state' near line 53: Unexpected token in expression: KwInvariant ('invariant') at line 53:9 +specs/fpga/vcd_conformance_compare.t27 | Error: Compile error: parse error in fn 'compare_result_init' near line 219: unexpected token after expression statement: Ident +specs/fpga/verification/build_verify.t27 | Error: Compile error: parse error in fn 'test_module_count' near line 45: Unexpected token in expression: KwInvariant ('invariant') at line 45:9 +specs/github/auth.t27 | Error: Compile error: parse error at module level near line 7: Unexpected token in expression: Colon (':') at line 7:14 +specs/github/comments.t27 | Error: Compile error: parse error at module level near line 3: Unexpected token in expression: Colon (':') at line 3:14 +specs/github/issues.t27 | Error: Compile error: parse error at module level near line 3: Unexpected token in expression: Colon (':') at line 3:14 +specs/github/prs.t27 | Error: Compile error: parse error at module level near line 3: Unexpected token in expression: Colon (':') at line 3:14 +specs/github/tests/e2e_full_flow.t27 | Error: Compile error: parse error at module level near line 8: Unexpected token in expression: Colon (':') at line 8:14 +specs/graph/knowledge_graph.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 101:59 +specs/hslm/forward_pass.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 82:134 +specs/igla/coder/arch.t27 | Error: Compile error: parse error in fn 'apply_rope_q' near line 211: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16 +specs/igla/coder/bench_proxy.t27 | Error: Compile error: parse error in fn 'compute_pass_at_1' near line 109: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", +specs/igla/coder/benchmark.t27 | Error: Compile error: parse error in fn 'sacrebleu_precision' near line 127: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16 +specs/igla/coder/dataset.t27 | Error: Compile error: parse error in fn 'round_trip_accuracy' near line 627: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16 +specs/igla/coder/eval.t27 | Error: Compile error: parse error in fn 'pass_at_k' near line 108: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", +specs/igla/coder/pipeline.t27 | Error: Compile error: parse error in fn 'compute_team_match_reward' near line 598: unknown cast target type `f32`; expected one of ["bool", "u8", "i8" +specs/igla/coder/prm.t27 | Error: Compile error: parse error in fn 'char_match_ratio' near line 196: parse error near line 196: unknown cast target type `f32`; expected one of [ +specs/igla/coder/tokenizer.t27 | Error: Compile error: parse error in fn 'next_word_inner' near line 286: parse error near line 286: Expected RBracket, got Colon (':') at line 286:26 +specs/igla/coder/training.t27 | Error: Compile error: parse error in fn 'compute_lr' near line 120: parse error near line 120: unknown cast target type `f32`; expected one of ["bool" +specs/igla/race/backend.t27 | Error: Compile error: parse error at module level near line 394: unexpected token after expression statement: KwFn +specs/igla/race/eda.t27 | Error: Compile error: parse error in fn 'compute_backend_realizability' near line 39: unknown cast target type `f32`; expected one of ["bool", "u8", " +specs/igla/race/formal.t27 | Error: Compile error: parse error in fn 'compute_coverage' near line 241: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", +specs/igla/race/opcodes.t27 | Error: Compile error: parse error in fn 'module_identity_latency_1' near line 336: unexpected token after expression statement: Ident +specs/igla/race/rtl.t27 | Error: Compile error: Unexpected top-level token: KwModule ('module') at line 448:26 +specs/igla/race/yosys.t27 | Error: Compile error: parse error at module level near line 228: unexpected token after expression statement: KwFn +specs/interop/gf_cross_language.t27 | Error: Compile error: parse error at module level near line 7: unexpected token after expression statement: Ident +specs/isa/ternary_arithmetic.t27 | Error: Compile error: Expected LBrace, got Number ('257') at line 35:48 +specs/isa/ternary_bitwise.t27 | Error: Compile error: Expected LBrace, got Number ('257') at line 29:68 +specs/isa/ternary_deque.t27 | Error: Compile error: Expected LBrace, got Number ('257') at line 29:76 +specs/isa/ternary_encoding.t27 | Error: Compile error: parse error at module level near line 4: unexpected token after expression statement: Ident +specs/isa/ternary_gates.t27 | Error: Compile error: Expected LBrace, got Number ('257') at line 30:28 +specs/isa/ternary_hash.t27 | Error: Compile error: parse error in fn 'insert_lookup' near line 102: Unexpected token in expression: RBracket (']') at line 102:27 +specs/isa/ternary_pattern_matching.t27 | Error: Compile error: parse error in fn 'match_exact_found' near line 110: Unexpected token in expression: RBracket (']') at line 110:36 +specs/isa/ternary_search.t27 | Error: Compile error: parse error in fn 'linear_search_found' near line 113: Unexpected token in expression: RBracket (']') at line 113:38 +specs/isa/ternary_set.t27 | Error: Compile error: parse error in fn 'insert_contains' near line 127: Unexpected token in expression: RBracket (']') at line 127:27 +specs/isa/ternary_shift.t27 | Error: Compile error: Expected LBrace, got Number ('257') at line 34:66 +specs/isa/ternary_sorting.t27 | Error: Compile error: parse error in fn 'bubble_sort' near line 117: Unexpected token in expression: RBracket (']') at line 117:29 +specs/lsp/language.t27 | Error: Compile error: parse error in fn 'symbol_kind_to_string' near line 311: Unexpected token in expression: KwModule ('module') at line 311:10 +specs/lsp/protocol.t27 | Error: Compile error: parse error in fn 'response_error_create' near line 200: Expected RBrace, got PlusPlus ('++') at line 200:31 +specs/math/constants.t27 | Error: Compile error: parse error in fn 'pow' near line 98: Expected LParen, got Ident ('negative') at line 98:22 +specs/math/e8_lie_algebra.t27 | Error: Compile error: parse error in fn 'cos' near line 221: parse error near line 221: unknown cast target type `f64`; expected one of ["bool", "u8", +specs/math/gf_competitive.t27 | Error: Compile error: parse error in fn 'decode_complexity_returns_3_formats' near line 55: unexpected token after expression statement: Bang +specs/math/pellis_precision_verify.t27 | Error: Compile error: parse error in fn 'count_significant_digits' near line 88: Expected LBrace, got LParen ('(') at line 88:24 +specs/math/phi_split_optimality.t27 | Error: Compile error: parse error in fn 'optimal_ratio_by_self_similarity' near line 53: unknown cast target type `f64`; expected one of ["bool", "u8" +specs/math/phi_universal_attractor.t27 | Error: Compile error: parse error in fn 'bit_allocation_attractor' near line 166: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", +specs/math/property_test_template.t27 | Error: Compile error: parse error at module level near line 429: unexpected token after expression statement: Ident +specs/math/radix_economy.t27 | Error: Compile error: parse error in fn 'ternary_range' near line 56: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", "i16 +specs/math/zamolodchikov_e8.t27 | Error: Compile error: parse error in fn 'cos' near line 178: parse error near line 178: unknown cast target type `f64`; expected one of ["bool", "u8", +specs/memory/formula_embed.t27 | Error: Compile error: parse error in fn 'pad_features' near line 109: Expected LBrace, got Colon (':') at line 109:31 +specs/memory/semantic_search.t27 | Error: Compile error: parse error in fn 'semantic_search' near line 95: Expected LBrace, got Colon (':') at line 95:28 +specs/ml/optimizer/adamw.t27 | Error: Compile error: Expected LBrace, got Colon (':') at line 93:65 +specs/ml/optimizer/lr_scheduler.t27 | Error: Compile error: Expected LBrace, got Colon (':') at line 53:45 +specs/ml/optimizer/sgd_momentum.t27 | Error: Compile error: Expected LBrace, got Colon (':') at line 76:117 +specs/ml/transformer/feed_forward.t27 | Error: Compile error: Expected LBrace, got Colon (':') at line 128:72 +specs/ml/transformer/mha_block.t27 | Error: Compile error: Expected LBrace, got Colon (':') at line 106:104 +specs/ml/transformer/multi_head_attn.t27 | Error: Compile error: Expected LBrace, got Colon (':') at line 130:95 +specs/ml/transformer/norm.t27 | Error: Compile error: Expected LBrace, got Colon (':') at line 135:68 +specs/ml/transformer/positional_enc.t27 | Error: Compile error: Expected LBrace, got KwStruct ('struct') at line 67:40 +specs/neural/forward_pass.t27 | Error: Compile error: parse error at module level near line 10: unexpected token after expression statement: Ident +specs/nn/attention.t27 | Error: Compile error: parse error in fn 'sacred_attention_init' near line 84: parse error near line 84: parse error near line 84: unknown cast target +specs/nn/hslm.t27 | Error: Compile error: parse error in fn 'rms_norm_forward' near line 212: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", +specs/nn/phi_rope.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident +specs/nn/sacred_attention.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident +specs/numeric/bigint.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 50:31 +specs/numeric/formats.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 61:39 +specs/numeric/gf12.t27 | Error: Compile error: parse error in fn 'decode' near line 88: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 +specs/numeric/gf16.t27 | Error: Compile error: parse error in fn 'gf16_exp' near line 824: parse error near line 824: parse error near line 824: Unexpected token in expression +specs/numeric/gf20.t27 | Error: Compile error: parse error in fn 'decode' near line 89: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 +specs/numeric/gf24.t27 | Error: Compile error: parse error in fn 'decode' near line 89: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 +specs/numeric/gf32.t27 | Error: Compile error: parse error in fn 'decode' near line 90: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 +specs/numeric/gf4.t27 | Error: Compile error: parse error in fn 'decode' near line 97: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 +specs/numeric/gf64.t27 | Error: Compile error: parse error in fn 'decode' near line 80: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 +specs/numeric/gf8.t27 | Error: Compile error: parse error in fn 'decode' near line 98: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 +specs/numeric/goldenfloat_family.t27 | Error: Compile error: parse error in fn 'get_format_by_name' near line 232: Unexpected token in expression: KwConst ('const') at line 232:14 +specs/numeric/lucas_accumulator.t27 | Error: Compile error: parse error in fn 'phi_acc' near line 55: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", "i16", "u3 +specs/numeric/phi_ratio.t27 | Error: Compile error: parse error in fn 'phi_split' near line 52: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", "i16", " +specs/numeric/posit_ladder_control.t27 | Error: Compile error: parse error in fn 'useed' near line 52: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32" +specs/numeric/tf3.t27 | Error: Compile error: parse error in fn 'tf3_from_f32' near line 139: parse error near line 139: Unexpected token in expression: Equals ('=') at line +specs/physics/chimera_best_gamma.t27 | Error: Compile error: parse error in fn 'formula' near line 14: unexpected token after expression statement: RParen +specs/physics/e8_lqg_bridge.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/physics/formula_discovery.t27 | Error: Compile error: parse error in fn 'chimera_div' near line 47: unexpected token after expression statement: LBrace +specs/physics/gamma-conflict.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/physics/hslm_benchmark.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/physics/lqg_cs_bridge.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/physics/p2_brain_physics.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 53:55 +specs/physics/quantum.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident +specs/physics/sacred_verification.t27 | Error: Compile error: parse error in fn 'verify_formula' near line 388: Expected LParen, got Ident ('abs_error') at line 388:28 +specs/physics/su2_chern_simons.t27 | Error: Compile error: parse error in fn 's_matrix_element' near line 113: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", +specs/pins/parser.t27 | Error: Compile error: parse error at module level near line 40: Unexpected token in expression: Comma (',') at line 40:10 +specs/pipeline/benchmarks.t27 | Error: Compile error: parse error in fn 'percentile_sample' near line 66: Unexpected token in expression: RBracket (']') at line 66:46 +specs/pipeline/e2e_test.t27 | Error: Compile error: parse error in fn 'pipeline_progress' near line 79: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", +specs/portable/relay_observer.t27 | Error: Compile error: parse error at module level near line 6: Unexpected token in expression: Colon (':') at line 6:16 +specs/provider/adapters.t27 | Error: Compile error: parse error in fn 'adapter_config_create' near line 209: Expected RBrace, got Semicolon (';') at line 209:36 +specs/provider/schema.t27 | Error: Compile error: parse error in fn 'provider_config_create' near line 268: Expected RBrace, got Semicolon (';') at line 268:36 +specs/provider/transform.t27 | Error: Compile error: parse error in fn 'transform_messages' near line 201: parse error near line 201: parse error near line 201: Unexpected token in +specs/queen/lotus.t27 | Error: Compile error: parse error in fn 'evaluate_quality' near line 304: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", +specs/queen/task_analysis.t27 | Error: Compile error: parse error at module level near line 9: Unexpected token in expression: LBrace ('{') at line 9:27 +specs/runtime/execute.t27 | Error: Compile error: Expected LBrace, got RParen (')') at line 238:77 +specs/runtime/instance.t27 | Error: Compile error: parse error at module level near line 13: Expected RBrace, got Ident ('ProcessID') at line 13:23 +specs/runtime/process.t27 | Error: Compile error: parse error in fn 'process_continue' near line 313: Expected identifier after '.', got KwContinue +specs/sandbox/health.t27 | Error: Compile error: Unexpected top-level token: Ident ('trait') at line 32:5 +specs/sandbox/https_enforce.t27 | Error: Compile error: parse error in fn 'should_redirect' near line 57: unexpected token after expression statement: Ident +specs/sandbox/modules.t27 | Error: Compile error: Unexpected top-level token: KwUse ('use') at line 18:5 +specs/sandbox/orphan_detection.t27 | Error: Compile error: parse error at module level near line 19: unexpected token after expression statement: Ident +specs/sandbox/session_timeout.t27 | Error: Compile error: parse error at module level near line 14: unexpected token after expression statement: Ident +specs/scratch/w368_hex_width.t27 | Error: Compile error: parse error in fn 'w368_hex_width_const_ok' near line 9: unexpected token after expression statement: KwTrue +specs/scratch/w369_bin_width.t27 | Error: Compile error: parse error in fn 'w369_bin_width_const_ok' near line 9: unexpected token after expression statement: KwTrue +specs/scratch/w370_const_order.t27 | Error: Compile error: parse error in fn 'w370_const_order_ok' near line 11: unexpected token after expression statement: KwTrue +specs/scratch/w371_early_return.t27 | Error: Compile error: parse error in fn 'w371_early_return_ok' near line 10: unexpected token after expression statement: KwTrue +specs/scratch/w371_verilog_keyword.t27 | Error: Compile error: parse error in fn 'w371_verilog_keyword_ok' near line 21: unexpected token after expression statement: KwTrue +specs/scratch/w372_local_keyword.t27 | Error: Compile error: parse error in fn 'w372_local_keyword_task' near line 9: unexpected token after expression statement: Ident +specs/scratch/w373_struct_field_keyword.t27 | Error: Compile error: parse error in fn 'w373_struct_field_keyword_sum' near line 18: unexpected token after expression statement: Ident +specs/scratch/w374_module_keyword.t27 | Error: Compile error: parse error in fn 'w374_module_keyword_sum' near line 11: unexpected token after expression statement: Ident +specs/scratch/w375_early_return.t27 | Error: Compile error: parse error in fn 'w375_early_return_sign' near line 23: unexpected token after expression statement: Ident +specs/scratch/w376_cast_width.t27 | Error: Compile error: parse error in fn 'w376_cast_width_basic' near line 27: unexpected token after expression statement: Ident +specs/scratch/w377_struct_field_mapping.t27 | Error: Compile error: parse error at module level near line 14: Unexpected token in expression: Semicolon (';') at line 14:2 +specs/scratch/w378_let_destructuring.t27 | Error: Compile error: parse error in fn 'w378_let_destructuring_basic' near line 27: unexpected token after expression statement: Ident +specs/scratch/w379_let_destructuring_generalized.t27 | Error: Compile error: parse error in fn 'use_pair_ok' near line 31: unexpected token after expression statement: Ident +specs/scratch/w380_tuple_return.t27 | Error: Compile error: parse error in fn 'use_pair_ok' near line 26: unexpected token after expression statement: Ident +specs/scratch/w381_tuple_call_chain.t27 | Error: Compile error: parse error in fn 'sum_pair_ok' near line 22: unexpected token after expression statement: Ident +specs/scratch/w528_parse_const_2d.t27 | Error: Compile error: parse error in fn 'dummy' near line 10: unexpected token after expression statement: KwTrue +specs/scratch/w534_negative_cast_to_string.t27 | Error: Compile error: parse error in fn 'make_label' near line 6: unknown cast target type `String`; expected one of ["bool", "u8", "i8", "u16", "i16" +specs/scratch/w543_negative_nonlowerable_call_init.t27 | Error: Compile error: parse error in fn 'make_label' near line 8: unknown cast target type `String`; expected one of ["bool", "u8", "i8", "u16", "i16" +specs/scratch/w544_negative_nonlowerable_var_call_init.t27 | Error: Compile error: parse error in fn 'make_label' near line 6: unknown cast target type `String`; expected one of ["bool", "u8", "i8", "u16", "i16" +specs/scratch/w592_bench_module_3x2p15_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 294914: Unexpected token in expression: Semicolon (';') at line 294914:6 +specs/scratch/w593_bench_module_5x2p15_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 491518: Unexpected token in expression: Semicolon (';') at line 491518:6 +specs/scratch/w594_bench_module_7x2p14_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 344058: Unexpected token in expression: Semicolon (';') at line 344058:6 +specs/scratch/w595_bench_module_9x2p13_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 221174: Unexpected token in expression: Semicolon (';') at line 221174:6 +specs/scratch/w596_bench_module_11x2p12_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 135154: Unexpected token in expression: Semicolon (';') at line 135154:6 +specs/scratch/w597_bench_module_13x2p11_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 79854: Unexpected token in expression: Semicolon (';') at line 79854:6 +specs/scratch/w598_bench_module_15x2p10_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 46058: Unexpected token in expression: Semicolon (';') at line 46058:6 +specs/scratch/w599_bench_module_17x2p9_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 26086: Unexpected token in expression: Semicolon (';') at line 26086:6 +specs/scratch/w600_bench_module_19x2p8_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 14562: Unexpected token in expression: Semicolon (';') at line 14562:6 +specs/scratch/w601_bench_module_21x2p7_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 8030: Unexpected token in expression: Semicolon (';') at line 8030:6 +specs/scratch/w602_bench_module_23x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 4378: Unexpected token in expression: Semicolon (';') at line 4378:6 +specs/scratch/w603_bench_module_25x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 4758: Unexpected token in expression: Semicolon (';') at line 4758:6 +specs/scratch/w604_bench_module_27x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 5138: Unexpected token in expression: Semicolon (';') at line 5138:6 +specs/scratch/w605_bench_module_29x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 5518: Unexpected token in expression: Semicolon (';') at line 5518:6 +specs/scratch/w606_bench_module_31x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 5898: Unexpected token in expression: Semicolon (';') at line 5898:6 +specs/scratch/w607_bench_module_33x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 6278: Unexpected token in expression: Semicolon (';') at line 6278:6 +specs/scratch/w608_bench_module_35x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 6658: Unexpected token in expression: Semicolon (';') at line 6658:6 +specs/scratch/w609_bench_module_37x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 7038: Unexpected token in expression: Semicolon (';') at line 7038:6 +specs/scratch/w610_bench_module_39x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 7418: Unexpected token in expression: Semicolon (';') at line 7418:6 +specs/scratch/w611_bench_module_41x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 7798: Unexpected token in expression: Semicolon (';') at line 7798:6 +specs/scratch/w612_bench_module_43x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 8178: Unexpected token in expression: Semicolon (';') at line 8178:6 +specs/scratch/w613_bench_module_45x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 8558: Unexpected token in expression: Semicolon (';') at line 8558:6 +specs/scratch/w614_bench_module_47x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 8938: Unexpected token in expression: Semicolon (';') at line 8938:6 +specs/scratch/w615_bench_module_49x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 9318: Unexpected token in expression: Semicolon (';') at line 9318:6 +specs/scratch/w616_bench_module_51x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 9698: Unexpected token in expression: Semicolon (';') at line 9698:6 +specs/scratch/w617_bench_module_53x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 10078: Unexpected token in expression: Semicolon (';') at line 10078:6 +specs/scratch/w618_bench_module_55x2p6_aos_var_call_write.t27 | Error: Compile error: parse error at module level near line 10458: Unexpected token in expression: Semicolon (';') at line 10458:6 +specs/scratch/w619_bench_module_57x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 12770: Expected RBracket, got Eof ('') at line 12770:1 +specs/scratch/w620_bench_module_59x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 13216: Expected RBracket, got Eof ('') at line 13216:1 +specs/scratch/w621_bench_module_61x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 13662: Expected RBracket, got Eof ('') at line 13662:1 +specs/scratch/w622_bench_module_63x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 14108: Expected RBracket, got Eof ('') at line 14108:1 +specs/scratch/w623_bench_module_65x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 14548: Expected RBracket, got Eof ('') at line 14548:1 +specs/scratch/w624_bench_module_67x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 14988: Expected RBracket, got Eof ('') at line 14988:1 +specs/scratch/w625_bench_module_69x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 15428: Expected RBracket, got Eof ('') at line 15428:1 +specs/scratch/w626_bench_module_71x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 15868: Expected RBracket, got Eof ('') at line 15868:1 +specs/scratch/w627_bench_module_73x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 16308: Expected RBracket, got Eof ('') at line 16308:1 +specs/scratch/w628_bench_module_75x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 32: Unexpected token in expression: Comma (',') at line 32:24 +specs/scratch/w629_bench_module_77x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 32: Unexpected token in expression: Comma (',') at line 32:24 +specs/scratch/w630_bench_module_79x2p6_aos_var_call_write.t27 | Error: Compile error: parse error in fn 'make_grid' near line 32: Unexpected token in expression: Comma (',') at line 32:24 +specs/server/project.t27 | Error: Compile error: parse error in fn 'create_project' near line 53: Unexpected token in expression: PlusPlus ('++') at line 53:28 +specs/server/provider.t27 | Error: Compile error: parse error in fn 'provider_type_values' near line 177: unexpected token after expression statement: Ident +specs/server/router.t27 | Error: Compile error: parse error in fn 'route_match' near line 127: parse error near line 127: parse error near line 127: Unexpected token in express +specs/server/routes.t27 | Error: Compile error: parse error in fn 'http_method_values' near line 27: unexpected token after expression statement: Ident +specs/server/session.t27 | Error: Compile error: parse error in fn 'session_state_values' near line 188: unexpected token after expression statement: Ident +specs/server/sse.t27 | Error: Compile error: parse error in fn 'client_new' near line 127: Unexpected token in expression: KwFn ('fn') at line 127:23 +specs/server/vm.t27 | Error: Compile error: parse error in fn 'vm_step' near line 181: Unexpected token in expression: LBrace ('{') at line 181:24 +specs/shell/process.t27 | Error: Compile error: Expected LBrace, got LParen ('(') at line 14:21 +specs/shell/schema.t27 | Error: Compile error: parse error in fn 'process_options_full' near line 235: Unexpected token in expression: LBrace ('{') at line 235:31 +specs/storage/kv.t27 | Error: Compile error: Expected LParen, got Lt ('<') at line 15:12 +specs/sync/index.t27 | Error: Compile error: parse error at module level near line 13: Expected RBrace, got Ident ('SyncID') at line 13:19 +specs/ternary/hybrid_arithmetic.t27 | Error: Compile error: parse error at module level near line 49: Unexpected token in expression: Semicolon (';') at line 49:6 +specs/ternary/hybrid_bigint.t27 | Error: Compile error: parse error at module level near line 10: unexpected token after expression statement: Ident +specs/ternary/packed_trit.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 75:61 +specs/test_framework/core.t27 | Error: Compile error: parse error at module level near line 64: unexpected token after expression statement: Ident +specs/test_framework/graph_drift_detection.t27 | Error: Compile error: parse error at module level near line 7: Unexpected token in expression: LBrace ('{') at line 7:31 +specs/test_framework/property_test_template.t27 | Error: Compile error: parse error at module level near line 7: Unexpected token in expression: LBrace ('{') at line 7:31 +specs/test_framework/runner.t27 | Error: Compile error: parse error at module level near line 9: Unexpected token in expression: LBrace ('{') at line 9:11 +specs/test_framework/verilog_bench_harness.t27 | Error: Compile error: parse error at module level near line 7: Unexpected token in expression: LBrace ('{') at line 7:31 +specs/tools/registry.t27 | Error: Compile error: parse error in fn 'registry_with_tools' near line 166: Unexpected token in expression: LBrace ('{') at line 166:47 +specs/tools/schema.t27 | Error: Compile error: parse error at module level near line 7: unexpected token after expression statement: Ident +specs/tri/agent/agent_run.t27 | Error: Compile error: parse error at module level near line 5: Unexpected token in expression: Equals ('=') at line 5:12 +specs/tri/agent/eternal_monitor.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 63:1 +specs/tri/agent/faculty_board.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 54:1 +specs/tri/agent/governance_agent.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Comma +specs/tri/collections/array.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:30 +specs/tri/collections/bitmap.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 126:1 +specs/tri/collections/bitset.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 97:1 +specs/tri/collections/bitvector.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 106:1 +specs/tri/collections/btree.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:29 +specs/tri/collections/circular_buffer.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 79:1 +specs/tri/collections/deque.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 89:1 +specs/tri/collections/either.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:30 +specs/tri/collections/interval.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 61:1 +specs/tri/collections/list.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:25 +specs/tri/collections/lru.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:27 +specs/tri/collections/map.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:27 +specs/tri/collections/maybe.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:26 +specs/tri/collections/option.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:27 +specs/tri/collections/priority_queue.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 87:1 +specs/tri/collections/queue.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:26 +specs/tri/collections/result.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:30 +specs/tri/collections/ring_buffer.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:25 +specs/tri/collections/set.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:28 +specs/tri/collections/skip_list.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:29 +specs/tri/collections/stack.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:26 +specs/tri/collections/state.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:29 +specs/tri/collections/tuple.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:30 +specs/tri/collections/variant.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:28 +specs/tri/crypto/base32.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 56:1 +specs/tri/crypto/base64.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 86:1 +specs/tri/crypto/hmac.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 56:1 +specs/tri/encoding/json.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 67:1 +specs/tri/encoding/markup.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 47:1 +specs/tri/encoding/mime.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 48:1 +specs/tri/encoding/msgpack.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 56:1 +specs/tri/graph/graph.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:26 +specs/tri/graph/prims_mst.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 37:1 +specs/tri/graph/topological_sort.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 46:1 +specs/tri/io/compress.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 46:1 +specs/tri/io/io.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:23 +specs/tri/io/reader.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:30 +specs/tri/io/writer.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:30 +specs/tri/io/zip.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:27 +specs/tri/math/bezier.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 51:1 +specs/tri/math/matrix.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 98:1 +specs/tri/math/polynomial.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 86:1 +specs/tri/net/async.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:27 +specs/tri/net/async_stream.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:27 +specs/tri/net/channel.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:28 +specs/tri/net/url.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 70:1 +specs/tri/pipeline/builder.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:28 +specs/tri/pipeline/spec_writer.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 43:1 +specs/tri/search/aho_corasick.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 74:1 +specs/tri/search/bloom_filter.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 57:1 +specs/tri/search/boyer_moore.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 46:1 +specs/tri/search/match.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: KwConst +specs/tri/search/regex.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 62:1 +specs/tri/trees/fenwick_tree.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 87:1 +specs/tri/trees/kd_tree.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 84:1 +specs/tri/trees/octree.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 84:1 +specs/tri/trees/quadtree.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 82:1 +specs/tri/trees/rtree.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 69:1 +specs/tri/trees/segment_tree.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 67:1 +specs/tri/trees/suffix_array.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 56:1 +specs/tri/trees/tree.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:25 +specs/tri/trees/trie.t27 | Error: Compile error: parse error at module level near line 13: Unexpected token in expression: KwStruct ('struct') at line 13:29 +specs/tri/utils/args.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: KwConst +specs/tri/utils/bytes.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 106:1 +specs/tri/utils/template.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 51:1 +specs/tri/utils/utf8.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 70:1 +specs/vm/jit_semantics.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 73:58 +specs/vsa/jones_polynomial.t27 | Error: Compile error: parse error in fn 'writhe' near line 24: unexpected token after expression statement: Colon +specs/vsa/ops.t27 | Error: Compile error: parse error in fn 'hamming_similarity' near line 175: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16" +specs/vsa/packed_vsa.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 58:74 +specs/vsa/sequence_hdc.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 96:88 +specs/vsa/vsa_core.t27 | Error: Compile error: parse error in fn 'vsa_bind_self_inverse_property' near line 705: unexpected token after expression statement: KwFor +test_highlight.t27 | Error: Compile error: Unexpected top-level token: KwModule ('module') at line 4:5 From 24e59db1e35071315ae2a75cba0a5a09f2aa99df Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Wed, 19 Aug 2026 00:10:01 +0700 Subject: [PATCH 6/8] fix(bootstrap): seal --save must not record output that does not exist t27c seal --save sealed a spec no backend accepts, writing gen_hash_*: 'none' as though it were a hash. #2210 showed that batch re-sealing the 113 stale seals would have recorded 348 such claims. Two defects in one function, and the first is familiar: Err(_) => "none".to_string(), discards the compiler's own diagnosis -- the same swallowing pattern fixed across the Python tools in #2187/#2189/#2193, here in the Rust CLI -- and --save then wrote the 'none' out as a fact. Now the failure is kept and reported, and --save refuses: refusing to seal specs/ml/optimizer/adamw.t27: 4 of 4 backends rejected it gen-zig: Expected LBrace, got Colon (':') at line 93:65 ... A seal with gen_hash=none claims reproducibility for output that does not exist. Exit 1, no file written. A spec that generates still seals normally. --force keeps the deliberate case available and explicit rather than silent. Scope stated rather than implied: the identical Err(_) => 'none' pattern also exists in the HTTP seal_handler near line 2330. Fixing it there changes the JSON response shape, so it is left alone and named rather than half-done. My first patch hit that handler by accident -- the pattern appears twice and the naive replace found the wrong one first -- and the compiler caught it as an undefined variable. Closes #2211 Refs #2210 Co-Authored-By: Claude Opus 5 --- bootstrap/src/main.rs | 57 +++++++++++++++++++++++++++++++++++++------ docs/NOW.md | 11 +++++++++ 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/bootstrap/src/main.rs b/bootstrap/src/main.rs index ab73a8efd..998931a7d 100644 --- a/bootstrap/src/main.rs +++ b/bootstrap/src/main.rs @@ -676,6 +676,10 @@ enum Commands { /// Verify current hashes match previously saved seals #[arg(long)] verify: bool, + + /// Seal even when a backend rejected the spec, recording gen_hash=none + #[arg(long)] + force: bool, }, /// Encode integer to ternary TernaryEncode { @@ -3903,6 +3907,11 @@ struct SealHashes { gen_hash_verilog: String, gen_hash_c: String, gen_hash_rust: String, + /// (backend, message) for each backend that refused the spec. The four hash + /// fields carry the literal "none" in that case, and `--save` used to write it + /// as though it were a hash -- a seal asserting reproducibility for output that + /// does not exist. Keeping the reason means the refusal can say why. + failures: Vec<(String, String)>, } /// Compute all seal hashes for a .t27 spec file @@ -3920,27 +3929,41 @@ fn compute_seal_hashes(input_path: &str) -> anyhow::Result { let spec_hash = format!("sha256:{}", sha256_hex(source.as_bytes())); + let mut failures: Vec<(String, String)> = Vec::new(); let gen_hash_zig = match compiler::Compiler::compile(&source) { Ok(zig_code) => format!("sha256:{}", sha256_hex(zig_code.as_bytes())), - Err(_) => "none".to_string(), + Err(e) => { + failures.push(("zig".to_string(), e.to_string())); + "none".to_string() + } }; let gen_hash_verilog = match compiler::Compiler::compile_verilog(&source) { Ok(verilog_code) => format!("sha256:{}", sha256_hex(verilog_code.as_bytes())), - Err(_) => "none".to_string(), + Err(e) => { + failures.push(("verilog".to_string(), e.to_string())); + "none".to_string() + } }; let gen_hash_c = match compiler::Compiler::compile_c(&source) { Ok(c_code) => format!("sha256:{}", sha256_hex(c_code.as_bytes())), - Err(_) => "none".to_string(), + Err(e) => { + failures.push(("c".to_string(), e.to_string())); + "none".to_string() + } }; let gen_hash_rust = match compiler::Compiler::compile_rust(&source) { Ok(rust_code) => format!("sha256:{}", sha256_hex(rust_code.as_bytes())), - Err(_) => "none".to_string(), + Err(e) => { + failures.push(("rust".to_string(), e.to_string())); + "none".to_string() + } }; Ok(SealHashes { + failures, module, spec_path: input_path.to_string(), spec_hash, @@ -3962,7 +3985,7 @@ fn seal_file_path(module: &str, input_path: &str) -> std::path::PathBuf { Path::new(".trinity").join("seals").join(name) } -fn run_seal(input_path: &str, save: bool, verify: bool) -> anyhow::Result<()> { +fn run_seal(input_path: &str, save: bool, verify: bool, force: bool) -> anyhow::Result<()> { let hashes = compute_seal_hashes(input_path)?; if verify { @@ -4006,6 +4029,26 @@ fn run_seal(input_path: &str, save: bool, verify: bool) -> anyhow::Result<()> { std::process::exit(1); } } else if save { + // A seal records "this spec produced these four outputs". If a backend refused + // the spec, the corresponding field is the literal "none", and writing that as + // though it were a hash makes the seal assert reproducibility for output which + // does not exist. 348 of 1114 specs in this repository do not generate at all; + // re-sealing them in bulk would have recorded 348 such claims. + if !hashes.failures.is_empty() && !force { + eprintln!( + "refusing to seal {}: {} of 4 backends rejected it", + hashes.spec_path, + hashes.failures.len() + ); + for (backend, msg) in &hashes.failures { + eprintln!(" gen-{}: {}", backend, msg.lines().next().unwrap_or("")); + } + eprintln!(); + eprintln!("A seal with gen_hash=none claims reproducibility for output that"); + eprintln!("does not exist. Fix the spec, or pass --force if the gap is"); + eprintln!("deliberate and you want it on the record."); + std::process::exit(1); + } // --save: compute hashes and write to .trinity/seals/.json let seals_dir = Path::new(".trinity").join("seals"); fs::create_dir_all(&seals_dir)?; @@ -8484,7 +8527,7 @@ async fn main() -> anyhow::Result<()> { Commands::GenC { input } => run_gen_c(&input)?, Commands::GenRust { input } => run_gen_rust(&input)?, Commands::Conformance { input } => run_conformance(&input)?, - Commands::Seal { input, save, verify } => run_seal(&input, save, verify)?, + Commands::Seal { input, save, verify, force } => run_seal(&input, save, verify, force)?, Commands::Compile { input, backend, output } => { run_compile(&input, &backend, output.as_deref())? } @@ -8766,7 +8809,7 @@ fn main() -> anyhow::Result<()> { Commands::GenC { input } => run_gen_c(&input)?, Commands::GenRust { input } => run_gen_rust(&input)?, Commands::Conformance { input } => run_conformance(&input)?, - Commands::Seal { input, save, verify } => run_seal(&input, save, verify)?, + Commands::Seal { input, save, verify, force } => run_seal(&input, save, verify, force)?, Commands::Compile { input, backend, output } => { run_compile(&input, &backend, output.as_deref())? } diff --git a/docs/NOW.md b/docs/NOW.md index f2cb943a8..f5dadc9e3 100644 --- a/docs/NOW.md +++ b/docs/NOW.md @@ -1,3 +1,14 @@ +# NOW -- seal --save refuses a spec no backend accepts (2026-08-19) + +Last updated: 2026-08-19 + +## fix(bootstrap): stop sealing output that does not exist (Closes #2211) + +- `t27c seal --save` wrote `gen_hash_*: "none"` as though it were a hash. #2210 showed batch re-sealing the 113 stale seals would have recorded 348 such claims -- reproducibility assertions for output that does not exist +- **Two defects in one function.** `Err(_) => "none".to_string()` discarded the compiler's own diagnosis -- the same swallowing pattern fixed across the Python tools in #2187/#2189/#2193, here in the Rust CLI -- and `--save` then wrote the `none` out +- Now: exit 1, **no file written**, and the compiler's message printed per backend (`Expected LBrace, got Colon (':') at line 93:65`). A generating spec still seals normally; `--force` keeps the deliberate case explicit rather than silent +- **Scope stated rather than implied:** the same `Err(_) => "none"` exists in the HTTP `seal_handler`. Fixing it there changes the response shape, so it is named here rather than half-done. My first patch hit that handler by accident -- the pattern appears twice and the naive replace found the wrong one -- and the compiler caught it via an undefined variable + # NOW -- 348 of 1114 specs do not generate (2026-08-18) Last updated: 2026-08-18 From 88fadb6bb3d308be39db3e85881870f3eff25316 Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Wed, 19 Aug 2026 00:28:17 +0700 Subject: [PATCH 7/8] feat(lang): add -=, *=, |=, &=, ^= across token, lexer, parser and three backends specs/base/types.t27 -- a base module -- did not parse: result |= encoding << bit_pos; // pack_trit, line 172 Unexpected token in expression: Equals ('=') at line 172:13 Only += existed. The rest lexed as two tokens and died in parse_expr on the bare '='; MinusEquals and the others were not in the token enum at all. The part that mattered most: all three code generators did if node.extra_op == "+=" { self.write(" += "); } else { self.write(" = "); } so teaching the parser |= without touching them would have emitted x = rhs for x |= rhs -- silently dropping the operator. A miscompilation is worse than the parse error it replaces. This therefore changes four places together: the token enum, the lexer, the parser, and all three backends through a shared compound_binop(). Verified by reading the generated code rather than assuming it. C emits x |= 3; Verilog expands to x = x | 3; and the same for all six operators. Honest yield: 2 of 346, not the ~11 estimated. Six specs contain -=, four *= and one |=, but only specs/base/types.t27 and compiler/runtime/runtime.t27 are fixed by this alone; the rest carry further errors. M5 freeze ceremony performed. bootstrap/build.rs refuses to build when compiler.rs changes without a seal update -- a deliberate gate that makes a change to the compiler core explicit rather than incidental. The seal is exactly sha256(compiler.rs), and stage0/FROZEN_HASH is updated accordingly. A dead arm in my own checker, found on the way: check_specs_generate.py ran gen-zig, and there is no gen-zig subcommand -- the Zig backend is 'gen'. That arm always returned non-zero and never contributed a verdict. It did not change the headline, since a spec passing any other backend still passed, but the corrected count is 768 generate / 346 not, against 766/348. Closes #2212 Refs #2211 Co-Authored-By: Claude Opus 5 --- bootstrap/src/compiler.rs | 106 +++++++++++++++++++++++++++--- bootstrap/stage0/FROZEN_HASH | 2 +- docs/NOW.md | 13 ++++ tools/check_specs_generate.py | 11 +++- tools/specs_generate_baseline.txt | 4 +- 5 files changed, 120 insertions(+), 16 deletions(-) diff --git a/bootstrap/src/compiler.rs b/bootstrap/src/compiler.rs index 1ad55821a..b88540c4f 100644 --- a/bootstrap/src/compiler.rs +++ b/bootstrap/src/compiler.rs @@ -203,6 +203,14 @@ pub enum TokenKind { ShiftLeft, ShiftRight, PlusEquals, + // Only += existed. -=, *=, |=, &=, ^= lexed as two tokens and the parser died + // on the bare '='. Among the 348 specs that do not generate, 6 use -=, 4 use *= + // and 1 uses |= -- including specs/base/types.t27 at pack_trit line 172. + MinusEquals, + StarEquals, + PipeEquals, + AmpEquals, + CaretEquals, PlusPercent, MinusPercent, StarPercent, @@ -597,6 +605,61 @@ impl Lexer { }; } + if two == [b'-', b'='] { + self.advance(); + self.advance(); + return Token { + kind: TokenKind::MinusEquals, + lexeme: String::from("-="), + line: start_line, + col: start_col, + }; + } + + if two == [b'*', b'='] { + self.advance(); + self.advance(); + return Token { + kind: TokenKind::StarEquals, + lexeme: String::from("*="), + line: start_line, + col: start_col, + }; + } + + if two == [b'|', b'='] { + self.advance(); + self.advance(); + return Token { + kind: TokenKind::PipeEquals, + lexeme: String::from("|="), + line: start_line, + col: start_col, + }; + } + + if two == [b'&', b'='] { + self.advance(); + self.advance(); + return Token { + kind: TokenKind::AmpEquals, + lexeme: String::from("&="), + line: start_line, + col: start_col, + }; + } + + if two == [b'^', b'='] { + self.advance(); + self.advance(); + return Token { + kind: TokenKind::CaretEquals, + lexeme: String::from("^="), + line: start_line, + col: start_col, + }; + } + if two == [b'+', b'%'] { self.advance(); self.advance(); @@ -2027,15 +2090,24 @@ impl Parser { } // Check for += assignment - if self.current.kind == TokenKind::PlusEquals { - self.advance(); // consume += + let compound_op = match self.current.kind { + TokenKind::PlusEquals => Some("+="), + TokenKind::MinusEquals => Some("-="), + TokenKind::StarEquals => Some("*="), + TokenKind::PipeEquals => Some("|="), + TokenKind::AmpEquals => Some("&="), + TokenKind::CaretEquals => Some("^="), + _ => None, + }; + if let Some(cop) = compound_op { + self.advance(); // consume the compound operator let rhs = self.parse_expr()?; if self.current.kind == TokenKind::Semicolon { self.advance(); } let mut assign = Node::new(NodeKind::StmtAssign); assign.line = self.current.line as u32; - assign.extra_op = "+=".to_string(); + assign.extra_op = cop.to_string(); assign.children.push(expr); assign.children.push(rhs); return Ok(assign); @@ -4120,8 +4192,8 @@ impl Codegen { self.write_indent(); if node.children.len() >= 2 { self.gen_expr(&node.children[0]); - if node.extra_op == "+=" { - self.write(" += "); + if let Some(op) = compound_binop(&node.extra_op) { + self.write(&format!(" {}= ", op)); } else { self.write(" = "); } @@ -9523,10 +9595,10 @@ impl VerilogCodegen { self.in_lvalue = true; self.gen_verilog_expr(lhs); self.in_lvalue = false; - if node.extra_op == "+=" { + if let Some(op) = compound_binop(&node.extra_op) { self.write(asn); self.gen_verilog_expr(lhs); - self.write(" + "); + self.write(&format!(" {} ", op)); } else { self.write(asn); } @@ -11384,8 +11456,8 @@ impl CCodegen { self.gen_c_expr(&node.children[1]); } else { self.gen_c_expr(&node.children[0]); - if node.extra_op == "+=" { - self.write(" += "); + if let Some(op) = compound_binop(&node.extra_op) { + self.write(&format!(" {}= ", op)); } else { self.write(" = "); } @@ -12080,6 +12152,22 @@ fn resolve_import_path( // Compiler Interface // ============================================================================ +/// The binary operator inside a compound assignment: "|=" -> "|". +/// All three backends tested `extra_op == "+="` and fell through to " = " otherwise, +/// so accepting a new compound operator without touching them would have emitted +/// `x = rhs` for `x |= rhs` -- a miscompilation rather than an error. +fn compound_binop(extra_op: &str) -> Option<&'static str> { + match extra_op { + "+=" => Some("+"), + "-=" => Some("-"), + "*=" => Some("*"), + "|=" => Some("|"), + "&=" => Some("&"), + "^=" => Some("^"), + _ => None, + } +} + pub struct Compiler; #[allow(dead_code)] diff --git a/bootstrap/stage0/FROZEN_HASH b/bootstrap/stage0/FROZEN_HASH index f57d3ba2f..1df8aca74 100644 --- a/bootstrap/stage0/FROZEN_HASH +++ b/bootstrap/stage0/FROZEN_HASH @@ -1 +1 @@ -cd2822f290eb04ed9b6a6530357fea22dff6e09a4fb1ad7575ffc7d6ec744ff7 +8cfc4422d33df0202b88c69a898f622253154b034af19168345001a34d3093c5 diff --git a/docs/NOW.md b/docs/NOW.md index f5dadc9e3..bedfd3a55 100644 --- a/docs/NOW.md +++ b/docs/NOW.md @@ -1,3 +1,16 @@ +# NOW -- only += existed (2026-08-19) + +Last updated: 2026-08-19 + +## feat(lang): five missing compound assignments, and the three backends that would have miscompiled them (Closes #2212) + +- **`specs/base/types.t27`, a base module, did not parse.** `result |= encoding << bit_pos;` at `pack_trit` line 172. The cause is a missing language feature: only `+=` existed, and `-= *= |= &= ^=` lexed as two tokens and died in `parse_expr` on the bare `=` +- **The part that mattered most.** All three code generators did `if extra_op == "+=" { " += " } else { " = " }`, so teaching the *parser* `|=` without touching them would have emitted **`x = rhs`** for `x |= rhs` -- silently dropping the operator. A miscompilation is worse than the parse error it replaces. The change touches four places together: token enum, lexer, parser, and all three backends via a shared `compound_binop()` +- Verified by **reading the generated code**, not assuming: C emits `x |= 3`, Verilog expands to `x = x | 3`, for all six operators +- **Honest yield: 2 of 346, not the ~11 I estimated.** Six specs use `-=`, four `*=`, one `|=`, but only `specs/base/types.t27` and `compiler/runtime/runtime.t27` are fixed by this; the rest have further errors +- **M5 freeze ceremony performed.** `build.rs` refuses to build when `compiler.rs` changes without a seal update -- a deliberate gate making a change to the compiler core explicit. The seal is exactly `sha256(compiler.rs)` +- **A dead arm in my own checker, found on the way:** `check_specs_generate.py` ran `gen-zig`, and **there is no such subcommand** -- the Zig backend is `gen`. It always returned non-zero and never contributed a verdict. Corrected count: **768 generate, 346 do not**, against 766/348 before + # NOW -- seal --save refuses a spec no backend accepts (2026-08-19) Last updated: 2026-08-19 diff --git a/tools/check_specs_generate.py b/tools/check_specs_generate.py index b4a8d4d51..3e72ae5c9 100755 --- a/tools/check_specs_generate.py +++ b/tools/check_specs_generate.py @@ -50,7 +50,12 @@ ROOT = pathlib.Path(__file__).resolve().parent.parent BASELINE = ROOT / "tools/specs_generate_baseline.txt" -BACKENDS = ("c", "rust", "verilog", "zig") +# The Zig backend is `gen`, not `gen-zig` -- there is no gen-zig subcommand, so the +# first version of this list had a dead arm that always returned non-zero. It did not +# change the count (a spec passing any other backend still passed) but it meant the +# Zig backend never actually contributed a verdict. +BACKENDS = ("c", "rust", "verilog") +ZIG = "gen" def t27c(): @@ -70,8 +75,8 @@ def generates(t, sp): """(ok, first message). ok if ANY backend accepts it -- a spec written for one target should not be reported as broken because another target rejects it.""" first = "" - for m in BACKENDS: - r = subprocess.run([t, "gen-" + m, sp], capture_output=True, text=True, cwd=ROOT) + for cmd in [["gen-" + m] for m in BACKENDS] + [[ZIG]]: + r = subprocess.run([t] + cmd + [sp], capture_output=True, text=True, cwd=ROOT) if r.returncode == 0: return True, "" if not first: diff --git a/tools/specs_generate_baseline.txt b/tools/specs_generate_baseline.txt index 81c8dd85c..61a38412d 100644 --- a/tools/specs_generate_baseline.txt +++ b/tools/specs_generate_baseline.txt @@ -10,7 +10,6 @@ compiler/codegen/verilog/fpga_emission.t27 | Error: Compile error: parse error i compiler/codegen/zig/runtime.t27 | Error: Compile error: parse error in fn 'generate_main' near line 15: Unexpected token in expression: PlusPlus ('++') at line 15:80 compiler/parser/parser.t27 | Error: Compile error: parse error in fn 'Parser.new' near line 36: Expected RBrace, got KwConst ('const') at line 36:38 compiler/runtime/commands.t27 | Error: Compile error: parse error in fn 'spec_create' near line 33: Unexpected token in expression: LBrace ('{') at line 33:42 -compiler/runtime/runtime.t27 | Error: Compile error: parse error in fn 'setup_stack_frame' near line 121: Unexpected token in expression: Equals ('=') at line 121:23 compiler/runtime/validation.t27 | Error: Compile error: parse error in fn 'validate_policy_matrix' near line 216: parse error near line 216: parse error near line 216: Expected RBrace, compiler/skill/registry.t27 | Error: Compile error: parse error in fn 'create_skill' near line 200: Expected RBrace, got KwConst ('const') at line 200:31 examples/fpga/qmtech_minimal/design.t27 | Error: Compile error: parse error at module level near line 1: unexpected token after expression statement: Ident @@ -34,7 +33,6 @@ specs/base/ring_32.t27 | Error: Compile error: parse error at module level near specs/base/ternary_add.t27 | Error: Compile error: parse error in fn 'max_value' near line 64: Expected LBrace, got Colon (':') at line 64:19 specs/base/ternary_encoding.t27 | Error: Compile error: Expected LBrace, got Number ('257') at line 37:34 specs/base/ternary_memory.t27 | Error: Compile error: Expected LBrace, got Number ('257') at line 45:25 -specs/base/types.t27 | Error: Compile error: parse error in fn 'pack_trit' near line 172: Unexpected token in expression: Equals ('=') at line 172:13 specs/benchmarks/bench_main.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident specs/benchmarks/bench_nn.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident specs/benchmarks/gf16_bfloat16_nmse.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident @@ -153,7 +151,7 @@ specs/nn/sacred_attention.t27 | Error: Compile error: parse error at module leve specs/numeric/bigint.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 50:31 specs/numeric/formats.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 61:39 specs/numeric/gf12.t27 | Error: Compile error: parse error in fn 'decode' near line 88: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 -specs/numeric/gf16.t27 | Error: Compile error: parse error in fn 'gf16_exp' near line 824: parse error near line 824: parse error near line 824: Unexpected token in expression +specs/numeric/gf16.t27 | Error: Compile error: parse error in fn 'gf16_log' near line 848: Expected RParen, got Ident ('e38') at line 848:20 specs/numeric/gf20.t27 | Error: Compile error: parse error in fn 'decode' near line 89: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 specs/numeric/gf24.t27 | Error: Compile error: parse error in fn 'decode' near line 89: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 specs/numeric/gf32.t27 | Error: Compile error: parse error in fn 'decode' near line 90: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 From 2fa36322e4af78c5bb8f48c9aae5cd11a3a83729 Mon Sep 17 00:00:00 2001 From: Vasilev Dmitrii Date: Wed, 19 Aug 2026 00:36:18 +0700 Subject: [PATCH 8/8] lang: name the true state of float casts, and keep seal_handler's reasons 30 error instances across the non-generating specs are 'unknown cast target type f32/f64'. The cheap fix -- adding them to VALID_CAST_TYPES -- would have been wrong: var x: f32 parses today and the type tables know floats in four places, but the C generator emits the literal token f32, which is not a C type (five cc errors on a one-line probe, no typedef anywhere), and Verilog treats f32 as 32 plain bits with no float semantics. Float support is half-built end to end. Adding the cast targets would convert a visible parse error into uncompilable C and meaningless Verilog -- the compound-assignment lesson (#2212) at a scale where the missing half is 'implement floating point in three backends', which is an owner-level design decision rather than a gap. The parser now names the true state: cast to f32 is not supported: the language accepts float declarations, but no backend lowers float arithmetic (the C generator emits f32 verbatim, which is not a C type). This spec assumes a float-capable target that does not exist yet. Integer casts are untouched; a nonsense target still gets the old message. The 30 specs stay in the debt baseline with the truthful message attached. Also closes the last named instance of the swallowing pattern: seal_handler kept Err(_) => none after #2211 fixed the CLI path, because fixing it changes the response shape. Done additively -- existing fields unchanged, a new gen_failures array carries {backend, error} so a consumer can see why a hash is 'none' rather than treating the word as a digest. M5 ceremony performed for the compiler.rs change. Closes #2213 Refs #2212 Co-Authored-By: Claude Opus 5 --- bootstrap/src/compiler.rs | 15 ++++++++ bootstrap/src/main.rs | 24 ++++++++++-- bootstrap/stage0/FROZEN_HASH | 2 +- docs/NOW.md | 11 ++++++ tools/specs_generate_baseline.txt | 62 +++++++++++++++---------------- 5 files changed, 78 insertions(+), 36 deletions(-) diff --git a/bootstrap/src/compiler.rs b/bootstrap/src/compiler.rs index b88540c4f..b3d340ace 100644 --- a/bootstrap/src/compiler.rs +++ b/bootstrap/src/compiler.rs @@ -2743,6 +2743,21 @@ impl Parser { "bool", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "usize", ]; if !VALID_CAST_TYPES.contains(&base.as_str()) { + // f32/f64 parse in DECLARATIONS, so "unknown type" would be a lie here. + // The truth is narrower: no backend lowers float arithmetic -- the C + // generator emits the literal token `f32`, which is not a C type, and + // Verilog treats it as 32 plain bits. A cast that parses and then + // produces uncompilable C would be worse than this error, which is why + // f32/f64 are named here rather than added to the list. + if matches!(base.as_str(), "f32" | "f64") { + return Err(format!( + "cast to `{}` is not supported: the language accepts float \ + declarations, but no backend lowers float arithmetic (the C \ + generator emits `{}` verbatim, which is not a C type). This spec \ + assumes a float-capable target that does not exist yet.", + base, base + )); + } return Err(format!( "unknown cast target type `{}`; expected one of {:?}", base, VALID_CAST_TYPES diff --git a/bootstrap/src/main.rs b/bootstrap/src/main.rs index 998931a7d..ac23f8e21 100644 --- a/bootstrap/src/main.rs +++ b/bootstrap/src/main.rs @@ -2331,21 +2331,34 @@ async fn seal_handler( ) -> impl IntoResponse { let spec_hash = format!("sha256:{}", sha256_hex(req.source.as_bytes())); + let mut gen_failures: Vec = Vec::new(); let gen_hash_zig = match compiler::Compiler::compile(&req.source) { Ok(code) => format!("sha256:{}", sha256_hex(code.as_bytes())), - Err(_) => "none".to_string(), + Err(e) => { + gen_failures.push(serde_json::json!({"backend": "zig", "error": e.to_string()})); + "none".to_string() + } }; let gen_hash_verilog = match compiler::Compiler::compile_verilog(&req.source) { Ok(code) => format!("sha256:{}", sha256_hex(code.as_bytes())), - Err(_) => "none".to_string(), + Err(e) => { + gen_failures.push(serde_json::json!({"backend": "verilog", "error": e.to_string()})); + "none".to_string() + } }; let gen_hash_c = match compiler::Compiler::compile_c(&req.source) { Ok(code) => format!("sha256:{}", sha256_hex(code.as_bytes())), - Err(_) => "none".to_string(), + Err(e) => { + gen_failures.push(serde_json::json!({"backend": "c", "error": e.to_string()})); + "none".to_string() + } }; let gen_hash_rust = match compiler::Compiler::compile_rust(&req.source) { Ok(code) => format!("sha256:{}", sha256_hex(code.as_bytes())), - Err(_) => "none".to_string(), + Err(e) => { + gen_failures.push(serde_json::json!({"backend": "rust", "error": e.to_string()})); + "none".to_string() + } }; let output = serde_json::json!({ @@ -2354,6 +2367,9 @@ async fn seal_handler( "gen_hash_verilog": gen_hash_verilog, "gen_hash_c": gen_hash_c, "gen_hash_rust": gen_hash_rust, + // Additive: existing consumers keep their fields; new ones can see WHY a + // hash is "none" instead of treating the word as if it were a digest. + "gen_failures": gen_failures, }); ( diff --git a/bootstrap/stage0/FROZEN_HASH b/bootstrap/stage0/FROZEN_HASH index 1df8aca74..9d04b51f3 100644 --- a/bootstrap/stage0/FROZEN_HASH +++ b/bootstrap/stage0/FROZEN_HASH @@ -1 +1 @@ -8cfc4422d33df0202b88c69a898f622253154b034af19168345001a34d3093c5 +b27721c642927fb9c3c3a2d6418b61e1b0e68d2f416794a9764373085cb5b4cd diff --git a/docs/NOW.md b/docs/NOW.md index bedfd3a55..cd0261462 100644 --- a/docs/NOW.md +++ b/docs/NOW.md @@ -1,3 +1,14 @@ +# NOW -- the honest diagnostic, not the cheap fix (2026-08-19) + +Last updated: 2026-08-19 + +## lang: float casts named truthfully; seal_handler keeps its reasons (Closes #2213) + +- **30 cast errors (16 f32 + 14 f64) among the non-generating specs, and the cheap fix was wrong.** `var x: f32` parses and the type tables know floats in four places -- but the C generator emits the literal token `f32` (not a C type, 5 cc errors on a one-line probe) and Verilog treats it as 32 plain bits. Adding f32/f64 to VALID_CAST_TYPES would turn a visible parse error into uncompilable C -- the compound-assignment lesson at a scale where the missing half is 'implement floating point in three backends', an owner decision +- The parser now says the true state: *cast to f32 is not supported: the language accepts float declarations, but no backend lowers float arithmetic... This spec assumes a float-capable target that does not exist yet.* Integer casts untouched; nonsense targets keep the old message +- **The last named instance of the swallowing pattern is closed.** `seal_handler` kept `Err(_) => "none"` after #2211 fixed the CLI path. Done additively: existing response fields unchanged, new `gen_failures` array carries {backend, error} so a consumer sees WHY a hash is "none" +- M5 ceremony performed again for the compiler.rs change + # NOW -- only += existed (2026-08-19) Last updated: 2026-08-19 diff --git a/tools/specs_generate_baseline.txt b/tools/specs_generate_baseline.txt index 61a38412d..4c278ecb8 100644 --- a/tools/specs_generate_baseline.txt +++ b/tools/specs_generate_baseline.txt @@ -95,18 +95,18 @@ specs/github/prs.t27 | Error: Compile error: parse error at module level near li specs/github/tests/e2e_full_flow.t27 | Error: Compile error: parse error at module level near line 8: Unexpected token in expression: Colon (':') at line 8:14 specs/graph/knowledge_graph.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 101:59 specs/hslm/forward_pass.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 82:134 -specs/igla/coder/arch.t27 | Error: Compile error: parse error in fn 'apply_rope_q' near line 211: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16 -specs/igla/coder/bench_proxy.t27 | Error: Compile error: parse error in fn 'compute_pass_at_1' near line 109: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", -specs/igla/coder/benchmark.t27 | Error: Compile error: parse error in fn 'sacrebleu_precision' near line 127: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16 -specs/igla/coder/dataset.t27 | Error: Compile error: parse error in fn 'round_trip_accuracy' near line 627: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16 -specs/igla/coder/eval.t27 | Error: Compile error: parse error in fn 'pass_at_k' near line 108: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", -specs/igla/coder/pipeline.t27 | Error: Compile error: parse error in fn 'compute_team_match_reward' near line 598: unknown cast target type `f32`; expected one of ["bool", "u8", "i8" -specs/igla/coder/prm.t27 | Error: Compile error: parse error in fn 'char_match_ratio' near line 196: parse error near line 196: unknown cast target type `f32`; expected one of [ +specs/igla/coder/arch.t27 | Error: Compile error: parse error in fn 'apply_rope_q' near line 211: cast to `f32` is not supported: the language accepts float declarations, but no +specs/igla/coder/bench_proxy.t27 | Error: Compile error: parse error in fn 'compute_pass_at_1' near line 109: cast to `f32` is not supported: the language accepts float declarations, bu +specs/igla/coder/benchmark.t27 | Error: Compile error: parse error in fn 'sacrebleu_precision' near line 127: cast to `f32` is not supported: the language accepts float declarations, +specs/igla/coder/dataset.t27 | Error: Compile error: parse error in fn 'round_trip_accuracy' near line 627: cast to `f32` is not supported: the language accepts float declarations, +specs/igla/coder/eval.t27 | Error: Compile error: parse error in fn 'pass_at_k' near line 108: cast to `f32` is not supported: the language accepts float declarations, but no bac +specs/igla/coder/pipeline.t27 | Error: Compile error: parse error in fn 'compute_team_match_reward' near line 598: cast to `f32` is not supported: the language accepts float declarat +specs/igla/coder/prm.t27 | Error: Compile error: parse error in fn 'char_match_ratio' near line 196: parse error near line 196: cast to `f32` is not supported: the language acce specs/igla/coder/tokenizer.t27 | Error: Compile error: parse error in fn 'next_word_inner' near line 286: parse error near line 286: Expected RBracket, got Colon (':') at line 286:26 -specs/igla/coder/training.t27 | Error: Compile error: parse error in fn 'compute_lr' near line 120: parse error near line 120: unknown cast target type `f32`; expected one of ["bool" +specs/igla/coder/training.t27 | Error: Compile error: parse error in fn 'compute_lr' near line 120: parse error near line 120: cast to `f32` is not supported: the language accepts fl specs/igla/race/backend.t27 | Error: Compile error: parse error at module level near line 394: unexpected token after expression statement: KwFn -specs/igla/race/eda.t27 | Error: Compile error: parse error in fn 'compute_backend_realizability' near line 39: unknown cast target type `f32`; expected one of ["bool", "u8", " -specs/igla/race/formal.t27 | Error: Compile error: parse error in fn 'compute_coverage' near line 241: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", +specs/igla/race/eda.t27 | Error: Compile error: parse error in fn 'compute_backend_realizability' near line 39: cast to `f32` is not supported: the language accepts float decla +specs/igla/race/formal.t27 | Error: Compile error: parse error in fn 'compute_coverage' near line 241: cast to `f32` is not supported: the language accepts float declarations, but specs/igla/race/opcodes.t27 | Error: Compile error: parse error in fn 'module_identity_latency_1' near line 336: unexpected token after expression statement: Ident specs/igla/race/rtl.t27 | Error: Compile error: Unexpected top-level token: KwModule ('module') at line 448:26 specs/igla/race/yosys.t27 | Error: Compile error: parse error at module level near line 228: unexpected token after expression statement: KwFn @@ -125,14 +125,14 @@ specs/isa/ternary_sorting.t27 | Error: Compile error: parse error in fn 'bubble_ specs/lsp/language.t27 | Error: Compile error: parse error in fn 'symbol_kind_to_string' near line 311: Unexpected token in expression: KwModule ('module') at line 311:10 specs/lsp/protocol.t27 | Error: Compile error: parse error in fn 'response_error_create' near line 200: Expected RBrace, got PlusPlus ('++') at line 200:31 specs/math/constants.t27 | Error: Compile error: parse error in fn 'pow' near line 98: Expected LParen, got Ident ('negative') at line 98:22 -specs/math/e8_lie_algebra.t27 | Error: Compile error: parse error in fn 'cos' near line 221: parse error near line 221: unknown cast target type `f64`; expected one of ["bool", "u8", +specs/math/e8_lie_algebra.t27 | Error: Compile error: parse error in fn 'cos' near line 221: parse error near line 221: cast to `f64` is not supported: the language accepts float dec specs/math/gf_competitive.t27 | Error: Compile error: parse error in fn 'decode_complexity_returns_3_formats' near line 55: unexpected token after expression statement: Bang specs/math/pellis_precision_verify.t27 | Error: Compile error: parse error in fn 'count_significant_digits' near line 88: Expected LBrace, got LParen ('(') at line 88:24 -specs/math/phi_split_optimality.t27 | Error: Compile error: parse error in fn 'optimal_ratio_by_self_similarity' near line 53: unknown cast target type `f64`; expected one of ["bool", "u8" -specs/math/phi_universal_attractor.t27 | Error: Compile error: parse error in fn 'bit_allocation_attractor' near line 166: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", +specs/math/phi_split_optimality.t27 | Error: Compile error: parse error in fn 'optimal_ratio_by_self_similarity' near line 53: cast to `f64` is not supported: the language accepts float de +specs/math/phi_universal_attractor.t27 | Error: Compile error: parse error in fn 'bit_allocation_attractor' near line 166: cast to `f64` is not supported: the language accepts float declarati specs/math/property_test_template.t27 | Error: Compile error: parse error at module level near line 429: unexpected token after expression statement: Ident -specs/math/radix_economy.t27 | Error: Compile error: parse error in fn 'ternary_range' near line 56: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", "i16 -specs/math/zamolodchikov_e8.t27 | Error: Compile error: parse error in fn 'cos' near line 178: parse error near line 178: unknown cast target type `f64`; expected one of ["bool", "u8", +specs/math/radix_economy.t27 | Error: Compile error: parse error in fn 'ternary_range' near line 56: cast to `f64` is not supported: the language accepts float declarations, but no +specs/math/zamolodchikov_e8.t27 | Error: Compile error: parse error in fn 'cos' near line 178: parse error near line 178: cast to `f64` is not supported: the language accepts float dec specs/memory/formula_embed.t27 | Error: Compile error: parse error in fn 'pad_features' near line 109: Expected LBrace, got Colon (':') at line 109:31 specs/memory/semantic_search.t27 | Error: Compile error: parse error in fn 'semantic_search' near line 95: Expected LBrace, got Colon (':') at line 95:28 specs/ml/optimizer/adamw.t27 | Error: Compile error: Expected LBrace, got Colon (':') at line 93:65 @@ -144,24 +144,24 @@ specs/ml/transformer/multi_head_attn.t27 | Error: Compile error: Expected LBrace specs/ml/transformer/norm.t27 | Error: Compile error: Expected LBrace, got Colon (':') at line 135:68 specs/ml/transformer/positional_enc.t27 | Error: Compile error: Expected LBrace, got KwStruct ('struct') at line 67:40 specs/neural/forward_pass.t27 | Error: Compile error: parse error at module level near line 10: unexpected token after expression statement: Ident -specs/nn/attention.t27 | Error: Compile error: parse error in fn 'sacred_attention_init' near line 84: parse error near line 84: parse error near line 84: unknown cast target -specs/nn/hslm.t27 | Error: Compile error: parse error in fn 'rms_norm_forward' near line 212: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", +specs/nn/attention.t27 | Error: Compile error: parse error in fn 'sacred_attention_init' near line 84: parse error near line 84: parse error near line 84: cast to `f64` is not +specs/nn/hslm.t27 | Error: Compile error: parse error in fn 'rms_norm_forward' near line 212: cast to `f64` is not supported: the language accepts float declarations, but specs/nn/phi_rope.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident specs/nn/sacred_attention.t27 | Error: Compile error: parse error at module level near line 5: unexpected token after expression statement: Ident specs/numeric/bigint.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 50:31 specs/numeric/formats.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 61:39 -specs/numeric/gf12.t27 | Error: Compile error: parse error in fn 'decode' near line 88: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 +specs/numeric/gf12.t27 | Error: Compile error: parse error in fn 'decode' near line 88: cast to `f32` is not supported: the language accepts float declarations, but no backend specs/numeric/gf16.t27 | Error: Compile error: parse error in fn 'gf16_log' near line 848: Expected RParen, got Ident ('e38') at line 848:20 -specs/numeric/gf20.t27 | Error: Compile error: parse error in fn 'decode' near line 89: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 -specs/numeric/gf24.t27 | Error: Compile error: parse error in fn 'decode' near line 89: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 -specs/numeric/gf32.t27 | Error: Compile error: parse error in fn 'decode' near line 90: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 -specs/numeric/gf4.t27 | Error: Compile error: parse error in fn 'decode' near line 97: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 -specs/numeric/gf64.t27 | Error: Compile error: parse error in fn 'decode' near line 80: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 -specs/numeric/gf8.t27 | Error: Compile error: parse error in fn 'decode' near line 98: unknown cast target type `f32`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32 +specs/numeric/gf20.t27 | Error: Compile error: parse error in fn 'decode' near line 89: cast to `f32` is not supported: the language accepts float declarations, but no backend +specs/numeric/gf24.t27 | Error: Compile error: parse error in fn 'decode' near line 89: cast to `f32` is not supported: the language accepts float declarations, but no backend +specs/numeric/gf32.t27 | Error: Compile error: parse error in fn 'decode' near line 90: cast to `f32` is not supported: the language accepts float declarations, but no backend +specs/numeric/gf4.t27 | Error: Compile error: parse error in fn 'decode' near line 97: cast to `f32` is not supported: the language accepts float declarations, but no backend +specs/numeric/gf64.t27 | Error: Compile error: parse error in fn 'decode' near line 80: cast to `f64` is not supported: the language accepts float declarations, but no backend +specs/numeric/gf8.t27 | Error: Compile error: parse error in fn 'decode' near line 98: cast to `f32` is not supported: the language accepts float declarations, but no backend specs/numeric/goldenfloat_family.t27 | Error: Compile error: parse error in fn 'get_format_by_name' near line 232: Unexpected token in expression: KwConst ('const') at line 232:14 -specs/numeric/lucas_accumulator.t27 | Error: Compile error: parse error in fn 'phi_acc' near line 55: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", "i16", "u3 -specs/numeric/phi_ratio.t27 | Error: Compile error: parse error in fn 'phi_split' near line 52: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", "i16", " -specs/numeric/posit_ladder_control.t27 | Error: Compile error: parse error in fn 'useed' near line 52: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", "i16", "u32" +specs/numeric/lucas_accumulator.t27 | Error: Compile error: parse error in fn 'phi_acc' near line 55: cast to `f64` is not supported: the language accepts float declarations, but no backen +specs/numeric/phi_ratio.t27 | Error: Compile error: parse error in fn 'phi_split' near line 52: cast to `f64` is not supported: the language accepts float declarations, but no back +specs/numeric/posit_ladder_control.t27 | Error: Compile error: parse error in fn 'useed' near line 52: cast to `f64` is not supported: the language accepts float declarations, but no backend specs/numeric/tf3.t27 | Error: Compile error: parse error in fn 'tf3_from_f32' near line 139: parse error near line 139: Unexpected token in expression: Equals ('=') at line specs/physics/chimera_best_gamma.t27 | Error: Compile error: parse error in fn 'formula' near line 14: unexpected token after expression statement: RParen specs/physics/e8_lqg_bridge.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident @@ -172,15 +172,15 @@ specs/physics/lqg_cs_bridge.t27 | Error: Compile error: parse error at module le specs/physics/p2_brain_physics.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 53:55 specs/physics/quantum.t27 | Error: Compile error: parse error at module level near line 2: unexpected token after expression statement: Ident specs/physics/sacred_verification.t27 | Error: Compile error: parse error in fn 'verify_formula' near line 388: Expected LParen, got Ident ('abs_error') at line 388:28 -specs/physics/su2_chern_simons.t27 | Error: Compile error: parse error in fn 's_matrix_element' near line 113: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", +specs/physics/su2_chern_simons.t27 | Error: Compile error: parse error in fn 's_matrix_element' near line 113: cast to `f64` is not supported: the language accepts float declarations, but specs/pins/parser.t27 | Error: Compile error: parse error at module level near line 40: Unexpected token in expression: Comma (',') at line 40:10 specs/pipeline/benchmarks.t27 | Error: Compile error: parse error in fn 'percentile_sample' near line 66: Unexpected token in expression: RBracket (']') at line 66:46 -specs/pipeline/e2e_test.t27 | Error: Compile error: parse error in fn 'pipeline_progress' near line 79: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", +specs/pipeline/e2e_test.t27 | Error: Compile error: parse error in fn 'pipeline_progress' near line 79: cast to `f64` is not supported: the language accepts float declarations, but specs/portable/relay_observer.t27 | Error: Compile error: parse error at module level near line 6: Unexpected token in expression: Colon (':') at line 6:16 specs/provider/adapters.t27 | Error: Compile error: parse error in fn 'adapter_config_create' near line 209: Expected RBrace, got Semicolon (';') at line 209:36 specs/provider/schema.t27 | Error: Compile error: parse error in fn 'provider_config_create' near line 268: Expected RBrace, got Semicolon (';') at line 268:36 specs/provider/transform.t27 | Error: Compile error: parse error in fn 'transform_messages' near line 201: parse error near line 201: parse error near line 201: Unexpected token in -specs/queen/lotus.t27 | Error: Compile error: parse error in fn 'evaluate_quality' near line 304: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16", +specs/queen/lotus.t27 | Error: Compile error: parse error in fn 'evaluate_quality' near line 304: cast to `f64` is not supported: the language accepts float declarations, but specs/queen/task_analysis.t27 | Error: Compile error: parse error at module level near line 9: Unexpected token in expression: LBrace ('{') at line 9:27 specs/runtime/execute.t27 | Error: Compile error: Expected LBrace, got RParen (')') at line 238:77 specs/runtime/instance.t27 | Error: Compile error: parse error at module level near line 13: Expected RBrace, got Ident ('ProcessID') at line 13:23 @@ -341,7 +341,7 @@ specs/tri/utils/template.t27 | Error: Compile error: Expected RBrace, got Eof (' specs/tri/utils/utf8.t27 | Error: Compile error: Expected RBrace, got Eof ('') at line 70:1 specs/vm/jit_semantics.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 73:58 specs/vsa/jones_polynomial.t27 | Error: Compile error: parse error in fn 'writhe' near line 24: unexpected token after expression statement: Colon -specs/vsa/ops.t27 | Error: Compile error: parse error in fn 'hamming_similarity' near line 175: unknown cast target type `f64`; expected one of ["bool", "u8", "i8", "u16" +specs/vsa/ops.t27 | Error: Compile error: parse error in fn 'hamming_similarity' near line 175: cast to `f64` is not supported: the language accepts float declarations, b specs/vsa/packed_vsa.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 58:74 specs/vsa/sequence_hdc.t27 | Error: Compile error: Expected LBrace, got Semicolon (';') at line 96:88 specs/vsa/vsa_core.t27 | Error: Compile error: parse error in fn 'vsa_bind_self_inverse_property' near line 705: unexpected token after expression statement: KwFor