Skip to content

ci(spec-drift-guard): enforce specs/wire.t27 -> gen/rust/wire.rs SSOT byte-for-byte - #35

Merged
gHashTag merged 1 commit into
mainfrom
feat/spec-drift-guard
Jul 4, 2026
Merged

gHashTag merged 1 commit into
mainfrom
feat/spec-drift-guard

Conversation

@gHashTag

@gHashTag gHashTag commented Jul 4, 2026

Copy link
Copy Markdown
Owner

What

Adds .github/workflows/spec-drift-guard.yml: on push to main and on PRs touching specs/**, gen/**, build.rs, or the workflow itself, the job rebuilds t27c from gHashTag/t27@master, regenerates gen/rust/wire.rs from specs/wire.t27, and diffs against the committed file. Any drift fails the job with an ::error annotation pointing at the offending file.

Also refreshes two docs that went stale after #33:

  • docs/T27_PORT_STATUS.md: wire.rs row = T27-FIRST (full); mentions drift-guard.
  • docs/T27_FIRST_MIGRATION.md: ExprCast gap reframed as resolved for Rust; build.rs no-overwrite policy reframed as intentional (drift-guard is the enforcement mechanism); auto-gen table includes be_byte / u32_be.

Why

Weak-spot audit after the #33 T27-first flip surfaced that nothing in CI actually enforced the SSOT contract. build.rs refuses to overwrite committed gen/rust/wire.rs, and local manual regen matches, but a hand-edit slipping in would ship silently. This workflow closes that hole.

Coverage

  • Path filter: PR only runs the job when relevant paths change (fast for docs-only PRs).
  • Push to main runs unconditionally so a merge that skipped PR review still gets caught.
  • Uses dtolnay/rust-toolchain@stable + a plain cargo build; no cached secrets.

Verification (local)

Anchor: phi^2 + phi^-2 = 3.

…ire.t27

- .github/workflows/spec-drift-guard.yml: on push to main + PR touching
  specs/**, gen/**, build.rs, or the workflow itself, rebuild t27c from
  gHashTag/t27@master and regenerate gen/rust/wire.rs; diff -u against
  committed and fail with an ::error annotation on mismatch.
- docs/T27_PORT_STATUS.md: wire.rs row = T27-FIRST (full); note drift-guard.
- docs/T27_FIRST_MIGRATION.md: reflect that ExprCast gap is resolved, the
  build.rs no-overwrite is intentional (drift-guard enforces SSOT), and
  auto-gen table includes be_byte/u32_be.

Closes gap identified in weak-spot audit (silent drift risk between the
specs/wire.t27 SSOT and gen/rust/wire.rs). CI now enforces the T27-first
contract byte-for-byte.

Anchor: phi^2 + phi^-2 = 3.
@gHashTag
gHashTag merged commit f126dca into main Jul 4, 2026
3 checks passed
@gHashTag
gHashTag deleted the feat/spec-drift-guard branch July 4, 2026 13:26
gHashTag added a commit that referenced this pull request Jul 4, 2026
Replace `u32::from_be_bytes(b[2..6].try_into().ok()?)` (and the dst-slot
equivalent) with `u32_be(b[2], b[3], b[4], b[5])` — the auto-generated
function produced by t27c from specs/wire.t27.

Byte-order equivalence:
- `u32::from_be_bytes([b0,b1,b2,b3])` = (b0<<24)|(b1<<16)|(b2<<8)|b3.
- t27c-generated `u32_be(b0,b1,b2,b3)` = same expression (see gen/rust/wire.rs).
- `try_into().ok()?` on a 4-byte slice never returns None post the length
  check on line 82; removing it eliminates a dead error path.

Consequence: the parse-side arithmetic now lives under the SSOT contract.
spec-drift-guard CI (workflow spec-drift-guard.yml, merged in #35) is the
enforcement mechanism — any drift between specs/wire.t27 and gen/rust/wire.rs
now covers this reassembly path as well.

Closes weak-spot audit finding #5 (post-#33 loop): src/wire.rs still used
std::from_be_bytes rather than delegating to the auto-gen equivalent, so
the parse-path was outside the SSOT umbrella even though the serialize-path
(header_byte + be_byte) was inside.

Also re-exports `be_byte` and `u32_be` from the `gen` module for symmetry
with the other spec-driven helpers.

Verification (local):
- `cargo build`: clean.
- `cargo test --lib`: 101 passed / 0 failed. In particular
  `wire::tests::header_roundtrips` still passes, confirming byte-order
  equivalence end-to-end.

Anchor: phi^2 + phi^-2 = 3.

Co-authored-by: Perplexity Computer <agent@perplexity.ai>
gHashTag added a commit that referenced this pull request Jul 4, 2026
…n/c (#38)

Post t27#1337 (ExprCast lowered for Zig and C emitters), specs/wire.t27
can now round-trip through three text backends. This PR commits the
generated files and extends spec-drift-guard.yml to enforce byte-identity
on all of them.

Backends now under drift-guard:
- Rust: gen/rust/wire.rs (via t27c gen-rust)      — from #35
- Zig:  gen/zig/wire.zig (via t27c gen)           — new
- C:    gen/c/wire.c    (via t27c gen-c)          — new

Verified locally with t27c built from t27@3c912d9 (post-#1337 master):
- diff -u vs regenerated output on all three: empty.
- Zig cast form: @as(u8, @intcast((w >> 24) & 255)) etc.
- C   cast form: ((uint8_t)(((w >> 24) & 255))) etc.
- 0 occurrences of 'unsupported: ExprCast' in Zig or C output.
- cargo test --lib: 101 passed / 0 failed.

Docs refresh:
- docs/T27_FIRST_MIGRATION.md: ExprCast section marked resolved on all
  four backends (Rust #1320, Zig+C #1337, Verilog pre-#1320). Build
  section notes drift-guard covers all three text backends.
- docs/T27_PORT_STATUS.md: wire.rs row now says 'T27-FIRST (full,
  multi-target)' and lists all three gen files.

Option B closed end-to-end: upstream ExprCast in all four emitters,
tri-net multi-target drift-guard live, parse-path delegates to auto-gen
u32_be (#37). Anchor: phi^2 + phi^-2 = 3.

Co-authored-by: Perplexity Computer <agent@perplexity.ai>
gHashTag pushed a commit that referenced this pull request Jul 4, 2026
…dit-trail primitive

Bounded expansion (not full v1). The skeleton previously proposed the
auditability primitive abstractly (Sections 1-4); this commit adds Section
5 reporting that the primitive is now empirically realized end-to-end at
tri-net main dc1bebb + t27 master 3c912d9.

Section 5 subsections:

- 5.1 What is materialized -- one spec (specs/wire.t27), three generated
  backends (gen/{rust,zig,c}/wire.*), one workflow (spec-drift-guard.yml),
  consumer path under the same umbrella (src/wire.rs -> u32_be).
- 5.2 Audit-trail tuple (concrete instance) -- (tri-net@dc1bebb,
  t27@3c912d9, spec-drift-guard run) is the minimal fetch set for a third
  party to independently verify byte-identity.
- 5.3 Merge chain table -- 5 tri-net PRs (#33/#34/#35/#37/#38) + 2 t27
  PRs (#1320/#1337) with merge SHAs.
- 5.4 Empirical checks at HEAD -- three diff -u results (all empty), zero
  'unsupported: ExprCast' in Zig/C output, 101 lib tests green including
  header_roundtrips as empirical byte-order-equivalence proof.
- 5.5 What this reference impl does NOT show -- byte-identity is not
  functional correctness; only one spec is covered so far; no silicon;
  trust in t27c itself is not eliminated (moved, per Carrone 2026).

Sync updates across the doc:

- Header cross-link: 91a5b63 -> dc1bebb (post-#38).
- Section 3.1: describes all three gen targets, not just Rust.
- Section 3.2: drift-guard covers Rust + Zig + C; links to #35 + #38.
- Section 3.3: ExprCast marked resolved on all four backends
  (Rust #1320, Zig+C #1337, Verilog pre-#1320).
- Section 6 (Limits): removed obsolete 'Rust-only SSOT until #1333' bullet;
  added trust-surface-of-t27c and no-HDL-target-yet bullets.
- Section 7 (Future work): struck through completed Zig+C drift-guard
  item; added protocol-stack expansion, t27c deterministic-build items.
- Appendix A: three-target reproducibility recipe (8 steps), pins
  tri-net@dc1bebb + t27@3c912d9.

Draft only -- not for external circulation.

Anchor: phi^2 + phi^-2 = 3.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant