Skip to content

build(pipeline): pinned-t27c gen/rust + physical drift-guard (запрет писать в репо неправильно)#60

Draft
gHashTag wants to merge 10 commits into
mainfrom
feat/pipeline-guard-2026-07-10
Draft

build(pipeline): pinned-t27c gen/rust + physical drift-guard (запрет писать в репо неправильно)#60
gHashTag wants to merge 10 commits into
mainfrom
feat/pipeline-guard-2026-07-10

Conversation

@gHashTag

@gHashTag gHashTag commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Draft. Physically enforces the golden pipeline so the recurring breakage cannot land.

The recurring mistake

Someone commits gen/rust produced by a stale/wrong t27c (the 2026-07-07 direct-push break, f608dad), hand-edits generated Rust, or edits a spec without regenerating. Result: main doesn't build from a clean clone.

Root cause (proven)

f608dad regenerated with a STALE t27c. The upstream fixes already existed: let drop -> t27#1401, ExprCast -> t27#1320. The current t27c (4832ec6) carries both; regenerating with it yields valid Rust for the datapath.

What this PR does

  • .t27c-version pins the compiler to t27@4832ec6. gen/rust must be byte-identical to this t27c's output.
  • gen/rust/*.rs regenerated from specs/*.t27 with the pinned t27c (replaces the stale/invalid f608dad output). wire.rs is now the real generated output.
  • .github/workflows/spec-drift-guard.yml rebuilt: the old guard diffed deleted gen/zig+gen/c; the new one rebuilds t27c at the pinned SHA, regenerates all gen/rust, fails on any byte drift, then builds + tests.
  • docs/PIPELINE.md documents the one correct way + the t27c mutable-local limitation.
  • src/lib.rs: 9 zero-call-site modules stay unwired with an explicit reason (see below).

Honest limitation (tracked upstream, Lane A)

The pinned t27c still miscompiles a REASSIGNED mutable local: let x = 0; ... x = y; is folded to a const (E0425), let mut splits into let mut; + x = ..., var is only partially correct in complex bodies. So 9 generated modules can't compile yet; they stay unwired (zero call sites) but their gen is committed + drift-checked. Re-wire once t27c is fixed.

Verified

cargo build --all-targets green; cargo test = 103 passed; gen/rust byte-matches pinned t27c; all new files ASCII-only.

Physical lock

Branch protection on main (no direct push, required checks, no bypass) is set via the GitHub API — that is what would have blocked f608dad. This guard is the required check it plugs into.

phi^2 + phi^-2 = 3

main has not built from a clean clone since 2026-07-07: build.rs had 4
type errors and f608dad regenerated gen/rust/*.rs with a broken t27c
(let;, return () in -> u8 fns). Reproduced: cargo build fails, 0 tests
runnable at HEAD 6850649.

Surgical green fix (lib + 101 tests):
- build.rs: replace malformed .map_or(0, Option<SystemTime>) with and_then chain
- gen/rust/wire.rs: restore from last-green 2b28312 (used by src/wire.rs)
- src/lib.rs: unwire 9 generated re-export modules with ZERO call sites,
  pending t27c emitter fix (PR #44)

Verified on branch: cargo build --lib OK; cargo test --lib = 101 passed.
Binaries (trios_meshd, smoke_m1) remain stale vs the rewritten src API
(documented as P0b, not fixed blind).

Full audit, heatmap, science, 4-sprint plan, next-steps and 3 cooperation
lanes: docs/WAVE_REPORT_2026-07-10.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

phi^2 + phi^-2 = 3
Iteration 2 of the 2026-07-10 wave. smoke_m1.rs — the harness whose exact
output lines are quoted in docs/W12_M1_HW_RESULTS.md — did not compile
against the current lib: it uses Handshake/Node/MeshError, which exist in
src/crypto.rs and src/daemon.rs but were never re-exported at the crate
root (lib.rs had zero `pub use`). So the flagship M1 hw-evidence harness
was unbuildable from main.

Fix (purely additive, zero logic change):
- lib.rs: `pub use crypto::{Handshake, MeshError, Session}; pub use daemon::Node;`

Verified: cargo test --lib = 101 passed; cargo build --bin smoke-m1 OK;
`cargo run --bin smoke-m1` prints the full M1 PASS sequence (X25519 +
ChaCha20-Poly1305, tamper + replay rejected). Ground-truth on-wire size is
44 -> 83 bytes, resolving the doc-drift discrepancy (44->79 doc is stale).

Still open: trios_meshd (13 errors) needs the root shadow stubs removed
(Delivery struct vs router::Delivery enum; StaticKey/Hello stubs; two
Transport traits with different method sets) — an API-canonicalization
call best made together with the Sprint-2 crypto hardening (same file).

Refs #58, #59.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

phi^2 + phi^-2 = 3
Iteration 3 of the 2026-07-10 wave. Completes the P0 build fix end-to-end.

lib.rs held empty root "shadow stubs" (struct Delivery without variants,
struct Hello without parse/authenticated, struct StaticKey without from_seed,
a second Transport trait with send_to/recv_from) that shadowed the real
crypto::/discovery::/router::/daemon:: types. These stubs were dead (zero call
sites in src/; router.rs and modem.rs already use daemon::Transport), and they
were the sole reason trios_meshd could not compile.

Fix: remove the 5 dead stubs, re-export the real types:
  pub use crypto::{Handshake, MeshError, Session, StaticKey};
  pub use daemon::{Node, Transport};
  pub use discovery::Hello;
  pub use router::{Delivery, DropReason, MeshRouter};

Verified on a clean branch tree:
  cargo build --all-targets  -> Finished
  cargo test                 -> 101 passed; 0 failed
  cargo run --bin smoke-m1   -> full M1 PASS sequence
Both binaries (trios_meshd, smoke-m1) now build.

Correction to the report N2b framing: the types did NOT "no longer exist" —
they were shadowed. Report updated (heatmap N2b, E1.3, §7).

Refs #58, #59.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

phi^2 + phi^-2 = 3
Iteration 4 of the 2026-07-10 wave — light doc-drift cleanup, facts only.

Corrected against ground truth (verified 2026-07-10):
- #[test] blocks 110 -> 101 (tests/ dir removed 2026-07-07); command src tests -> src
- Rust source lines 4 463 -> 4 544
- "T27 ported: 1" clarified to "68 in tree / 1 wired into src" (the cited
  command returns 68, contradicting the 1)
- build snippet comment 110 -> 101, все в src/

Relinked moved files (now under docs/archive/): STRENGTHEN.md,
WAVE_N3_AUDITABILITY_GAP, W7_WEAK_POINTS_STRUCTURAL.

De-linked files not on main (live in unmerged PR #29): WAVE_DEPIN,
_recon/DEPIN_COMPETITORS — annotated as such.

Added a note that radio/README.md was deleted 2026-07-07; current
reproducible RF evidence is docs/W12_E2E_RF_TEST_RESULTS.md (30/30).

No broken relative links remain in README. No code touched.

Refs #58, #59.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

phi^2 + phi^-2 = 3
Iteration 5 of the 2026-07-10 wave. CI-integrity, mechanical, no design.

1. lefthook pre-push `cargo-build` was a no-op gate: `cargo build | tail -3`
   makes `$?` the exit code of `tail` (always 0), so a failed build passed
   the pre-push check. This is precisely how the broken 2026-07-07 build was
   pushed to main. Fixed to check cargo's exit directly (`if ! cargo build`).

2. Added a `cargo-audit` job (rustsec/audit-check@v2) so dependency
   advisories gate CI. Separate job — surfaces advisories without blocking
   build/test.

Accuracy note (anti-anchor): ci.yml already ran fmt + clippy -D warnings +
build + test, so the recon's "CI has no gates" was imprecise; the real hole
was the always-passing lefthook gate + no audit + no branch protection on
main (a GitHub setting, not a repo file — flagged for the owner).

Not touched: spec-drift-guard.yml still diffs deleted gen/zig + gen/c; that
guard is entangled with the t27c emitter fix (Lane A / PR #44) and should be
reduced to the rust backend only once t27c regenerates cleanly.

Refs #58, #59.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

phi^2 + phi^-2 = 3
Iteration 6 of the 2026-07-10 wave. Local-DoS hardening, bounded, no crypto.

The daemon read a hardcoded world-writable /tmp/mesh.drop on every tick and
treated any node id found there as link-failed. On a shared host, any local
user could write ids into that file and drop arbitrary mesh links on a
running node.

Fix (matches the existing TRIOS_WATCH / TRIOS_GATEWAY env-var idiom):
the M5 self-heal demo hook is now opt-in via TRIOS_SIM_DROPS, which names an
operator-chosen file. Unset (default) => no file is read, drop set is empty.
The demo still works: set TRIOS_SIM_DROPS=/path/you/control.

Verified: cargo build --all-targets OK; cargo test = 101 passed; no
hardcoded /tmp/mesh.drop path remains in code.

Refs #58, #59.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

phi^2 + phi^-2 = 3
Iteration 7 of the 2026-07-10 wave. Amplification-DoS hardening, bounded,
no crypto, no new deps.

The M4 gateway spawned a thread + an outbound TCP connect for every FETCH_REQ
with no bound. A flood of requests (or a Sybil) made the gateway spawn
unbounded threads and outbound connections.

Fix:
- MAX_INFLIGHT_FETCHES = 4, tracked with an AtomicUsize; a request over the
  cap is refused (logged) instead of spawning.
- fetch_public_ip now uses connect_timeout (4s) so a hung/unreachable host
  cannot pin a fetch slot indefinitely and defeat the cap (it already had a
  6s read timeout).

Verified: cargo build --all-targets OK; cargo test = 101 passed.

Refs #58, #59.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

phi^2 + phi^-2 = 3
…w-1)

Iteration 8 of the 2026-07-10 wave. Fresh audit of the previously-unexamined
routing module found a real P1 forwarding bug.

handle_frame selected the next hop with no exclusion of the neighbor the frame
arrived from, and no guard against a frame this node originated looping back.
With a node pair (A—C) whose only route toward the destination is via each
other, a packet ping-pongs A->C->A->C... until TTL is burned, making zero
forward progress — TTL was the only backstop.

Fix:
- drop a frame whose end-to-end src == self.id (looped back to origin)
- split-horizon: if the chosen next hop == `from`, drop instead of bouncing
- new DropReason::Loop for both (no exhaustive DropReason matches exist, so
  the added variant is safe)

Tests: +2 regression tests (frame_looped_back_to_origin_is_dropped,
split_horizon_no_bounce_back_to_sender). Suite 101 -> 103 passed;
cargo build --all-targets green.

Noted but NOT changed (semantically debatable, would alter max reach by one
hop): TTL is checked-then-decremented, so a fully-travelled packet spends its
last transmission on a ttl==0 frame the next hop always discards. Left for a
decision by the routing owner.

Refs #58, #59.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

phi^2 + phi^-2 = 3
…t-guard

The recurring breakage is people writing the repo the wrong way: committing
gen/rust produced by a stale/wrong t27c (the 2026-07-07 direct-push break),
hand-editing generated Rust, or editing a spec without regenerating. This makes
the wrong way physically impossible.

- .t27c-version: pin the compiler to t27@4832ec6 (carries the dropped-let #1401
  and ExprCast #1320 fixes). gen/rust must be byte-identical to this t27c.
- gen/rust/*.rs: regenerated from specs/*.t27 with the pinned t27c (replaces the
  stale/invalid output committed at f608dad). wire.rs now the real generated
  output, not a hand-restored copy.
- .github/workflows/spec-drift-guard.yml: rebuilt. Old guard diffed deleted
  gen/zig + gen/c backends (dead). New guard rebuilds t27c at the pinned SHA,
  regenerates all gen/rust, fails on ANY byte drift, then builds + tests.
- docs/PIPELINE.md: the one correct way + the mutable-local t27c limitation.
- src/lib.rs: 9 zero-call-site modules stay unwired with an explicit reason --
  t27c still miscompiles reassigned mutable locals (`let x=0; x=y` folds to a
  const -> E0425; `let mut` splits; `var` only partially correct). Their gen is
  still committed + drift-checked as canonical pinned-t27c output.

Verified: cargo build --all-targets green; cargo test = 103 passed; gen/rust
byte-matches the pinned t27c; all new files ASCII-only (L3).

Branch protection on main (no direct push, required checks) is set separately
via the GitHub API — it is the physical lock the pinned guard plugs into.

Refs #58.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

phi^2 + phi^-2 = 3
…ust pipeline

Bumps the pinned t27c to the verified fix commit and completes the pipeline so
every spec generates compiling Rust and all generated modules are wired.

- .t27c-version -> d7f3a73 (gHashTag/t27 #1456 optimizer removal + #1457
  array/index codegen, on branch fix/faithful-rust-c-codegen-1455). Verified:
  t27c suite 1494/1 (1 pre-existing Verilog failure), 0 regressions.
- gen/rust/*.rs regenerated with that t27c: the 2609-site E0425 wave -> 0.
- src/lib.rs: the 9 previously-unwired modules (mesh_routing, etx,
  adaptive_routing, multipath_routing, frame_buffer, flow_control,
  health_dashboard, anomaly_detector, quarantine_manager) are now wired, each
  with #[allow(dead_code, unused, unused_parens, clippy::all)] (zero call sites).
- specs/*.t27: fixed the genuine source bugs the correct codegen surfaced
  (#61) — path_valid typo, is_multipath_viable bool return,
  etx Q8.8 256-in-u8 width via ONE_FP, ~50 reassigned `let` -> `var`.
- docs/PIPELINE.md updated.

Verified: cargo build --all-targets green; cargo test = 103 passed; 0 warnings
(so clippy -D warnings stays green). gen/rust is byte-identical to the pinned
t27c output (drift-guard green).

Once t27 PR #1456 merges to master, bump .t27c-version to the master SHA
(identical output). Refs #58, #60, #61.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

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

Copy link
Copy Markdown
Owner Author

Full green pipeline — all 9 modules wired (commit 4adf850)

The specs/*.t27 -> t27c -> gen/rust -> src pipeline now generates compiling Rust end-to-end.

  • Pinned t27c bumped to d7f3a73 (t27 #1456 optimizer removal + #1457 array/index codegen, branch fix/faithful-rust-c-codegen-1455). t27c suite 1494/1, 0 regressions.
  • E0425 wave 2609 -> 0. All 9 previously-unwired modules now compile and are WIRED in src/lib.rs (each #[allow(dead_code, unused, unused_parens, clippy::all)] — zero call sites yet).
  • Genuine source-spec bugs fixed (Spec bugs surfaced by t27 #1456+#1457 codegen fixes (were masked while modules never compiled) #61): path_valid typo, is_multipath_viable bool return, etx Q8.8 256-in-u8 width via ONE_FP, ~50 reassigned let -> var.

Verified: cargo build --all-targets green, cargo test = 103 passed, 0 warnings (clippy -D stays green), gen byte-matches pinned t27c (drift-guard green).

Follow-up: once t27 #1456 merges to master, bump .t27c-version to the master SHA (identical output). This PR (still draft) is ready for review.

phi^2 + phi^-2 = 3

gHashTag pushed a commit that referenced this pull request Jul 10, 2026
…rt 1 of N3

The handshake computed only ee + ss and passed `ss` in BOTH the es and se slots,
so it had no forward secrecy and did not bind ephemerals into the session.

Fix: NoiseXX.ephemeral becomes a reusable StaticSecret (EphemeralSecret is
consumed by its first diffie_hellman; we need two), and complete_initiator/
responder compute the real ee/es/se so both sides derive the same key. Verified:
handshake_and_roundtrip + independent_handshakes pass, full suite 103 passed.

SCOPE: forward-secrecy half of N3 only. Identity auth (allow-list gating -> the
actual MITM defense), N4 (HELLO MAC), N5 (keystore) remain open per RFC #63 and
need owner sign-off. Based on the pipeline-guard branch (needs #60's build fix).
Draft — needs crypto review. Refs #58, #63.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

phi^2 + phi^-2 = 3
This was referenced Jul 10, 2026
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.

2 participants