---
name: w4-knocking-wave
description: "W4 knocking (releases#53) GATE PASSED by doyle 2026-07-31 @e2dd31d; #53 golden head ASSEMBLED + HANDED to deployah same day: assembly/access-control-53 @ddead1b (monic-w5 register moved to 3c60819); the wave's transferable lessons about tests that prove nothing."
metadata: 
  node_type: memory
  type: project
  originSessionId: 8e28e8a8-f88d-4789-8fed-69a2face2138
  modified: 2026-07-31T19:38:28.882Z
---

**Wave:** access-control W4 knocking, releases#53. Branch `build/knock-w4` off `main` @`5af470f`.
**GATE PASSED by doyle 2026-07-31 @`e2dd31d`** (full record on #53). Tip moved to **`9f01863`**
(comment-only toml follow-up) and I flagged the move before he noticed; he verified the delta and
**moved the register to `9f01863`** — that is the lane sha for the next golden assembly, alongside
hertz's `@cfecc77` + `@b6fbe40`. No further tip moves without pinging him. His one suite red was HIS harness (a `--bin` filter skipped building
`translate_proof_fixture`), not the wave. Design of record = CONTEXT.md @`5af470f` (knock grill,
operator + doyle). Eleven tasks T1–T11; close-out comment on #53 has the full table.
Nothing further owed on W4. **W5 (trust warning + monic store) is now DONE and gated too** —
see [[w5-monic-wave]] for its register sha and lessons; the golden register moved to
`build/monic-w5`, which subsumes this lane's `9f01863`.

**GOLDEN HEAD HANDED OFF 2026-07-31:** `assembly/access-control-53` @`ddead1b` = main@5af470f +
monic-w5@**3c60819** (second post-gate register move, 1-line CONTEXT activate-with-a-limit, delta
verified) + hertz cfecc77 + b6fbe40 + docs PRs #140/#141 + doyle's integration commit (Knock joins
`StreamFamily::ALL`[13] + one-way census — semantic merge conflict the uniform-table sweep guard
caught by design; hertz verified). Pre-gates green (clippy/traceable-reqs). Riders #1/#39 confirmed
unbuilt → detached from #53, both → EVAL, tangential split as #59 (ring timeout → minutes/30);
todlando's #39 code-read POSTED (issuecomment-5146772196): ring already blocks in the perchless
arm; the three immediate-return arms are reasoned AND all three already print explanatory output
(todlando self-corrected his "quieter than they should be" claim by checking cmd_ring before
posting) — so #39 is likely expectation/docs, repro-ask captures stderr + caller perch state. Intake record = #53 comment at 2026-07-31T18:25:09Z (timestamp verified by deployah's intake gate).
hertz #42 fact 1 closed: iroh 0.98.2 "relay=n0" default map IS the canary hosts (vendor naming);
canary-exposure decision → board request flagged needs-operator; live-dial legs held until golden.

**Deployah stop-and-refer, and the stale claim behind it:** my hand-off said "bump + changelog ride
the release PR per runbook" — WRONG, a pre-golden-era sentence carried by my own commune. Golden
runbook step 1: **bump + changelog go INTO the golden head** (tested sha == shipped sha; dedicated
release PR form RETIRED; no post-golden edits of any byte). v0.48.0 followed it @e09c96b. Ruled:
deployah authors bump v0.49.0 (MINOR — trust warning changes observable behavior of existing
surfaces) + changelog atop ddead1b, I re-verify the one-commit delta, golden ref at that head.
Counter 84 (decoded from v0.48.0 signed metadata). #39 gained the #141 cross-link (verified landed
2026-07-31T18:28:55Z): if #141 lands, #39 may be expectation/docs, not bugfix. todlando's promised
#39 code-read posted after nudge — see corrected line above.

**Gate fixup, and the class behind it:** doyle caught `REQ-KNOCK-KNOCKER-STAMP` claiming
`int ACTIVATED` in its registry comment while `required_stages` omitted `int`. Activated rather
than withdrew (the rung already carried the tag and its assertions are genuine), recorded the
tier's LIMIT, and swept the registry — the same sentence had been pasted onto two more reqs he
never named. See [[correct-by-replacement-not-annotation]] for the full protocol.

**Two-host proof:** role a HFENDULEAM / role b KITSUBITO, both trees pinned `f29e1c6` CLEAN with
rev-parse + status recorded FROM EACH SIDE, 3 passed 0 failed both. That per-side pinning is what
makes a two-host green mean anything — otherwise it evidences "whatever was on disk".

## kitsubito access recipe (hertz, verified 2026-07-31)

Its clones point at `SaberMage/spt-core`, but its `gh` is authed as SaberMage and **can read the
private `BigscreenVR/spt-bs-core`**. So:

    gh auth setup-git                    # once per session, else "could not read Username"
    git clone --bare https://github.com/BigscreenVR/spt-bs-core.git ~/<n>.git
    git --git-dir=$HOME/<n>.git worktree add --detach ~/<n> <branch>
    export PATH=$HOME/.cargo/bin:$PATH   # cargo NOT on non-interactive PATH
    export CARGO_TARGET_DIR=$HOME/<n>-target

`ssh git@github.com` is publickey-denied — https + gh helper only. NEVER build in
`~/actions-runner/_work/...` (CI workspace); scratch in `$HOME` only, and reap it.
Cold `--no-run` build of the twohost test ≈52s there. Two-host rig failures are hertz's class.

## The lesson that generalizes: tests that pass under the fault they guard

**Uniform-table blindness.** My attributability test walked every table row asserting
`is_attributable(row.id) == row.attributable` — correct-looking, and it stayed GREEN when I
replaced the reader with a hardcoded `surface == MSG`, because MSG was the only attributable row.
A single-source test over a table whose rows are UNIFORM in the property under test proves
nothing. Fix: take the table as a parameter and supply a fixture where a *non*-default row differs.
Doyle's standing gate question is now "would a hardcoded reader pass this fixture?"

**Anti-vacuity in cross-version pins.** A pin that a record "isn't classified as X" goes vacuous
the day the record's fields drift such that it never would have been. So also assert the shape it
must not resemble genuinely IS claimed by that arm. Written into KNOWN-HAZARDS 7.62's proof
obligation so it survives us forgetting.

**Mutation harness discipline (now doyle's standing guard #5).** Prove a GREEN BASELINE before
trusting any red, and sha-verify the restore. A timed-out harness left one mutation applied; I
grepped for the markers I remembered, missed it, and a later run took a mutated file as its
baseline — two reds were partly the stale bug. Grepping remembered markers is not a restore check.
Also: a mutation that fails to COMPILE proves nothing — redo it validly, never count it.

**A grep gate that reds on churn gets ignored.** "Any `+ load()` in the diff is a red" false-reds
when unchanged lines move; use net-count or paired +/-.

## Bugs found by RUNNING, not reading — every one composition-correct

Each layer was individually right; only end-to-end execution showed it. A bare-user knock approved
into a sender-endpoint rule keyed by NODE hex (inert, and lost the `origin user` narrowing);
`approve --mutual` claiming TWO-way then counter-knocking for what was already given; an ER `--for`
edit printing an undo naming a seat it hadn't used. Run the verbs and read the resulting JSON.

## Conclusion-vs-evidence gaps I made (both self-caught, both cheap to avoid)

- Read kitsubito's git remotes, concluded "my branch isn't fetchable there", and stopped — without
  checking whether credentials could reach the repo anyway. They could.
- Told doyle to gate `@6a8138b` **without having pushed it**; hertz caught that origin was still at
  the prior sha. Gating would have evidenced a tree missing the rung. **Push before you cite a sha.**

Related: [[instrument-soundness-guards]], [[husk-reads-as-default-defeats-durability]],
[[single-source-discriminant-marker]], [[premature-closure-guards]], [[cross-machine-test-rig]].
