a73x

5d41e106

docs: review-round records; four passages caught up with the code

a73x   2026-08-14 12:46

Commit message
docs: review-round records; four passages caught up with the code

New decisions.md section for the 2026-08-14 review round — one
pragmatic review over the whole branch, both Major and all six Minor
findings fixed the same day, each fix proven by a test that fails
without it: the shim's exclusive create and unaimable name, the timeout
arm joining pgid and settle in clearing exit_code, muxa's enumerated
exit codes and self-bounded span fetch, grants-must-be-spelled, and
ports as observations.

Passages that had drifted from the code, corrected in place: the
settle/pgid null-exit-code sentence now includes the timed-out wait;
the shim spells its random suffix in both files that name it; the
test-only-imports bullet is promoted from column to mechanism (the twin
split) and gains the every-grant-spelled record beside it; the leak-
verdicts bullet describes the trap-time sweep and marks the $OUT.q debt
paid; the check-gate bullet lists the shell syntax leg; deadcode.sh
gets the non-gating close-out line it was owed; and wasm_core is named
what it is — the one remaining dark root, compile-covered by the forced
wasm build and ABI verify, behavior-covered only by the web e2e.

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

docs/decisions.md
Old New
@@ -3118,8 +3118,8 @@ failed: <err>` — and a second tear after a spent redial says so in its own
3118 words. 3118 words.
3119 3119
3120 **`settled` means output went quiet, not that the process exited.** The 3120 **`settled` means output went quiet, not that the process exited.** The
3121 settle and pgid resolutions carry `exit_code: null` and a `phase` derived 3121 settle and pgid resolutions — and a timed-out wait, whatever its
3122 from marks, which on a markless shell reads `at_prompt` — the tracker 3122 mechanism — carry `exit_code: null` and a `phase` derived from marks, which on a markless shell reads `at_prompt` — the tracker
3123 never saw a `C`, so it is telling the truth about what it knows. Only 3123 never saw a `C`, so it is telling the truth about what it knows. Only
3124 `mechanism == "marks"` carries a trustworthy exit code, which is why every 3124 `mechanism == "marks"` carries a trustworthy exit code, which is why every
3125 reply names its mechanism. An agent that reads `exit_code` without reading 3125 reply names its mechanism. An agent that reads `exit_code` without reading
@@ -3139,9 +3139,9 @@ reply names its mechanism. An agent that reads `exit_code` without reading
3139 `PROMPT_COMMAND` member loses its marks (degrading to pgid/settle, not to 3139 `PROMPT_COMMAND` member loses its marks (degrading to pgid/settle, not to
3140 a wrong answer), and a compound string member (`a; b`) can re-arm the 3140 a wrong answer), and a compound string member (`a; b`) can re-arm the
3141 guard. Arrays — bash 5.1's default and what the shim prefers — are exact. 3141 guard. Arrays — bash 5.1's default and what the shim prefers — are exact.
3142 - **A SIGKILLed daemon orphans its `mux-shellint-{pid}` directory.** 3142 - **A SIGKILLed daemon orphans its `mux-shellint-{pid}-{random}`
3143 Bounded and per-pid, cleaned on every ordinary exit; a startup sweep of 3143 directory.** Bounded and per-pid, cleaned on every ordinary exit; a
3144 dead-pid directories is the roadmap item. `prepare()` failing is degraded 3144 startup sweep of dead-pid directories is the roadmap item. `prepare()` failing is degraded
3145 and never fatal: the session runs on pgid and settle, and says so on 3145 and never fatal: the session runs on pgid and settle, and says so on
3146 stderr, because refusing to start a daemon over an optional enhancement 3146 stderr, because refusing to start a daemon over an optional enhancement
3147 would invert the module's premise. 3147 would invert the module's premise.
@@ -3240,10 +3240,24 @@ two dialects.
3240 `client -> proxy` is production (ignoreSigpipe in the live attach path) 3240 `client -> proxy` is production (ignoreSigpipe in the live attach path)
3241 and is grandfathered with the debt comment at client.zig — relocating 3241 and is grandfathered with the debt comment at client.zig — relocating
3242 ignoreSigpipe to a leaf is the recorded fix, deliberately not taken here. 3242 ignoreSigpipe to a leaf is the recorded fix, deliberately not taken here.
3243 - **Test-only imports are a declared column, not an accident.** The testtmp 3243 - **Test-only imports are a declared column, and a mechanism.** The testtmp
3244 pattern (production modules importing test scaffolding used only inside 3244 pattern (production modules importing test scaffolding used only inside
3245 `test` blocks, kept out of release binaries by lazy compilation) is now 3245 `test` blocks) is stated per-row, and since the review round the column
3246 stated per-row. The strata computation excludes the column. 3246 is enforced: the eight rows with test grants get a test twin — a second
3247 module instance carrying the test imports, used only by the test builds —
3248 while the production instance never receives them. "Test scaffolding
3249 never ships" is a compile error a production reference triggers, not a
3250 convention lazy compilation happens to honor. The twins import
3251 production dependency instances, so no compilation holds two instances
3252 of one row. The strata computation excludes the column.
3253 - **Every grant must be spelled.** A build-graph-time check reads each
3254 row's root file and refuses every build — not just the gate — when a
3255 declared import never appears as `@import("name")` there. It caught its
3256 motivating case at once: exe→cmd, dead since its call site left
3257 main.zig, carried faithfully by the extract-and-diff (a pure refactor
3258 preserves mistakes too); the table stands at 75 edges. Stated limit:
3259 text cannot tell which column a use belongs to — the twin split is what
3260 separates the columns.
3247 - **refAllDecls in every test-loop module root, scope stated honestly.** 3261 - **refAllDecls in every test-loop module root, scope stated honestly.**
3248 Pub decls only — std.meta.declarations sees nothing private. Narrower 3262 Pub decls only — std.meta.declarations sees nothing private. Narrower
3249 still than the original silent-module-loss framing: in 0.15.2 a pub decl 3263 still than the original silent-module-loss framing: in 0.15.2 a pub decl
@@ -3256,21 +3270,30 @@ two dialects.
3256 namespace); engine was downgraded to plain because recursion reaches 3270 namespace); engine was downgraded to plain because recursion reaches
3257 pre-existing comptime errors inside vendored ghostty-vt (re-promote 3271 pre-existing comptime errors inside vendored ghostty-vt (re-promote
3258 when the dep is bumped); wasm_core is excluded because it is not in 3272 when the dep is bumped); wasm_core is excluded because it is not in
3259 the native test loop and a block there would never run. 3273 the native test loop and a block there would never run — it is the one
3274 remaining dark root: compile coverage comes from the wasm build `check`
3275 forces plus the ABI verify step, behavior only from the web e2e.
3260 - **Leak verdicts print, never panic.** The three gpa-backed binaries 3276 - **Leak verdicts print, never panic.** The three gpa-backed binaries
3261 (muxd, mux, muxweb) check `gpa.deinit()` and print 3277 (muxd, mux, muxweb) check `gpa.deinit()` and print
3262 `<binary>: LEAK: allocations outlived deinit` to stderr on `.leak` — 3278 `<binary>: LEAK: allocations outlived deinit` to stderr on `.leak` —
3263 never an exit-code change, because muxd's exit code carries the 3279 never an exit-code change, because muxd's exit code carries the
3264 session shell's. e2e captures every daemon's stderr and sweeps all 3280 session shell's. e2e captures every daemon's stderr and sweeps all
3265 captures at the end, behind a canary that fails if the sweep has 3281 captures in its EXIT trap — after the kills, before the rms — so a
3266 nothing to read; agent.sh checks the detached-daemon log after each 3282 failing run reports leaks too, and the trap moves the status in one
3267 clean stop, post process-exit, and fails loudly if the daemon outlives 3283 direction only (a leak promotes green to red, never masks the suite's
3268 the stop (a wedged daemon must not read as leak-free). Proven by 3284 own code). Captures deleted mid-suite bank their verdict at the moment
3269 deliberate leak: marker appeared, e2e failed at the sweep, agent failed 3285 of deletion (`rm_swept`), which paid off the old "uncovered $OUT.q"
3270 all three leakcheck sites. kill -9 paths print nothing — no false 3286 debt. The nothing-to-read canary stands wherever it would guard a green
3271 positive, no coverage, stated. Known uncovered captures: $OUT.q and the 3287 run and degrades to a note on an already-failing early exit — a
3272 other mid-suite rm'd files (recorded debt). muxa is arena-over- 3288 fabricated second defect would bury the real one. agent.sh gives every
3273 page_allocator by construction and has no verdict to check. 3289 daemon its own log via a per-scenario XDG_STATE_HOME and sweeps all of
3290 them at the end behind the same vacuous-green guard, so the daemons the
3291 per-stop leakcheck never saw (session-ended, destroyed, abandoned by a
3292 failing scenario) get verdicts too, and a missing log is a failure.
3293 Proven by deliberate leak at every layer: banked-at-rm, trap-on-green,
3294 trap-on-failing, and a marker in one daemon's log among five. kill -9
3295 paths print nothing — no false positive, no coverage, stated. muxa is
3296 arena-over-page_allocator by construction and has no verdict to check.
3274 - **The persistence soak phase owns the classes the Zig-side LEAK 3297 - **The persistence soak phase owns the classes the Zig-side LEAK
3275 marker (6a) never sees.** One daemon, N client lifecycles: every cycle 3298 marker (6a) never sees.** One daemon, N client lifecycles: every cycle
3276 must prove its client attached (a vacuous cycle fails the phase); fd 3299 must prove its client attached (a vacuous cycle fails the phase); fd
@@ -3282,5 +3305,49 @@ two dialects.
3282 rm'd. First real numbers (SOAK_CYCLES=8): fds 5->5 exact; RSS 3305 rm'd. First real numbers (SOAK_CYCLES=8): fds 5->5 exact; RSS
3283 9020->9128 kB (+108 kB across the 5 post-warmup cycles). 3306 9020->9128 kB (+108 kB across the 5 post-warmup cycles).
3284 - **`zig build check` is the pre-commit gate**: fmt (including 3307 - **`zig build check` is the pre-commit gate**: fmt (including
3285 build.zig.zon) + unit tests, seconds. e2e/agent/soak stay separate 3308 build.zig.zon) + unit tests + `sh -n` over every script in test/,
3286 steps — minutes-long and process-spawning. 3309 tools/ and deps/quic (shellcheck at error severity when installed,
3310 silently skipped when not), seconds. The scripts are file args, so
3311 their contents hash into the graph and only edited scripts re-check.
3312 e2e/agent/soak stay separate steps — minutes-long and process-spawning.
3313 - **deadcode.sh is non-gating, run by hand.** A textual pub-decl
3314 cross-reference whose output is review material, not a verdict —
3315 refAllDecls keeps deliberately-unreferenced decls analyzable, so
3316 "referenced nowhere outside its file" is a prompt to look, not a
3317 failure. Matching is literal (`-F`/`-qxF`): a filename is never a
3318 regex.
3319
3320 ### Review round (2026-08-14)
3321
3322 One pragmatic review over the whole branch; every finding above Minor
3323 was fixed the same day, each fix proven by a test that fails without it.
3324
3325 - **The shim directory is created exclusively and named unaimably.**
3326 `mux-shellint-{pid}-{random}` via `xdg.makeNewPrivateDir`: one
3327 `mkdir(0o700)` that neither follows a symlink nor adopts an existing
3328 entry, then a no-follow open. Closes a CWE-59 window (shared /tmp
3329 sockdir + guessable pid let a local user aim the old makePath+chmod at
3330 a directory they chose) and, via the random half, retires the pinned
3331 oddity where a leftover at the pid name silently cost a session its
3332 marks. EEXIST degrades to no-marks as before. `makePrivateDir` keeps
3333 its adopting behavior for the two callers under `~` where adopting is
3334 correct; the two functions' doc comments now name their threat models.
3335 - **A timed-out await clears `exit_code`.** The timeout arm now matches
3336 pgid and settle, so "an exit code is real only under `marks`" is
3337 uniformly true rather than true except in the one arm agents hit most.
3338 The persisted `last_return` snapshot is untouched — only the reply.
3339 - **muxa exit codes are enumerated and honest.** 0 answer, 1 error
3340 object, 2 usage, 3 await timeout, and new 4: the reply object could
3341 not be written (EPIPE/ENOSPC) — previously a silent exit 0 with no
3342 JSON, the one shape the contract forbids. A command's exit code is
3343 never muxa's. The post-return scrollback fetch now gets exactly its
3344 own 2s window (`spanFetchDeadline()`, no run-deadline parameter to
3345 misuse): under `@max` a `--timeout 0` run made the bonus fetch an
3346 unbounded hang.
3347 - **A port is an observation, not a derivation.** The `$$`-derived
3348 numbers in agent.sh and valgrind-quic.sh are first candidates only:
3349 bind-with-retry steps on the daemon's own "already listening on udp"
3350 refusal (any other failure reports immediately), and the port written
3351 back is the one the up-line named, so every dial targets what was
3352 bound. Two suites congruent mod 900, or a tuned ephemeral range, no
3353 longer collide.
docs/roadmap.md
Old New
@@ -253,7 +253,7 @@ blocker):
253 textually identical to a `PROMPT_COMMAND` member loses its marks 253 textually identical to a `PROMPT_COMMAND` member loses its marks
254 (degrading to pgid/settle), and a compound string member (`a; b`) can 254 (degrading to pgid/settle), and a compound string member (`a; b`) can
255 re-arm the guard — arrays, the modern default, are exact. 255 re-arm the guard — arrays, the modern default, are exact.
256 - **A SIGKILLed daemon orphans its `mux-shellint-{pid}` directory**; a 256 - **A SIGKILLed daemon orphans its `mux-shellint-{pid}-{random}` directory**; a
257 startup sweep of dead-pid directories is owed. Injection failing is 257 startup sweep of dead-pid directories is owed. Injection failing is
258 always degraded and never fatal. 258 always degraded and never fatal.
259 - **`--timeout N` can overshoot N** by the client's grace window (2s over a 259 - **`--timeout N` can overshoot N** by the client's grace window (2s over a