Skip to content

feat(wire): T27-first partial flip — specs/wire.t27 becomes SSOT - #33

Merged
gHashTag merged 5 commits into
mainfrom
feat/t27-first-wire
Jul 4, 2026
Merged

gHashTag merged 5 commits into
mainfrom
feat/t27-first-wire

Conversation

@gHashTag

@gHashTag gHashTag commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Summary

Flips src/wire.rs to consume auto-generated code from specs/wire.t27 via t27c gen-rust. The spec is now the source of truth for constants and pure predicates; the Rust module only adds ergonomic wrappers on top.

What changed

  • gen/rust/wire.rs (new, deterministic build output): auto-generated constants + predicates, plus documented hand-written stubs for be_byte / u32_be (see limitation below).
  • src/wire.rs: re-exports auto-gen symbols, keeps Header / FrameKind / to_bytes / parse on top. No local re-declaration of VERSION or HEADER_LEN anymore.
  • build.rs (new): optional t27c gen-rust invocation under T27C_REGENERATE=1. Silent on missing t27c, so CI without the compiler still builds.
  • docs/T27_PORT_STATUS.md: wire.rs row updated to 'T27-FIRST (partial)'.
  • docs/T27_FIRST_MIGRATION.md (new): rationale, bootstrap limitation, regeneration recipe.

Why partial

t27c-0.1.0 bootstrap has a parser bug on bit-shift expressions — both gen-rust and gen (Zig) drop ((w >> N) & 255) as u8 and emit return ();. So be_byte / u32_be cannot come from the compiler yet. They live inside gen/rust/wire.rs beneath a documented banner. Once the bit-shift bug is fixed upstream in gHashTag/t27, delete the stubs and let gen-rust emit them. Filing a repro issue against gHashTag/t27 as a follow-up.

Verification

  • cargo test --lib — 101/0 (includes two new guardrails: constants + predicates).
  • cargo test --test m2_routing_pure_logic — 25/0.
  • cargo fmt --all -- --check — clean.

No hardware runs, no fabricated metrics, no changes to crypto / modem / routing.

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

Constants (VERSION, KIND_HELLO, KIND_DATA, HEADER_LEN) and pure predicates
(frame_kind_valid, header_byte, parse_accepts) are now auto-generated into
gen/rust/wire.rs via t27c gen-rust. src/wire.rs re-exports them and keeps
only the ergonomic Rust wrappers (Header struct, FrameKind enum, to_bytes,
parse) on top.

Partial rather than full flip: t27c-0.1.0 has a bit-shift parser bug that
emits 'return ();' for expressions like ((w >> 24) & 255) as u8, so be_byte
and u32_be stay hand-written inside gen/rust/wire.rs (below a documented
banner) instead of coming from the compiler. Bug reproduces on gen-rust and
gen (Zig) both — it is in the shared frontend, not the emitter. To be filed
against gHashTag/t27.

build.rs invokes t27c only when T27C_REGENERATE=1 is set, so CI without
t27c installed still builds. gen/rust/ is committed as a deterministic
build output.

Guardrails added:
- t27_gen_constants_match_hand_written — pins auto-gen constant values.
- t27_gen_predicates_match_semantics — exercises the generated predicates.

Verified green:
- cargo test --lib: 101/0
- cargo test --test m2_routing_pure_logic: 25/0
- cargo fmt --all -- --check: clean

Docs:
- docs/T27_PORT_STATUS.md — wire.rs row flipped to 'T27-FIRST (partial)'.
- docs/T27_FIRST_MIGRATION.md — new; documents the flip, the bootstrap
  limitation, the build story, and the regeneration recipe.

Anchor: phi^2 + phi^-2 = 3
@gHashTag gHashTag added mesh TRI-NET mesh track documentation Docs labels Jul 4, 2026
…hift

Post-merge triage on the t27c bootstrap isolated the real trigger. The bug is
not in bit-shift parsing; it is missing ExprCast lowering in the Rust, Zig,
and C text emitters. The frontend builds the AST node correctly, but
expr_to_rust and its Zig/C peers have no arm for NodeKind::ExprCast and fall
through their default arm to the unit value '()'. gen-verilog is the only
backend that implements ExprCast.

Isolation table (all against current master t27c):
  w >> 24                  -> OK
  (w >> 24) & 255          -> OK
  (w >> 24) as u8          -> ()  <-- cast triggers it
  (w & 255) as u8          -> ()  <-- no shift, same failure
  42 as u32                -> ()
  x as u32                 -> ()
  ((a as u32) << 8) | ...  -> ((() << 8) | ())

Filed as gHashTag/t27#1314 with the isolation matrix and the compiler.rs
line reference.

Practical impact on this PR: unchanged. be_byte and u32_be still cannot come
from t27c because both use 'as u8' / 'as u32'. Hand-written stubs stay
beneath the banner in gen/rust/wire.rs until t27c ships an ExprCast arm in
expr_to_rust. This commit only fixes the wording in the banner and the
migration doc so the tracking issue is accurate.

Anchor: phi^2 + phi^-2 = 3
@gHashTag

gHashTag commented Jul 4, 2026

Copy link
Copy Markdown
Owner Author

Post-merge triage note before human-merge: upstream root cause is precisely identified and filed as gHashTag/t27#1314. The bug is missing ExprCast lowering in the Rust/Zig/C text emitters, not bit-shift parsing (my earlier guess in-thread). Isolation matrix and the exact compiler.rs fallthrough point (expr_to_rust at line 8054, default arm at line 8172) live in the issue.

Follow-up commit 880954e updates the banner in gen/rust/wire.rs and docs/T27_FIRST_MIGRATION.md so the tracking reference is honest. No code paths changed; still green:

  • cargo test --lib: 101/0
  • cargo test --test m2_routing_pure_logic: 25/0
  • cargo fmt --all -- --check: clean

Once t27c#1314 lands, follow-up PR: strip the hand-stub band from gen/rust/wire.rs, regenerate via T27C_REGENERATE=1 cargo build, verify diff.

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

@gHashTag

gHashTag commented Jul 4, 2026

Copy link
Copy Markdown
Owner Author

Upstream unblock landed: gHashTag/t27#1320ExprCast arm added to expr_to_rust (before default), mirrors the gen-verilog arm. t27c self-tests 20/0, gen-rust on specs/wire.t27 now lowers be_byte and u32_be correctly (was return ();).

Merge order once approved:

  1. Human-merge t27#1320 into t27:master.
  2. Rebuild t27c from that master.
  3. In tri-net feat/t27-first-wire: T27C_REGENERATE=1 t27c gen-rust specs/wire.t27 > gen/rust/wire.rs, verify diff drops the hand-stub band only, re-run tests.
  4. Then human-merge this PR feat(wire): T27-first partial flip — specs/wire.t27 becomes SSOT #33.

Zig + C emitters remain follow-up under t27#1314 (Rust arm in #1320 is the template). tri-net does not consume them today so this does not block the flip.

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

…20 + gen/ untouchable rule

- Two remaining 'bit-shift' references (build.rs note, Next flips) corrected to
  ExprCast lowering (t27#1314 → fixed by t27#1320). The Bootstrap-limitation
  section was already corrected in 880954e; these two were missed.
- Regeneration recipe updated to reflect pre-validated reality: post-#1320 regen
  overwrites the whole gen file (~49 removed / ~40 added), NOT just the stub
  band. Tests stay 101/0 + 25/0. Bigger diff is expected/correct (removes
  obsolete ExprCast banner + hand-stubs, normalises cosmetic rendering).
- New 'Rule: gen/ is untouchable raw output' section: gen/<lang>/* is never
  hand-edited; explanatory banners/comments go in the consumer (src/) or this
  doc. If t27c emits wrong, fix t27c upstream, don't patch gen/. Captures the
  diff-shape lesson so future flips (routing, gf16) don't repeat the trap.
gHashTag pushed a commit to gHashTag/t27 that referenced this pull request Jul 4, 2026
…f '()' (Closes #1314)

Add Expr::Cast arm in expr_to_rust (bootstrap/src/compiler.rs), mirroring
the gen-verilog arm at compiler.rs:4941. Before this fix, ExprCast fell
through to the default '_ => "()".to_string()' branch and generated
empty-tuple stubs in Rust output, silently corrupting any T27 spec using
bit-width casts.

Also update docs/NOW.md with an exprcast-rust-emitter entry (required by
the NOW Sync Gate).

Closes #1314 (gen-rust half; gen-c and gen-zig follow-ups tracked
separately). Unblocks gHashTag/tri-net#33 T27-first wire flip.

Anchor: phi^2 + phi^-2 = 3
gHashTag added a commit to gHashTag/t27 that referenced this pull request Jul 4, 2026
…f '()' (Closes #1314) (#1320)

Add Expr::Cast arm in expr_to_rust (bootstrap/src/compiler.rs), mirroring
the gen-verilog arm at compiler.rs:4941. Before this fix, ExprCast fell
through to the default '_ => "()".to_string()' branch and generated
empty-tuple stubs in Rust output, silently corrupting any T27 spec using
bit-width casts.

Also update docs/NOW.md with an exprcast-rust-emitter entry (required by
the NOW Sync Gate).

Closes #1314 (gen-rust half; gen-c and gen-zig follow-ups tracked
separately). Unblocks gHashTag/tri-net#33 T27-first wire flip.

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

Co-authored-by: Perplexity Computer <agent@perplexity.ai>
Regenerated via t27c (release, built from t27 master c4dc8ee) which now
includes the Expr::Cast arm in expr_to_rust that emits '(operand as
target)' instead of the empty-tuple stub. This closes the T27-first
partial flip that a6bb0b0 opened: gen/rust/wire.rs is now the full
canonical output of specs/wire.t27, not a hand-patched shim.

Diff shape: +40 / -49 (banner shrinks to the raw t27c header, be_byte /
u32_be / header_byte bodies swap their return-() stubs for real 'as u8'
/ 'as u32' casts). Tests: cargo test --lib 101/0, cargo test --test
m2_routing_pure_logic 25/0.

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

Refs #33
gHashTag pushed a commit that referenced this pull request Jul 4, 2026
Real t27c gen-rust emits idiomatic-T27 output (literal return + explicit
parens) which fails 'cargo clippy -- -D warnings' with needless_return,
unnecessary_parens, and unused_parens. Since gen/ is untouchable (see
docs/T27_FIRST_MIGRATION.md), scope the allow to the wrapping mod in
src/wire.rs rather than hand-editing the generated file.

Cleaner Rust rendering (drop trailing 'return', drop wrapping parens on
whole-expression returns and on if-condition wrappers) is upstream work
on gHashTag/t27 in expr_to_rust; when that lands, the allow can shrink
or disappear on the next regeneration.

cargo build 101/0 lib, m2_routing_pure_logic 25/0, cargo fmt clean.

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

Refs #33
Real t27c gen-rust emits idiomatic-T27 output (literal return + explicit
parens) which fails 'cargo clippy -- -D warnings' with needless_return,
unnecessary_parens, and unused_parens. Since gen/ is untouchable (see
docs/T27_FIRST_MIGRATION.md), scope the allow to the wrapping mod in
src/wire.rs rather than hand-editing the generated file.

Cleaner Rust rendering (drop trailing 'return', drop wrapping parens on
whole-expression returns and on if-condition wrappers) is upstream work
on gHashTag/t27 in expr_to_rust; when that lands, the allow can shrink
or disappear on the next regeneration.

cargo build 101/0 lib, m2_routing_pure_logic 25/0, cargo fmt clean.

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

Refs #33
@gHashTag
gHashTag force-pushed the feat/t27-first-wire branch from 7f0db07 to 45d84ce Compare July 4, 2026 13:02
@gHashTag
gHashTag marked this pull request as ready for review July 4, 2026 13:05
@gHashTag
gHashTag merged commit 77a9a49 into main Jul 4, 2026
2 checks passed
@gHashTag
gHashTag deleted the feat/t27-first-wire branch July 4, 2026 13:05
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 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
Second + third T27-first flips (after wire.t27 #33). Both specs produce
CLEAN gen-rust output (0 broken casts, 0 unsupported) — no dynamic arrays
needed, ExprCast lowering (t27@3c912d9) handles all 'as u8'/'as u32'.

Generated (6 files, 3 targets × 2 specs):
  gen/rust/hello.rs  (67L) — MAX_HEARD, hello_byte, reports_hearing, etc.
  gen/rust/etx.rs    (68L) — OPTIMISTIC, DEAD_EPS, ONE_FP, calc_etx, etc.
  gen/zig/hello.zig  — @as/@intcast form
  gen/zig/etx.zig
  gen/c/hello.c      — ((uint8_t)(...)) form
  gen/c/etx.c

Guardrail tests (tests/t27_gen_hello_guardrail.rs, 4 tests):
  - hello constants (MAX_HEARD=3, HEADER_LEN=13)
  - hello byte-layout (src field BE, n at idx 8)
  - etx constants (OPTIMISTIC, DEAD_EPS, ONE_FP in Q8.8)

Gate: cargo test --all = 141 passed, 0 failed (was 137 + 4 new).

Drift-guard extension (to cover hello + etx) follows in next commit.
gHashTag pushed a commit that referenced this pull request Jul 22, 2026
…-end measurement

Single-process loopback confounded every metric and repeatedly produced broken-ruler
results: sent and recv were the SAME node's counters (delivery ratios >100% from
timing offsets, waves #26/#33/#37), jitter==0 meant "no stream" not "clean link"
(#24), and a cross-thread crash-race hid until it fired (#33). There was no way to
verify the UI or a real MITM either. Fix: run TWO independent TriNetMonitor instances
that dial each other over real UDP.

Three dev-only env hooks (no-ops in a shipping run):
  TRINET_LOG=<path>          per-instance log (LogBus) so each process's counters read apart
  TRINET_LISTEN=<port>       this instance's UDP listen port
  TRINET_AUTOCALL=host:port  auto-dial a 1-1 call on launch (INVITE bypassed)
CallManager.startCall now honors a distinct listen port so two locals don't collide.
smoke/two_endpoint_rig.sh orchestrates A(:8000) <-> B(:8100) and reports the CROSS-process
delivery A->B = (B received)/(A sent) — the honest number a single process cannot give.

Verified live: two real windowed processes establish a bidirectional call (macOS shares
the camera, so both send AND receive). Clean link: A->B 98.7%, B->A 93.4%. With 25%
induced packet loss on B: A->B still 96.7% -- i.e. the layered loss-recovery stack
(grouped FEC + whole-NAL NACK + per-fragment NACK from #31-33) recovers 25% loss to ~97%
frame delivery, now proven over two genuine processes instead of a self-loopback.

Mac-only (the rig runs two Mac instances); the env hooks are inert dev tooling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Docs mesh TRI-NET mesh track

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant