Skip to content

Nothing checks whether a seal gen_hash still matches what the compiler emits; 116 were stale #3415

Description

@gHashTag

A seal records four gen_hash_* fields — the hashes of what each backend emitted. Those are the fields that make it a claim about generated code rather than about a file listing.

Nothing checks them.

Measured on master, before this

gen_hash_rust stale 109
gen_hash_zig stale 7
gen_hash_c stale 0
gen_hash_verilog stale 0
spec_hash stale 0

The 116 were left by five merged backend repairs — #3401, #3403, #3405, #3407, #3411 — which are mine. Every one of them changed emitted Rust, and none of them touched a spec, so spec_hash stayed correct and every coverage and staleness check in the repository stayed green while a sixth of the Rust seals described output the compiler no longer produces.

What the existing checks actually cover

  • check_seal_coverage.py — does a seal describe a spec that exists, unchanged at source. It is about spec_path and spec_hash.
  • Seal Staleness Warning — the NMSE manifest seal, sha256(bootstrap/src/compiler.rs) against FROZEN_HASH. Unrelated to .trinity/seals, and it always exits 0 by design.
  • t27c seal --verify <spec> — answers exactly this question, per spec, with a precise MISMATCH line. Nothing called it across the corpus.

Controls, so this is a finding and not a broken probe: --verify exits 1 on specs/ar/restraint.t27 with gen_hash_rust: MISMATCH (saved=7d50c681…, current=e60d0df7…) and the other three MATCH; it exits 0 on specs/fpga/testbench/apb_bridge_tb.t27.

Two things found while repairing it

1. The seal set is duplicated. 1313 seals for 728 distinct specs; 547 specs carry more than one seal file. t27c seal --save writes to .trinity/seals/<module>.json — one name — so refreshing through the tool fixed 116 → 58 and left every duplicate stale. Some of the duplicate names are not module names at all:

specs/tri/utils/logger.t27 -> [[]const u8.json, utils_[]const u8.json, utils_TriLogger.json]

A seal named after a type string. Which name is canonical is a decision, and the cleanup is filed rather than done here.

2. gen_hash=none is a separate debt and is counted apart. 169 seals record none for at least one backend — the backend rejected the spec when it was sealed. --save refuses to overwrite those ("4 of 4 backends rejected it"), so they need a different repair and would otherwise inflate the headline. That 169 independently reproduces the figure an earlier audit reported for none == none seals.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions