docs(W7): no-paste-review rule for Option B handoff (W7 workstream precondition) - #43
Merged
Merged
Conversation
Ratifies W7 collab choice: Option B (divide by concern, not by host), with one refinement mandatory before workstream start. The refinement closes W6.2 weak-point 1.8 (draft-lived-in-sandbox, review-went-by-paste). In W7 the doc-layer specifically cannot approve against paste — approve is only valid against committed text in a w7/docs/* branch, fetched via git or gh api. Compiler and testing layers follow the same rule as preferred, with a 10-line-diff exception for fast clarifications. All approves must cite a SHA so the review is reproducibly bound to file state, not to transient chat paste. This is the anti-anchor discipline of PR #42 promoted from ad-hoc practice to a written rule for the whole W7 cycle. phi^2 + phi^-2 = 3
This was referenced Jul 5, 2026
gHashTag
added a commit
that referenced
this pull request
Jul 5, 2026
Adds two sibling rules to no-paste-review in docs/W7_COLLAB_OPTIONS.md: 1. SHA-advance re-review rule — approve binds to cited SHA; branch advance between approve and merge requires explicit re-confirm with delta bullet-list. Silent SHA-swap forbidden. Applies to all layers. 2. External-dep timer rule — PR blocked on external dependency must have terminal-event triggers (won't-fix / closing PR / explicit reject) + backstop timer (default 14d from upstream issue publication). Whichever comes first. Together with no-paste-review (PR #43), these form the temporal-precision triad governing W7 review workflow: - no-paste-review: spatial locality (review \ne paste) - SHA-advance: temporal drift within PR (approve \ne merge-state) - external-dep timer: temporal drift outside PR (draft \ne infinite wait) GLM peer-review @ e1d29f3: APPROVE. First application of SHA-advance rule to itself (head unchanged since approve). phi^2 + phi^-2 = 3
gHashTag
added a commit
that referenced
this pull request
Jul 5, 2026
…2; NAMED_CONST] (#47) W7.3 grammar-expansion increment #1 — collection-typed params using [u32; NAMED_CONST] syntax matching the tri-net/specs audit corpus. Path-confirmed via t27c gen-rust: 1000/1000 gen-rust succeeded, 1924 [u32; NAMED_CONST] in .t27 input → 1924 Vec<> in Rust output, exact one-to-one. W6.2 Class 2 defect surface (Vec<> param-position) exercised by construction. Independently verified by GLM re-review at 9bbc103: - Documented 1000-spec sweep: 1924 Vec<> in gen-rust output - Independent t27c run on specs/anomaly_detector.t27: rc=0, 7 Vec<> confirmed Discipline chain observations (this PR): - Anchor #4 recorded: any claim verified against ground truth requires scoping the verification tool to the same corpus as the claim. - SHA-advance rule (PR #45): applied at 247427d → 9bbc103 with delta bullet-list in PR body. - No-paste-review rule (PR #43): GLM approved against committed body text with SHA citation. Commits (post-squash provenance): - 2080510 fix(W7.3): word-boundary anchor normalize_ast regex - 247427d feat(W7.3): grammar-expansion target #1 — collection-typed params (Zig-style, OBSOLETED) - 9bbc103 fix(W7.3): rewrite collection-params to [u32; NAMED_CONST] per audit-corpus ground truth Base: main @ 3272583 (PR #46, E1+E2 frozen baseline). E3 still timer-blocked (backstop 2026-07-19 12:24 UTC per PR #44). phi^2 + phi^-2 = 3
gHashTag
pushed a commit
that referenced
this pull request
Jul 23, 2026
…NAT brick) #42 gave each side its public address (STUN), #43 punched between two KNOWN ports. The missing glue: serialize the candidate LIST so the two sides can exchange it over a signaling/rendezvous channel, and orchestrate a real connect that probes ALL of the peer's candidates and nominates the one that answers (a NAT may silently drop some pairs). IceSession.swift does both, pure + standalone, reusing HolePunch's probe/ack codec and priority: * Ice.encode/decode: [count:2][kind:1][port:2][ipLen:1][ip] per candidate, bounds-checked on parse; * Ice.connect(localPort, remote[]): bind one socket, probe every remote for the whole window, ack observed sources, nominate the highest-priority remote that actually answered; report the bound port as the media socket to hand off. Verified in smoke/harness/ice_session.swift (10th verify.sh test, verify: 10 passed, 0 failed): serialization round-trips + rejects garbage; and TWO real in-process sessions exchange serialized blobs and connect over loopback UDP while correctly discarding a decoy candidate (192.0.2.2, RFC 5737 unroutable) that never answers. Ran 3x, 3/3 deterministic. Nominate by "did it ACK", never by priority alone — that is what makes a dead higher-priority candidate get skipped instead of selected. Do not early-exit on first success (strands the peer mid-handshake); run the full window, keep acking. Boundary: loopback proves serialize/exchange/connect/nominate over real UDP, NOT traversal of a real NAT (two separate NATs). The three bricks (STUN, punch, session) are harness-proven; wiring connect() into CallManager before the media socket, fed by the room's exchanged candidates, is the integration step. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gHashTag
pushed a commit
that referenced
this pull request
Jul 23, 2026
…fore building it The three NAT bricks (STUN #42, punch #43, ICE session #44) all assume the peers already hold each other's candidate lists. Whatever rendezvous carries that list must NOT be trusted to read or forge it: an injected candidate redirects the call to a machine the attacker controls (classic ICE candidate-injection / call hijack; WebRTC blocks it with signed SDP + a DTLS fingerprint). This is a prerequisite for a rendezvous, not an afterthought — shipping candidate exchange unsealed is a call-hijack hole. CandidateOffer.swift (pure; reuses MeshCrypto.inviteAuthKey + Ice serialization): seal [version][tiebreaker:8][expiry:8][Ice candidate list] under a room-derived key, with an expiry so a captured offer cannot be replayed later, and an ICE controlling/controlled tiebreaker. The offer key is domain-separated from the invite key by one HKDF step so a candidate offer and an invite can never be cross-interpreted. Verified in smoke/harness/candidate_offer.swift (11th verify.sh test, 13 checks, verify: 11 passed, 0 failed): honest round-trip recovers the list + tiebreaker; wrong room passphrase -> nil (confidential); flipped auth-tag byte -> nil (unforgeable); the offer does NOT open under the raw invite key (domain separation); past-TTL -> nil (stale, un-replayable); role resolves oppositely for the two peers. Clock is injected so expiry is deterministic; only static room-key derivation is used, so no MeshCrypto() is built and the Keychain is untouched. Four harness-proven NAT/exchange modules now exist (StunClient, HolePunch, IceSession, CandidateOffer); none are in project.yml / wired into CallManager yet — that integration, fed by a rendezvous carrying these sealed offers, is next. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gHashTag
pushed a commit
that referenced
this pull request
Jul 23, 2026
…r -> sealed offer) Four waves built harness-proven but UNWIRED NAT modules (StunClient #42, HolePunch #43, IceSession #44, CandidateOffer #45). Proven-in-a-harness is not proven-in-the-product, and four modules outside the binary is a growing debt. This wave puts them in the shipping Mac app and proves they run there, WITHOUT touching the working same-subnet call. * project.yml: register the four modules + a new NatDiagnostics; xcodegen regenerated the tracked pbxproj (clean +20 lines, only the 5 files, no churn). * NatDiagnostics.run(): off-main at launch (.onAppear), gathers host + STUN server-reflexive candidates and seals a CandidateOffer under the current room, then logs it. Additive only — nothing in the call/media path changes. Verified LIVE in the built binary (not a harness): launched with TRINET_LOG and read back TRINET NAT: candidates host=["192.168.1.104"] srflx=182.232.218.171:59434 -> sealed offer 83B (room=lobby) so StunClient.hostCandidates + gatherServerReflexive (real public address via Google STUN) + CandidateOffer.make all execute inside the app; the app did not crash, so the working call is intact. Deferred deliberately: the iOS embed (static file list is fragile) and the real integration — deliver the offer via a rendezvous and run Ice.connect before the media socket. The app now HOLDS its sealed candidate offer; delivering it and connecting on it is next. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gHashTag
pushed a commit
that referenced
this pull request
Jul 24, 2026
…mmetric NAT Kernel NAT emulation is unavailable here (`sudo -n true` -> "a password is required", so pfctl/dnctl are out). But the property that actually breaks hole punching needs no root to model: a symmetric NAT allocates a different external port PER DESTINATION, so the peer's probes arrive from an address that is NOT in the candidate list it advertised — that list was learned from a STUN server and is useless to us. smoke/harness/symmetric_nat.swift models exactly that (the peer advertises a dead port and speaks from another) and FAILED against the previous code: Ice.connect only ever probed the advertised list, so it never nominated anything. A real gap, found by building the adversarial case rather than assuming the design covered it. Fix: learn PEER-REFLEXIVE candidates. A probe arriving from an unknown source is added as a candidate, so it gets probed and can be nominated. 3/3 runs pass after the fix; added as the 14th verify.sh test (verify: 14 passed, 0 failed). The iOS Ice enum was re-mirrored so all six NAT enums stay byte-identical; both apps build. CORRECTION to the previous commit's wording: the fd hand-off alone is NOT "symmetric-NAT support". What makes a ONE-SIDED symmetric NAT work is ack-to-the-observed-source (wave #43) + peer-reflexive discovery (this commit) + the fd hand-off keeping that mapping alive. Symmetric-on-BOTH-sides still cannot punch — neither side's first packet is admitted — and needs a relay (TURN-style). That gap is real and remains open; do not read a one-sided test as more than it is. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose: ratify W7 collab choice (Option B — divide by concern, not by host) and lock in one mandatory refinement to its handoff protocol before W7 workstreams open.
Refinement
Closes W6.2 weak-point 1.8 (draft-lived-in-sandbox, review-went-by-paste — the mechanism behind the Vec-grep-anchor, differential-narrative-anchor, and all-modes-anchor episodes documented in
docs/W6_CODEGEN_AUDIT_2026-07-05.md§Anchor-bias record).Rule tiers:
w7/docs/*) — mandatory: approve only against committed text in the branch.git fetch origin <branch> && git show <branch>:<path>(orgh api /contents/) before approve. Paste is navigation context, not approval object.Reviewed against <sha>/Approved at <sha>) so approve is reproducibly bound to file state.Why this comes before any W7.x workstream
Option B's whole strength is layer separation with explicit dependency-through-Base. Without the no-paste-review rule, the doc-layer (W7.5 paper §4.5 companion, W7.7 trust ledger) — the two highest-stakes workstreams of W7 — would inherit the same review-by-paste failure mode that produced the anchor-bias episodes of W6.2. The refinement makes that impossible by construction.
Scope
docs/W7_COLLAB_OPTIONS.mdphi^2 + phi^-2 = 3