Skip to content

ci(spec-drift-guard): extend to Zig + C — three-backend byte-identity enforcement#38

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

ci(spec-drift-guard): extend to Zig + C — three-backend byte-identity enforcement#38
gHashTag merged 1 commit into
mainfrom
feat/spec-drift-guard-multi-target

Conversation

@gHashTag

@gHashTag gHashTag commented Jul 4, 2026

Copy link
Copy Markdown
Owner

What

Extends .github/workflows/spec-drift-guard.yml from one backend (Rust) to three (Rust + Zig + C), and commits the newly-generatable output files:

Why this is possible now

gHashTag/t27#1337 (merged into t27 master @ 3c912d9) lowered ExprCast in the Zig and C emitters:

  • Zig arm: @as(<T>, @intCast(<operand>)) — narrows and widens (stronger than the @as-only suggestion in t27#1333).
  • C arm: ((<uintN_t>)(<operand>)) via Self::type_to_c.

Before that, gen (Zig) silently dropped every as-cast (_ => {} default arm) and gen-c emitted /* unsupported: ExprCast */. Since specs/wire.t27 uses (w >> 24) & 255) as u8 in be_byte and four b as u32 shifts in u32_be, neither backend could produce compilable output until #1337.

Local verification (t27c from t27@3c912d9)

  • t27c gen-rust specs/wire.t27 | diff -u gen/rust/wire.rs - → empty
  • t27c gen specs/wire.t27 | diff -u gen/zig/wire.zig - → empty
  • t27c gen-c specs/wire.t27 | diff -u gen/c/wire.c - → empty
  • grep -c 'unsupported: ExprCast' gen/zig/wire.zig gen/c/wire.c → 0 / 0
  • cargo test --lib → 101 passed / 0 failed
  • Sample of new Zig emission: return @as(u8, @intCast((w >> 24) & 255));
  • Sample of new C emission: return ((uint8_t)(((w >> 24) & 255)));

Workflow structure

Three regen + diff step-pairs, each with its own ::error file=…:: annotation on drift. Path filter unchanged (specs/**, gen/**, build.rs, workflow itself) — coverage widens because gen/** now matches three directories.

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 lists all three text backends under drift-guard.
  • docs/T27_PORT_STATUS.md: wire.rs row upgraded to 'T27-FIRST (full, multi-target)'.

Chain context

Closes Option B end-to-end for this loop:

  • ✅ Upstream Zig+C ExprCast — t27#1337 merged @ 3c912d9
  • ✅ Multi-target drift-guard — this PR
  • ✅ Parse-path u32_be delegation — #37 merged @ 0e1f1f2

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

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.
@gHashTag
gHashTag merged commit dc1bebb into main Jul 4, 2026
3 checks passed
@gHashTag
gHashTag deleted the feat/spec-drift-guard-multi-target branch July 4, 2026 14:17
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.
gHashTag pushed a commit that referenced this pull request Jul 4, 2026
…= 9 checks)

Refactored from 6 copy-pasted step pairs (wire-only) into 3 compact
loop-based steps (one per backend: Rust/Zig/C). Each loops over all
specs [wire, hello, etx], regenerates from t27c, diffs against committed.

Scalable: adding the next spec (crc16, byte_utils, ...) = add the name
to the for-loop in each step. No new step needed.

Drift matrix coverage now:
  wire.t27  × {Rust, Zig, C} = 3 checks (existing, verified by #38)
  hello.t27 × {Rust, Zig, C} = 3 checks (NEW)
  etx.t27   × {Rust, Zig, C} = 3 checks (NEW)
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