Skip to content

W6.1: structural fuzz — cross-backend acceptance agreement (1000 specs, 100.0%) - #41

Merged
gHashTag merged 1 commit into
mainfrom
feat/w6-structural-fuzz
Jul 7, 2026
Merged

gHashTag merged 1 commit into
mainfrom
feat/w6-structural-fuzz

Conversation

@gHashTag

@gHashTag gHashTag commented Jul 5, 2026

Copy link
Copy Markdown
Owner

What

Adds a minimal differential fuzzer for the t27c front end and reports the cross-backend accept/reject decision.

  • scripts/fuzz/gen_specs.py — random .t27 spec generator, three buckets (valid / malformed / semi-valid), fixed seed 0xF1F1F1F1.
  • scripts/fuzz/run_fuzz.py — runs each spec through t27c gen-rust, t27c gen (Zig), t27c gen-c; aggregates exit codes + stderr class per file; asserts all three backends agree.
  • docs/W6_STRUCTURAL_FUZZ_2026-07-05.md — methodology, result, reproduction, honest scope.

Pilot result (t27@879c1c7, sandbox VM)

Metric Value
Specs fuzzed 1000
All-three-accept 930
All-three-reject 70
Disagreements 0
Cross-backend agreement 100.000 %
Reject class agreement 70 / 70

All rejects came from one damage class (drop-close-brace), classified identically as parse-error by all three backends. Wall-clock: ~5 s for 3000 subprocess calls.

Scope

W6.1 answers exactly one question: do the Rust / Zig / C emitters agree on the boundary of the language t27c accepts? — yes, on a 1000-sample, with zero divergence.

W6.1 does not prove functional equivalence of the generated code across the three backends. That is W6.2 (runtime differential), gated on this pilot.

The report also flags a separate, honest finding: the current t27c parser is permissive on non-brace lexical injuries — worth revisiting on a different axis, but does not weaken the agreement claim (whatever it accepts, it accepts uniformly across the three code emitters).

Repro

python3 scripts/fuzz/gen_specs.py --n 1000 --outdir bench/fuzz_specs
python3 scripts/fuzz/run_fuzz.py \
    --t27c ../t27/target/release/t27c \
    --specs-dir bench/fuzz_specs \
    --out bench/fuzz_results

Expected: n_disagree = 0, agreement_pct = 100.0.

Not for merge

Draft. Real workshop happens under review; on approval this feeds the paper §5.6 with a concrete pre-runtime equivalence bound before moving to W6.2.

phi^2 + phi^-2 = 3

…0 specs)

Adds a small differential fuzzer for the t27c front end and reports the
cross-backend accept/reject decision.

Setup:
- scripts/fuzz/gen_specs.py generates random spec bodies in 3 buckets
  (valid / malformed / semi-valid), seed = 0xF1F1F1F1.
- scripts/fuzz/run_fuzz.py invokes t27c gen-rust / gen / gen-c on every
  spec, captures exit code + stderr classification, checks agreement.

Pilot result at t27@879c1c7 (sha256 recorded in the report):
- 1000 specs × 3 backends = 3000 subprocess calls, ~5s wall-clock
- 930 all-three-accept, 70 all-three-reject, 0 disagreements
- Cross-backend agreement: 100.000%
- All 70 rejects came from one damage class (drop-close-brace), all three
  backends classified them identically as parse-error.

Interpretation (see docs/W6_STRUCTURAL_FUZZ_2026-07-05.md):
- The three code emitters agree perfectly on which specs t27c accepts.
- The current t27c front end is permissive on lexical injuries other
  than an unbalanced brace: honest finding, separate axis, out of W6.1
  scope but flagged in the report.
- W6.1 does NOT prove functional equivalence of generated code — that
  is W6.2 (runtime differential), gated on this pilot.

Artifacts:
- scripts/fuzz/{gen_specs,run_fuzz}.py — 288 + 183 lines
- bench/fuzz_specs/manifest.json + seed-reproducible .t27 files (gitignored)
- bench/fuzz_results/fuzz_raw.csv (3000 rows) + fuzz_summary.json
- docs/W6_STRUCTURAL_FUZZ_2026-07-05.md — methodology + result + repro

No fabrication: every number in the report is from the harness JSON at
run time.

phi^2 + phi^-2 = 3
@gHashTag
gHashTag marked this pull request as ready for review July 7, 2026 12:26
@gHashTag
gHashTag merged commit befd839 into main Jul 7, 2026
2 checks passed
@gHashTag
gHashTag deleted the feat/w6-structural-fuzz branch July 7, 2026 12:26
gHashTag pushed a commit that referenced this pull request Jul 22, 2026
…aversal

The call has connected only same-subnet peers for its entire life; every wave
report v0.7..v0.11 named "add STUN" as the #1 usability unlock and deferred it.
Codecs, FEC, crypto and BWE are all polish on a call that cannot even be
established across two networks. Root cause: neither side knows its own PUBLIC
address, so there is nothing for a later hole-punch to aim at.

StunClient.swift (pure + standalone, like MeshCrypto / VideoFEC) is a minimal
STUN (RFC 5389) Binding client: encode a Binding Request, parse XOR-MAPPED-ADDRESS
(IPv4 + IPv6), enumerate host candidates (getifaddrs), and a best-effort
server-reflexive query over raw BSD UDP. The XOR unmasking is endian-sensitive:
  X-Port = port XOR (cookie>>16); X-Addr = addr XOR cookie          (IPv4)
  X-Addr = addr XOR (cookie || transaction-id)                      (IPv6)

Verified two independent ways:
  * OFFLINE, bit-exact against the IETF's own RFC 5769 reference vectors
    (2.2 -> 192.0.2.1:32853, 2.3 -> [2001:db8:...:6677]:32853) in
    smoke/harness/stun_vectors.swift, now the 8th test in verify.sh
    (verify: 8 passed, 0 failed).
  * LIVE end-to-end: gatherServerReflexive("stun.l.google.com",19302) returned
    this machine's real public ip:port; host candidates returned the LAN IPv4.

RFC 5769's official vectors keep the gate hermetic (no network dependency, unlike
the #41 Keychain hang). Not yet wired into the transport — exchanging candidates
and hole-punching is the next brick, so StunClient.swift is harness-proven but
not in project.yml until it is used.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gHashTag pushed a commit that referenced this pull request Jul 23, 2026
…nnect

Both platforms hold a sealed candidate offer (#45-47) but had no way to DELIVER it
to the peer. Even serverless P2P needs a meeting point for the first exchange
(WebRTC = signaling server, BitTorrent = tracker/DHT, tri-net = the mesh).
Rendezvous.swift is the CLIENT: address the relay by roomHash = SHA256(passphrase)
so it never sees the passphrase, publish your sealed offer, fetch the peer's. The
relay is a BLIND pairing service — offers are sealed, so it cannot read or forge
candidates; it only matches "someone else who hashed the same room" with you.

Verified in smoke/harness/rendezvous.swift (12th verify.sh test, 15 checks, 5x for
determinism, verify: 12 passed, 0 failed): pure layer — wire codec, roomHash
blinding, mailbox pairing logic; LIVE layer — a reference UDP rendezvous server +
two clients that gather -> seal -> publish -> fetch -> open -> Ice.connect and
actually connect over loopback KNOWING ONLY A SHARED ROOM NAME. That is the whole
serverless-connection chain end-to-end on one machine.

Also fixed a verify.sh regression this exposed (NOT caused by rendezvous): the
keychain harness began hanging because waves #46/#47 launched the real SIGNED app,
which stored its device identity under the default keychain account; a fresh
unsigned harness touching that signed item blocks on a GUI SecurityAgent prompt
(the #41 watchdog caught it as a timeout). The app launch poisoned the shared
keychain — identity before shared medium. Fix: export TRINET_KC_ACCOUNT=verify so
the keychain harness uses an isolated, harness-owned account; the app's real
identity item is left untouched.

roomHash and the seal are independent defenses: the hash hides WHICH room from the
relay, the seal hides WHAT candidates. Boundary: loopback proves discover +
exchange + punch + connect over real UDP; a deployment needs the relay host (a
tiny stateless service, or the mesh) and two separate NATs for real traversal.
Rendezvous is client-only, harness-proven, Mac-only this wave; the iOS mirror and
the CallManager integration are the last two steps.

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant