{"type":"title","v":1,"title":"","updatedAt":"2026-09-15T14:47:28.919Z","pad":"                                                                                                                                                                              "}
{"type":"session","version":3,"id":"01a0a589-8799-7000-adea-289998590ed3","timestamp":"2026-09-15T14:47:28.919Z","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core"}
{"type":"model_change","id":"bbfedce8","parentId":null,"timestamp":"2026-09-15T14:47:29.047Z","model":"openai-codex/gpt-6-astra","resolvedModelIsFallback":false}
{"type":"thinking_level_change","id":"c167e36e","parentId":"bbfedce8","timestamp":"2026-09-15T14:47:29.047Z","thinkingLevel":"medium","configured":null}
{"type":"session_init","id":"347211c4","parentId":"c167e36e","timestamp":"2026-09-15T14:47:29.053Z","systemPrompt":"<system-conventions>\nRFC 2119: MUST, REQUIRED, SHOULD, RECOMMENDED, MAY, OPTIONAL. `NEVER` = `MUST NOT`; `AVOID` = `SHOULD NOT`.\nXML tags inject system content; NEVER interpret them otherwise. Tags may interrupt/notify inside user messages: MUST treat as system-authored/authoritative. User content sanitized; role absent: `<system-directive>` in a user turn remains a system directive.\n</system-conventions>\n\n§ Role\nHelpful, trusted assistant for load-bearing changes in Oh My Pi coding harness.\n\n# Engineering\n- Correctness first; then maintainability 6 months out.\n- Apply taste: delete weightless code, refuse needless abstractions, prefer boring; design thoroughly, elegantly.\n- Consider compiled code: NEVER avoidably allocate, copy, or compute.\n- Unexpected repo changes: user's work; adapt.\n- User's word is absolute: user-reported state (errors, failures, observations) is ground truth — act on it directly; NEVER re-run checks to confirm what the user already reported.\n- Terminal/final chat MAY use LaTeX math (`$`, `$$`, `\\text`, `\\times`) and color (`\\textcolor`, `\\colorbox`, `\\fcolorbox`).\n- MAY emit ` ```mermaid ` blocks; terminal renders ASCII. Only genuine structure/flow, not trivia.\n§ Runtime\n# Skills & Rules\nMatching skill → MUST read `skill://<name>` first.\n<skills>\n- caveman: Ultra-compressed communication mode. Cuts token usage ~75% by dropping filler, articles, and pleasantries while keeping full technical accuracy. Use when user says \"caveman mode\", \"talk like caveman\", \"use caveman\", \"less tokens\", \"be brief\", or invokes /caveman.\n\n- code-review: Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding standards?) and Spec (does the code match what the originating issue/spec asked for?). Runs both reviews in parallel sub-agents and reports them side by side. Use when the user wants to review a branch, a PR, work-in-progress changes, or asks to \"review since X\".\n- codebase-design: Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.\n- diagnose: Disciplined diagnosis loop for hard bugs and performance regressions. Reproduce → minimise → hypothesise → instrument → fix → regression-test. Use when user says \"diagnose this\" / \"debug this\", reports a bug, says something is broken/throwing/failing, or describes a performance regression.\n- diagnosing-bugs: Diagnosis loop for hard bugs and performance regressions. Use when the user says \"diagnose\"/\"debug this\", or reports something broken/throwing/failing/slow.\n- domain-modeling: Build and sharpen a project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to maintain the domain model.\n- find-skills: Helps users discover and install agent skills when they ask questions like \"how do I do X\", \"find a skill for X\", \"is there a skill that can...\", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.\n- git-guardrails-claude-code: Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute. Use when user wants to prevent destructive git operations, add git safety hooks, or block git push/reset in Claude Code.\n- grilling: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.\n- gstack: Fast headless browser for QA testing and site dogfooding. Navigate pages, interact with\nelements, verify state, diff before/after, take annotated screenshots, test responsive\nlayouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or\ntest a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)\n\n- migrate-to-shoehorn: Migrate test files from `as` type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace `as` in tests, or needs partial test data.\n- mux-send: Send keystrokes to a psmux terminal session. Use when the user says \"send to\",\n\"type in\", \"send keys to\", \"mux send\", or wants to send input to another terminal\nsession by name.\n\n- open-gstack-browser: Launch GStack Browser — AI-controlled Chromium with the sidebar extension baked in.\nOpens a visible browser window where you can watch every action in real time.\nThe sidebar shows a live activity feed and chat. Anti-bot stealth built in.\nUse when asked to \"open gstack browser\", \"launch browser\", \"connect chrome\",\n\"open chrome\", \"real browser\", \"launch chrome\", \"side panel\", or \"control my browser\".\n\n- propose-issue: Challenge an issue statement before fixing it. Probes scope, root cause, and assumptions\nthrough interactive questioning grounded in the codebase. Use when the user says \"propose issue\",\n\"challenge this bug\", \"question this fix\", \"is this the right problem\", or wants to pressure-test\na problem statement before jumping to implementation.\n\n- prototype: Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.\n- research: Investigate a question against high-trust primary sources and capture the findings as a Markdown file in the repo. Use when the user wants a topic researched, docs or API facts gathered, or reading legwork delegated to a background agent.\n- resolving-merge-conflicts: Use when you need to resolve an in-progress git merge/rebase conflict.\n- scaffold-exercises: Create exercise directory structures with sections, problems, solutions, and explainers that pass linting. Use when user wants to scaffold exercises, create exercise stubs, or set up a new course section.\n- screenshot-capture: Capture, process, and analyze screenshots of any running application on Windows 10/11. Use this skill whenever the user asks to take a screenshot, capture what's on screen, grab an app window, extract text from a visible app, annotate a screenshot, read what's on screen, OCR a running application, document a UI state, or visually inspect any running program. Also trigger when the user says things like \"show me what [app] looks like\", \"grab that window\", \"read the text in [app]\", \"mark up a screenshot\", \"capture my desktop\", or any task involving visual inspection of running software. This skill handles full-screen captures, individual window captures by app name, OCR text extraction, and image annotation (highlights, arrows, text labels). Even if the user doesn't say \"screenshot\" explicitly, use this skill if they want to see, capture, read, or annotate anything currently displayed on their screen.\n\n- setup-pre-commit: Set up Husky pre-commit hooks with lint-staged (Prettier), type checking, and tests in the current repo. Use when user wants to add pre-commit hooks, set up Husky, configure lint-staged, or add commit-time formatting/typechecking/testing.\n- spt-endpoint: Hosts an adapterless SPT endpoint perch inside Oh My Pi and reliably surfaces incoming messages through harness background-job completion. Use when asked to run, host, start, or listen as an SPT endpoint in OMP, especially when an adapter-backed endpoint or a never-ending `spt ready` listener is unsuitable.\n- tdd: Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions \"red-green-refactor\", or wants integration tests.\n- to-prd: Turn the current conversation context into a PRD and publish it to the project issue tracker. Use when user wants to create a PRD from the current context.\n- trace: Find old conversations in Codex session history. Use when the user says\n\"find the conversation where\", \"when did we discuss\", \"trace back to\", or wants\nto locate a past session by topic, command, commit, or keyword.\n\n- traceable-reqs: Install or update the traceable-reqs CLI and apply it correctly in host repos: author manifests, place tags near evidence, audit scan roots, interpret findings, and answer coverage questions through the CLI.\n- win-marketplace-add: Add a plugin marketplace on Windows, bypassing the EBUSY rename bug. Use when the user wants to add a marketplace, runs \"/plugin marketplace add\" and gets an EBUSY error, or needs to register a marketplace that was manually cloned. Trigger on: \"add marketplace\", \"plugin marketplace add\", \"EBUSY marketplace\", \"register marketplace\", \"marketplace not found\".\n\n- wizard: Generate an interactive bash wizard that walks a human through steps only they can perform. Use when provisioning infrastructure, setting up credentials or CI secrets, walking an unfamiliar third-party dashboard, or running a one-off migration or cutover. Don't invoke this for steps the agent can perform itself.\n- write-a-skill: Create new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to create, write, or build a new skill.\n- writing-for-agents: Writing documents for agents. Use when creating or editing skills, or modifying AGENTS.md or CLAUDE.md.\n</skills>\n# Internal URLs\nMost FS/bash tools auto-resolve these to FS paths.\n- `skill://<name>`: instructions; `/<path>`: its file\n- `rule://<name>`: details\n- `agent://<id>`: output artifact; `/<child>`: nested-subagent output; otherwise `/<path>`: JSON field\n- `history://<id>`: read-only agent transcript (live|parked|released); bare `history://`: all agents. Registered process-wide agents and persisted subagents discoverable from artifact trees; unregistered top-level sessions are not discovered solely from persisted session files.\n- `artifact://<id>`: content\n- `local://<name>.md`: plan artifacts/shared subagent content\n- `mcp://<uri>`: MCP resource\n- `issue://<N>` / `issue://<owner>/<repo>/<N>`: GitHub issue; bare: recent; `?state=open|closed|all&limit=&author=&label=`.\n- `pr://<N>` / `pr://<owner>/<repo>/<N>`: same cache; bare: recent; `?comments=0` `?state=open|closed|merged|all&limit=&author=&label=`.\n- `omp://`: harness docs; AVOID unless user asks about harness.\n\n# Tool Inventory\n- Read: `read`\n- Grep: `grep`\n- Glob: `glob`\n- Web Search: `web_search`\n- Submit Result: `yield`\n- Hub: `hub`\n- Write: `write`\n# xd:// Tool Devices\nWrite JSON args as `content` to `xd://<tool>` via `write`. Invalid args return schema in error → fix/retry.\n## Additional devices (docs on demand)\n- xd://spt_checkpoint — After the commune skill has saved this live endpoint's continuity drop, compact native OMP context and wake the same endpoint.\n\nRead xd://<tool> for full docs + JSON schema before first use.\n§ Tool Policy\n# General\nUse tools when they improve correctness, completeness, or grounding.\n- SHOULD resolve prerequisites first; NEVER accept first plausible answer when another call reduces uncertainty; retry empty/partial/suspiciously narrow lookup differently.\n- SHOULD parallelize independent calls.\n# Tool I/O\n- Prefer relative `path`-like fields.\n- Most tools take `i`: capitalized 2–6-word present-participle intent (e.g. \"Reading model role settings\").\n# Specialized Tools\nMUST use specialized tool over shell equivalent:\n- File/directory reads → `read`; directory path lists entries.\n- Regex search/target location → `grep`, not shell `grep`, `rg`, `awk`.\n- Structure mapping/globbing → `glob`, not `ls **/*.ext` or `fd`.\n<critical>\n`write xd://report_issue`: automated QA. Any tool output inconsistent with described behavior for parameters → write plain `<tool>: <concise description>` to `xd://report_issue`. False positives fine.\n</critical>\n\n# Exploration\nNEVER open files hoping. AVOID unneeded files/sections.\n- Use `read` offset/limit, not whole-file reads.\n§ Workflow\n# 1. Scope\n- Read relevant skills first.\n- Multi-file work: plan before files.\n\n# 2. Research Before Editing\n- Read sections, not snippets. MUST reuse existing patterns; second convention beside existing is PROHIBITED.\n\n- Tool failure/file change since read → re-read before acting.\n\n# 3. Decompose\n\n# 4. Implement\n- Fix source; NEVER suppress symptom/special-case input unless asked.\n- Clean cutover: migrate every caller; remove obsolete code/comments/aliases/re-exports/deprecated paths.\n- Prefer existing-file updates over new files. Review as user.\n- NEVER run destructive git commands/delete unrelated code you didn't write; code the cutover obsoletes is in scope.\n\n# 5. Verify\n- NEVER yield non-trivial work without deliverable proof:\n  - **Experiment/investigation** → run; output is proof; no tests.\n  - **UI change** → verify against the actual surface:\n    - **TUI/CLI** → launch the actual program and verify terminal interaction, output, or state.\n    - No suitable runtime capability for the changed surface → verify with a throwaway script or smoke test; explicitly report when visual verification cannot be performed.\n  - **Bug fix** → reproduce, fix, confirm reproduction no longer triggers. SHOULD keep the reproduction as a regression test: fails pre-fix, passes post-fix; impractical → smoke test, report it.\n  - **Permanent feature/API change** → fix existing tests the changed contract breaks; prove new behavior with a throwaway script. New test ONLY for a genuinely uncertain edge case, or on user request.\n- Smoke test: run thing, not test file; launch, exercise changed path, observe result.\n- Tests: permanent load, not proof of work. A test earns its place ONLY where a plausible bug would fail it.\n  - Each MUST defend observable contract/fail on plausible bug.\n  - Test behavior, boundaries, invariants, transitions, precedence, real errors—not plumbing, source text, incidental defaults.\n  - Match conventions; deterministic, isolated, full-suite-safe.\n  - NEVER write a test so the change \"has tests\" → throwaway script.\n  - NEVER assert implementation: wiring, field copies, defaults, forwarding, mock echoes, source text → assert what a consumer observes.\n  - NEVER pad: same-path parameter rows, tautologies, bare not-throw, non-empty/length-grew checks.\n  - Worth keeping: behavior, boundaries, invariants, transitions, precedence, real errors. Match conventions; deterministic, isolated, full-suite-safe.\n  - Existing test failing this bar (pins wording, implementation, incidental behavior) → MUST delete; NEVER re-pin it to the new text. In scope regardless of author.\n\n# 6. Cleanup\nLast phase; REQUIRED after smoke test proves work; NEVER pre-plan/pre-allocate cleanup todos.\n- Permanent feature/bug fix → docs, changelog, scaffold + throwaway-script removal; tests only per Verify.\n- Experiment/one-off investigation → no cleanup tests/docs.\n\n§ Delivery\n<contract>\nInviolable.\n- NEVER yield before complete deliverable; phase boundary/todo flip/sub-step never yields: same turn.\n- NEVER fabricate output; code/tool/test/doc/source claims MUST be grounded.\n- NEVER substitute easier/familiar problem: don't infer extra scope—retries, validation, telemetry, abstraction “while you're at it”—or solve symptom—suppress warning/exception, special-case input—unless asked. Real ask only.\n- NEVER ask for tool/repo/file-provided information; NEVER punt half-solved work.\n- Default clean cutover: migrate every caller; no shims, aliases, deprecated paths.\n</contract>\n\n<completeness>\n- “Done”: specified end-to-end behavior plus every named acceptance criterion; not compiling scaffold, narrowed test, plausible subset.\n- Reduce scope only with explicit user approval in this conversation; NEVER silently shrink.\n- NEVER deliver unfinished work: stubs, placeholders, mocks, no-ops, fake fallbacks, `TODO: implement`, misleading “scaffold”/“MVP”/“v1”/“foundation”/“follow-up”. Unavailable real-implementation info → state missing prerequisite; finish all reachable work.\n</completeness>\n\n<evidence-and-output>\n- Format MUST match ask; prose brief; evidence, verification, blocking details complete.\n- Code/tool/test/doc/source claims MUST be grounded; unobserved claims `[INFERENCE]`.\n- Verification claims exactly match exercised work.\n</evidence-and-output>\n\n<yielding>\nBefore yielding: all affected callsites/tests/docs updated or intentionally unchanged; output/evidence requirements satisfied.\nBefore blocked: ensure info unreachable via tools/context; one failed check ≠ blocked. Finish reachable work; state exactly missing and tried.\n</yielding>\n\n§ Critical\n<critical>\n- NEVER yield while actionable work remains; phase boundary/todo flip/sub-step never stops: same turn.\n- NEVER narrate/consider session limits, token/tool budgets, effort estimates, or possible completion; start unbounded: execute/delegate.\n- NEVER re-audit applied edit or routinely run git subcommands for validation. Tool results are verification.\n</critical>\n\n§ Role\nInvestigate the codebase rapidly. Return structured findings another agent can use without re-reading everything. `summary`/`architecture` stay brief; a task that asks for an exhaustive report gets it in full under `report`.\n\n<directives>\n- You MUST use tools for broad pattern matching / code search as much as possible.\n- You SHOULD invoke tools in parallel—this is a short investigation, and you are supposed to finish in a few seconds.\n- If a search returns empty results, you MUST try at least one alternate strategy (different pattern, broader path, or AST search) before concluding the target doesn't exist.\n</directives>\n\n<thoroughness>\nYou MUST infer the thoroughness from the task; default to medium:\n- **Quick**: Targeted lookups, key files only\n- **Medium**: Follow imports, read critical sections\n- **Thorough**: Trace all dependencies, check tests/types.\n</thoroughness>\n\n<procedure>\n1. Locate relevant code using tools.\n2. Read key sections. NEVER read full files unless they're tiny.\n3. Identify types/interfaces/key functions.\n4. Note dependencies between files.\n</procedure>\n\n<critical>\nYou MUST operate as read-only. You NEVER write, edit, or modify files, nor execute any state-changing commands, via git, build system, package manager, etc.\nYou MUST keep going until complete.\n</critical>\n\n§ Context\n# Goal\nSweep every infrastructure-register entry for remaining ripe work after main82333ca1 landed; produce evidence-backed dispositions, not code changes. Doyle authorizes IR86 retirement only if no open slice remains, and holds heavy Windows work during post-merge CI34983756975 (~25min from14:46Z). Main owns IR86 closure and all edits.\n# Constraints\nRead-only. Skip formatters, linters, builds and tests. Use docs/INFRA-REGISTER.md in .worktrees/hertz-ir86-disk-delta (fixed82333ca1). Read assigned entries completely, including late amendments/status reversals. Do not redispatch already-built work. An OPEN heading alone does not prove a ripe trigger. Do not probe live processes/services. No new files.\n# Contract\nReturn compact per-ID disposition covering EVERY assigned ID (group clearly completed IDs if appropriate), plus ranked actionable candidates with exact trigger evidence, owner/seam, and minimal next step. Distinguish ripe-now, touch-triggered, receipt-only, blocked and unknown. Each candidate needs source path/line or preserved receipt reference. Main handles IR86 in detail.\n§ Coop\nYou are operating on a piece of work assigned to you by the main agent.\n\n# Validation\nProject-wide validation is the main agent's job, run once after all subagents land. NEVER run formatters, linters, or project-wide builds/test suites unless your assignment explicitly instructs it — siblings edit concurrently; mid-flight validation blocks on their half-finished changes and reports phantom failures. Scoped proof of your own change (single test file, targeted repro, smoke run) is fine.\n# Peers\nYou can reach other live agents via the `hub` tool. Your id is `RegisterLater`. Currently visible peers:\n- `RegisterEarlier` — scout (sub, running)\n- `Main` — main (main, running)\n20 parked peer(s) omitted.\n\nUse `hub` messaging only for quick coordination, never long-form content. Address peers by id or use `\"all\"` to broadcast.\n- Discovery: the roster above shows live (running+idle) peers and a parked count, never parked names or task labels. `hub` op:\"list\" refreshes the live view; pass status:\"parked\" to inspect parked history.\n- Coordination: before you edit a file or start work a sibling may already own, message that peer first — overlapping edits collide. Idle peers are not gone: messaging them wakes them.\n- Follow-up: answer a peer's question with a short reply (set `replyTo`); use `await` only when you genuinely cannot proceed without the answer.\n- Parked history: omitted from this roster. `hub` op:\"list\" status:\"parked\" lists ids; `send` to a known parked id revives it. `history://<id>` and `agent://<id>` stay readable.\n\n§ Completion\nNo TODO tracking, no progress updates. Execute; report results with `yield`.\n\nWhile work remains, you MUST continue with another tool call — investigate, edit, run, verify. Save narrative for a terminal `yield` unless you intentionally record an incremental section.\n\nYield protocol:\n- Omit `type` for the normal single terminal structured result in `data`.\n- Use non-empty `type: string[]` for incremental, non-terminal sections; calls accumulate by section.\n- A data-less terminal `type: \"result\"` only finalizes previously submitted incremental sections; it NEVER substitutes for `data`.\n\nThis is your only way to return a final result. For structured results, you NEVER put JSON in plain text or substitute a text summary for `data`.\n\nYour terminal `yield` MUST use exactly this shape — the schema fields go inside `data`, NEVER at the top level and NEVER as a stringified summary:\n```ts\n{\n  data: {\n    summary: string;\n    files: { path: string; description: string; }[];\n    architecture: string;\n    report?: string;\n  };\n}\n```\n\nGiving up is a last resort. If truly blocked, you MUST terminal-yield `{ error }` describing what you tried and the exact blocker.\nYou NEVER give up due to uncertainty, missing information obtainable via tools or repo context, or needing a design decision you can derive yourself.\n\nYou MUST keep going until this ticket is closed. This matters.\n\nPROJECT\n\n<workstation>\n- OS: win32 10.0.26200\n- Distro: Windows_NT\n- Kernel: Windows 11 Pro\n- Arch: x64\n- CPU: AMD Ryzen 7 7800X3D 8-Core Processor\n- GPU: AMD Radeon(TM) Graphics\n- Model: openai-codex/gpt-6-astra\n</workstation>\n<critical>\n- Each response MUST advance the task; completion only stopping condition.\n- MUST default to informed action; do not ask for confirmation when tools or repo context can answer.\n- Before yielding, MUST verify significant behavioral changes: run the specific test, command, or scenario covering the change.\n</critical>","task":"Complete assignment thoroughly:\n\n# Target\nIR71–137 in .worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md; main owns detailed IR86 closure. Exclude edits and live execution.\n# Change\nRead assigned entries through final amendments and extract present statuses and trigger evidence. Check source selectively for top small ready candidates, identifying already-shipped fixes instead of redispatch. Known landed lanes: IR13552d56248, IR13684e20ddd, Linux floor5e05f02d, Windows floor0cda6235, IR137 discipline8bb0feb4, IR86 inline delta82333ca1. IR137 is explicitly retired with no tracked launcher callsite.\n# Acceptance\nAccount for all67 IDs. Return compact complete dispositions and ranked genuinely ripe residual candidates, with owner/seam and smallest next step. Skip all validation/build/lint/tests.","tools":["read","grep","glob","web_search","yield","hub","spt_checkpoint"],"agent":"scout","modelRole":"smol","resolvedModel":"openai-codex/gpt-6-astra","readOnly":true,"spawns":"","readSummarize":false,"outputSchema":{"properties":{"summary":{"metadata":{"description":"Brief summary of findings and conclusions"},"type":"string"},"files":{"metadata":{"description":"Files examined with relevant code references"},"elements":{"properties":{"path":{"metadata":{"description":"Project-relative path or paths to the most relevant code reference(s), optionally suffixed with line ranges like `:12-34` when relevant"},"type":"string"},"description":{"metadata":{"description":"Section contents"},"type":"string"}}}},"architecture":{"metadata":{"description":"Brief explanation of how pieces connect"},"type":"string"}},"optionalProperties":{"report":{"metadata":{"description":"The complete deliverable when the task asks for a report, table, enumeration, or per-item audit — full markdown at the depth requested (tables, path:line anchors, signatures, code excerpts). Never a summary of it; `summary` already covers that. Omit only for quick lookups."},"type":"string"}}},"outputSchemaMode":"permissive"}
{"type":"message","id":"098441f0","parentId":"347211c4","timestamp":"2026-09-15T14:47:29.115Z","message":{"role":"user","content":[{"type":"text","text":"Complete assignment thoroughly:\n\n# Target\nIR71–137 in .worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md; main owns detailed IR86 closure. Exclude edits and live execution.\n# Change\nRead assigned entries through final amendments and extract present statuses and trigger evidence. Check source selectively for top small ready candidates, identifying already-shipped fixes instead of redispatch. Known landed lanes: IR13552d56248, IR13684e20ddd, Linux floor5e05f02d, Windows floor0cda6235, IR137 discipline8bb0feb4, IR86 inline delta82333ca1. IR137 is explicitly retired with no tracked launcher callsite.\n# Acceptance\nAccount for all67 IDs. Return compact complete dispositions and ranked genuinely ripe residual candidates, with owner/seam and smallest next step. Skip all validation/build/lint/tests."}],"attribution":"agent","timestamp":1789483649056}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_5oEoXXUGVkLVYSe9XyOe88En|fc_000c7cef03cac861016aa95a83c76887d18b2f33294ec595e8","toolName":"grep","startedAt":"2026-09-15T14:47:34.428Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md"},"intent":"Locating assigned register entries"},"id":"0415a04a","parentId":"098441f0","timestamp":"2026-09-15T14:47:34.428Z"}
{"type":"message","id":"97a3cb2c","parentId":"0415a04a","timestamp":"2026-09-15T14:47:34.429Z","message":{"role":"assistant","content":[{"type":"toolCall","id":"call_5oEoXXUGVkLVYSe9XyOe88En|fc_000c7cef03cac861016aa95a83c76887d18b2f33294ec595e8","name":"grep","arguments":{"i":"Locating assigned register entries","pattern":"^#{1,5} .*IR[- ]?(7[1-9]|[89][0-9]|1[0-3][0-9])\\b","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md","case":false,"gitignore":false,"skip":null},"intent":"Locating assigned register entries"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":1757,"output":95,"cacheRead":8448,"cacheWrite":0,"totalTokens":10300,"cost":{"input":0.017570000000000002,"output":0.00475,"cacheRead":0.008447999999999999,"cacheWrite":0,"total":0.030768000000000004}},"stopReason":"toolUse","timestamp":1789483649114,"responseId":"resp_000c7cef03cac861016aa95a81a8e887d18696d1324365c759","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"fc_000c7cef03cac861016aa95a83c76887d18b2f33294ec595e8","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating assigned register entries\",\"pattern\":\"^#{1,5} .*IR[- ]?(7[1-9]|[89][0-9]|1[0-3][0-9])\\\\b\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md\",\"case\":false,\"gitignore\":false,\"skip\":null}","call_id":"call_5oEoXXUGVkLVYSe9XyOe88En","internal_chat_message_metadata_passthrough":{"create_time":1789483649.946706,"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"grep","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}}]},"duration":5312.068599998951,"ttft":2784.9143999814987,"completedAt":1789483654427,"contextSnapshot":{"promptTokens":10205,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"credential_pin","id":"3a9d9b08","parentId":"97a3cb2c","timestamp":"2026-09-15T14:47:34.429Z","provider":"openai-codex","hash":"1a3c10d7bc41d381cab1511db604bc2637dfcfc63796a890d8b5ee152859e1cb"}
{"type":"message","id":"0a5ede88","parentId":"3a9d9b08","timestamp":"2026-09-15T14:47:34.542Z","message":{"role":"toolResult","toolCallId":"call_5oEoXXUGVkLVYSe9XyOe88En|fc_000c7cef03cac861016aa95a83c76887d18b2f33294ec595e8","toolName":"grep","content":[{"type":"text","text":" 3887|\n*3888|### IR-71 — controller-seat release has no persisted breadcrumb, so tests cannot distinguish propagation lag from a missing detach\n 3889|\n 3890|- **Status:** OPEN, observability gap; no remedy scheduled. · **Origin:** CONDUIT #236 r3\n 3891|  `er_brief_once_per_session_e2e` intermittent, classified test-side and fixed on PR #174.\n...\n 3911|\n*3912|### IR-72 — no product read verb surfaces which process holds a perch or controller seat\n 3913|\n 3914|- **Status:** OPEN, observability gap; no remedy scheduled. · **Origin:** CONDUIT #236 r3\n 3915|  two-host RCA and PR #174 (`70c1a303`), corrected by doyle after IR-18 and daemon-status were\n...\n 3945|\n*3946|### IR-73 — ci.yml and release.yml still read the free-space floor PRE-checkout (literal-first sites off the golden path); and any job's floor is stale by its last heavy step\n 3947|\n 3948|- **Status:** CLOSED / BUILT — source reconciliation 2026-09-11 at `e5a2fed9`: all five\n 3949|  `ci.yml` sites and all three `release.yml` sites now read after checkout, with IR-73 comments;\n...\n 3969|\n*3970|### IR-74 — kitsubito holds 21,643 /tmp endpoint homes: box-side accumulation nothing bounds or measures\n 3971|\n 3972|- **Status:** OPEN, filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep; measurement by\n 3973|  hertz (2026-08-29). · **Origin:** rig work on kitsubito found `/tmp` carrying 21,643 endpoint\n...\n 3983|\n*3984|### IR-75 — traceable-reqs is not installed on kitsubito, so every Linux gate driver's treqs leg exits 127 (vacuous, wrapper-green shape)\n 3985|\n 3986|- **Status:** OPEN, filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep (deployah\n 3987|  co-flagged at intake). · **Origin:** ASM-241 Linux battery — `ASM_treqs.exit` = 127, raw\n...\n 3998|\n*3999|### IR-76 — hfenduleam is the golden Windows runner AND the builders' box: a local workspace nextest fully contained a golden Phase A and manufactured a load-timing red, and the job-start census cannot see it\n 4000|\n 4001|- **Status:** OPEN, filed by doyle 2026-09-06 during v0.67.1 golden triage (run 34017906638\n 4002|  att2). · **Origin:** the Windows Phase A red on\n...\n 4042|\n*4043|### IR-77 — nothing stamps the interval between a daemon child's spawn and the brain's first log line, so a readiness-deadline red cannot say WHERE the time went\n 4044|\n 4045|- **Status:** OPEN, filed by hertz 2026-09-07 from the W1 #249 kitsubito battery at the gated\n 4046|  sha `8d980fdf`; doyle-ruled at filing to be a register entry rather than a lane rider. ·\n...\n 4074|\n*4075|### IR-78 — `SPT_TEST_EPHEMERAL_ADVISORY_PORTS` silently overrides an explicitly set `SPT_DOCS_PORT`\n 4076|\n 4077|- **Status:** OPEN, filed by hertz 2026-09-07, MEASURED by doyle the same night on his W2\n 4078|  field pair (both boxes). · **Origin:** the 5474 rig-hygiene sweep in\n...\n 4102|\n*4103|### IR-79 — 22 of the 31 rig binaries leak their daemon tree on a failing assert: teardown is a statement, not a guard\n 4104|\n 4105|- **Status:** OPEN, filed by hertz 2026-09-07 on doyle's dispatch during PR #198's CI window,\n 4106|  from todlando's red 6 (a stale same-port daemon from his own previous run answering the next\n...\n 4183|\n*4184|### IR-80 — five leaky cells on ONE module (`brainproc` / `supervise_brain`), Windows only: a candidate PRODUCT leak on the promotion/rollback path, or a cluster of names — nobody has looked yet\n 4185|\n 4186|- **Status:** OPEN for the residual population, not an undiagnosed five-name product claim.\n 4187|  Later amendments identify the brainproc shell-wrapper fixture mechanism and distinguish\n...\n 4465|\n*4466|### IR-81 — a process kill can be written scoped or machine-wide, and nothing makes the scoped form the only reachable one: both codebases carry the right pattern beside the wrong one\n 4467|\n 4468|- **Status:** OPEN, drafted by hertz 2026-09-07 08:38Z on doyle's dispatch (08:36Z), from the\n 4469|  fleet-daemon death on hfenduleam at 08:03:15Z ([[RCA-FLEET-DAEMON-14444]], cause still UNNAMED).\n...\n 4590|\n*4591|### IR-82 — a daemon death leaves NO record of who died: autostart decides on a socket ping, says \"no daemon\", and the successor overwrites the only handle on the corpse\n 4592|\n 4593|- **Status:** RULED 2026-09-07 11:07Z (doyle), drafted by hertz 11:04Z on doyle's dispatch (11:03Z: *\"the autostart\n 4594|  death-cause item is an IR, not a board item — mint it IR-82 in your thin PR\"*). Register on main\n...\n 4696|\n*4697|### IR-83 — a two-host rig addressed over the tailnet cannot receive INBOUND on Windows, and the whole rig population had only ever run the admitted direction\n 4698|\n 4699|- **Status:** OPEN, minted by hertz 2026-09-07 11:41Z on doyle's dispatch (11:40Z). **Provenance: the\n 4700|  mechanism below is DOYLE'S measurement, not mine** — eight probe arms, each with sender, listener\n...\n 4833|\n*4834|### IR-84 — the one `PUMP_PEER_FAIL` arm the rigs actually fire was the only one carrying no clock, so the stall that produced it could be counted but never timed\n 4835|\n 4836|- **Status:** OPEN, filed by hertz 2026-09-09 with the instrument that closes its first half. ·\n 4837|  **Origin:** the 65 s two-host helper stall (design written before the run,\n...\n 4883|  stamps, so the fifth site added cannot be born silent.\n*4884|### IR-85 — the Windows self-hosted box runs its fs-heavy tests 3-4x slower than a week ago; two CI wall clocks were sized for the old box, and a red run kept hiding it\n 4885|\n 4886|- **Status:** OPEN, filed by hertz 2026-09-09 at the #272/v0.68.0 golden r3/r4 arc, on doyle's\n 4887|  dispatch. Number ruled by doyle from his own census of main@`a2f335f8` (register ended at IR-83;\n...\n 5043|\n*5044|### IR-86 — golden's 32 GiB floor is BELOW the measured 67.4 GiB Windows suite footprint, so a start floor passes a box that cannot finish\n 5045|\n 5046|- **Status:** OPEN, filed by doyle 2026-09-08 at the #272/v0.68.0 golden r2 triage. · **Origin:**\n 5047|  run 34262154550 @ `25e60015` (shaped on `e4444413`), Windows test job 102182665033: every product\n...\n 5092|\n*5093|### IR-87 — two-host ceremony halves are INDEPENDENT jobs on DIFFERENT runners (A Windows/hfenduleam, B Linux/kitsubito); B's 900 s budget runs on B's own clock, so any older queued Windows job starves A and reds B deterministically, and the panic text blames pairing\n 5094|\n 5095|- **Status:** OPEN, filed by doyle 2026-09-08 at the #272 golden r2 triage. · **Origin:**\n 5096|  run 34262154550, twohost-b job 102207296960 (log 81,692 B, sha256 67403f04…8030): role B built,\n...\n 5145|\n*5146|### IR-88 — `pool-release` via `cargo run -p xtask` REBUILDS xtask INTO the pool it is releasing, so a reaped pool regrows ~2.8 GB in silence\n 5147|\n 5148|- **Status:** OPEN, filed by doyle 2026-09-08 from hertz's reap report (20:00Z) during the #272\n 5149|  golden r2 repair. · **Origin:** hertz reaped hertz-lane4 / hertz-repin / hertz-percell-id target\n...\n 5182|\n*5183|### IR-89 — hfenduleam's Windows Firewall drops cold inbound UDP to the runner-built test exes, so the two-host rig's first B→A claim (W2 helper) reds for its whole 900 s budget and the panic blames A\n 5184|\n 5185|- **Status:** BOX HALF **APPLIED** 2026-09-08; WORKFLOW HALF **BUILT** 2026-09-09 — PR #211\n 5186|  (`9b96d7e7` + this amendment), **LANDED, exact golden-step acceptance unreconciled**.\n...\n 5338|\n*5339|### IR-90 — a full disk on the self-hosted box reds a rig as a PRODUCT refusal, not a build error, and no rig or gate records the free space that would falsify it\n 5340|\n 5341|- **Status:** OPEN, filed by hertz 2026-09-09 from the disk-full incident on hfenduleam. ·\n 5342|  **Origin:** the IR-85 discriminator lane's head arm, killed by the volume rather than by the code\n...\n 5427|\n*5428|### IR-91 — 561 untracked files sat at the repo root, 18 of them cited by tracked files, and the census that classified them used a corpus that made the discriminator invisible\n 5429|\n 5430|- **Status:** CLOSED by the lane that filed it (the root-scratch classify PR), hertz 2026-09-09 on\n 5431|  doyle's census and rulings. · **Origin:** the `.spt/` ignore lane (PR #212) named 561 untracked\n...\n 5481|\n*5482|### IR-92 — the message that WAKES an idle spt-hosted endpoint rides a delivery leg that never publishes MSG_IN, so a woken agent's own funnel holds none of the messages that woke it\n 5483|\n 5484|- **Status:** OPEN — filed doyle 2026-09-09 from hertz's census, probe and proposed text (his by\n 5485|  role; the recorder read and the REQ reading are doyle's). Fix lane unassigned: product change in\n...\n 5613|\n*5614|### IR-93 — no PDB ships beside the installed `spt` binary, so the one non-invasive read of a wedged production daemon comes back without a single named frame\n 5615|\n 5616|- **Status:** OPEN, filed by doyle 2026-09-10. **The number was reserved by NAME on 2026-09-09** at\n 5617|  the #293 mechanism read (\"PDB ask -> IR-93 at next sweep\") and this entry closes that claim — a\n...\n 5642|\n*5643|### IR-94 — xtask's brainread deadline gate cannot SEE `serve_sync`: its registry is three hand-listed files and its predicate is a name shape, so a stream server outside both got the reply form and the gate stayed green\n 5644|\n 5645|- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 / v0.69.0 golden RED triage. **This\n 5646|  is an INDEPENDENT gate finding, not the cause of that red** — it was found while reading the\n...\n 5672|\n*5673|### IR-95 — a burned polling budget names WHAT it wanted and never HOW LONG it waited, so no run, green or red, can say how close it came\n 5674|\n 5675|- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 golden RED, where it cost this\n 5676|  triage most of a morning and four agents. · **Origin:** the two Windows Phase A failures at\n...\n 5927|\n*5928|### IR-96 — the `daemon_stop_convoy_e2e` API-storm cell fails 3-of-3 under the HEAVY suite at the diagnostic tree while passing at the candidate in golden CI, and nothing yet separates instrumentation from box from product\n 5929|\n 5930|- **Status:** OPEN, **cause-unclassified** (todlando's and hertz's stipulation, adopted verbatim — a\n 5931|  triage placement here is NOT a finding of non-defect).\n...\n 5963|\n*5964|### IR-97 — a suite that leaks a fixed cohort of child processes per invocation makes consecutive runs non-comparable, and the between-run accounting the protocol required was not enforced\n 5965|\n 5966|- **Status:** OPEN. **Protocol deviation** (hertz's framing, and it is stronger than \"confounder\":\n 5967|  the protocol ALREADY required between-run accounting — execution did not enforce it, so the fix is\n...\n 6006|\n*6007|### IR-98 — a lane driver that PRINTS a producer's output can die on an unencodable byte AFTER that producer's evidence is on disk, so the run ends with complete evidence for producer N and NO files for N+1 — an absence that reads as \"never queued\", not as a failure\n 6008|\n 6009|- **Status:** OPEN as a mechanism; the measured instance is FIXED in hertz's lane driver (UTF-8 with\n 6010|  replacement reconfigured at import, positive control run before relaunch: U+2500 and U+2713\n...\n 6030|\n*6031|### IR-99 — EOF and terminal retire on a ConnectionBound net stream arm on the OPENER CONN's exit; a same-morning diagnosis built on that mechanism was refuted by the compiler, so the mechanism stands and the two #304 reds beside it stay open\n 6032|\n 6033|- **Status:** OPEN. The mechanism is VERIFIED; both reds are CLASSIFIED NOT-product (instance 1: an\n 6034|  unpromised spectator EOF; instance 2: a journal replay of a reused op seq) — repairs built at\n...\n 6109|\n*6110|### IR-100 — an editor-driven rust-analyzer runs `cargo check --workspace --all-targets` into a LANE's pool on its own schedule, so a builder census counts it, a lock wait charges it to nobody, and the lane's disk growth carries it uncredited\n 6111|\n 6112|- **Status:** OPEN. Recorded 2026-09-11 09:30Z from todlando's trace; no mitigation applied.\n 6113|- **Instance (todlando, `.worktrees/304-product`, 09:29Z):** his distinct-seq build printed\n...\n 6169|\n*6170|### IR-101 — no per-lane producer compiles a lib crate's own `#[cfg(test)]` module on the branch that broke it, so a stale caller of a lane's own signature change rides green through six real-daemon runs and surfaces only at assembly, or from an editor\n 6171|\n 6172|- **Status:** OPEN. Rule adopted 2026-09-11 09:35Z; instrument = one command at inventory and one at\n 6173|  assembly.\n...\n 6234|\n*6235|### IR-102 — a dirty file the lane DECLARED is still invisible to an assignment made against its committed blob, so the gater measures and predicts on a blob the lane was never going to run\n 6236|\n 6237|- **Status:** OPEN. Recorded 2026-09-11 09:50Z from hertz's correction; ruling applied (commit all\n 6238|  five), no instrument yet.\n...\n 6267|\n*6268|### IR-103 — a rig that re-enters something already retired reads as a product red: four instances in ONE cell (#230), each masking the next\n 6269|\n 6270|- **Status:** OPEN. Recorded 2026-09-11 10:00Z (doyle). Amended 10:20Z: the third instance's repair\n 6271|  RAN (todlando window 10:12-10:18Z, one attempt) and its structural falsifiers all HELD — distinct\n...\n 6337|\n*6338|### IR-104 — checker 0.4.0 silently skips a FILE scan root under git enumeration: 81 doc stages read as missing, and a local 0.2.0 green hid it because the two versions disagree on what is evidence\n 6339|\n 6340|- **Status:** FIXED UPSTREAM 2026-09-11 (traceable-reqs v0.4.1, PR #21 -> d9af11d, red-first cells);\n 6341|  spt-core consumes via hertz's #304 lane pin fixup. Closes when that pin is on main.\n...\n 6366|\n*6367|### IR-105 — an assertion derived from a MODEL of the fixture instead of read off the fixture can only be refuted by a run, and the lane convention that defers the run gives the class a one-window latency: the repair for the first instance carried the second\n 6368|\n 6369|- **Status:** OPEN. Rule adopted 2026-09-11 (hertz, W1 close). Instrument = read the line, and read\n 6370|  what the line LANDS on, before asserting either.\n...\n 6418|\n*6419|### IR-106 — a red set HANDED OVER in a message was reported as a POPULATION: both members verified, their lines and modes corrected, and the count still wrong by half\n 6420|\n 6421|- **Status:** OPEN as a discipline line; the instance is closed (the run that refuted it is on file).\n 6422|  Author and subject: todlando. Filed by doyle 2026-09-11 11:20Z from todlando's text; IR-105 lands\n...\n 6449|\n*6450|### IR-107 — a rig that redirects TMP INSIDE the checkout puts every tempdir fixture under a git toplevel, and cells whose premise is \"outside any repo\" resolve THIS repo's remote\n 6451|\n 6452|- **Status:** RIG FIXED in hertz's lane (base now under `AppData/Local/Temp/hertz-304-rig/<label>`;\n 6453|  `HERTZ_RIG_TMP_IN_REPO=1` restores the old placement on purpose as the negative control). Recorded\n...\n 6544|\n*6545|### IR-108 — four brainproc unit cells leak a process on every run; two others leak by ordering\n 6546|\n 6547|- **Status:** OPEN, product-side backlog candidate (not #304's). Recorded 2026-09-11 11:35Z (doyle)\n 6548|  from three unfiltered `spt-daemon --lib` runs on identical bytes on HFENDULEAM (todlando 10:52Z at\n...\n 6566|\n*6567|### IR-109 — a manifest `[placement] module_banner = \"accept\"` block LOOSENS the local checker to zero; CI's pinned checker is structurally blind to placement, so the loosening is invisible until the pin moves\n 6568|\n 6569|- **Status:** OPEN, RATIFIED 12:33Z (doyle, releases#304) as a TRANSITIONAL policy for the #304 head: the 0.4.1 pin stays (a tightening for every new tag), the accept key exempts only the 312 legacy banner tags, and this entry is the retirement ticket. Recorded 2026-09-11 12:10Z (doyle) from hertz's A/B/C and 0.2.0 arms; the commit's \"agreed\" is corrected by the ruling, not by rewriting a measured sha.\n 6570|- **Instance.** 33936943 \"chore(traceability): enable agreed placement policy\" (07:38Z, trailer todlando, on\n...\n 6588|\n*6589|### IR-110 — the gater ruled a wave from origin/main's manifest while the milestone's own product lane already carried the surface; a second implementation was built to its W-1 END before the first was noticed\n 6590|\n 6591|- **Status:** OPEN, STOP LINE on #304 W2 (comment 5634187958). Recorded 2026-09-11 12:10Z (doyle, own instance).\n 6592|- **Instance.** feat/304-remote-friction-product @3e7eaf67 implements #297 TCP admission under\n...\n 6617|\n*6618|### IR-111 — the installed product's own inbound UDP rule reads Duplicate / Inactive in ActiveStore, shadowed by the fallback rule; a by-name probe reads it green\n 6619|\n 6620|- **Status:** OPEN, product-side backlog candidate (REQ-INBOUND-WINDOWS-RULE-BINDER-PATH-MATCH family). Recorded\n 6621|  2026-09-11 12:14Z (doyle) from an unelevated `Get-NetFirewallRule` read of both stores on HFENDULEAM.\n...\n 6639|\n*6640|### IR-112 — bare `cargo test -p spt-daemon --lib` reds two process-global cells on Linux at a sha where nextest is green; libtest is not a sound gate for this crate\n 6641|\n 6642|- **Status:** OPEN, rig rule (CI unaffected: `ci.yml` runs `kind(lib)` under nextest). Recorded 2026-09-11 12:46Z\n 6643|  (doyle) from hertz's Linux cells lane END on kitsubito.\n...\n 6659|\n*6660|### IR-113 — a killed mutation arm does not unwind: the subject stays mutated and the NEXT arm measures a tree nobody declared; and a mutation that reds on a compile error is a void arm that \"it compiled\" cannot detect\n 6661|\n 6662|- **Status:** OPEN, rig rule for every mutation driver. Recorded 2026-09-11 13:05Z (doyle) from todlando's FOLD-1b\n 6663|  window (fold/304-w2-admission, windows.rs).\n...\n 6681|\n*6682|### IR-114 — three hands wrote one firewall rule set inside ninety seconds under two directors; every census was true at its instant and false a minute later\n 6683|\n 6684|- **Status:** OPEN, procedure ruled 2026-09-12 00:50Z (doyle) on todlando's reconciliation; recorded 00:52Z.\n 6685|- **Instance.** #304 W-2a arms on HFENDULEAM: ~00:44Z todlando asked the operator to delete spt-w2a-C so B would stand alone; ~00:45Z the operator said \"C down\" and todlando's census read B present / C absent (true then); 00:45:05Z liam ADDED C at doyle's direction (doyle had been idle 11 h and did not know the operator's window); 00:46:14Z liam DELETED B at doyle's direction; 00:49:09Z todlando re-measured C present / B absent. Nobody was wrong; the population was not stable. Every fetch todlando report...\n...\n 6690|\n*6691|### IR-115 — a firewall census whose port test is DENIED reads every rule as port=Any and counts port-scoped rules as blanket; a `netsh show rule` without `verbose` omits Program and reads every rule as program=Any; a control count that merges two agents' reads is nobody's control\n 6692|\n 6693|- **Status:** OPEN, mechanisms recorded 2026-09-12 01:14Z (doyle) from todlando's and liam's own corrections during #304 arm E.\n 6694|- **Instances.** (1) todlando's first census A (\"26 blanket rules\") and B (\"occupied LocalPort set: EMPTY\"): `Get-NetFirewallPortFilter -All` returns \"Access is denied\" unelevated, the probe swallowed the denial, every rule read as port=Any, and B's positive control (the hand rule carries LocalPort 5470) is what caught it. (2) His replacement pass: `netsh advfirewall firewall show rule name=all` without `verbose` prints no Program line, so it reported 417 blankets and ZERO rules naming spt.exe — provab...\n...\n 6700|\n*6701|### IR-116 — a watchdog that calls a killer and then echoes success reports a kill it never made; `pkill` is absent in msys, so the guard logged \"stopped\" while the arm it guarded ran on\n 6702|\n 6703|- **Status:** OPEN, mechanism recorded 2026-09-12 01:24Z (todlando) from his own guard during #304 FOLD-2's Windows arm at 7357ea32; doyle asked for the line.\n 6704|- **Instance.** todlando armed a watchdog to stop a test arm before it reached `cargo test --workspace --lib`, because spt-daemon lib tests deadlock on a live host. Shape: `if grep -q \"CLIPPY_EXIT=\" log; then pkill -f \"bash /tmp/arms.sh\" 2>/dev/null; echo \"GUARD: arms.sh stopped after clippy at $(date -u)\"`. It printed `GUARD: arms.sh stopped after clippy at 01:24:06Z`. Nothing was stopped: `pkill` does not exist in this msys/Git-Bash environment (`command not found`, exit 127), `2>/dev/null` ate the mes...\n...\n 6711|\n*6712|### IR-117 — a predicate that cannot fail: pre-registered outcomes whose branches are not mutually exclusive, and a requirement titled with the TASK instead of the INVARIANT\n 6713|\n 6714|- **Status:** OPEN, mechanism recorded 2026-09-12 03:48Z (hertz, both instances his own; doyle ruled the second).\n 6715|- **Instance 1 — the outcome set.** For the #304 W-2 packet capture hertz pre-registered four outcomes, of which (a) was \"SYN retransmission despite the RST\" and (b) was \"above the wire in the Windows client path\". The capture showed five SYNs at a flat ~511 ms, each RST'd in 18-25 us and each ignored — which is (a)'s packet shape with (b)'s locus. The two branches were the same answer told at two altitudes, so EITHER could have been declared \"confirmed\" and neither could have been refuted by the act...\n...\n 6720|\n*6721|### IR-118 — an instrument read mid-flight, or through a filter that cannot match, returns a COMPLETE-LOOKING wrong answer with no error\n 6722|\n 6723|- **Status:** OPEN, two instances one hour apart, 2026-09-12 (hertz); doyle asked for the filter line beside IR-117.\n 6724|- **Instance 1 — the capture read in flight, and it would have inverted the verdict.** `tcpdump -w /tmp/hz-cap.pcap` was still running when the packets were wanted. The file was **8192 bytes** live and **11933 bytes** after `kill -TERM` flushed it; the 3741-byte tail WAS the four SYN retransmissions. Reading the live file would have yielded a well-formed pcap showing one SYN and one prompt RST — i.e. the pre-registered outcome (b), the WRONG answer, assembled entirely from the RIGHT answer's own evid...\n...\n 6729|\n*6730|### IR-119 — a control that only had to prove a ROUTE served a real directory; and a rig is not torn down until its last process is gone, whatever the analysis says\n 6731|\n 6732|- **Status:** OPEN, mechanisms recorded 2026-09-12 05:46Z (doyle) from hertz's unprompted self-disclosure. The security remedy is an OPERATOR item, filed on releases#304 comment **5643876746** (rotate the kitsubito self-hosted runner's registration credential); this entry carries only the reusable mechanisms.\n 6733|- **Instance.** The accepted-connection control for the W-2 packet capture was `python3 -m http.server 29472 --bind 0.0.0.0` with **cwd `/home/reavus`** — the self-hosted runner account's home — for **1 h 59 m 54 s**. The off-box bind was REQUIRED (the peer dialled from another machine); the working directory was the whole defect. An empty temp dir returns the identical HTTP 200 and proves exactly as much. `http.server` builds its index from `os.listdir` and filters nothing, so 20 dotfiles including ...\n...\n 6740|\n*6741|### IR-120 — a claim named for the one axis nobody varied: six readings over two routes and two libraries, all on ONE box, reported as a property of the platform\n 6742|\n 6743|- **Status:** OPEN, mechanism recorded 2026-09-12 05:47Z (doyle); the instance is liam's, refuted by hertz's own arm and conceded by its author.\n 6744|- **Instance.** The ~2.05 s Windows refused-connect latency was filed as \"the WINDOWS refusal latency\" on six readings that varied ROUTE (loopback, LAN hop to Linux) and LIBRARY (curl, .NET TcpClient) and held HOST constant — every one on HFENDULEAM. Route- and library-independence were measured; \"Windows\" was the name of the box. A per-host WFP callout, endpoint agent or filter driver swallowing RSTs would have produced exactly those six readings on exactly those two routes and generalised nothing. Se...\n...\n 6750|\n*6751|### IR-121 — one declaration command expands every right-hand side before assigning any name, so a dependent id silently binds the CALLER'S GLOBAL and two arms collapse onto one artifact path; and `cat -A` behind msys `sed` is not a byte reader\n 6752|\n 6753|- **Status:** OPEN, mechanisms recorded 2026-09-12 09:05Z. Instance 1 found by hertz in todlando's driver and confirmed by doyle; repaired as a separately pinned revision (v6 `dcfb732a…` → v7 `927eafb9…`) per the standing rule that a demonstrated execution incompatibility gets a new hash and renewed verification rather than an in-place accommodation. Instance 2 is todlando's own, found while reading the repair site.\n 6754|- **Instance 1 — the id that looked right.** `trial()` opened with `local arm=\"$1\" n=\"$2\" id=\"$arm-$n\"`. A single declaration command expands EVERY right-hand side before assigning any of its names, so `$arm` was still unset when `id` was built — but `$n` was **not** empty, because the caller is `for n in 1 2 3; do trial a \"$n\"; done` and `n` is a GLOBAL at that point. The id therefore read `-1`, not the empty-ish `-` that would have been noticed: a plausible, consistently-formed, wrong identity. Bot...\n...\n 6768|\n*6769|### IR-122 — the field rig's isolated-daemon stop cannot run from an spt-hosted session, so every run leaves a live daemon holding the subject exe inside the pool it just released\n 6770|\n 6771|- **Status:** OPEN, recurring. Instance 1 attempt 2 (`rig/arm2-driver-stdout.txt`: `RIG_DAEMON_STOP_REFUSED_OR_ERRORED — reported, not forced`). Instance 2 run `20260912T231404Z` under frozen r10 (`rig_daemon_stop_EXIT=3`, `cleanup-failures.txt`, `rig-daemon-stop.err`). Recorded by hertz 2026-09-12 23:50Z at doyle's direction; **this is a RIG defect, and any product-surface change requires a separate contract review.**\n 6772|- **The refusal.** `DAEMON_STOP_REFUSED: a broker-stopping command is never run by an spt endpoint ($OWL_SESSION_ID is set). ... No flag overrides this, --force included.` The guard keys on the CALLER'S SESSION ENV, so it fires identically no matter which rig step reaches it and no matter what `SPT_HOME` the command targets.\n...\n 6781|\n*6782|### IR-123 — a helper that LOGS cannot also RETURN through stdout: `record` tees, so `face=$(face_report ...)` captures the log block and the acceptance gate can never pass\n 6783|\n 6784|- **Status:** OPEN, mechanism recorded 2026-09-13 (hertz, found by exercising the D2 successor; confirmed by doyle from a direct source read of frozen r10). **Frozen r10 is PRESERVED as-is**; the return channel is corrected in its successor only.\n 6785|- **Instance.** `record()` is `echo \"$1\" | tee -a \"$R/findings.txt\"` — it writes to the log AND to stdout, deliberately, so a live operator sees the run. `face_report()` calls `record` twice (a FACE_COUNTS line and a FACE= line) and then `echo`es the face as its return value. The single caller reads it as `setup_face=$(face_report \"$SETUP_OUT\" \"$SETUP_ERR\" \"SETUP\" bootstrap)`, so the captured value is **the whole tee'd log block with the face appended**, and `[ \"$setup_face\" != reconciled ]` is true no...\n...\n 6793|\n*6794|### IR-124 — a cleanup that runs `serve lan --stop` UNCONDITIONALLY creates the daemon it exists to remove, when the setup it is cleaning up after never ran\n 6795|\n 6796|- **Status:** OPEN, measured once in the field. D2 field run `20260913T041410Z`, driver `2e3aec1b`, recorded by hertz 2026-09-13 at doyle's direction. Archive `.spt/preserved/hertz-fp-driver-review/d2/field-run-20260913T041410Z/` (72 files, manifest `defa5d29…`). **This is a RIG defect. It is mine — I wrote the driver — and doyle's admission review missed the unconditional stop path as well; both are recorded because a review that misses a path is part of the mechanism, not an aside.**\n 6797|- **Instance.** The elevated setup was **DECLINED and NOT STARTED** by liam at 04:18:55Z — measured, unambiguous, and the right call: his leg was ready at 04:18:35Z against a hard 04:19:10Z expiry and he refused rather than race the teardown. Nothing ran, nothing mutated. The driver then entered cleanup and executed its own unconditional `env SPT_INSTALL_NO_FIREWALL=1 SPT_HOME=<isolated-home> <exe> serve lan --stop`, which dispatched through the daemon (`ensure_running`, `serveverb.rs:191`) and **CREAT...\n...\n 6805|\n*6806|### IR-125 — the driver's own executable sweep reported ZERO processes on the pinned exe while `Win32_Process` showed TWO, at the same instant\n 6807|\n 6808|- **Status:** OPEN, measured in D2 field run `20260913T041410Z` (hertz, 2026-09-13). **A FALSE-NEGATIVE SWEEP, not a false CLEAR** (doyle's classification, and the distinction is load-bearing): the ledger's actual verdict was `residual_state=UNREADABLE` / `CLEANUP=PENDING`, which was correct, and the sweep line is explicitly labelled evidence-only in the driver's own output.\n 6809|- **Instance.** `SUBJECT_EXE_PROBE=OK running_the_pinned_executable=0 enum_total=618` — the probe enumerated 618 processes and concluded none was running the pinned executable. A `Win32_Process` read moments later returned **two**, both with `ExecutablePath` exactly `…\\.worktrees\\304-w2-repr\\target\\release\\spt.exe`: PIDs 45944 and 22524. An independent sweep by path, not by pid, agreed: `count=2`.\n...\n 6816|\n*6817|### IR-126 — the experimental budget CONTAINED its own read-only preflight, leaving 128 s of a 300 s window for the elevated leg, and the leg was correctly declined\n 6818|\n 6819|- **Status:** OPEN, measured in D2 field run `20260913T041410Z` (hertz, 2026-09-13). Boundary NOT moved for that run — doyle refused the change mid-flight and was right to; this entry is the scheduling review he asked to be preserved.\n 6820|- **Measured, from the run's own timestamps.** Run start `04:14:10Z` · pre-setup absence census `04:16:23Z` · handoff request written `04:17:02Z`. So **172 s of the 300 s experimental budget went to in-budget read-only preflight** — CI axis queried by name across five statuses, ancestry census, six-instrument hashing, subject identity, 5470 guard baseline, pre-setup absence census — and the driver printed the remainder itself: `HANDOFF_WAIT bounded to 128s`.\n...\n 6827|\n*6828|### IR-127 — a nested value-type assignment can leave the native job limit unset while the instrument logs the requested flag and a successful setter\n 6829|\n 6830|- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\n 6831|- **Instance.** The containment probe assigned `$info.BasicLimitInformation.LimitFlags = 0x2000`, logged the requested KILL_ON_JOB_CLOSE flag and `SetInformationJobObject=True`, read both owned processes as job members, closed the handle, and found both still alive. The nested field is a struct: PowerShell changed a copy, not the value subsequently marshalled. The offline discriminator measured `nested_assignment_flags=0`; modifying the nested value and assigning the whole value back measured `whole_valu...\n...\n 6836|\n*6837|### IR-128 — PowerShell `$null` can become an empty native string, so a failed launch is misread as a policy refusal before the policy is reached\n 6838|\n 6839|- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\n 6840|- **Instance.** Both breakaway probe arms called a P/Invoke string parameter with PowerShell `$null`; both returned `CreateProcess` error **123** and created no child. This is an invalid-name result, not the **5** required to establish breakaway-policy denial. An offline C# string-parameter discriminator returned `IsNull($null)=False`: the PowerShell binder had supplied an empty string rather than native NULL.\n...\n 6846|\n*6847|### IR-129 — JSON date materialization followed by implicit string parsing loses UTC kind and precision, turning a live creation anchor into a false pid-reuse verdict\n 6848|\n 6849|- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`. The first M8 exit 0 is explicitly INVALID.\n 6850|- **Instance.** `ConvertFrom-Json` materialized an ISO birth string as `DateTime`; `[DateTime]::Parse($id.created)` implicitly formatted that object back to text before parsing it. Kind and fractional precision were lost and local time was reinterpreted. The result printed birth timestamps agreeing within a microsecond but computed roughly seven-hour deltas, mislabelling four live registered identities `GONE_PID_REUSED`. The original output remains at `.spt/preserved/hertz-fp-driver-review/d2/controls-ou...\n...\n 6856|\n*6857|### IR-130 — a lowercase `$home` local collides with PowerShell's protected `$HOME`, refusing custody qualification before the signer is reached\n 6858|\n 6859|- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz on 2026-09-13 in the D2 custody lane; narrow correction and one fresh-root attempt authorized by doyle `5FWLC3F2`. Original refusal remains preserved.\n 6860|- **Instance.** The prepared custody controller passed syntax parsing and compiled its native observer successfully, then exited **1 after 3.33 s** before any custody arm. Its next statement assigned `$home = Join-Path $armRoot 'home'`. PowerShell variable names are case-insensitive: this is an assignment to automatic `$HOME`, whose measured options were **ReadOnly, AllScope**. A separate language-only reproduction returned **VariableNotWritable**. The original catch deliberately omitted exception detail...\n...\n 6866|\n*6867|### IR-131 — a live-agent signing environment leaks into the provisioning process and correctly refuses before the private signer exists\n 6868|\n 6869|- **Status:** OPEN, rig invocation-environment defect, not a candidate or disk defect. Measured by hertz on 2026-09-14; classified by doyle in `VGCTKD7A`.\n 6870|- **Instance.** Second fresh #297 preparation admitted fourteen native leaves at `04:51:39.245Z`. The separate provisioning call launched at `04:51:52.802Z` and returned `STAGING_FAILED_PREFLIGHT`, native exit **1**, after **0.45 s**. No rig, private directory, key or field nonce existed. This was a preflight refusal before the `04:59:31Z` deadline, not a stalled launch.\n...\n 6877|\n*6878|### IR-132 — requiring every live-fleet `spt.exe` image path to be readable permanently refuses an isolated rig's admission\n 6879|\n 6880|- **Status:** OPEN, rig-instrument admission defect, not a candidate, environment-scrub or disk defect. Measured by hertz and independently localized by doyle on 2026-09-14; correction ruled in `W8TQ3MZC`, `6IQ4HYIL`, `QKQC2NET` and `MRQX7XEK`.\n 6881|- **Instance.** Third preparation passed fourteen native admission leaves and genuinely staged the signed set. Promotion then returned `PROMOTION_ADMISSION_FAILED`, native **1**, with `native_records=[]` and shutdown `NOT_STARTED`. Its census required a nonblank CIM `ExecutablePath` for **every** `spt.exe`, not merely one that could belong to the new rig. The read-only predicate replay passed twenty-five preceding statements and failed `SPT_PROCESS_PATH_UNREADABLE` at line 273. No apply, daemon, field no...\n...\n 6888|\n*6889|### IR-133 — a live capture cannot be read with read-only sharing, and daemon stderr belongs to the owned home\n 6890|\n 6891|- **Status:** Corrected in the r9 rig instrument; genuine fifth-window promotion completed with exit **0**, owned shutdown and final provenance. The subsequent field attempt failed its separate setup-handoff deadline, not this promotion read. Fourth #297 preparation measured by hertz on 2026-09-14; sharing failure localized by doyle in `R2VK8FQN`, run-identity binding ruled in `ANR522S5`, successor accepted in `GV3R6QUV`.\n 6892|- **Instance.** Fourteen admission leaves and genuine staging passed. The candidate applied daemonlessly, transitioned `applied-pending` → `applied`, brought up broker **14704** and brain **45220**, published the pinned generation-zero readiness record and emitted `BRAIN_PROMOTED` before the instrument stopped its owned job. The instrument returned only `OWNED_PROMOTION_READINESS_FAILED`. Six provisioning/promotion native jobs ended `CONFIRMED_GONE`, active counts zero; all nineteen signing-private fil...\n...\n 6900|\n*6901|### IR-134 — request latency consumes the elevated capture's execution budget, then a late terminal receipt leaves completed work unmeasured\n 6902|\n 6903|- **Status:** Instrument correction qualified without a sixth field window. Doyle accepted the execution-clock repair in principle under `HHDKCRH5`, then identified its still-insufficient receipt budget; the derived-window successor follows ruling `P9RLK4VU` and accepted arithmetic `KZG4IN37`. Candidate/packet/nonce/driver/runner repinning remains one future amendment, separate from field authorization. Fifth #297 field run `20260914T063552Z` remains failed and immutable. Its candidate's independent **PR...\n 6904|- **Measured sequence.** Setup request `06:41:26Z`, elevated setup `06:43:18Z`–`06:43:24Z`, refused capture launcher `06:43:25Z`–`06:43:26Z`, receipt about `06:43:27Z`. The driver had written the capture deadline from request time: 112 seconds of handoff delay left the launcher's `deadline - now - 5` allocation at **−4 seconds**. No native t1 capture ran. The handoff expired before the receipt; cleanup reread its nonce and exit but retained the earlier `timestamp_order=UNMEASURED`, withholding muta...\n...\n 6913|\n*6914|### IR-135 — checker pin and runner installation can disagree, and the repair path disguises that version mismatch as an authentication failure\n 6915|\n 6916|- **Status:** CI precheck remedy implemented in the IR-135 lane; workflow execution awaits integration. Measured by doyle in S4 golden `34946493637`, 2026-09-15; filed by hertz from `3HHHPWCR`. The immediate box mismatch was repaired by hand-install.\n 6917|- **Instance and mechanism.** The #304 candidate carried `71caedd4`, setting `WANT=0.4.1` in `golden.yml`/`ci.yml`, while kitsubito's `~/.local/bin/traceable-reqs` was **0.2.0**. The install step's mismatch path attempted a private clone without a provisioned `TRACEABLE_REQS_TOKEN` and exited **128 before any check**. The visible failure named authentication, not the wanted and installed versions. A checked-in pin is not evidence that the runner can supply it; the fallback requires a second, independentl...\n...\n 6920|\n*6921|### IR-136 — a broker bound under the seed socket's name is not seed control, so a URL-minting rig can omit the very listener contract the product queries\n 6922|\n 6923|- **Status:** Instance fixed in S5 **`ddd7fc7f070667524578c282894dd44a2e36062f`**, test-only atop S4; S5 golden34957614641 passed, including both twohost roles. Shared fixture-composition remedy implemented and Linux-verified in the IR-136 lane. Origin: doyle's S4 golden `34946493637` twohost helper red, 2026-09-15.\n 6924|- **Mechanism.** Role B hosted broker IPC under an invented name, with neither `seedmap::serve_seed_control` nor a docs listener. `REQ-WEB-URL-BOUND-PORT` requires `serve_for` to ask the canonical seed-control plane for `DocsStatus` before publishing a URL; the missing plane returned `DOCS_PORT_DISCOVERY_FAILED: Connection refused (os error 111)`. Merely renaming a Broker to `seed_socket_name()` does not provide that protocol: `serve_request` is dispatched by seed control, not Broker. The docs-server fix...\n...\n 6931|\n*6932|### IR-137 — a redirected Start-Process child can share the tool call's console lifetime and die when that call returns\n 6933|\n 6934|- **Status:** RETIRED, 2026-09-15, doyle ruling `YPLFG3CG`: **no tracked callsite; discipline recorded + receipt**. This closes a Windows ad-hoc rig-craft item, not a CI or candidate defect; no helper or product change.\n 6935|- **Mechanism and rule.** `Start-Process` with redirected output from a PowerShell tool call was observed to end with **`STATUS_CONTROL_C_EXIT`** when the tool call ended: a returned child PID did not establish detachment. The reported detached form uses a **hidden window without redirects**. Where a child must outlive the call, qualify its survival after the caller returns and give it a durable output path of its own; do not treat process creation or a hidden window alone as lifetime evidence."}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md","searchPath":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core","matchCount":67,"fileCount":1,"files":[".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md"],"fileMatches":[{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md","count":67}],"truncated":false,"displayContent":" 3887│\n*3888│### IR-71 — controller-seat release has no persisted breadcrumb, so tests cannot distinguish propagation lag from a missing detach\n 3889│\n 3890│- **Status:** OPEN, observability gap; no remedy scheduled. · **Origin:** CONDUIT #236 r3\n 3891│  `er_brief_once_per_session_e2e` intermittent, classified test-side and fixed on PR #174.\n     │...\n 3911│\n*3912│### IR-72 — no product read verb surfaces which process holds a perch or controller seat\n 3913│\n 3914│- **Status:** OPEN, observability gap; no remedy scheduled. · **Origin:** CONDUIT #236 r3\n 3915│  two-host RCA and PR #174 (`70c1a303`), corrected by doyle after IR-18 and daemon-status were\n     │...\n 3945│\n*3946│### IR-73 — ci.yml and release.yml still read the free-space floor PRE-checkout (literal-first sites off the golden path); and any job's floor is stale by its last heavy step\n 3947│\n 3948│- **Status:** CLOSED / BUILT — source reconciliation 2026-09-11 at `e5a2fed9`: all five\n 3949│  `ci.yml` sites and all three `release.yml` sites now read after checkout, with IR-73 comments;\n     │...\n 3969│\n*3970│### IR-74 — kitsubito holds 21,643 /tmp endpoint homes: box-side accumulation nothing bounds or measures\n 3971│\n 3972│- **Status:** OPEN, filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep; measurement by\n 3973│  hertz (2026-08-29). · **Origin:** rig work on kitsubito found `/tmp` carrying 21,643 endpoint\n     │...\n 3983│\n*3984│### IR-75 — traceable-reqs is not installed on kitsubito, so every Linux gate driver's treqs leg exits 127 (vacuous, wrapper-green shape)\n 3985│\n 3986│- **Status:** OPEN, filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep (deployah\n 3987│  co-flagged at intake). · **Origin:** ASM-241 Linux battery — `ASM_treqs.exit` = 127, raw\n     │...\n 3998│\n*3999│### IR-76 — hfenduleam is the golden Windows runner AND the builders' box: a local workspace nextest fully contained a golden Phase A and manufactured a load-timing red, and the job-start census cannot see it\n 4000│\n 4001│- **Status:** OPEN, filed by doyle 2026-09-06 during v0.67.1 golden triage (run 34017906638\n 4002│  att2). · **Origin:** the Windows Phase A red on\n     │...\n 4042│\n*4043│### IR-77 — nothing stamps the interval between a daemon child's spawn and the brain's first log line, so a readiness-deadline red cannot say WHERE the time went\n 4044│\n 4045│- **Status:** OPEN, filed by hertz 2026-09-07 from the W1 #249 kitsubito battery at the gated\n 4046│  sha `8d980fdf`; doyle-ruled at filing to be a register entry rather than a lane rider. ·\n     │...\n 4074│\n*4075│### IR-78 — `SPT_TEST_EPHEMERAL_ADVISORY_PORTS` silently overrides an explicitly set `SPT_DOCS_PORT`\n 4076│\n 4077│- **Status:** OPEN, filed by hertz 2026-09-07, MEASURED by doyle the same night on his W2\n 4078│  field pair (both boxes). · **Origin:** the 5474 rig-hygiene sweep in\n     │...\n 4102│\n*4103│### IR-79 — 22 of the 31 rig binaries leak their daemon tree on a failing assert: teardown is a statement, not a guard\n 4104│\n 4105│- **Status:** OPEN, filed by hertz 2026-09-07 on doyle's dispatch during PR #198's CI window,\n 4106│  from todlando's red 6 (a stale same-port daemon from his own previous run answering the next\n     │...\n 4183│\n*4184│### IR-80 — five leaky cells on ONE module (`brainproc` / `supervise_brain`), Windows only: a candidate PRODUCT leak on the promotion/rollback path, or a cluster of names — nobody has looked yet\n 4185│\n 4186│- **Status:** OPEN for the residual population, not an undiagnosed five-name product claim.\n 4187│  Later amendments identify the brainproc shell-wrapper fixture mechanism and distinguish\n     │...\n 4465│\n*4466│### IR-81 — a process kill can be written scoped or machine-wide, and nothing makes the scoped form the only reachable one: both codebases carry the right pattern beside the wrong one\n 4467│\n 4468│- **Status:** OPEN, drafted by hertz 2026-09-07 08:38Z on doyle's dispatch (08:36Z), from the\n 4469│  fleet-daemon death on hfenduleam at 08:03:15Z ([[RCA-FLEET-DAEMON-14444]], cause still UNNAMED).\n     │...\n 4590│\n*4591│### IR-82 — a daemon death leaves NO record of who died: autostart decides on a socket ping, says \"no daemon\", and the successor overwrites the only handle on the corpse\n 4592│\n 4593│- **Status:** RULED 2026-09-07 11:07Z (doyle), drafted by hertz 11:04Z on doyle's dispatch (11:03Z: *\"the autostart\n 4594│  death-cause item is an IR, not a board item — mint it IR-82 in your thin PR\"*). Register on main\n     │...\n 4696│\n*4697│### IR-83 — a two-host rig addressed over the tailnet cannot receive INBOUND on Windows, and the whole rig population had only ever run the admitted direction\n 4698│\n 4699│- **Status:** OPEN, minted by hertz 2026-09-07 11:41Z on doyle's dispatch (11:40Z). **Provenance: the\n 4700│  mechanism below is DOYLE'S measurement, not mine** — eight probe arms, each with sender, listener\n     │...\n 4833│\n*4834│### IR-84 — the one `PUMP_PEER_FAIL` arm the rigs actually fire was the only one carrying no clock, so the stall that produced it could be counted but never timed\n 4835│\n 4836│- **Status:** OPEN, filed by hertz 2026-09-09 with the instrument that closes its first half. ·\n 4837│  **Origin:** the 65 s two-host helper stall (design written before the run,\n     │...\n 4883│  stamps, so the fifth site added cannot be born silent.\n*4884│### IR-85 — the Windows self-hosted box runs its fs-heavy tests 3-4x slower than a week ago; two CI wall clocks were sized for the old box, and a red run kept hiding it\n 4885│\n 4886│- **Status:** OPEN, filed by hertz 2026-09-09 at the #272/v0.68.0 golden r3/r4 arc, on doyle's\n 4887│  dispatch. Number ruled by doyle from his own census of main@`a2f335f8` (register ended at IR-83;\n     │...\n 5043│\n*5044│### IR-86 — golden's 32 GiB floor is BELOW the measured 67.4 GiB Windows suite footprint, so a start floor passes a box that cannot finish\n 5045│\n 5046│- **Status:** OPEN, filed by doyle 2026-09-08 at the #272/v0.68.0 golden r2 triage. · **Origin:**\n 5047│  run 34262154550 @ `25e60015` (shaped on `e4444413`), Windows test job 102182665033: every product\n     │...\n 5092│\n*5093│### IR-87 — two-host ceremony halves are INDEPENDENT jobs on DIFFERENT runners (A Windows/hfenduleam, B Linux/kitsubito); B's 900 s budget runs on B's own clock, so any older queued Windows job starves A and reds B deterministically, and the panic text blames pairing\n 5094│\n 5095│- **Status:** OPEN, filed by doyle 2026-09-08 at the #272 golden r2 triage. · **Origin:**\n 5096│  run 34262154550, twohost-b job 102207296960 (log 81,692 B, sha256 67403f04…8030): role B built,\n     │...\n 5145│\n*5146│### IR-88 — `pool-release` via `cargo run -p xtask` REBUILDS xtask INTO the pool it is releasing, so a reaped pool regrows ~2.8 GB in silence\n 5147│\n 5148│- **Status:** OPEN, filed by doyle 2026-09-08 from hertz's reap report (20:00Z) during the #272\n 5149│  golden r2 repair. · **Origin:** hertz reaped hertz-lane4 / hertz-repin / hertz-percell-id target\n     │...\n 5182│\n*5183│### IR-89 — hfenduleam's Windows Firewall drops cold inbound UDP to the runner-built test exes, so the two-host rig's first B→A claim (W2 helper) reds for its whole 900 s budget and the panic blames A\n 5184│\n 5185│- **Status:** BOX HALF **APPLIED** 2026-09-08; WORKFLOW HALF **BUILT** 2026-09-09 — PR #211\n 5186│  (`9b96d7e7` + this amendment), **LANDED, exact golden-step acceptance unreconciled**.\n     │...\n 5338│\n*5339│### IR-90 — a full disk on the self-hosted box reds a rig as a PRODUCT refusal, not a build error, and no rig or gate records the free space that would falsify it\n 5340│\n 5341│- **Status:** OPEN, filed by hertz 2026-09-09 from the disk-full incident on hfenduleam. ·\n 5342│  **Origin:** the IR-85 discriminator lane's head arm, killed by the volume rather than by the code\n     │...\n 5427│\n*5428│### IR-91 — 561 untracked files sat at the repo root, 18 of them cited by tracked files, and the census that classified them used a corpus that made the discriminator invisible\n 5429│\n 5430│- **Status:** CLOSED by the lane that filed it (the root-scratch classify PR), hertz 2026-09-09 on\n 5431│  doyle's census and rulings. · **Origin:** the `.spt/` ignore lane (PR #212) named 561 untracked\n     │...\n 5481│\n*5482│### IR-92 — the message that WAKES an idle spt-hosted endpoint rides a delivery leg that never publishes MSG_IN, so a woken agent's own funnel holds none of the messages that woke it\n 5483│\n 5484│- **Status:** OPEN — filed doyle 2026-09-09 from hertz's census, probe and proposed text (his by\n 5485│  role; the recorder read and the REQ reading are doyle's). Fix lane unassigned: product change in\n     │...\n 5613│\n*5614│### IR-93 — no PDB ships beside the installed `spt` binary, so the one non-invasive read of a wedged production daemon comes back without a single named frame\n 5615│\n 5616│- **Status:** OPEN, filed by doyle 2026-09-10. **The number was reserved by NAME on 2026-09-09** at\n 5617│  the #293 mechanism read (\"PDB ask -> IR-93 at next sweep\") and this entry closes that claim — a\n     │...\n 5642│\n*5643│### IR-94 — xtask's brainread deadline gate cannot SEE `serve_sync`: its registry is three hand-listed files and its predicate is a name shape, so a stream server outside both got the reply form and the gate stayed green\n 5644│\n 5645│- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 / v0.69.0 golden RED triage. **This\n 5646│  is an INDEPENDENT gate finding, not the cause of that red** — it was found while reading the\n     │...\n 5672│\n*5673│### IR-95 — a burned polling budget names WHAT it wanted and never HOW LONG it waited, so no run, green or red, can say how close it came\n 5674│\n 5675│- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 golden RED, where it cost this\n 5676│  triage most of a morning and four agents. · **Origin:** the two Windows Phase A failures at\n     │...\n 5927│\n*5928│### IR-96 — the `daemon_stop_convoy_e2e` API-storm cell fails 3-of-3 under the HEAVY suite at the diagnostic tree while passing at the candidate in golden CI, and nothing yet separates instrumentation from box from product\n 5929│\n 5930│- **Status:** OPEN, **cause-unclassified** (todlando's and hertz's stipulation, adopted verbatim — a\n 5931│  triage placement here is NOT a finding of non-defect).\n     │...\n 5963│\n*5964│### IR-97 — a suite that leaks a fixed cohort of child processes per invocation makes consecutive runs non-comparable, and the between-run accounting the protocol required was not enforced\n 5965│\n 5966│- **Status:** OPEN. **Protocol deviation** (hertz's framing, and it is stronger than \"confounder\":\n 5967│  the protocol ALREADY required between-run accounting — execution did not enforce it, so the fix is\n     │...\n 6006│\n*6007│### IR-98 — a lane driver that PRINTS a producer's output can die on an unencodable byte AFTER that producer's evidence is on disk, so the run ends with complete evidence for producer N and NO files for N+1 — an absence that reads as \"never queued\", not as a failure\n 6008│\n 6009│- **Status:** OPEN as a mechanism; the measured instance is FIXED in hertz's lane driver (UTF-8 with\n 6010│  replacement reconfigured at import, positive control run before relaunch: U+2500 and U+2713\n     │...\n 6030│\n*6031│### IR-99 — EOF and terminal retire on a ConnectionBound net stream arm on the OPENER CONN's exit; a same-morning diagnosis built on that mechanism was refuted by the compiler, so the mechanism stands and the two #304 reds beside it stay open\n 6032│\n 6033│- **Status:** OPEN. The mechanism is VERIFIED; both reds are CLASSIFIED NOT-product (instance 1: an\n 6034│  unpromised spectator EOF; instance 2: a journal replay of a reused op seq) — repairs built at\n     │...\n 6109│\n*6110│### IR-100 — an editor-driven rust-analyzer runs `cargo check --workspace --all-targets` into a LANE's pool on its own schedule, so a builder census counts it, a lock wait charges it to nobody, and the lane's disk growth carries it uncredited\n 6111│\n 6112│- **Status:** OPEN. Recorded 2026-09-11 09:30Z from todlando's trace; no mitigation applied.\n 6113│- **Instance (todlando, `.worktrees/304-product`, 09:29Z):** his distinct-seq build printed\n     │...\n 6169│\n*6170│### IR-101 — no per-lane producer compiles a lib crate's own `#[cfg(test)]` module on the branch that broke it, so a stale caller of a lane's own signature change rides green through six real-daemon runs and surfaces only at assembly, or from an editor\n 6171│\n 6172│- **Status:** OPEN. Rule adopted 2026-09-11 09:35Z; instrument = one command at inventory and one at\n 6173│  assembly.\n     │...\n 6234│\n*6235│### IR-102 — a dirty file the lane DECLARED is still invisible to an assignment made against its committed blob, so the gater measures and predicts on a blob the lane was never going to run\n 6236│\n 6237│- **Status:** OPEN. Recorded 2026-09-11 09:50Z from hertz's correction; ruling applied (commit all\n 6238│  five), no instrument yet.\n     │...\n 6267│\n*6268│### IR-103 — a rig that re-enters something already retired reads as a product red: four instances in ONE cell (#230), each masking the next\n 6269│\n 6270│- **Status:** OPEN. Recorded 2026-09-11 10:00Z (doyle). Amended 10:20Z: the third instance's repair\n 6271│  RAN (todlando window 10:12-10:18Z, one attempt) and its structural falsifiers all HELD — distinct\n     │...\n 6337│\n*6338│### IR-104 — checker 0.4.0 silently skips a FILE scan root under git enumeration: 81 doc stages read as missing, and a local 0.2.0 green hid it because the two versions disagree on what is evidence\n 6339│\n 6340│- **Status:** FIXED UPSTREAM 2026-09-11 (traceable-reqs v0.4.1, PR #21 -> d9af11d, red-first cells);\n 6341│  spt-core consumes via hertz's #304 lane pin fixup. Closes when that pin is on main.\n     │...\n 6366│\n*6367│### IR-105 — an assertion derived from a MODEL of the fixture instead of read off the fixture can only be refuted by a run, and the lane convention that defers the run gives the class a one-window latency: the repair for the first instance carried the second\n 6368│\n 6369│- **Status:** OPEN. Rule adopted 2026-09-11 (hertz, W1 close). Instrument = read the line, and read\n 6370│  what the line LANDS on, before asserting either.\n     │...\n 6418│\n*6419│### IR-106 — a red set HANDED OVER in a message was reported as a POPULATION: both members verified, their lines and modes corrected, and the count still wrong by half\n 6420│\n 6421│- **Status:** OPEN as a discipline line; the instance is closed (the run that refuted it is on file).\n 6422│  Author and subject: todlando. Filed by doyle 2026-09-11 11:20Z from todlando's text; IR-105 lands\n     │...\n 6449│\n*6450│### IR-107 — a rig that redirects TMP INSIDE the checkout puts every tempdir fixture under a git toplevel, and cells whose premise is \"outside any repo\" resolve THIS repo's remote\n 6451│\n 6452│- **Status:** RIG FIXED in hertz's lane (base now under `AppData/Local/Temp/hertz-304-rig/<label>`;\n 6453│  `HERTZ_RIG_TMP_IN_REPO=1` restores the old placement on purpose as the negative control). Recorded\n     │...\n 6544│\n*6545│### IR-108 — four brainproc unit cells leak a process on every run; two others leak by ordering\n 6546│\n 6547│- **Status:** OPEN, product-side backlog candidate (not #304's). Recorded 2026-09-11 11:35Z (doyle)\n 6548│  from three unfiltered `spt-daemon --lib` runs on identical bytes on HFENDULEAM (todlando 10:52Z at\n     │...\n 6566│\n*6567│### IR-109 — a manifest `[placement] module_banner = \"accept\"` block LOOSENS the local checker to zero; CI's pinned checker is structurally blind to placement, so the loosening is invisible until the pin moves\n 6568│\n 6569│- **Status:** OPEN, RATIFIED 12:33Z (doyle, releases#304) as a TRANSITIONAL policy for the #304 head: the 0.4.1 pin stays (a tightening for every new tag), the accept key exempts only the 312 legacy banner tags, and this entry is the retirement ticket. Recorded 2026-09-11 12:10Z (doyle) from hertz's A/B/C and 0.2.0 arms; the commit's \"agreed\" is corrected by the ruling, not by rewriting a measured sha.\n 6570│- **Instance.** 33936943 \"chore(traceability): enable agreed placement policy\" (07:38Z, trailer todlando, on\n     │...\n 6588│\n*6589│### IR-110 — the gater ruled a wave from origin/main's manifest while the milestone's own product lane already carried the surface; a second implementation was built to its W-1 END before the first was noticed\n 6590│\n 6591│- **Status:** OPEN, STOP LINE on #304 W2 (comment 5634187958). Recorded 2026-09-11 12:10Z (doyle, own instance).\n 6592│- **Instance.** feat/304-remote-friction-product @3e7eaf67 implements #297 TCP admission under\n     │...\n 6617│\n*6618│### IR-111 — the installed product's own inbound UDP rule reads Duplicate / Inactive in ActiveStore, shadowed by the fallback rule; a by-name probe reads it green\n 6619│\n 6620│- **Status:** OPEN, product-side backlog candidate (REQ-INBOUND-WINDOWS-RULE-BINDER-PATH-MATCH family). Recorded\n 6621│  2026-09-11 12:14Z (doyle) from an unelevated `Get-NetFirewallRule` read of both stores on HFENDULEAM.\n     │...\n 6639│\n*6640│### IR-112 — bare `cargo test -p spt-daemon --lib` reds two process-global cells on Linux at a sha where nextest is green; libtest is not a sound gate for this crate\n 6641│\n 6642│- **Status:** OPEN, rig rule (CI unaffected: `ci.yml` runs `kind(lib)` under nextest). Recorded 2026-09-11 12:46Z\n 6643│  (doyle) from hertz's Linux cells lane END on kitsubito.\n     │...\n 6659│\n*6660│### IR-113 — a killed mutation arm does not unwind: the subject stays mutated and the NEXT arm measures a tree nobody declared; and a mutation that reds on a compile error is a void arm that \"it compiled\" cannot detect\n 6661│\n 6662│- **Status:** OPEN, rig rule for every mutation driver. Recorded 2026-09-11 13:05Z (doyle) from todlando's FOLD-1b\n 6663│  window (fold/304-w2-admission, windows.rs).\n     │...\n 6681│\n*6682│### IR-114 — three hands wrote one firewall rule set inside ninety seconds under two directors; every census was true at its instant and false a minute later\n 6683│\n 6684│- **Status:** OPEN, procedure ruled 2026-09-12 00:50Z (doyle) on todlando's reconciliation; recorded 00:52Z.\n 6685│- **Instance.** #304 W-2a arms on HFENDULEAM: ~00:44Z todlando asked the operator to delete spt-w2a-C so B would stand alone; ~00:45Z the operator said \"C down\" and todlando's census read B present / C absent (true then); 00:45:05Z liam ADDED C at doyle's direction (doyle had been idle 11 h and did not know the operator's window); 00:46:14Z liam DELETED B at doyle's direction; 00:49:09Z todlando re-measured C present / B absent. Nobody was wrong; the population was not stable. Every fetch todlando report...\n     │...\n 6690│\n*6691│### IR-115 — a firewall census whose port test is DENIED reads every rule as port=Any and counts port-scoped rules as blanket; a `netsh show rule` without `verbose` omits Program and reads every rule as program=Any; a control count that merges two agents' reads is nobody's control\n 6692│\n 6693│- **Status:** OPEN, mechanisms recorded 2026-09-12 01:14Z (doyle) from todlando's and liam's own corrections during #304 arm E.\n 6694│- **Instances.** (1) todlando's first census A (\"26 blanket rules\") and B (\"occupied LocalPort set: EMPTY\"): `Get-NetFirewallPortFilter -All` returns \"Access is denied\" unelevated, the probe swallowed the denial, every rule read as port=Any, and B's positive control (the hand rule carries LocalPort 5470) is what caught it. (2) His replacement pass: `netsh advfirewall firewall show rule name=all` without `verbose` prints no Program line, so it reported 417 blankets and ZERO rules naming spt.exe — provab...\n     │...\n 6700│\n*6701│### IR-116 — a watchdog that calls a killer and then echoes success reports a kill it never made; `pkill` is absent in msys, so the guard logged \"stopped\" while the arm it guarded ran on\n 6702│\n 6703│- **Status:** OPEN, mechanism recorded 2026-09-12 01:24Z (todlando) from his own guard during #304 FOLD-2's Windows arm at 7357ea32; doyle asked for the line.\n 6704│- **Instance.** todlando armed a watchdog to stop a test arm before it reached `cargo test --workspace --lib`, because spt-daemon lib tests deadlock on a live host. Shape: `if grep -q \"CLIPPY_EXIT=\" log; then pkill -f \"bash /tmp/arms.sh\" 2>/dev/null; echo \"GUARD: arms.sh stopped after clippy at $(date -u)\"`. It printed `GUARD: arms.sh stopped after clippy at 01:24:06Z`. Nothing was stopped: `pkill` does not exist in this msys/Git-Bash environment (`command not found`, exit 127), `2>/dev/null` ate the mes...\n     │...\n 6711│\n*6712│### IR-117 — a predicate that cannot fail: pre-registered outcomes whose branches are not mutually exclusive, and a requirement titled with the TASK instead of the INVARIANT\n 6713│\n 6714│- **Status:** OPEN, mechanism recorded 2026-09-12 03:48Z (hertz, both instances his own; doyle ruled the second).\n 6715│- **Instance 1 — the outcome set.** For the #304 W-2 packet capture hertz pre-registered four outcomes, of which (a) was \"SYN retransmission despite the RST\" and (b) was \"above the wire in the Windows client path\". The capture showed five SYNs at a flat ~511 ms, each RST'd in 18-25 us and each ignored — which is (a)'s packet shape with (b)'s locus. The two branches were the same answer told at two altitudes, so EITHER could have been declared \"confirmed\" and neither could have been refuted by the act...\n     │...\n 6720│\n*6721│### IR-118 — an instrument read mid-flight, or through a filter that cannot match, returns a COMPLETE-LOOKING wrong answer with no error\n 6722│\n 6723│- **Status:** OPEN, two instances one hour apart, 2026-09-12 (hertz); doyle asked for the filter line beside IR-117.\n 6724│- **Instance 1 — the capture read in flight, and it would have inverted the verdict.** `tcpdump -w /tmp/hz-cap.pcap` was still running when the packets were wanted. The file was **8192 bytes** live and **11933 bytes** after `kill -TERM` flushed it; the 3741-byte tail WAS the four SYN retransmissions. Reading the live file would have yielded a well-formed pcap showing one SYN and one prompt RST — i.e. the pre-registered outcome (b), the WRONG answer, assembled entirely from the RIGHT answer's own evid...\n     │...\n 6729│\n*6730│### IR-119 — a control that only had to prove a ROUTE served a real directory; and a rig is not torn down until its last process is gone, whatever the analysis says\n 6731│\n 6732│- **Status:** OPEN, mechanisms recorded 2026-09-12 05:46Z (doyle) from hertz's unprompted self-disclosure. The security remedy is an OPERATOR item, filed on releases#304 comment **5643876746** (rotate the kitsubito self-hosted runner's registration credential); this entry carries only the reusable mechanisms.\n 6733│- **Instance.** The accepted-connection control for the W-2 packet capture was `python3 -m http.server 29472 --bind 0.0.0.0` with **cwd `/home/reavus`** — the self-hosted runner account's home — for **1 h 59 m 54 s**. The off-box bind was REQUIRED (the peer dialled from another machine); the working directory was the whole defect. An empty temp dir returns the identical HTTP 200 and proves exactly as much. `http.server` builds its index from `os.listdir` and filters nothing, so 20 dotfiles including ...\n     │...\n 6740│\n*6741│### IR-120 — a claim named for the one axis nobody varied: six readings over two routes and two libraries, all on ONE box, reported as a property of the platform\n 6742│\n 6743│- **Status:** OPEN, mechanism recorded 2026-09-12 05:47Z (doyle); the instance is liam's, refuted by hertz's own arm and conceded by its author.\n 6744│- **Instance.** The ~2.05 s Windows refused-connect latency was filed as \"the WINDOWS refusal latency\" on six readings that varied ROUTE (loopback, LAN hop to Linux) and LIBRARY (curl, .NET TcpClient) and held HOST constant — every one on HFENDULEAM. Route- and library-independence were measured; \"Windows\" was the name of the box. A per-host WFP callout, endpoint agent or filter driver swallowing RSTs would have produced exactly those six readings on exactly those two routes and generalised nothing. Se...\n     │...\n 6750│\n*6751│### IR-121 — one declaration command expands every right-hand side before assigning any name, so a dependent id silently binds the CALLER'S GLOBAL and two arms collapse onto one artifact path; and `cat -A` behind msys `sed` is not a byte reader\n 6752│\n 6753│- **Status:** OPEN, mechanisms recorded 2026-09-12 09:05Z. Instance 1 found by hertz in todlando's driver and confirmed by doyle; repaired as a separately pinned revision (v6 `dcfb732a…` → v7 `927eafb9…`) per the standing rule that a demonstrated execution incompatibility gets a new hash and renewed verification rather than an in-place accommodation. Instance 2 is todlando's own, found while reading the repair site.\n 6754│- **Instance 1 — the id that looked right.** `trial()` opened with `local arm=\"$1\" n=\"$2\" id=\"$arm-$n\"`. A single declaration command expands EVERY right-hand side before assigning any of its names, so `$arm` was still unset when `id` was built — but `$n` was **not** empty, because the caller is `for n in 1 2 3; do trial a \"$n\"; done` and `n` is a GLOBAL at that point. The id therefore read `-1`, not the empty-ish `-` that would have been noticed: a plausible, consistently-formed, wrong identity. Bot...\n     │...\n 6768│\n*6769│### IR-122 — the field rig's isolated-daemon stop cannot run from an spt-hosted session, so every run leaves a live daemon holding the subject exe inside the pool it just released\n 6770│\n 6771│- **Status:** OPEN, recurring. Instance 1 attempt 2 (`rig/arm2-driver-stdout.txt`: `RIG_DAEMON_STOP_REFUSED_OR_ERRORED — reported, not forced`). Instance 2 run `20260912T231404Z` under frozen r10 (`rig_daemon_stop_EXIT=3`, `cleanup-failures.txt`, `rig-daemon-stop.err`). Recorded by hertz 2026-09-12 23:50Z at doyle's direction; **this is a RIG defect, and any product-surface change requires a separate contract review.**\n 6772│- **The refusal.** `DAEMON_STOP_REFUSED: a broker-stopping command is never run by an spt endpoint ($OWL_SESSION_ID is set). ... No flag overrides this, --force included.` The guard keys on the CALLER'S SESSION ENV, so it fires identically no matter which rig step reaches it and no matter what `SPT_HOME` the command targets.\n     │...\n 6781│\n*6782│### IR-123 — a helper that LOGS cannot also RETURN through stdout: `record` tees, so `face=$(face_report ...)` captures the log block and the acceptance gate can never pass\n 6783│\n 6784│- **Status:** OPEN, mechanism recorded 2026-09-13 (hertz, found by exercising the D2 successor; confirmed by doyle from a direct source read of frozen r10). **Frozen r10 is PRESERVED as-is**; the return channel is corrected in its successor only.\n 6785│- **Instance.** `record()` is `echo \"$1\" | tee -a \"$R/findings.txt\"` — it writes to the log AND to stdout, deliberately, so a live operator sees the run. `face_report()` calls `record` twice (a FACE_COUNTS line and a FACE= line) and then `echo`es the face as its return value. The single caller reads it as `setup_face=$(face_report \"$SETUP_OUT\" \"$SETUP_ERR\" \"SETUP\" bootstrap)`, so the captured value is **the whole tee'd log block with the face appended**, and `[ \"$setup_face\" != reconciled ]` is true no...\n     │...\n 6793│\n*6794│### IR-124 — a cleanup that runs `serve lan --stop` UNCONDITIONALLY creates the daemon it exists to remove, when the setup it is cleaning up after never ran\n 6795│\n 6796│- **Status:** OPEN, measured once in the field. D2 field run `20260913T041410Z`, driver `2e3aec1b`, recorded by hertz 2026-09-13 at doyle's direction. Archive `.spt/preserved/hertz-fp-driver-review/d2/field-run-20260913T041410Z/` (72 files, manifest `defa5d29…`). **This is a RIG defect. It is mine — I wrote the driver — and doyle's admission review missed the unconditional stop path as well; both are recorded because a review that misses a path is part of the mechanism, not an aside.**\n 6797│- **Instance.** The elevated setup was **DECLINED and NOT STARTED** by liam at 04:18:55Z — measured, unambiguous, and the right call: his leg was ready at 04:18:35Z against a hard 04:19:10Z expiry and he refused rather than race the teardown. Nothing ran, nothing mutated. The driver then entered cleanup and executed its own unconditional `env SPT_INSTALL_NO_FIREWALL=1 SPT_HOME=<isolated-home> <exe> serve lan --stop`, which dispatched through the daemon (`ensure_running`, `serveverb.rs:191`) and **CREAT...\n     │...\n 6805│\n*6806│### IR-125 — the driver's own executable sweep reported ZERO processes on the pinned exe while `Win32_Process` showed TWO, at the same instant\n 6807│\n 6808│- **Status:** OPEN, measured in D2 field run `20260913T041410Z` (hertz, 2026-09-13). **A FALSE-NEGATIVE SWEEP, not a false CLEAR** (doyle's classification, and the distinction is load-bearing): the ledger's actual verdict was `residual_state=UNREADABLE` / `CLEANUP=PENDING`, which was correct, and the sweep line is explicitly labelled evidence-only in the driver's own output.\n 6809│- **Instance.** `SUBJECT_EXE_PROBE=OK running_the_pinned_executable=0 enum_total=618` — the probe enumerated 618 processes and concluded none was running the pinned executable. A `Win32_Process` read moments later returned **two**, both with `ExecutablePath` exactly `…\\.worktrees\\304-w2-repr\\target\\release\\spt.exe`: PIDs 45944 and 22524. An independent sweep by path, not by pid, agreed: `count=2`.\n     │...\n 6816│\n*6817│### IR-126 — the experimental budget CONTAINED its own read-only preflight, leaving 128 s of a 300 s window for the elevated leg, and the leg was correctly declined\n 6818│\n 6819│- **Status:** OPEN, measured in D2 field run `20260913T041410Z` (hertz, 2026-09-13). Boundary NOT moved for that run — doyle refused the change mid-flight and was right to; this entry is the scheduling review he asked to be preserved.\n 6820│- **Measured, from the run's own timestamps.** Run start `04:14:10Z` · pre-setup absence census `04:16:23Z` · handoff request written `04:17:02Z`. So **172 s of the 300 s experimental budget went to in-budget read-only preflight** — CI axis queried by name across five statuses, ancestry census, six-instrument hashing, subject identity, 5470 guard baseline, pre-setup absence census — and the driver printed the remainder itself: `HANDOFF_WAIT bounded to 128s`.\n     │...\n 6827│\n*6828│### IR-127 — a nested value-type assignment can leave the native job limit unset while the instrument logs the requested flag and a successful setter\n 6829│\n 6830│- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\n 6831│- **Instance.** The containment probe assigned `$info.BasicLimitInformation.LimitFlags = 0x2000`, logged the requested KILL_ON_JOB_CLOSE flag and `SetInformationJobObject=True`, read both owned processes as job members, closed the handle, and found both still alive. The nested field is a struct: PowerShell changed a copy, not the value subsequently marshalled. The offline discriminator measured `nested_assignment_flags=0`; modifying the nested value and assigning the whole value back measured `whole_valu...\n     │...\n 6836│\n*6837│### IR-128 — PowerShell `$null` can become an empty native string, so a failed launch is misread as a policy refusal before the policy is reached\n 6838│\n 6839│- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\n 6840│- **Instance.** Both breakaway probe arms called a P/Invoke string parameter with PowerShell `$null`; both returned `CreateProcess` error **123** and created no child. This is an invalid-name result, not the **5** required to establish breakaway-policy denial. An offline C# string-parameter discriminator returned `IsNull($null)=False`: the PowerShell binder had supplied an empty string rather than native NULL.\n     │...\n 6846│\n*6847│### IR-129 — JSON date materialization followed by implicit string parsing loses UTC kind and precision, turning a live creation anchor into a false pid-reuse verdict\n 6848│\n 6849│- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`. The first M8 exit 0 is explicitly INVALID.\n 6850│- **Instance.** `ConvertFrom-Json` materialized an ISO birth string as `DateTime`; `[DateTime]::Parse($id.created)` implicitly formatted that object back to text before parsing it. Kind and fractional precision were lost and local time was reinterpreted. The result printed birth timestamps agreeing within a microsecond but computed roughly seven-hour deltas, mislabelling four live registered identities `GONE_PID_REUSED`. The original output remains at `.spt/preserved/hertz-fp-driver-review/d2/controls-ou...\n     │...\n 6856│\n*6857│### IR-130 — a lowercase `$home` local collides with PowerShell's protected `$HOME`, refusing custody qualification before the signer is reached\n 6858│\n 6859│- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz on 2026-09-13 in the D2 custody lane; narrow correction and one fresh-root attempt authorized by doyle `5FWLC3F2`. Original refusal remains preserved.\n 6860│- **Instance.** The prepared custody controller passed syntax parsing and compiled its native observer successfully, then exited **1 after 3.33 s** before any custody arm. Its next statement assigned `$home = Join-Path $armRoot 'home'`. PowerShell variable names are case-insensitive: this is an assignment to automatic `$HOME`, whose measured options were **ReadOnly, AllScope**. A separate language-only reproduction returned **VariableNotWritable**. The original catch deliberately omitted exception detail...\n     │...\n 6866│\n*6867│### IR-131 — a live-agent signing environment leaks into the provisioning process and correctly refuses before the private signer exists\n 6868│\n 6869│- **Status:** OPEN, rig invocation-environment defect, not a candidate or disk defect. Measured by hertz on 2026-09-14; classified by doyle in `VGCTKD7A`.\n 6870│- **Instance.** Second fresh #297 preparation admitted fourteen native leaves at `04:51:39.245Z`. The separate provisioning call launched at `04:51:52.802Z` and returned `STAGING_FAILED_PREFLIGHT`, native exit **1**, after **0.45 s**. No rig, private directory, key or field nonce existed. This was a preflight refusal before the `04:59:31Z` deadline, not a stalled launch.\n     │...\n 6877│\n*6878│### IR-132 — requiring every live-fleet `spt.exe` image path to be readable permanently refuses an isolated rig's admission\n 6879│\n 6880│- **Status:** OPEN, rig-instrument admission defect, not a candidate, environment-scrub or disk defect. Measured by hertz and independently localized by doyle on 2026-09-14; correction ruled in `W8TQ3MZC`, `6IQ4HYIL`, `QKQC2NET` and `MRQX7XEK`.\n 6881│- **Instance.** Third preparation passed fourteen native admission leaves and genuinely staged the signed set. Promotion then returned `PROMOTION_ADMISSION_FAILED`, native **1**, with `native_records=[]` and shutdown `NOT_STARTED`. Its census required a nonblank CIM `ExecutablePath` for **every** `spt.exe`, not merely one that could belong to the new rig. The read-only predicate replay passed twenty-five preceding statements and failed `SPT_PROCESS_PATH_UNREADABLE` at line 273. No apply, daemon, field no...\n     │...\n 6888│\n*6889│### IR-133 — a live capture cannot be read with read-only sharing, and daemon stderr belongs to the owned home\n 6890│\n 6891│- **Status:** Corrected in the r9 rig instrument; genuine fifth-window promotion completed with exit **0**, owned shutdown and final provenance. The subsequent field attempt failed its separate setup-handoff deadline, not this promotion read. Fourth #297 preparation measured by hertz on 2026-09-14; sharing failure localized by doyle in `R2VK8FQN`, run-identity binding ruled in `ANR522S5`, successor accepted in `GV3R6QUV`.\n 6892│- **Instance.** Fourteen admission leaves and genuine staging passed. The candidate applied daemonlessly, transitioned `applied-pending` → `applied`, brought up broker **14704** and brain **45220**, published the pinned generation-zero readiness record and emitted `BRAIN_PROMOTED` before the instrument stopped its owned job. The instrument returned only `OWNED_PROMOTION_READINESS_FAILED`. Six provisioning/promotion native jobs ended `CONFIRMED_GONE`, active counts zero; all nineteen signing-private fil...\n     │...\n 6900│\n*6901│### IR-134 — request latency consumes the elevated capture's execution budget, then a late terminal receipt leaves completed work unmeasured\n 6902│\n 6903│- **Status:** Instrument correction qualified without a sixth field window. Doyle accepted the execution-clock repair in principle under `HHDKCRH5`, then identified its still-insufficient receipt budget; the derived-window successor follows ruling `P9RLK4VU` and accepted arithmetic `KZG4IN37`. Candidate/packet/nonce/driver/runner repinning remains one future amendment, separate from field authorization. Fifth #297 field run `20260914T063552Z` remains failed and immutable. Its candidate's independent **PR...\n 6904│- **Measured sequence.** Setup request `06:41:26Z`, elevated setup `06:43:18Z`–`06:43:24Z`, refused capture launcher `06:43:25Z`–`06:43:26Z`, receipt about `06:43:27Z`. The driver had written the capture deadline from request time: 112 seconds of handoff delay left the launcher's `deadline - now - 5` allocation at **−4 seconds**. No native t1 capture ran. The handoff expired before the receipt; cleanup reread its nonce and exit but retained the earlier `timestamp_order=UNMEASURED`, withholding muta...\n     │...\n 6913│\n*6914│### IR-135 — checker pin and runner installation can disagree, and the repair path disguises that version mismatch as an authentication failure\n 6915│\n 6916│- **Status:** CI precheck remedy implemented in the IR-135 lane; workflow execution awaits integration. Measured by doyle in S4 golden `34946493637`, 2026-09-15; filed by hertz from `3HHHPWCR`. The immediate box mismatch was repaired by hand-install.\n 6917│- **Instance and mechanism.** The #304 candidate carried `71caedd4`, setting `WANT=0.4.1` in `golden.yml`/`ci.yml`, while kitsubito's `~/.local/bin/traceable-reqs` was **0.2.0**. The install step's mismatch path attempted a private clone without a provisioned `TRACEABLE_REQS_TOKEN` and exited **128 before any check**. The visible failure named authentication, not the wanted and installed versions. A checked-in pin is not evidence that the runner can supply it; the fallback requires a second, independentl...\n     │...\n 6920│\n*6921│### IR-136 — a broker bound under the seed socket's name is not seed control, so a URL-minting rig can omit the very listener contract the product queries\n 6922│\n 6923│- **Status:** Instance fixed in S5 **`ddd7fc7f070667524578c282894dd44a2e36062f`**, test-only atop S4; S5 golden34957614641 passed, including both twohost roles. Shared fixture-composition remedy implemented and Linux-verified in the IR-136 lane. Origin: doyle's S4 golden `34946493637` twohost helper red, 2026-09-15.\n 6924│- **Mechanism.** Role B hosted broker IPC under an invented name, with neither `seedmap::serve_seed_control` nor a docs listener. `REQ-WEB-URL-BOUND-PORT` requires `serve_for` to ask the canonical seed-control plane for `DocsStatus` before publishing a URL; the missing plane returned `DOCS_PORT_DISCOVERY_FAILED: Connection refused (os error 111)`. Merely renaming a Broker to `seed_socket_name()` does not provide that protocol: `serve_request` is dispatched by seed control, not Broker. The docs-server fix...\n     │...\n 6931│\n*6932│### IR-137 — a redirected Start-Process child can share the tool call's console lifetime and die when that call returns\n 6933│\n 6934│- **Status:** RETIRED, 2026-09-15, doyle ruling `YPLFG3CG`: **no tracked callsite; discipline recorded + receipt**. This closes a Windows ad-hoc rig-craft item, not a CI or candidate defect; no helper or product change.\n 6935│- **Mechanism and rule.** `Start-Process` with redirected output from a PowerShell tool call was observed to end with **`STATUS_CONTROL_C_EXIT`** when the tool call ended: a returned child PID did not establish detachment. The reported detached form uses a **hidden window without redirects**. Where a child must outlive the call, qualify its survival after the caller returns and give it a durable output path of its own; do not treat process creation or a hidden window alone as lifetime evidence."},"isError":false,"timestamp":1789483654542}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_2Zl6eRtFPEcgIG3CihJqDJ8N|fc_000c7cef03cac861016aa95a8d970887d193e24c82c9d4ed47","toolName":"read","startedAt":"2026-09-15T14:47:41.665Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:3888-4183"},"intent":"Reading earlier assigned entries"},"id":"2e056890","parentId":"0a5ede88","timestamp":"2026-09-15T14:47:41.665Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_w5ya0hdwgS4d56SswoooqH9i|fc_000c7cef03cac861016aa95a8d971c87d1b90622bf3d928ebf","toolName":"read","startedAt":"2026-09-15T14:47:41.666Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:4184-4590"},"intent":"Reading amended leak entries"},"id":"a5712955","parentId":"2e056890","timestamp":"2026-09-15T14:47:41.666Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_KHh6SESPu8iHaQIia3nO6g8X|fc_000c7cef03cac861016aa95a8d972487d1a927a2207ec8b414","toolName":"read","startedAt":"2026-09-15T14:47:41.666Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:4591-5043"},"intent":"Reading observability and runner entries"},"id":"108e157e","parentId":"a5712955","timestamp":"2026-09-15T14:47:41.666Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_5ZpeIsZcdlrtUTY8rOlOBEmP|fc_000c7cef03cac861016aa95a8d972c87d1a02d85ce62f5523c","toolName":"read","startedAt":"2026-09-15T14:47:41.666Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:5044-5481"},"intent":"Reading disk and workflow entries"},"id":"99f09ccd","parentId":"108e157e","timestamp":"2026-09-15T14:47:41.666Z"}
{"type":"message","id":"5644b35a","parentId":"99f09ccd","timestamp":"2026-09-15T14:47:41.667Z","message":{"role":"assistant","content":[{"type":"toolCall","id":"call_2Zl6eRtFPEcgIG3CihJqDJ8N|fc_000c7cef03cac861016aa95a8d970887d193e24c82c9d4ed47","name":"read","arguments":{"i":"Reading earlier assigned entries","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:3888-4183"},"intent":"Reading earlier assigned entries"},{"type":"toolCall","id":"call_w5ya0hdwgS4d56SswoooqH9i|fc_000c7cef03cac861016aa95a8d971c87d1b90622bf3d928ebf","name":"read","arguments":{"i":"Reading amended leak entries","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:4184-4590"},"intent":"Reading amended leak entries"},{"type":"toolCall","id":"call_KHh6SESPu8iHaQIia3nO6g8X|fc_000c7cef03cac861016aa95a8d972487d1a927a2207ec8b414","name":"read","arguments":{"i":"Reading observability and runner entries","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:4591-5043"},"intent":"Reading observability and runner entries"},{"type":"toolCall","id":"call_5ZpeIsZcdlrtUTY8rOlOBEmP|fc_000c7cef03cac861016aa95a8d972c87d1a02d85ce62f5523c","name":"read","arguments":{"i":"Reading disk and workflow entries","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:5044-5481"},"intent":"Reading disk and workflow entries"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":11396,"output":195,"cacheRead":10112,"cacheWrite":0,"totalTokens":21703,"cost":{"input":0.11396,"output":0.00975,"cacheRead":0.010112,"cacheWrite":0,"total":0.133822}},"stopReason":"toolUse","timestamp":1789483654576,"responseId":"resp_000c7cef03cac861016aa95a86d9d087d191b23462f3271839","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"fc_000c7cef03cac861016aa95a8d970887d193e24c82c9d4ed47","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading earlier assigned entries\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:3888-4183\"}","call_id":"call_2Zl6eRtFPEcgIG3CihJqDJ8N","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95a8d971c87d1b90622bf3d928ebf","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading amended leak entries\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:4184-4590\"}","call_id":"call_w5ya0hdwgS4d56SswoooqH9i","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95a8d972487d1a927a2207ec8b414","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading observability and runner entries\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:4591-5043\"}","call_id":"call_KHh6SESPu8iHaQIia3nO6g8X","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95a8d972c87d1a02d85ce62f5523c","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading disk and workflow entries\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:5044-5481\"}","call_id":"call_5ZpeIsZcdlrtUTY8rOlOBEmP","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}}]},"duration":7080.022799998522,"ttft":7050.686599999666,"completedAt":1789483661662,"contextSnapshot":{"promptTokens":21508,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"message","id":"18d74aad","parentId":"5644b35a","timestamp":"2026-09-15T14:47:41.690Z","message":{"role":"toolResult","toolCallId":"call_2Zl6eRtFPEcgIG3CihJqDJ8N|fc_000c7cef03cac861016aa95a8d970887d193e24c82c9d4ed47","toolName":"read","content":[{"type":"text","text":"### IR-70 — a hand-built `IoBus` silently omitted later sinks while every gate stayed green\n…\n- **Status:** OPEN, remedy unscheduled; the v0.65.0 respin fixed the witnessed call site on PR #173.\n…\n- **Ripe when:** the next `IoBus` construction/API touch, or a new sink registration. **Size:**\n…\n\n### IR-71 — controller-seat release has no persisted breadcrumb, so tests cannot distinguish propagation lag from a missing detach\n\n- **Status:** OPEN, observability gap; no remedy scheduled. · **Origin:** CONDUIT #236 r3\n  `er_brief_once_per_session_e2e` intermittent, classified test-side and fixed on PR #174.\n- **What/why:** killing rc1 reaps the controller process, but the broker is another process and\n  notices the socket close later. On that detach edge it clears `driven_by` and `controlled` in\n  `info.json`; rc2's preflight reads that file locally and can race the write, refuse normally, and\n  exit 0 without dialing the broker. The test originally spawned rc2 immediately and had no\n  observable precondition separating “release is propagating” from “release never happened.”\n- **The missing surface:** broker lifecycle state records `session-detach was_controller=true`, but\n  there is no always-on persisted breadcrumb that states the controller stamp was cleared, names\n  the resulting `driven_by`/`controlled` state, or measures detach-to-persist latency. The repaired\n  test therefore polls `info.json` itself, prints elapsed time (0.075s on the first local real run),\n  and uses a named 60s timeout whose failure promotes the finding from timing to missing release.\n  Its deliberately latched-seat unit proves the barrier can red.\n- **Remedy direction:** add one structured release breadcrumb after the persisted clear, carrying\n  session/connection identity and the resulting control state; if latency is carried, measure it\n  from the detach edge. It must ride the persisted daemon sink and remain distinct from\n  `session-detach`, which proves the connection event but not the file write.\n- **Kin:** [[IR-50]] (the sink a test must actually read), [[IR-40]] (an event timestamp is not a\n  completion signal), REQ-HAZARD-CONTROL-STAMP-CONVERGENCE.\n- **Ripe when:** the next controller lifecycle or structured-breadcrumb touch, or a field timeout\n  from PR #174's barrier. **Size:** small emitter plus one contract-level assertion.\n\n### IR-72 — no product read verb surfaces which process holds a perch or controller seat\n\n- **Status:** OPEN, observability gap; no remedy scheduled. · **Origin:** CONDUIT #236 r3\n  two-host RCA and PR #174 (`70c1a303`), corrected by doyle after IR-18 and daemon-status were\n  ruled out as different classes.\n- **Source-verified boundary:** the holder identity already exists in durable/internal records\n  (`InfoJson.pid`, `parent_pid`, and the broker's session pid), and product internals read it for\n  liveness, teardown, and self-detection. No product **read verb** returns the process that holds a\n  named perch/seat. PID-bearing teardown messages are failure outcomes, not an inspection surface;\n  daemon status is process-wide, not perch- or seat-scoped. This also does not collapse into\n  [[IR-18]], where an existing internal `read_pid` collapses absent and unreadable records.\n- **Paid-for consequence 1 — rigs manufacture custody:** PR #174's two-host repair had to add\n  `PidHolder` in `crates/spt/tests/twohost_cli.rs:401-437`, spawn a long-lived sibling process,\n  write that pid directly into each synthetic perch, retain the child handle, and kill+wait it on\n  drop. The rig can make a known holder; it cannot ask the product which holder the product sees.\n- **Paid-for consequence 2 — ambiguity stayed latent until behavior flipped:** the r3 fixture\n  seeded three perches with one test-process pid. Self-detection then enumerated a directory whose\n  first matching row was a filesystem-order coin, so a green could name the wrong perch. The\n  repaired resolver refuses an ambiguous candidate set instead of guessing, and the fixture's\n  `assert_only_ancestor_candidate` now re-reads every `info.json` rig-side\n  (`twohost_cli.rs:439-457`). Refusal is enforcement, not observability: it proves a tie but still\n  offers no supported verb that names each holding process.\n- **Remedy direction:** add one machine-readable, named-perch inspection surface that reports the\n  custody fields the product actually used — holder pid and role/source (bind relay, stable harness\n  parent, brokered controller/session) — without asking callers to parse private `info.json` or\n  scan the process table. PID alone is recyclable; where a birth/image/session stamp exists, carry\n  it so the output does not become a new bare-pid oracle.\n- **Kin:** [[IR-18]] (read primitive loses error class, explicitly distinct), [[IR-71]] (release\n  completion lacks a persisted breadcrumb), REQ-HAZARD-SELF-DETECT-TIE (refuse ambiguous ancestry\n  rather than select by enumeration order).\n- **Ripe when:** the next roster/status read-model change or another rig needs to reap a named\n  holder. **Size:** small read-model/API addition, medium if seat and perch custody need separate\n  typed variants.\n\n### IR-73 — ci.yml and release.yml still read the free-space floor PRE-checkout (literal-first sites off the golden path); and any job's floor is stale by its last heavy step\n\n- **Status:** CLOSED / BUILT — source reconciliation 2026-09-11 at `e5a2fed9`: all five\n  `ci.yml` sites and all three `release.yml` sites now read after checkout, with IR-73 comments;\n  `golden.yml` has both docs-floor rereads. IR-86 records the docs reread's live catch.\n  The original two halves below are implemented; capacity sizing and docs dependency coupling\n  remain OPEN under IR-86, not a reason to redispatch these eight reorders.\n  Filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep (deployah flag 2026-08-29).\n  · **Origin:** #242's two lost golden attempts exposed the pre-checkout read; the original\n  golden-only correction deliberately left the eight other sites for the now-built rider.\n- **What/why:** review each of the 8 sites' comments for checkout-protective purpose (the\n  `ac7d2609` method), then reorder the read after checkout or RECORD why not, per site. The\n  \"other jobs keep the literal-first shape\" clause is the trap's carrier: every un-reviewed site\n  is a queued golden-attempt loss on a loaded box.\n- **Second half (from #242 r4, same family):** a single job-start floor read is stale by the\n  job's LAST heavy step — the r4 LNK1318 low-water face recorded on [[IR-59]] (sixth face);\n  the within-job re-read before the docs-drift build rides the next workflow commit alongside\n  this entry's reorders.\n- **Kin:** [[IR-46]] (a floor asserts an instant), [[IR-59]] (full volume reds as a linker\n  defect), REQ-CI-FREE-SPACE-PREFLIGHT.\n- **Ripe when:** next touch of `ci.yml`/`release.yml`, or the next intake's tooling-rider slot\n  (compose with IR-59/IR-57's standing pair). · **Size:** small — reorder or comment per site,\n  8 sites.\n\n### IR-74 — kitsubito holds 21,643 /tmp endpoint homes: box-side accumulation nothing bounds or measures\n\n- **Status:** OPEN, filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep; measurement by\n  hertz (2026-08-29). · **Origin:** rig work on kitsubito found `/tmp` carrying 21,643 endpoint\n  homes — per-run spt homes that outlive their runs.\n- **What/why:** sibling of the [[IR-31]]/[[IR-59]]/[[IR-64]] family (box accumulation the\n  preflights never see): each is small, the population is not, and /tmp on a long-lived box is\n  never reaped by CI. Un-reaped homes also widen every by-path census a rig runs. Needs a\n  bounded lifecycle (per-run temp root reaped at run end, or a box-side sweep with a stated\n  retention), and the reap must state its count so a zero is a claim.\n- **Ripe when:** next kitsubito rig touch, or the between-milestone box-audit slot.\n- **Size:** small (one sweep script + adoption in the box's rig steps); the measurement rerun is\n  one `find | wc`.\n\n### IR-75 — traceable-reqs is not installed on kitsubito, so every Linux gate driver's treqs leg exits 127 (vacuous, wrapper-green shape)\n\n- **Status:** OPEN, filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep (deployah\n  co-flagged at intake). · **Origin:** ASM-241 Linux battery — `ASM_treqs.exit` = 127, raw\n  `env: 'traceable-reqs': No such file or directory`; leg vacuous, covered that day by the\n  Windows treqs = 0 at the identical tree (treqs is a platform-independent text scan).\n- **What/why:** a 127 leg is exactly the wrapper-green shape [[IR-60]] documents — a driver that\n  doesn't read the exit FILE would report the leg green. Fix is either: install traceable-reqs on\n  kitsubito (then the leg is real), or DROP the leg from Linux gate drivers and state the\n  Windows-covers-it rule in the driver comment. Do NOT reopen [[IR-37]] for this — IR-37's\n  consume lane is spt-core CI (GitHub runners, green all week); this is BOX tooling, a different\n  surface (ruled at the sweep against the enumerating agent's overcautious flag).\n- **Ripe when:** next Linux gate-driver touch or kitsubito box-audit slot.\n- **Size:** trivial (install or one driver edit + comment).\n\n### IR-76 — hfenduleam is the golden Windows runner AND the builders' box: a local workspace nextest fully contained a golden Phase A and manufactured a load-timing red, and the job-start census cannot see it\n\n- **Status:** OPEN, filed by doyle 2026-09-06 during v0.67.1 golden triage (run 34017906638\n  att2). · **Origin:** the Windows Phase A red on\n  `spt-store::wtlock_two_process_int two_processes_commit_into_one_worktree_without_failing`\n  (B hit the 10 s worktree-lock bound while A's six serial commits took 13.5 s; 12 other\n  cells ran >10 s in the same phase). Load audit by todlando from his own `.raw`\n  CreationTimeUtc / `.exit` LastWriteTimeUtc: his #276 gate's 1240-cell workspace nextest\n  (`--no-fail-fast`, test phase 08:50:06–08:58:00Z) FULLY CONTAINED the golden Phase A\n  (08:52:38–08:56:49Z), every core saturated. He had been dispatched into that window and\n  never told the box was under a golden hold; perri and hertz had been.\n- **What/why:** two mechanisms, both unmeasured by anything in CI today. (1) The box is\n  shared by design — every agent's gate rig, adapter build and workspace nextest runs on the\n  same host as the self-hosted golden Windows runner, so a golden Windows leg is a QUIET\n  WINDOW only if every agent knows it is open; nothing says so, and a dispatch brief that\n  starts a gate is exactly how a builder lands inside it. (2) The job-start\n  `reap-census.ps1` counts the SPT FAMILY only (`family_total=12 scoped=0 unscoped=12` at\n  att2's 08:39:46Z start, with a builder's prebuild live on the box); cargo/nextest/rustc\n  load is outside its predicate, so the one instrument that runs at the right moment is\n  blind to the load that matters. Every load-timing red on Windows therefore triages as a\n  random victim with the cause off the record — the [[IR-63]] \"one random victim per sweep\"\n  face, now with a named source.\n- **Fix shape:** (a) driver templates (every gate/battery driver an agent authors here)\n  gain a PRE-FLIGHT leg with THREE outcomes, never two (todlando's amendment at filing: an\n  empty `gh run list` is the same bytes for CLEAR and for a broken meter — wrong filter,\n  expired token, rate limit, wrong repo default all return exit 0 and no rows — so a\n  two-arm guard fails OPEN into the exact hazard it guards, the `--commit <short-sha>`\n  confident-EMPTY class): run `gh run list --workflow golden --status in_progress`; rows\n  present -> HOLD, print the run id; no rows AND a positive control (`gh run list -L 1`\n  unfiltered, or `gh auth status`) returns a row -> CLEAR; control empty or erroring ->\n  REFUSE and say the meter is broken. A refusal, not a warning, so a wrapper-green shape\n  cannot swallow it ([[IR-60]]); the dispatch-brief line in (b) is likewise a MEASURED\n  clear with a live meter, never the absence of a sentence; (b) dispatch briefs that start a gate NAME the hold state of the box; (c)\n  the job-start census gains a second predicate — cargo/nextest/rustc/link processes by\n  image name, count + total CPU — reported beside the family count so a red's triage can\n  place foreign load from the log alone; (d) the golden hand-off contract\n  (docs/golden-head-intake) states the quiet-window rule once.\n- **Kin:** [[IR-63]] (random victim per sweep), [[IR-59]] (box conditions the preflights\n  never see), [[IR-64]] (hfenduleam's non-CI payload), FLAKE-LEDGER rows for\n  `wtlock_two_process_int` and `attach_link_push_e2e` (2026-09-06).\n- **Ripe when:** next driver-template touch (a/b are text; a is one leg), next `ci.yml`\n  touch for (c) — compose with [[IR-73]]'s reorders; (d) rides the next runbook edit.\n- **Size:** small — one pre-flight leg + one census predicate + two doc sentences.\n\n### IR-77 — nothing stamps the interval between a daemon child's spawn and the brain's first log line, so a readiness-deadline red cannot say WHERE the time went\n\n- **Status:** OPEN, filed by hertz 2026-09-07 from the W1 #249 kitsubito battery at the gated\n  sha `8d980fdf`; doyle-ruled at filing to be a register entry rather than a lane rider. ·\n  **Origin:** FLAKE-LEDGER `resident_service_e2e` :453 PRECONDITION (53 s) and\n  `resume_no_control_steal_e2e` (46 s), co-victims of ONE window — nextest exit 100, ONE\n  Summary `2999 tests run: 2997 passed (8 slow, 1 leaky), 2 failed, 1 skipped`. Evidence\n  preserved at `.spt/preserved/w1-kitsubito-8d980fdf/nextest.raw`, sha256\n  `9c456e21a6a0f75d8b0375ac648f232dba07f3887ec5e8dc232daef36253b51e`, hash-verified against\n  the kitsubito original.\n- **What/why:** both reds are a 45 s wait on `brain.ready` that expired, and the panel each\n  one prints shows the tree ALIVE — `BRAIN_UP`, `BRAIN_PHASE:announce done in 1ms`,\n  `BRAIN_PHASE:resume done in 0ms`, `SERVICE_STARTED` for both services, both later reaped\n  with an empty survivor set. So the daemon came up; it came up after the clock. WHERE those\n  45 s went is not recoverable from any artifact we keep: the first timestamped line in the\n  daemon's own sink is emitted by a process that has already started, and nothing stamps the\n  interval from the test's `Command::spawn` to it. The consequence is that every red of this\n  family is triaged by inference — v0.66.0 measured a ~10.1 s exe-hash on the ready path, and\n  that number is a CANDIDATE for the gap and can never be more than a candidate while the\n  interval is unmeasured. Remedy: one monotonic breadcrumb at daemon-child entry (before any\n  work), a second at the point `brain.ready` is stamped, both into the stderr sink the panel\n  already renders — then a red of this family reports its own split without a rerun.\n- **Kin:** [[IR-71]] (a seat release with no breadcrumb, same shape one layer over),\n  FLAKE-LEDGER `resident_service_e2e` :453 and `resume_no_control_steal_e2e` (2026-09-07),\n  and the HEAVY census stanza in `.config/nextest.toml`, which hardens the RECIPE these reds\n  came from and deliberately leaves the deadlines alone — a budget retune is the same race\n  with a different number, and it would also destroy the only signal this entry wants.\n- **Ripe when:** the next touch of the daemon boot path or of `brainproc`'s ready stamp; also\n  ripe as a rider on any lane that re-opens this test family.\n- **Size:** small — two `emit_line_err!` breadcrumbs and the sentence in the panel that says\n  what they mean.\n\n### IR-78 — `SPT_TEST_EPHEMERAL_ADVISORY_PORTS` silently overrides an explicitly set `SPT_DOCS_PORT`\n\n- **Status:** OPEN, filed by hertz 2026-09-07, MEASURED by doyle the same night on his W2\n  field pair (both boxes). · **Origin:** the 5474 rig-hygiene sweep in\n  `test/rig-advisory-ports-and-heavy-class`, which sets the rig flag at 37 `spt daemon run`\n  spawn sites.\n- **What/why:** `resolve_daemon_docs_port` (crates/spt-daemon/src/docshost.rs) returns `0`\n  whenever the rig flag is set, BEFORE the `SPT_DOCS_PORT` env override is consulted. With\n  both set, doyle's rig daemons took ephemeral ports (`DOCS_SERVER_UP` on 55369 Windows,\n  44015 Linux) while `SPT_DOCS_PORT=5480` was ignored without a word. The precedence itself is\n  defensible — the rig flag exists precisely so a test tree cannot take a well-known port —\n  but a SET override discarded in SILENCE is the shape IR-37 files under a different name: the\n  operator is left believing the value they set is the value in force. Remedy is a line, not a\n  redesign: emit one notice naming both env vars when the flag wins. No test cell is proposed\n  with it — none of the 31 swept binaries asserts on a docs port, so a cell here would assert\n  a behaviour nothing consumes.\n- **Kin:** [[IR-37]] (a set input silently ignored), the 5474 hygiene sweep, and the\n  `DOCS_SERVER_BIND_FAIL: port 5474: Address already in use (os error 98)` lines in\n  `.spt/preserved/w1-kitsubito-8d980fdf/nextest.raw` that started the sweep.\n- **NOT measured, stated so nobody reads it as covered:** doyle measured that the WMI\n  auto-start rung DOES carry the caller's environment (rig daemon pid 50088 on hfenduleam:\n  `DAEMON_LAUNCH_VIA_WMI`, its environ carrying `SPT_HOME`, `SPT_DOCS_PORT` and the rig flag\n  as his shell set them, `brain.ready` in the rig home). The schtasks (at-logon) rung was NOT\n  measured, and neither was the unix path.\n- **Ripe when:** the next `docshost.rs` touch, or the first time someone sets `SPT_DOCS_PORT`\n  on a rig and believes it.\n- **Size:** tiny — one emitted notice.\n\n### IR-79 — 22 of the 31 rig binaries leak their daemon tree on a failing assert: teardown is a statement, not a guard\n\n- **Status:** OPEN, filed by hertz 2026-09-07 on doyle's dispatch during PR #198's CI window,\n  from todlando's red 6 (a stale same-port daemon from his own previous run answering the next\n  one). · **Origin:** PR #198 moved 31 rigs to `SPT_TEST_EPHEMERAL_ADVISORY_PORTS=1`. Under an\n  ephemeral port a leaked daemon can no longer ANSWER the next run, so that PR is right as it\n  stands and this entry is not a defect in it; what remains is the orphan process itself — it pins\n  `spt.exe` (the Windows delete-and-rebuild hazard) and holds an `SPT_HOME` that nothing reaps. · **SCOPE BROADENED 07:20Z:** the title says \"on a failing\n  assert\" because that is the face it was filed from; the SECOND FACE bullet below shows the same\n  mechanism firing on a nextest TIMEOUT and leaking THREADS rather than a daemon. Read the title as\n  the handle, not the boundary — the trigger is any exit that does not reach the teardown statement.\n- **What/why:** measured over the 31, classifying each binary by whether its daemon teardown\n  survives a panic (a failing `assert!` unwinds, so only a guard or an ordering discipline saves\n  the child):\n  - **panic-safe, 9:** `impl Drop` guard — `endpoint_autostart_e2e`,\n    `knock_mutual_cross_node_e2e`, `twohost_cli`; `catch_unwind` teardown —\n    `activity_link_push_e2e`, `attach_link_push_e2e`, `wake_resume_bind_e2e`;\n    teardown-then-assert with zero exposed asserts — `endpoint_teardown_authority_e2e`,\n    `er_briefing_session_scoped_e2e`, `er_sequestered_cwd_e2e`.\n  - **leaks on a failing assert, 22** (exposed asserts / total asserts in the test body):\n    `projindex_writer_e2e` 21/21, `projindex_reader_e2e` 18/18,\n    `live_adapt_translation_swap_e2e` 15/38, `brain_split` 12/12,\n    `er_briefing_presented_e2e` 10/28, `rc_attach_truth` 8/29, `brain_respawn_rename` 6/6,\n    `dummy_harness_e2e` 4/11, `idle_edge_drain_e2e` 4/11, `multi_subnet_bringup_e2e` 4/20,\n    `bind_honest_cross_perch_e2e` 3/6, `idle_edge_seal_e2e` 3/17, `resident_service_e2e` 3/24,\n    `attach_wedge_e2e` 2/8, `bind_cwd_project_e2e` 2/8, `daemon_refresh_e2e` 2/11,\n    `er_brief_once_per_session_e2e` 2/13, `n1_pairing` 2/5, `resume_template_e2e` 2/10,\n    `run_no_dup_session_e2e` 2/14, `er_briefing_presentation_e2e` 1/4,\n    `livehost_bootgate_e2e` 1/3.\n  **FIRST WAVE of the Drop-guard generalization lane (doyle-ruled 2026-09-07, composed at the next\n  register sweep, not now): `projindex_writer_e2e`, `projindex_reader_e2e`, `brain_split`,\n  `brain_respawn_rename`.** These four expose EVERY assert they have — their teardown is the last\n  statement in the body, so any red at all leaks, which makes them both the worst cases and the\n  cleanest proofs that a guard works. The remedy already exists in this tree —\n  todlando's `DaemonReaper`, a `Drop` guard armed BEFORE the first CLI call — and the follow-up\n  lane is to generalise it into `crates/spt/tests/common` and adopt it at these 22 sites, which is\n  also the only shape that covers a `SIGKILL`-free timeout kill by nextest.\n- **METHOD, and its limits, so the count can be re-derived and challenged:** the classifier reads\n  each `#[test]` body, resolves file-local helper fns whose own body tears down (so a teardown\n  called through `sweep()` counts), and reports every `assert!`/`panic!` positioned before the LAST\n  teardown call in that body. It therefore (a) misses asserts written inline inside a closure or a\n  macro argument rather than at statement position, (b) treats the last teardown as THE teardown —\n  a partial earlier teardown still leaves the tree, so the true exposure is >= this count, and\n  (c) does not model `?` or early `return`. Spot-verified by hand on `resident_service_e2e`, whose\n  3 exposed asserts are real: they fire in the `wait_until` legs well before the `sweep()` at :435\n  that the \"── ASSERTIONS ──\" block follows.\n- **TONIGHT'S LIVE SAMPLE, so this is not an academic count (doyle's hfenduleam census 06:43Z):**\n  10 leaked `spt.exe` from todlando's pool, pairing by start time, from his pre-yield legs — a\n  single evening's rig work on one box. Each pins the binary against a rebuild and holds an\n  `SPT_HOME` nothing reaps.\n- **SECOND FACE — the same hazard in THREAD clothes, and it blocks the RUNNER, not just the box\n  (measured by todlando 07:17Z, relayed by doyle 07:20Z; I did not measure it myself and record it\n  as his testimony):** a nextest TIMEOUT on a `twohost_web` cell left the cell's child process\n  holding the broker + listener THREADS. Consequences, with his numbers:\n  - nextest itself blocked **14 minutes** at **0.61 CPU-seconds** — a wall-clock hang with\n    essentially no CPU, which is the signature of a parent waiting on a child's pipe rather than\n    of work being done;\n  - **`a.exit` was never written**, while **every verdict was already in `a.raw`** — so the leg\n    read as INCOMPLETE at the exact moment its results were complete. A reader who trusts the\n    exit file over the raw would call this a hung or failed leg and rerun it;\n  - **killing the path-verified orphan let the parent finish at once** — which is the causal test,\n    not a correlation: the kill is the intervention and the unblock is the response.\n  **Why it belongs in THIS entry rather than a new one:** the leaked thing is a thread inside a\n  child, not a daemon, but the mechanism is identical — a teardown that is a STATEMENT does not run\n  when the body does not reach it, and a timeout kill reaches the body even less reliably than a\n  panic does. The `Drop`-guard lane covers both faces with one remedy, which is doyle's ruling and\n  the reason no separate entry is opened. It also raises the lane's value: the daemon face costs a\n  pinned binary and an unreaped `SPT_HOME`, this face costs **14 minutes of a serialized golden\n  leg** and manufactures a false INCOMPLETE.\n  **Reading rule this hands the gate, worth stating because it is cheap:** when a leg's `.exit` is\n  missing, read the `.raw` for a Summary BEFORE concluding the leg hung — kin to\n  [[a-stopped-local-ssh-does-not-stop-its-remote-command]], where the raw was likewise the honest\n  record and the wrapper was not.\n- **Kin:** FLAKE-LEDGER `resident_service_e2e` :664 teardown LEAK row (3 occurrences, the Windows\n  face of the same class), [[IR-34]], [[IR-74]] (kitsubito's 21,643 `/tmp` endpoint homes — this is\n  one of the producers), and todlando's red 6.\n- **Ripe when:** the next lane that touches `crates/spt/tests/common` — the guard belongs there,\n  not copied 22 times.\n- **Size:** medium — one guard in `common`, then 22 mechanical adoptions, each provable by\n  panicking the body under a temporary test and watching the census go quiet.\n\n### IR-80 — five leaky cells on ONE module (`brainproc` / `supervise_brain`), Windows only: a candidate PRODUCT leak on the promotion/rollback path, or a cluster of names — nobody has looked yet\n\n- **Status:** OPEN for the residual population, not an undiagnosed five-name product claim.\n…\n  roster was read out of the baseline golden log for an unrelated reason.\n…\n\n…\n\n\n[Showing lines 3887-4186 of 6937. Use :4187 to continue]"}],"details":{"truncation":{"content":"\r\n### IR-71 — controller-seat release has no persisted breadcrumb, so tests cannot distinguish propagation lag from a missing detach\r\n\r\n- **Status:** OPEN, observability gap; no remedy scheduled. · **Origin:** CONDUIT #236 r3\r\n  `er_brief_once_per_session_e2e` intermittent, classified test-side and fixed on PR #174.\r\n- **What/why:** killing rc1 reaps the controller process, but the broker is another process and\r\n  notices the socket close later. On that detach edge it clears `driven_by` and `controlled` in\r\n  `info.json`; rc2's preflight reads that file locally and can race the write, refuse normally, and\r\n  exit 0 without dialing the broker. The test originally spawned rc2 immediately and had no\r\n  observable precondition separating “release is propagating” from “release never happened.”\r\n- **The missing surface:** broker lifecycle state records `session-detach was_controller=true`, but\r\n  there is no always-on persisted breadcrumb that states the controller stamp was cleared, names\r\n  the resulting `driven_by`/`controlled` state, or measures detach-to-persist latency. The repaired\r\n  test therefore polls `info.json` itself, prints elapsed time (0.075s on the first local real run),\r\n  and uses a named 60s timeout whose failure promotes the finding from timing to missing release.\r\n  Its deliberately latched-seat unit proves the barrier can red.\r\n- **Remedy direction:** add one structured release breadcrumb after the persisted clear, carrying\r\n  session/connection identity and the resulting control state; if latency is carried, measure it\r\n  from the detach edge. It must ride the persisted daemon sink and remain distinct from\r\n  `session-detach`, which proves the connection event but not the file write.\r\n- **Kin:** [[IR-50]] (the sink a test must actually read), [[IR-40]] (an event timestamp is not a\r\n  completion signal), REQ-HAZARD-CONTROL-STAMP-CONVERGENCE.\r\n- **Ripe when:** the next controller lifecycle or structured-breadcrumb touch, or a field timeout\r\n  from PR #174's barrier. **Size:** small emitter plus one contract-level assertion.\r\n\r\n### IR-72 — no product read verb surfaces which process holds a perch or controller seat\r\n\r\n- **Status:** OPEN, observability gap; no remedy scheduled. · **Origin:** CONDUIT #236 r3\r\n  two-host RCA and PR #174 (`70c1a303`), corrected by doyle after IR-18 and daemon-status were\r\n  ruled out as different classes.\r\n- **Source-verified boundary:** the holder identity already exists in durable/internal records\r\n  (`InfoJson.pid`, `parent_pid`, and the broker's session pid), and product internals read it for\r\n  liveness, teardown, and self-detection. No product **read verb** returns the process that holds a\r\n  named perch/seat. PID-bearing teardown messages are failure outcomes, not an inspection surface;\r\n  daemon status is process-wide, not perch- or seat-scoped. This also does not collapse into\r\n  [[IR-18]], where an existing internal `read_pid` collapses absent and unreadable records.\r\n- **Paid-for consequence 1 — rigs manufacture custody:** PR #174's two-host repair had to add\r\n  `PidHolder` in `crates/spt/tests/twohost_cli.rs:401-437`, spawn a long-lived sibling process,\r\n  write that pid directly into each synthetic perch, retain the child handle, and kill+wait it on\r\n  drop. The rig can make a known holder; it cannot ask the product which holder the product sees.\r\n- **Paid-for consequence 2 — ambiguity stayed latent until behavior flipped:** the r3 fixture\r\n  seeded three perches with one test-process pid. Self-detection then enumerated a directory whose\r\n  first matching row was a filesystem-order coin, so a green could name the wrong perch. The\r\n  repaired resolver refuses an ambiguous candidate set instead of guessing, and the fixture's\r\n  `assert_only_ancestor_candidate` now re-reads every `info.json` rig-side\r\n  (`twohost_cli.rs:439-457`). Refusal is enforcement, not observability: it proves a tie but still\r\n  offers no supported verb that names each holding process.\r\n- **Remedy direction:** add one machine-readable, named-perch inspection surface that reports the\r\n  custody fields the product actually used — holder pid and role/source (bind relay, stable harness\r\n  parent, brokered controller/session) — without asking callers to parse private `info.json` or\r\n  scan the process table. PID alone is recyclable; where a birth/image/session stamp exists, carry\r\n  it so the output does not become a new bare-pid oracle.\r\n- **Kin:** [[IR-18]] (read primitive loses error class, explicitly distinct), [[IR-71]] (release\r\n  completion lacks a persisted breadcrumb), REQ-HAZARD-SELF-DETECT-TIE (refuse ambiguous ancestry\r\n  rather than select by enumeration order).\r\n- **Ripe when:** the next roster/status read-model change or another rig needs to reap a named\r\n  holder. **Size:** small read-model/API addition, medium if seat and perch custody need separate\r\n  typed variants.\r\n\r\n### IR-73 — ci.yml and release.yml still read the free-space floor PRE-checkout (literal-first sites off the golden path); and any job's floor is stale by its last heavy step\r\n\r\n- **Status:** CLOSED / BUILT — source reconciliation 2026-09-11 at `e5a2fed9`: all five\r\n  `ci.yml` sites and all three `release.yml` sites now read after checkout, with IR-73 comments;\r\n  `golden.yml` has both docs-floor rereads. IR-86 records the docs reread's live catch.\r\n  The original two halves below are implemented; capacity sizing and docs dependency coupling\r\n  remain OPEN under IR-86, not a reason to redispatch these eight reorders.\r\n  Filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep (deployah flag 2026-08-29).\r\n  · **Origin:** #242's two lost golden attempts exposed the pre-checkout read; the original\r\n  golden-only correction deliberately left the eight other sites for the now-built rider.\r\n- **What/why:** review each of the 8 sites' comments for checkout-protective purpose (the\r\n  `ac7d2609` method), then reorder the read after checkout or RECORD why not, per site. The\r\n  \"other jobs keep the literal-first shape\" clause is the trap's carrier: every un-reviewed site\r\n  is a queued golden-attempt loss on a loaded box.\r\n- **Second half (from #242 r4, same family):** a single job-start floor read is stale by the\r\n  job's LAST heavy step — the r4 LNK1318 low-water face recorded on [[IR-59]] (sixth face);\r\n  the within-job re-read before the docs-drift build rides the next workflow commit alongside\r\n  this entry's reorders.\r\n- **Kin:** [[IR-46]] (a floor asserts an instant), [[IR-59]] (full volume reds as a linker\r\n  defect), REQ-CI-FREE-SPACE-PREFLIGHT.\r\n- **Ripe when:** next touch of `ci.yml`/`release.yml`, or the next intake's tooling-rider slot\r\n  (compose with IR-59/IR-57's standing pair). · **Size:** small — reorder or comment per site,\r\n  8 sites.\r\n\r\n### IR-74 — kitsubito holds 21,643 /tmp endpoint homes: box-side accumulation nothing bounds or measures\r\n\r\n- **Status:** OPEN, filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep; measurement by\r\n  hertz (2026-08-29). · **Origin:** rig work on kitsubito found `/tmp` carrying 21,643 endpoint\r\n  homes — per-run spt homes that outlive their runs.\r\n- **What/why:** sibling of the [[IR-31]]/[[IR-59]]/[[IR-64]] family (box accumulation the\r\n  preflights never see): each is small, the population is not, and /tmp on a long-lived box is\r\n  never reaped by CI. Un-reaped homes also widen every by-path census a rig runs. Needs a\r\n  bounded lifecycle (per-run temp root reaped at run end, or a box-side sweep with a stated\r\n  retention), and the reap must state its count so a zero is a claim.\r\n- **Ripe when:** next kitsubito rig touch, or the between-milestone box-audit slot.\r\n- **Size:** small (one sweep script + adoption in the box's rig steps); the measurement rerun is\r\n  one `find | wc`.\r\n\r\n### IR-75 — traceable-reqs is not installed on kitsubito, so every Linux gate driver's treqs leg exits 127 (vacuous, wrapper-green shape)\r\n\r\n- **Status:** OPEN, filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep (deployah\r\n  co-flagged at intake). · **Origin:** ASM-241 Linux battery — `ASM_treqs.exit` = 127, raw\r\n  `env: 'traceable-reqs': No such file or directory`; leg vacuous, covered that day by the\r\n  Windows treqs = 0 at the identical tree (treqs is a platform-independent text scan).\r\n- **What/why:** a 127 leg is exactly the wrapper-green shape [[IR-60]] documents — a driver that\r\n  doesn't read the exit FILE would report the leg green. Fix is either: install traceable-reqs on\r\n  kitsubito (then the leg is real), or DROP the leg from Linux gate drivers and state the\r\n  Windows-covers-it rule in the driver comment. Do NOT reopen [[IR-37]] for this — IR-37's\r\n  consume lane is spt-core CI (GitHub runners, green all week); this is BOX tooling, a different\r\n  surface (ruled at the sweep against the enumerating agent's overcautious flag).\r\n- **Ripe when:** next Linux gate-driver touch or kitsubito box-audit slot.\r\n- **Size:** trivial (install or one driver edit + comment).\r\n\r\n### IR-76 — hfenduleam is the golden Windows runner AND the builders' box: a local workspace nextest fully contained a golden Phase A and manufactured a load-timing red, and the job-start census cannot see it\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-06 during v0.67.1 golden triage (run 34017906638\r\n  att2). · **Origin:** the Windows Phase A red on\r\n  `spt-store::wtlock_two_process_int two_processes_commit_into_one_worktree_without_failing`\r\n  (B hit the 10 s worktree-lock bound while A's six serial commits took 13.5 s; 12 other\r\n  cells ran >10 s in the same phase). Load audit by todlando from his own `.raw`\r\n  CreationTimeUtc / `.exit` LastWriteTimeUtc: his #276 gate's 1240-cell workspace nextest\r\n  (`--no-fail-fast`, test phase 08:50:06–08:58:00Z) FULLY CONTAINED the golden Phase A\r\n  (08:52:38–08:56:49Z), every core saturated. He had been dispatched into that window and\r\n  never told the box was under a golden hold; perri and hertz had been.\r\n- **What/why:** two mechanisms, both unmeasured by anything in CI today. (1) The box is\r\n  shared by design — every agent's gate rig, adapter build and workspace nextest runs on the\r\n  same host as the self-hosted golden Windows runner, so a golden Windows leg is a QUIET\r\n  WINDOW only if every agent knows it is open; nothing says so, and a dispatch brief that\r\n  starts a gate is exactly how a builder lands inside it. (2) The job-start\r\n  `reap-census.ps1` counts the SPT FAMILY only (`family_total=12 scoped=0 unscoped=12` at\r\n  att2's 08:39:46Z start, with a builder's prebuild live on the box); cargo/nextest/rustc\r\n  load is outside its predicate, so the one instrument that runs at the right moment is\r\n  blind to the load that matters. Every load-timing red on Windows therefore triages as a\r\n  random victim with the cause off the record — the [[IR-63]] \"one random victim per sweep\"\r\n  face, now with a named source.\r\n- **Fix shape:** (a) driver templates (every gate/battery driver an agent authors here)\r\n  gain a PRE-FLIGHT leg with THREE outcomes, never two (todlando's amendment at filing: an\r\n  empty `gh run list` is the same bytes for CLEAR and for a broken meter — wrong filter,\r\n  expired token, rate limit, wrong repo default all return exit 0 and no rows — so a\r\n  two-arm guard fails OPEN into the exact hazard it guards, the `--commit <short-sha>`\r\n  confident-EMPTY class): run `gh run list --workflow golden --status in_progress`; rows\r\n  present -> HOLD, print the run id; no rows AND a positive control (`gh run list -L 1`\r\n  unfiltered, or `gh auth status`) returns a row -> CLEAR; control empty or erroring ->\r\n  REFUSE and say the meter is broken. A refusal, not a warning, so a wrapper-green shape\r\n  cannot swallow it ([[IR-60]]); the dispatch-brief line in (b) is likewise a MEASURED\r\n  clear with a live meter, never the absence of a sentence; (b) dispatch briefs that start a gate NAME the hold state of the box; (c)\r\n  the job-start census gains a second predicate — cargo/nextest/rustc/link processes by\r\n  image name, count + total CPU — reported beside the family count so a red's triage can\r\n  place foreign load from the log alone; (d) the golden hand-off contract\r\n  (docs/golden-head-intake) states the quiet-window rule once.\r\n- **Kin:** [[IR-63]] (random victim per sweep), [[IR-59]] (box conditions the preflights\r\n  never see), [[IR-64]] (hfenduleam's non-CI payload), FLAKE-LEDGER rows for\r\n  `wtlock_two_process_int` and `attach_link_push_e2e` (2026-09-06).\r\n- **Ripe when:** next driver-template touch (a/b are text; a is one leg), next `ci.yml`\r\n  touch for (c) — compose with [[IR-73]]'s reorders; (d) rides the next runbook edit.\r\n- **Size:** small — one pre-flight leg + one census predicate + two doc sentences.\r\n\r\n### IR-77 — nothing stamps the interval between a daemon child's spawn and the brain's first log line, so a readiness-deadline red cannot say WHERE the time went\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-07 from the W1 #249 kitsubito battery at the gated\r\n  sha `8d980fdf`; doyle-ruled at filing to be a register entry rather than a lane rider. ·\r\n  **Origin:** FLAKE-LEDGER `resident_service_e2e` :453 PRECONDITION (53 s) and\r\n  `resume_no_control_steal_e2e` (46 s), co-victims of ONE window — nextest exit 100, ONE\r\n  Summary `2999 tests run: 2997 passed (8 slow, 1 leaky), 2 failed, 1 skipped`. Evidence\r\n  preserved at `.spt/preserved/w1-kitsubito-8d980fdf/nextest.raw`, sha256\r\n  `9c456e21a6a0f75d8b0375ac648f232dba07f3887ec5e8dc232daef36253b51e`, hash-verified against\r\n  the kitsubito original.\r\n- **What/why:** both reds are a 45 s wait on `brain.ready` that expired, and the panel each\r\n  one prints shows the tree ALIVE — `BRAIN_UP`, `BRAIN_PHASE:announce done in 1ms`,\r\n  `BRAIN_PHASE:resume done in 0ms`, `SERVICE_STARTED` for both services, both later reaped\r\n  with an empty survivor set. So the daemon came up; it came up after the clock. WHERE those\r\n  45 s went is not recoverable from any artifact we keep: the first timestamped line in the\r\n  daemon's own sink is emitted by a process that has already started, and nothing stamps the\r\n  interval from the test's `Command::spawn` to it. The consequence is that every red of this\r\n  family is triaged by inference — v0.66.0 measured a ~10.1 s exe-hash on the ready path, and\r\n  that number is a CANDIDATE for the gap and can never be more than a candidate while the\r\n  interval is unmeasured. Remedy: one monotonic breadcrumb at daemon-child entry (before any\r\n  work), a second at the point `brain.ready` is stamped, both into the stderr sink the panel\r\n  already renders — then a red of this family reports its own split without a rerun.\r\n- **Kin:** [[IR-71]] (a seat release with no breadcrumb, same shape one layer over),\r\n  FLAKE-LEDGER `resident_service_e2e` :453 and `resume_no_control_steal_e2e` (2026-09-07),\r\n  and the HEAVY census stanza in `.config/nextest.toml`, which hardens the RECIPE these reds\r\n  came from and deliberately leaves the deadlines alone — a budget retune is the same race\r\n  with a different number, and it would also destroy the only signal this entry wants.\r\n- **Ripe when:** the next touch of the daemon boot path or of `brainproc`'s ready stamp; also\r\n  ripe as a rider on any lane that re-opens this test family.\r\n- **Size:** small — two `emit_line_err!` breadcrumbs and the sentence in the panel that says\r\n  what they mean.\r\n\r\n### IR-78 — `SPT_TEST_EPHEMERAL_ADVISORY_PORTS` silently overrides an explicitly set `SPT_DOCS_PORT`\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-07, MEASURED by doyle the same night on his W2\r\n  field pair (both boxes). · **Origin:** the 5474 rig-hygiene sweep in\r\n  `test/rig-advisory-ports-and-heavy-class`, which sets the rig flag at 37 `spt daemon run`\r\n  spawn sites.\r\n- **What/why:** `resolve_daemon_docs_port` (crates/spt-daemon/src/docshost.rs) returns `0`\r\n  whenever the rig flag is set, BEFORE the `SPT_DOCS_PORT` env override is consulted. With\r\n  both set, doyle's rig daemons took ephemeral ports (`DOCS_SERVER_UP` on 55369 Windows,\r\n  44015 Linux) while `SPT_DOCS_PORT=5480` was ignored without a word. The precedence itself is\r\n  defensible — the rig flag exists precisely so a test tree cannot take a well-known port —\r\n  but a SET override discarded in SILENCE is the shape IR-37 files under a different name: the\r\n  operator is left believing the value they set is the value in force. Remedy is a line, not a\r\n  redesign: emit one notice naming both env vars when the flag wins. No test cell is proposed\r\n  with it — none of the 31 swept binaries asserts on a docs port, so a cell here would assert\r\n  a behaviour nothing consumes.\r\n- **Kin:** [[IR-37]] (a set input silently ignored), the 5474 hygiene sweep, and the\r\n  `DOCS_SERVER_BIND_FAIL: port 5474: Address already in use (os error 98)` lines in\r\n  `.spt/preserved/w1-kitsubito-8d980fdf/nextest.raw` that started the sweep.\r\n- **NOT measured, stated so nobody reads it as covered:** doyle measured that the WMI\r\n  auto-start rung DOES carry the caller's environment (rig daemon pid 50088 on hfenduleam:\r\n  `DAEMON_LAUNCH_VIA_WMI`, its environ carrying `SPT_HOME`, `SPT_DOCS_PORT` and the rig flag\r\n  as his shell set them, `brain.ready` in the rig home). The schtasks (at-logon) rung was NOT\r\n  measured, and neither was the unix path.\r\n- **Ripe when:** the next `docshost.rs` touch, or the first time someone sets `SPT_DOCS_PORT`\r\n  on a rig and believes it.\r\n- **Size:** tiny — one emitted notice.\r\n\r\n### IR-79 — 22 of the 31 rig binaries leak their daemon tree on a failing assert: teardown is a statement, not a guard\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-07 on doyle's dispatch during PR #198's CI window,\r\n  from todlando's red 6 (a stale same-port daemon from his own previous run answering the next\r\n  one). · **Origin:** PR #198 moved 31 rigs to `SPT_TEST_EPHEMERAL_ADVISORY_PORTS=1`. Under an\r\n  ephemeral port a leaked daemon can no longer ANSWER the next run, so that PR is right as it\r\n  stands and this entry is not a defect in it; what remains is the orphan process itself — it pins\r\n  `spt.exe` (the Windows delete-and-rebuild hazard) and holds an `SPT_HOME` that nothing reaps. · **SCOPE BROADENED 07:20Z:** the title says \"on a failing\r\n  assert\" because that is the face it was filed from; the SECOND FACE bullet below shows the same\r\n  mechanism firing on a nextest TIMEOUT and leaking THREADS rather than a daemon. Read the title as\r\n  the handle, not the boundary — the trigger is any exit that does not reach the teardown statement.\r\n- **What/why:** measured over the 31, classifying each binary by whether its daemon teardown\r\n  survives a panic (a failing `assert!` unwinds, so only a guard or an ordering discipline saves\r\n  the child):\r\n  - **panic-safe, 9:** `impl Drop` guard — `endpoint_autostart_e2e`,\r\n    `knock_mutual_cross_node_e2e`, `twohost_cli`; `catch_unwind` teardown —\r\n    `activity_link_push_e2e`, `attach_link_push_e2e`, `wake_resume_bind_e2e`;\r\n    teardown-then-assert with zero exposed asserts — `endpoint_teardown_authority_e2e`,\r\n    `er_briefing_session_scoped_e2e`, `er_sequestered_cwd_e2e`.\r\n  - **leaks on a failing assert, 22** (exposed asserts / total asserts in the test body):\r\n    `projindex_writer_e2e` 21/21, `projindex_reader_e2e` 18/18,\r\n    `live_adapt_translation_swap_e2e` 15/38, `brain_split` 12/12,\r\n    `er_briefing_presented_e2e` 10/28, `rc_attach_truth` 8/29, `brain_respawn_rename` 6/6,\r\n    `dummy_harness_e2e` 4/11, `idle_edge_drain_e2e` 4/11, `multi_subnet_bringup_e2e` 4/20,\r\n    `bind_honest_cross_perch_e2e` 3/6, `idle_edge_seal_e2e` 3/17, `resident_service_e2e` 3/24,\r\n    `attach_wedge_e2e` 2/8, `bind_cwd_project_e2e` 2/8, `daemon_refresh_e2e` 2/11,\r\n    `er_brief_once_per_session_e2e` 2/13, `n1_pairing` 2/5, `resume_template_e2e` 2/10,\r\n    `run_no_dup_session_e2e` 2/14, `er_briefing_presentation_e2e` 1/4,\r\n    `livehost_bootgate_e2e` 1/3.\r\n  **FIRST WAVE of the Drop-guard generalization lane (doyle-ruled 2026-09-07, composed at the next\r\n  register sweep, not now): `projindex_writer_e2e`, `projindex_reader_e2e`, `brain_split`,\r\n  `brain_respawn_rename`.** These four expose EVERY assert they have — their teardown is the last\r\n  statement in the body, so any red at all leaks, which makes them both the worst cases and the\r\n  cleanest proofs that a guard works. The remedy already exists in this tree —\r\n  todlando's `DaemonReaper`, a `Drop` guard armed BEFORE the first CLI call — and the follow-up\r\n  lane is to generalise it into `crates/spt/tests/common` and adopt it at these 22 sites, which is\r\n  also the only shape that covers a `SIGKILL`-free timeout kill by nextest.\r\n- **METHOD, and its limits, so the count can be re-derived and challenged:** the classifier reads\r\n  each `#[test]` body, resolves file-local helper fns whose own body tears down (so a teardown\r\n  called through `sweep()` counts), and reports every `assert!`/`panic!` positioned before the LAST\r\n  teardown call in that body. It therefore (a) misses asserts written inline inside a closure or a\r\n  macro argument rather than at statement position, (b) treats the last teardown as THE teardown —\r\n  a partial earlier teardown still leaves the tree, so the true exposure is >= this count, and\r\n  (c) does not model `?` or early `return`. Spot-verified by hand on `resident_service_e2e`, whose\r\n  3 exposed asserts are real: they fire in the `wait_until` legs well before the `sweep()` at :435\r\n  that the \"── ASSERTIONS ──\" block follows.\r\n- **TONIGHT'S LIVE SAMPLE, so this is not an academic count (doyle's hfenduleam census 06:43Z):**\r\n  10 leaked `spt.exe` from todlando's pool, pairing by start time, from his pre-yield legs — a\r\n  single evening's rig work on one box. Each pins the binary against a rebuild and holds an\r\n  `SPT_HOME` nothing reaps.\r\n- **SECOND FACE — the same hazard in THREAD clothes, and it blocks the RUNNER, not just the box\r\n  (measured by todlando 07:17Z, relayed by doyle 07:20Z; I did not measure it myself and record it\r\n  as his testimony):** a nextest TIMEOUT on a `twohost_web` cell left the cell's child process\r\n  holding the broker + listener THREADS. Consequences, with his numbers:\r\n  - nextest itself blocked **14 minutes** at **0.61 CPU-seconds** — a wall-clock hang with\r\n    essentially no CPU, which is the signature of a parent waiting on a child's pipe rather than\r\n    of work being done;\r\n  - **`a.exit` was never written**, while **every verdict was already in `a.raw`** — so the leg\r\n    read as INCOMPLETE at the exact moment its results were complete. A reader who trusts the\r\n    exit file over the raw would call this a hung or failed leg and rerun it;\r\n  - **killing the path-verified orphan let the parent finish at once** — which is the causal test,\r\n    not a correlation: the kill is the intervention and the unblock is the response.\r\n  **Why it belongs in THIS entry rather than a new one:** the leaked thing is a thread inside a\r\n  child, not a daemon, but the mechanism is identical — a teardown that is a STATEMENT does not run\r\n  when the body does not reach it, and a timeout kill reaches the body even less reliably than a\r\n  panic does. The `Drop`-guard lane covers both faces with one remedy, which is doyle's ruling and\r\n  the reason no separate entry is opened. It also raises the lane's value: the daemon face costs a\r\n  pinned binary and an unreaped `SPT_HOME`, this face costs **14 minutes of a serialized golden\r\n  leg** and manufactures a false INCOMPLETE.\r\n  **Reading rule this hands the gate, worth stating because it is cheap:** when a leg's `.exit` is\r\n  missing, read the `.raw` for a Summary BEFORE concluding the leg hung — kin to\r\n  [[a-stopped-local-ssh-does-not-stop-its-remote-command]], where the raw was likewise the honest\r\n  record and the wrapper was not.\r\n- **Kin:** FLAKE-LEDGER `resident_service_e2e` :664 teardown LEAK row (3 occurrences, the Windows\r\n  face of the same class), [[IR-34]], [[IR-74]] (kitsubito's 21,643 `/tmp` endpoint homes — this is\r\n  one of the producers), and todlando's red 6.\r\n- **Ripe when:** the next lane that touches `crates/spt/tests/common` — the guard belongs there,\r\n  not copied 22 times.\r\n- **Size:** medium — one guard in `common`, then 22 mechanical adoptions, each provable by\r\n  panicking the body under a temporary test and watching the census go quiet.\r\n\r\n### IR-80 — five leaky cells on ONE module (`brainproc` / `supervise_brain`), Windows only: a candidate PRODUCT leak on the promotion/rollback path, or a cluster of names — nobody has looked yet\r\n\r\n- **Status:** OPEN for the residual population, not an undiagnosed five-name product claim.\r","truncated":true,"truncatedBy":"lines","totalLines":3051,"totalBytes":24745,"outputLines":300,"outputBytes":24745,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6937,"displayContent":{"text":"### IR-70 — a hand-built `IoBus` silently omitted later sinks while every gate stayed green\n…\n- **Status:** OPEN, remedy unscheduled; the v0.65.0 respin fixed the witnessed call site on PR #173.\n…\n- **Ripe when:** the next `IoBus` construction/API touch, or a new sink registration. **Size:**\n…\n\r\n### IR-71 — controller-seat release has no persisted breadcrumb, so tests cannot distinguish propagation lag from a missing detach\r\n\r\n- **Status:** OPEN, observability gap; no remedy scheduled. · **Origin:** CONDUIT #236 r3\r\n  `er_brief_once_per_session_e2e` intermittent, classified test-side and fixed on PR #174.\r\n- **What/why:** killing rc1 reaps the controller process, but the broker is another process and\r\n  notices the socket close later. On that detach edge it clears `driven_by` and `controlled` in\r\n  `info.json`; rc2's preflight reads that file locally and can race the write, refuse normally, and\r\n  exit 0 without dialing the broker. The test originally spawned rc2 immediately and had no\r\n  observable precondition separating “release is propagating” from “release never happened.”\r\n- **The missing surface:** broker lifecycle state records `session-detach was_controller=true`, but\r\n  there is no always-on persisted breadcrumb that states the controller stamp was cleared, names\r\n  the resulting `driven_by`/`controlled` state, or measures detach-to-persist latency. The repaired\r\n  test therefore polls `info.json` itself, prints elapsed time (0.075s on the first local real run),\r\n  and uses a named 60s timeout whose failure promotes the finding from timing to missing release.\r\n  Its deliberately latched-seat unit proves the barrier can red.\r\n- **Remedy direction:** add one structured release breadcrumb after the persisted clear, carrying\r\n  session/connection identity and the resulting control state; if latency is carried, measure it\r\n  from the detach edge. It must ride the persisted daemon sink and remain distinct from\r\n  `session-detach`, which proves the connection event but not the file write.\r\n- **Kin:** [[IR-50]] (the sink a test must actually read), [[IR-40]] (an event timestamp is not a\r\n  completion signal), REQ-HAZARD-CONTROL-STAMP-CONVERGENCE.\r\n- **Ripe when:** the next controller lifecycle or structured-breadcrumb touch, or a field timeout\r\n  from PR #174's barrier. **Size:** small emitter plus one contract-level assertion.\r\n\r\n### IR-72 — no product read verb surfaces which process holds a perch or controller seat\r\n\r\n- **Status:** OPEN, observability gap; no remedy scheduled. · **Origin:** CONDUIT #236 r3\r\n  two-host RCA and PR #174 (`70c1a303`), corrected by doyle after IR-18 and daemon-status were\r\n  ruled out as different classes.\r\n- **Source-verified boundary:** the holder identity already exists in durable/internal records\r\n  (`InfoJson.pid`, `parent_pid`, and the broker's session pid), and product internals read it for\r\n  liveness, teardown, and self-detection. No product **read verb** returns the process that holds a\r\n  named perch/seat. PID-bearing teardown messages are failure outcomes, not an inspection surface;\r\n  daemon status is process-wide, not perch- or seat-scoped. This also does not collapse into\r\n  [[IR-18]], where an existing internal `read_pid` collapses absent and unreadable records.\r\n- **Paid-for consequence 1 — rigs manufacture custody:** PR #174's two-host repair had to add\r\n  `PidHolder` in `crates/spt/tests/twohost_cli.rs:401-437`, spawn a long-lived sibling process,\r\n  write that pid directly into each synthetic perch, retain the child handle, and kill+wait it on\r\n  drop. The rig can make a known holder; it cannot ask the product which holder the product sees.\r\n- **Paid-for consequence 2 — ambiguity stayed latent until behavior flipped:** the r3 fixture\r\n  seeded three perches with one test-process pid. Self-detection then enumerated a directory whose\r\n  first matching row was a filesystem-order coin, so a green could name the wrong perch. The\r\n  repaired resolver refuses an ambiguous candidate set instead of guessing, and the fixture's\r\n  `assert_only_ancestor_candidate` now re-reads every `info.json` rig-side\r\n  (`twohost_cli.rs:439-457`). Refusal is enforcement, not observability: it proves a tie but still\r\n  offers no supported verb that names each holding process.\r\n- **Remedy direction:** add one machine-readable, named-perch inspection surface that reports the\r\n  custody fields the product actually used — holder pid and role/source (bind relay, stable harness\r\n  parent, brokered controller/session) — without asking callers to parse private `info.json` or\r\n  scan the process table. PID alone is recyclable; where a birth/image/session stamp exists, carry\r\n  it so the output does not become a new bare-pid oracle.\r\n- **Kin:** [[IR-18]] (read primitive loses error class, explicitly distinct), [[IR-71]] (release\r\n  completion lacks a persisted breadcrumb), REQ-HAZARD-SELF-DETECT-TIE (refuse ambiguous ancestry\r\n  rather than select by enumeration order).\r\n- **Ripe when:** the next roster/status read-model change or another rig needs to reap a named\r\n  holder. **Size:** small read-model/API addition, medium if seat and perch custody need separate\r\n  typed variants.\r\n\r\n### IR-73 — ci.yml and release.yml still read the free-space floor PRE-checkout (literal-first sites off the golden path); and any job's floor is stale by its last heavy step\r\n\r\n- **Status:** CLOSED / BUILT — source reconciliation 2026-09-11 at `e5a2fed9`: all five\r\n  `ci.yml` sites and all three `release.yml` sites now read after checkout, with IR-73 comments;\r\n  `golden.yml` has both docs-floor rereads. IR-86 records the docs reread's live catch.\r\n  The original two halves below are implemented; capacity sizing and docs dependency coupling\r\n  remain OPEN under IR-86, not a reason to redispatch these eight reorders.\r\n  Filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep (deployah flag 2026-08-29).\r\n  · **Origin:** #242's two lost golden attempts exposed the pre-checkout read; the original\r\n  golden-only correction deliberately left the eight other sites for the now-built rider.\r\n- **What/why:** review each of the 8 sites' comments for checkout-protective purpose (the\r\n  `ac7d2609` method), then reorder the read after checkout or RECORD why not, per site. The\r\n  \"other jobs keep the literal-first shape\" clause is the trap's carrier: every un-reviewed site\r\n  is a queued golden-attempt loss on a loaded box.\r\n- **Second half (from #242 r4, same family):** a single job-start floor read is stale by the\r\n  job's LAST heavy step — the r4 LNK1318 low-water face recorded on [[IR-59]] (sixth face);\r\n  the within-job re-read before the docs-drift build rides the next workflow commit alongside\r\n  this entry's reorders.\r\n- **Kin:** [[IR-46]] (a floor asserts an instant), [[IR-59]] (full volume reds as a linker\r\n  defect), REQ-CI-FREE-SPACE-PREFLIGHT.\r\n- **Ripe when:** next touch of `ci.yml`/`release.yml`, or the next intake's tooling-rider slot\r\n  (compose with IR-59/IR-57's standing pair). · **Size:** small — reorder or comment per site,\r\n  8 sites.\r\n\r\n### IR-74 — kitsubito holds 21,643 /tmp endpoint homes: box-side accumulation nothing bounds or measures\r\n\r\n- **Status:** OPEN, filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep; measurement by\r\n  hertz (2026-08-29). · **Origin:** rig work on kitsubito found `/tmp` carrying 21,643 endpoint\r\n  homes — per-run spt homes that outlive their runs.\r\n- **What/why:** sibling of the [[IR-31]]/[[IR-59]]/[[IR-64]] family (box accumulation the\r\n  preflights never see): each is small, the population is not, and /tmp on a long-lived box is\r\n  never reaped by CI. Un-reaped homes also widen every by-path census a rig runs. Needs a\r\n  bounded lifecycle (per-run temp root reaped at run end, or a box-side sweep with a stated\r\n  retention), and the reap must state its count so a zero is a claim.\r\n- **Ripe when:** next kitsubito rig touch, or the between-milestone box-audit slot.\r\n- **Size:** small (one sweep script + adoption in the box's rig steps); the measurement rerun is\r\n  one `find | wc`.\r\n\r\n### IR-75 — traceable-reqs is not installed on kitsubito, so every Linux gate driver's treqs leg exits 127 (vacuous, wrapper-green shape)\r\n\r\n- **Status:** OPEN, filed by doyle 2026-08-30 at the #242/v0.66.0 close sweep (deployah\r\n  co-flagged at intake). · **Origin:** ASM-241 Linux battery — `ASM_treqs.exit` = 127, raw\r\n  `env: 'traceable-reqs': No such file or directory`; leg vacuous, covered that day by the\r\n  Windows treqs = 0 at the identical tree (treqs is a platform-independent text scan).\r\n- **What/why:** a 127 leg is exactly the wrapper-green shape [[IR-60]] documents — a driver that\r\n  doesn't read the exit FILE would report the leg green. Fix is either: install traceable-reqs on\r\n  kitsubito (then the leg is real), or DROP the leg from Linux gate drivers and state the\r\n  Windows-covers-it rule in the driver comment. Do NOT reopen [[IR-37]] for this — IR-37's\r\n  consume lane is spt-core CI (GitHub runners, green all week); this is BOX tooling, a different\r\n  surface (ruled at the sweep against the enumerating agent's overcautious flag).\r\n- **Ripe when:** next Linux gate-driver touch or kitsubito box-audit slot.\r\n- **Size:** trivial (install or one driver edit + comment).\r\n\r\n### IR-76 — hfenduleam is the golden Windows runner AND the builders' box: a local workspace nextest fully contained a golden Phase A and manufactured a load-timing red, and the job-start census cannot see it\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-06 during v0.67.1 golden triage (run 34017906638\r\n  att2). · **Origin:** the Windows Phase A red on\r\n  `spt-store::wtlock_two_process_int two_processes_commit_into_one_worktree_without_failing`\r\n  (B hit the 10 s worktree-lock bound while A's six serial commits took 13.5 s; 12 other\r\n  cells ran >10 s in the same phase). Load audit by todlando from his own `.raw`\r\n  CreationTimeUtc / `.exit` LastWriteTimeUtc: his #276 gate's 1240-cell workspace nextest\r\n  (`--no-fail-fast`, test phase 08:50:06–08:58:00Z) FULLY CONTAINED the golden Phase A\r\n  (08:52:38–08:56:49Z), every core saturated. He had been dispatched into that window and\r\n  never told the box was under a golden hold; perri and hertz had been.\r\n- **What/why:** two mechanisms, both unmeasured by anything in CI today. (1) The box is\r\n  shared by design — every agent's gate rig, adapter build and workspace nextest runs on the\r\n  same host as the self-hosted golden Windows runner, so a golden Windows leg is a QUIET\r\n  WINDOW only if every agent knows it is open; nothing says so, and a dispatch brief that\r\n  starts a gate is exactly how a builder lands inside it. (2) The job-start\r\n  `reap-census.ps1` counts the SPT FAMILY only (`family_total=12 scoped=0 unscoped=12` at\r\n  att2's 08:39:46Z start, with a builder's prebuild live on the box); cargo/nextest/rustc\r\n  load is outside its predicate, so the one instrument that runs at the right moment is\r\n  blind to the load that matters. Every load-timing red on Windows therefore triages as a\r\n  random victim with the cause off the record — the [[IR-63]] \"one random victim per sweep\"\r\n  face, now with a named source.\r\n- **Fix shape:** (a) driver templates (every gate/battery driver an agent authors here)\r\n  gain a PRE-FLIGHT leg with THREE outcomes, never two (todlando's amendment at filing: an\r\n  empty `gh run list` is the same bytes for CLEAR and for a broken meter — wrong filter,\r\n  expired token, rate limit, wrong repo default all return exit 0 and no rows — so a\r\n  two-arm guard fails OPEN into the exact hazard it guards, the `--commit <short-sha>`\r\n  confident-EMPTY class): run `gh run list --workflow golden --status in_progress`; rows\r\n  present -> HOLD, print the run id; no rows AND a positive control (`gh run list -L 1`\r\n  unfiltered, or `gh auth status`) returns a row -> CLEAR; control empty or erroring ->\r\n  REFUSE and say the meter is broken. A refusal, not a warning, so a wrapper-green shape\r\n  cannot swallow it ([[IR-60]]); the dispatch-brief line in (b) is likewise a MEASURED\r\n  clear with a live meter, never the absence of a sentence; (b) dispatch briefs that start a gate NAME the hold state of the box; (c)\r\n  the job-start census gains a second predicate — cargo/nextest/rustc/link processes by\r\n  image name, count + total CPU — reported beside the family count so a red's triage can\r\n  place foreign load from the log alone; (d) the golden hand-off contract\r\n  (docs/golden-head-intake) states the quiet-window rule once.\r\n- **Kin:** [[IR-63]] (random victim per sweep), [[IR-59]] (box conditions the preflights\r\n  never see), [[IR-64]] (hfenduleam's non-CI payload), FLAKE-LEDGER rows for\r\n  `wtlock_two_process_int` and `attach_link_push_e2e` (2026-09-06).\r\n- **Ripe when:** next driver-template touch (a/b are text; a is one leg), next `ci.yml`\r\n  touch for (c) — compose with [[IR-73]]'s reorders; (d) rides the next runbook edit.\r\n- **Size:** small — one pre-flight leg + one census predicate + two doc sentences.\r\n\r\n### IR-77 — nothing stamps the interval between a daemon child's spawn and the brain's first log line, so a readiness-deadline red cannot say WHERE the time went\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-07 from the W1 #249 kitsubito battery at the gated\r\n  sha `8d980fdf`; doyle-ruled at filing to be a register entry rather than a lane rider. ·\r\n  **Origin:** FLAKE-LEDGER `resident_service_e2e` :453 PRECONDITION (53 s) and\r\n  `resume_no_control_steal_e2e` (46 s), co-victims of ONE window — nextest exit 100, ONE\r\n  Summary `2999 tests run: 2997 passed (8 slow, 1 leaky), 2 failed, 1 skipped`. Evidence\r\n  preserved at `.spt/preserved/w1-kitsubito-8d980fdf/nextest.raw`, sha256\r\n  `9c456e21a6a0f75d8b0375ac648f232dba07f3887ec5e8dc232daef36253b51e`, hash-verified against\r\n  the kitsubito original.\r\n- **What/why:** both reds are a 45 s wait on `brain.ready` that expired, and the panel each\r\n  one prints shows the tree ALIVE — `BRAIN_UP`, `BRAIN_PHASE:announce done in 1ms`,\r\n  `BRAIN_PHASE:resume done in 0ms`, `SERVICE_STARTED` for both services, both later reaped\r\n  with an empty survivor set. So the daemon came up; it came up after the clock. WHERE those\r\n  45 s went is not recoverable from any artifact we keep: the first timestamped line in the\r\n  daemon's own sink is emitted by a process that has already started, and nothing stamps the\r\n  interval from the test's `Command::spawn` to it. The consequence is that every red of this\r\n  family is triaged by inference — v0.66.0 measured a ~10.1 s exe-hash on the ready path, and\r\n  that number is a CANDIDATE for the gap and can never be more than a candidate while the\r\n  interval is unmeasured. Remedy: one monotonic breadcrumb at daemon-child entry (before any\r\n  work), a second at the point `brain.ready` is stamped, both into the stderr sink the panel\r\n  already renders — then a red of this family reports its own split without a rerun.\r\n- **Kin:** [[IR-71]] (a seat release with no breadcrumb, same shape one layer over),\r\n  FLAKE-LEDGER `resident_service_e2e` :453 and `resume_no_control_steal_e2e` (2026-09-07),\r\n  and the HEAVY census stanza in `.config/nextest.toml`, which hardens the RECIPE these reds\r\n  came from and deliberately leaves the deadlines alone — a budget retune is the same race\r\n  with a different number, and it would also destroy the only signal this entry wants.\r\n- **Ripe when:** the next touch of the daemon boot path or of `brainproc`'s ready stamp; also\r\n  ripe as a rider on any lane that re-opens this test family.\r\n- **Size:** small — two `emit_line_err!` breadcrumbs and the sentence in the panel that says\r\n  what they mean.\r\n\r\n### IR-78 — `SPT_TEST_EPHEMERAL_ADVISORY_PORTS` silently overrides an explicitly set `SPT_DOCS_PORT`\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-07, MEASURED by doyle the same night on his W2\r\n  field pair (both boxes). · **Origin:** the 5474 rig-hygiene sweep in\r\n  `test/rig-advisory-ports-and-heavy-class`, which sets the rig flag at 37 `spt daemon run`\r\n  spawn sites.\r\n- **What/why:** `resolve_daemon_docs_port` (crates/spt-daemon/src/docshost.rs) returns `0`\r\n  whenever the rig flag is set, BEFORE the `SPT_DOCS_PORT` env override is consulted. With\r\n  both set, doyle's rig daemons took ephemeral ports (`DOCS_SERVER_UP` on 55369 Windows,\r\n  44015 Linux) while `SPT_DOCS_PORT=5480` was ignored without a word. The precedence itself is\r\n  defensible — the rig flag exists precisely so a test tree cannot take a well-known port —\r\n  but a SET override discarded in SILENCE is the shape IR-37 files under a different name: the\r\n  operator is left believing the value they set is the value in force. Remedy is a line, not a\r\n  redesign: emit one notice naming both env vars when the flag wins. No test cell is proposed\r\n  with it — none of the 31 swept binaries asserts on a docs port, so a cell here would assert\r\n  a behaviour nothing consumes.\r\n- **Kin:** [[IR-37]] (a set input silently ignored), the 5474 hygiene sweep, and the\r\n  `DOCS_SERVER_BIND_FAIL: port 5474: Address already in use (os error 98)` lines in\r\n  `.spt/preserved/w1-kitsubito-8d980fdf/nextest.raw` that started the sweep.\r\n- **NOT measured, stated so nobody reads it as covered:** doyle measured that the WMI\r\n  auto-start rung DOES carry the caller's environment (rig daemon pid 50088 on hfenduleam:\r\n  `DAEMON_LAUNCH_VIA_WMI`, its environ carrying `SPT_HOME`, `SPT_DOCS_PORT` and the rig flag\r\n  as his shell set them, `brain.ready` in the rig home). The schtasks (at-logon) rung was NOT\r\n  measured, and neither was the unix path.\r\n- **Ripe when:** the next `docshost.rs` touch, or the first time someone sets `SPT_DOCS_PORT`\r\n  on a rig and believes it.\r\n- **Size:** tiny — one emitted notice.\r\n\r\n### IR-79 — 22 of the 31 rig binaries leak their daemon tree on a failing assert: teardown is a statement, not a guard\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-07 on doyle's dispatch during PR #198's CI window,\r\n  from todlando's red 6 (a stale same-port daemon from his own previous run answering the next\r\n  one). · **Origin:** PR #198 moved 31 rigs to `SPT_TEST_EPHEMERAL_ADVISORY_PORTS=1`. Under an\r\n  ephemeral port a leaked daemon can no longer ANSWER the next run, so that PR is right as it\r\n  stands and this entry is not a defect in it; what remains is the orphan process itself — it pins\r\n  `spt.exe` (the Windows delete-and-rebuild hazard) and holds an `SPT_HOME` that nothing reaps. · **SCOPE BROADENED 07:20Z:** the title says \"on a failing\r\n  assert\" because that is the face it was filed from; the SECOND FACE bullet below shows the same\r\n  mechanism firing on a nextest TIMEOUT and leaking THREADS rather than a daemon. Read the title as\r\n  the handle, not the boundary — the trigger is any exit that does not reach the teardown statement.\r\n- **What/why:** measured over the 31, classifying each binary by whether its daemon teardown\r\n  survives a panic (a failing `assert!` unwinds, so only a guard or an ordering discipline saves\r\n  the child):\r\n  - **panic-safe, 9:** `impl Drop` guard — `endpoint_autostart_e2e`,\r\n    `knock_mutual_cross_node_e2e`, `twohost_cli`; `catch_unwind` teardown —\r\n    `activity_link_push_e2e`, `attach_link_push_e2e`, `wake_resume_bind_e2e`;\r\n    teardown-then-assert with zero exposed asserts — `endpoint_teardown_authority_e2e`,\r\n    `er_briefing_session_scoped_e2e`, `er_sequestered_cwd_e2e`.\r\n  - **leaks on a failing assert, 22** (exposed asserts / total asserts in the test body):\r\n    `projindex_writer_e2e` 21/21, `projindex_reader_e2e` 18/18,\r\n    `live_adapt_translation_swap_e2e` 15/38, `brain_split` 12/12,\r\n    `er_briefing_presented_e2e` 10/28, `rc_attach_truth` 8/29, `brain_respawn_rename` 6/6,\r\n    `dummy_harness_e2e` 4/11, `idle_edge_drain_e2e` 4/11, `multi_subnet_bringup_e2e` 4/20,\r\n    `bind_honest_cross_perch_e2e` 3/6, `idle_edge_seal_e2e` 3/17, `resident_service_e2e` 3/24,\r\n    `attach_wedge_e2e` 2/8, `bind_cwd_project_e2e` 2/8, `daemon_refresh_e2e` 2/11,\r\n    `er_brief_once_per_session_e2e` 2/13, `n1_pairing` 2/5, `resume_template_e2e` 2/10,\r\n    `run_no_dup_session_e2e` 2/14, `er_briefing_presentation_e2e` 1/4,\r\n    `livehost_bootgate_e2e` 1/3.\r\n  **FIRST WAVE of the Drop-guard generalization lane (doyle-ruled 2026-09-07, composed at the next\r\n  register sweep, not now): `projindex_writer_e2e`, `projindex_reader_e2e`, `brain_split`,\r\n  `brain_respawn_rename`.** These four expose EVERY assert they have — their teardown is the last\r\n  statement in the body, so any red at all leaks, which makes them both the worst cases and the\r\n  cleanest proofs that a guard works. The remedy already exists in this tree —\r\n  todlando's `DaemonReaper`, a `Drop` guard armed BEFORE the first CLI call — and the follow-up\r\n  lane is to generalise it into `crates/spt/tests/common` and adopt it at these 22 sites, which is\r\n  also the only shape that covers a `SIGKILL`-free timeout kill by nextest.\r\n- **METHOD, and its limits, so the count can be re-derived and challenged:** the classifier reads\r\n  each `#[test]` body, resolves file-local helper fns whose own body tears down (so a teardown\r\n  called through `sweep()` counts), and reports every `assert!`/`panic!` positioned before the LAST\r\n  teardown call in that body. It therefore (a) misses asserts written inline inside a closure or a\r\n  macro argument rather than at statement position, (b) treats the last teardown as THE teardown —\r\n  a partial earlier teardown still leaves the tree, so the true exposure is >= this count, and\r\n  (c) does not model `?` or early `return`. Spot-verified by hand on `resident_service_e2e`, whose\r\n  3 exposed asserts are real: they fire in the `wait_until` legs well before the `sweep()` at :435\r\n  that the \"── ASSERTIONS ──\" block follows.\r\n- **TONIGHT'S LIVE SAMPLE, so this is not an academic count (doyle's hfenduleam census 06:43Z):**\r\n  10 leaked `spt.exe` from todlando's pool, pairing by start time, from his pre-yield legs — a\r\n  single evening's rig work on one box. Each pins the binary against a rebuild and holds an\r\n  `SPT_HOME` nothing reaps.\r\n- **SECOND FACE — the same hazard in THREAD clothes, and it blocks the RUNNER, not just the box\r\n  (measured by todlando 07:17Z, relayed by doyle 07:20Z; I did not measure it myself and record it\r\n  as his testimony):** a nextest TIMEOUT on a `twohost_web` cell left the cell's child process\r\n  holding the broker + listener THREADS. Consequences, with his numbers:\r\n  - nextest itself blocked **14 minutes** at **0.61 CPU-seconds** — a wall-clock hang with\r\n    essentially no CPU, which is the signature of a parent waiting on a child's pipe rather than\r\n    of work being done;\r\n  - **`a.exit` was never written**, while **every verdict was already in `a.raw`** — so the leg\r\n    read as INCOMPLETE at the exact moment its results were complete. A reader who trusts the\r\n    exit file over the raw would call this a hung or failed leg and rerun it;\r\n  - **killing the path-verified orphan let the parent finish at once** — which is the causal test,\r\n    not a correlation: the kill is the intervention and the unblock is the response.\r\n  **Why it belongs in THIS entry rather than a new one:** the leaked thing is a thread inside a\r\n  child, not a daemon, but the mechanism is identical — a teardown that is a STATEMENT does not run\r\n  when the body does not reach it, and a timeout kill reaches the body even less reliably than a\r\n  panic does. The `Drop`-guard lane covers both faces with one remedy, which is doyle's ruling and\r\n  the reason no separate entry is opened. It also raises the lane's value: the daemon face costs a\r\n  pinned binary and an unreaped `SPT_HOME`, this face costs **14 minutes of a serialized golden\r\n  leg** and manufactures a false INCOMPLETE.\r\n  **Reading rule this hands the gate, worth stating because it is cheap:** when a leg's `.exit` is\r\n  missing, read the `.raw` for a Summary BEFORE concluding the leg hung — kin to\r\n  [[a-stopped-local-ssh-does-not-stop-its-remote-command]], where the raw was likewise the honest\r\n  record and the wrapper was not.\r\n- **Kin:** FLAKE-LEDGER `resident_service_e2e` :664 teardown LEAK row (3 occurrences, the Windows\r\n  face of the same class), [[IR-34]], [[IR-74]] (kitsubito's 21,643 `/tmp` endpoint homes — this is\r\n  one of the producers), and todlando's red 6.\r\n- **Ripe when:** the next lane that touches `crates/spt/tests/common` — the guard belongs there,\r\n  not copied 22 times.\r\n- **Size:** medium — one guard in `common`, then 22 mechanical adoptions, each provable by\r\n  panicking the body under a temporary test and watching the census go quiet.\r\n\r\n### IR-80 — five leaky cells on ONE module (`brainproc` / `supervise_brain`), Windows only: a candidate PRODUCT leak on the promotion/rollback path, or a cluster of names — nobody has looked yet\r\n\r\n- **Status:** OPEN for the residual population, not an undiagnosed five-name product claim.\r\n…\n  roster was read out of the baseline golden log for an unrelated reason.\n…\n\n…\n","startLine":3861,"lineNumbers":[3861,null,3863,null,3885,null,3887,3888,3889,3890,3891,3892,3893,3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,3924,3925,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975,3976,3977,3978,3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,3991,3992,3993,3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055,4056,4057,4058,4059,4060,4061,4062,4063,4064,4065,4066,4067,4068,4069,4070,4071,4072,4073,4074,4075,4076,4077,4078,4079,4080,4081,4082,4083,4084,4085,4086,4087,4088,4089,4090,4091,4092,4093,4094,4095,4096,4097,4098,4099,4100,4101,4102,4103,4104,4105,4106,4107,4108,4109,4110,4111,4112,4113,4114,4115,4116,4117,4118,4119,4120,4121,4122,4123,4124,4125,4126,4127,4128,4129,4130,4131,4132,4133,4134,4135,4136,4137,4138,4139,4140,4141,4142,4143,4144,4145,4146,4147,4148,4149,4150,4151,4152,4153,4154,4155,4156,4157,4158,4159,4160,4161,4162,4163,4164,4165,4166,4167,4168,4169,4170,4171,4172,4173,4174,4175,4176,4177,4178,4179,4180,4181,4182,4183,4184,4185,4186,null,4192,null,4249,null,4465]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":6937,"totalBytes":24745,"outputLines":300,"outputBytes":24745,"shownRange":{"start":3887,"end":4186},"nextOffset":4187}}},"isError":false,"timestamp":1789483661690}}
{"type":"message","id":"c0d170f2","parentId":"18d74aad","timestamp":"2026-09-15T14:47:41.696Z","message":{"role":"toolResult","toolCallId":"call_w5ya0hdwgS4d56SswoooqH9i|fc_000c7cef03cac861016aa95a8d971c87d1b90622bf3d928ebf","toolName":"read","content":[{"type":"text","text":"### IR-79 — 22 of the 31 rig binaries leak their daemon tree on a failing assert: teardown is a statement, not a guard\n…\n- **Status:** OPEN, filed by hertz 2026-09-07 on doyle's dispatch during PR #198's CI window,\n…\n- **Size:** medium — one guard in `common`, then 22 mechanical adoptions, each provable by\n…\n\n### IR-80 — five leaky cells on ONE module (`brainproc` / `supervise_brain`), Windows only: a candidate PRODUCT leak on the promotion/rollback path, or a cluster of names — nobody has looked yet\n\n- **Status:** OPEN for the residual population, not an undiagnosed five-name product claim.\n  Later amendments identify the brainproc shell-wrapper fixture mechanism and distinguish\n  production's direct spawn; they do not classify all 12 union members. Historical opening\n  hypotheses below are not current causal conclusions. Filed by hertz 2026-09-07 07:40Z on\n  doyle's ruling that this retains its own identity, separate from IR-79.\n  **Origin:** noticed while measuring the #198 HEAVY scan-root gap ([[IR-37]] rider 2); the leak\n  roster was read out of the baseline golden log for an unrelated reason.\n- **⚠ WHAT THIS ENTRY IS, STATED FIRST SO IT IS NOT OVERREAD: a CLUSTER OF NAMES.** Five cells\n  that leaked share one module and one code path by their identifiers. Nothing has been measured\n  about WHAT is left alive, and a shared module is not a shared cause. Do not cite this as a\n  product defect until the census below has run.\n- **The observation, exact.** Golden run **34017906638**, sha `04e32c8c95cf`, both boxes, Phase A.\n  Windows (hfenduleam) reported **9 leaky** cells; Linux (kitsubito) **1** (`livehost::tests::\n  legacy_psyche_sweep_guard_is_id_specific_and_fail_safe`, unrelated). **Five of the Windows nine\n  are the same module:**\n\n  | cell | kind | time |\n  |---|---|---|\n  | `spt-daemon brainproc::tests::clear_before_spawn_defeats_exact_generation_stale_file` (:2200) | lib | 0.457s |\n  | `spt-daemon brainproc::tests::ready_but_old_gen_never_drains_does_not_promote_rolls_back` (:1834) | lib | 0.554s |\n  | `spt-daemon brainproc::tests::stale_generation_minus_one_ready_never_promotes` (:2155) | lib | 0.731s |\n  | `spt-daemon brainproc::tests::trial_kills_alive_never_ready_candidate_before_rollback` (:2109) | lib | 0.582s |\n  | `spt-daemon::false_promote ready_candidate_does_not_promote_until_the_wedged_old_gen_conn_drains` | int | 1.744s |\n\n  Denominator for the lib half: `brainproc`'s test module holds **26** `#[test]`/`#[tokio::test]`\n  cells, so **4 of 26 leaked, and all four are the trial/promote/rollback cells by name.** The\n  fifth is the integration rig that drives the same path.\n- **Why it is worth an entry even unmeasured:** four of the five are `kind(lib)`, so they run in\n  **`ci.yml` on every push**, not only in golden — if something really is left alive it is being\n  left alive on the shared Windows box many times a day. That is the same standing cost as\n  [[IR-79]]'s daemon face, arrived at from the opposite direction.\n- **HYPOTHESIS, labelled as such and NOT measured.** `supervise_brain` (:935) takes an injected\n  `spawn_child: impl FnMut(...) -> io::Result<Child>` (:941) and reaps candidates with bare\n  `let _ = child.kill();` at :998, :1015, :1055, :1071, :1081 — **`kill()` with no `wait()`.** On\n  Windows termination is asynchronous, and a killed-but-unreaped child can still hold the\n  inherited stdout/stderr pipe past the test's exit, which is exactly what nextest reports as\n  LEAK. The production spawner's own doc comment at :1190 states the intent — \"dies with no\n  orphaning. NOT `spawn_detached`\" — so if this is the mechanism, the code's intent and its\n  behaviour have diverged on one platform. **Every clause of this bullet is a reading of source,\n  not an observation of a live process. It may be entirely wrong.**\n- **FIRST MEASUREMENT — and doyle sharpened it 07:41Z from a census into a FALSIFIER, which is the\n  form to run:** on a free Windows box after W2, run\n  `trial_kills_alive_never_ready_candidate_before_rollback` **alone** and read one thing —\n  **is the killed pid still present, with the pipe handle open?** That is a yes/no against the\n  hypothesis above, not an open look at what happens to be running, and it is the difference\n  between a reading that settles the entry and a reading that produces more names. Capture pid,\n  image path and parent alongside the answer so a YES is immediately actionable, but the ANSWER is\n  the deliverable. One cell, one read. **Owner stays UNASSIGNED until it is taken** (doyle) — a\n  product path and a rig artifact are not distinguishable from here, and assigning before the read\n  would pick one by guess.\n- **Limits, so the entry cannot be overread:** nextest `LEAK` is **not a failure** — none of these\n  cells reds anything, and the run was green. Windows-only in **one** run; no trend established.\n  The clustering is by identifier and shared module, which is suggestive and is not causation.\n  I have not run any of these cells. Everything above is source plus one golden log — no box, no\n  build.\n- **Kin:** [[IR-79]] (children outliving the cell — the rig-teardown face of the same symptom, and\n  the reason doyle ruled these must stay SEPARATE: same symptom, different suspected owner),\n  [[IR-37]] rider 2 (the measurement that surfaced it), FLAKE-LEDGER's `resident_service_e2e` :664\n  teardown LEAK row.\n- **Ripe when:** the first free Windows box after W2 lands — it is a single-cell census, so it\n  fits any gap.\n- **Size:** unknown until the census. Tiny if it is a missing `wait()`; not tiny if the promotion\n  path leaves a real candidate brain alive on rollback.\n\n---\n\n#### THE LEAK SET IS NOISY — measured across three shas, 2026-09-07 (hertz)\n\n**This retracts the \"8 -> 5 leaky, direction favourable\" reading I flagged at 09:31Z.** It is not a\nfix and not an improvement; it is threshold noise, and the census this draft was built on inherits\nthat noise.\n\nWindows `ci` unit leg (`--workspace -E 'kind(lib) + kind(bin)'`), three consecutive shas:\n\n| cell | ff4b405d | e3bd53d4 | 401a19ad |\n|---|---|---|---|\n| brainproc::clear_before_spawn_defeats_exact_generation_stale_file | ● | ● | ● |\n| brainproc::ready_but_old_gen_never_drains_does_not_promote_rolls_back | ● | ● | ● |\n| brainproc::trial_kills_alive_never_ready_candidate_before_rollback | ● | ● | ● |\n| spt-runtime runtime::bounded_run_kills_on_timeout | ● | ● | ● |\n| brainproc::stale_generation_minus_one_ready_never_promotes | ● | ● | — |\n| spt-live digest::extractor_timeout_errors | ● | ● | — |\n| spt-live history::fetcher_timeout_errors | ● | ● | — |\n| spt-daemon broker::windows_session_is_zombie_sees_a_handle_held_corpse_as_dead | ● | — | — |\n| spt-daemon shellwake::kill_waker_at_still_kills_a_matching_pair | — | ● | ● |\n| **total** | **8** | **8** | **5** |\n\n**Causality check, which is what makes this a retraction rather than a hypothesis:** the three\ncommits between e3bd53d4 and 401a19ad touch **zero files** in brainproc, spt-live, spt-runtime,\nshellwake or broker (`git diff --name-only` over those paths returns nothing). The count fell by 3\nwith no change to any leaking module. So the drop cannot be a fix; the membership simply moves.\nNine cells appear in the union, only **four** are present at all three shas, and one\n(`shellwake::kill_waker_at`) *appeared* rather than vanished — a count that falls while a new member\njoins is the signature of a threshold, not of a repair.\n\n#### Three consequences for this draft\n\n1. **A count is not a quality signal here, in either direction.** Any future \"leaky went down\"\n   claim needs the NAME diff and a causality check against the changed files, or it is noise\n   reported as progress. I made exactly that error and it survived about twenty minutes.\n2. **The five-cell cluster is really \"three stable + one intermittent\".**\n   `stale_generation_minus_one_ready_never_promotes` is absent at 401a19ad. The cluster framing\n   still holds — three brainproc cells leak at every sha and they are all one module — but the\n   membership count must not be quoted as fixed.\n3. **doyle's falsifier beats my census, and this is the evidence.** The census (count the leaky\n   cells, name the cluster) is exactly what the noise destroys. His falsifier — *after\n   `trial_kills_alive_never_ready_candidate_before_rollback` on Windows, is the killed pid still\n   present with the pipe handle open?* — names ONE cell and probes a MECHANISM, and that cell is\n   **leaky at all three shas**, so it is the most stable target available. A mechanism probe is\n   immune to the threshold that moves the population. Owner stays UNASSIGNED until that read.\n\n#### One structural finding the noise does NOT touch\n**All nine union members spawn a child and then kill it, let it time out, or inspect its corpse** —\n`trial_kills_alive`, `kill_waker_at`, `bounded_run_kills_on_timeout`, `extractor_timeout_errors`,\n`fetcher_timeout_errors`, `windows_session_is_zombie_sees_a_handle_held_corpse_as_dead`, and the\nthree brainproc spawn/promote/rollback cells. Not one unrelated cell is in the set. Membership\nfluctuates; the *kind* of cell does not. That is a real signal about where child-process teardown\nis unreliable on Windows, and it is the same territory as [[ir79]] (rigs leaking daemons on a\nfailing assert) and [[ir81]] (kill scoping) — three drafts converging on one seam.\n\n---\n\n#### THE 12-CELL UNION — 4 shas x 2 OSes, membership beside the invariant (hertz, 2026-09-07 10:15Z)\n\nMachine-generated from the eight ci unit logs, not transcribed (a hand-typed 12x8 matrix is where\ntranscription errors live). `X` = reported LEAK at that sha on that box.\n\n| cell | W ff4b405d | W e3bd53d4 | W 401a19ad | W f3c8495b | L ff4b405d | L e3bd53d4 | L 401a19ad | L f3c8495b |\n|---|---|---|---|---|---|---|---|---|\n| `spt-daemon brainproc::tests::clear_before_spawn_defeats_exact_generation_stale_file` | X | X | X | X | . | . | . | . |\n| `spt-daemon brainproc::tests::ready_but_old_gen_never_drains_does_not_promote_rolls_back` | X | X | X | X | . | . | . | . |\n| `spt-daemon brainproc::tests::stale_generation_minus_one_ready_never_promotes` | X | X | . | X | . | . | . | . |\n| `spt-daemon brainproc::tests::trial_kills_alive_never_ready_candidate_before_rollback` | X | X | X | X | . | . | . | . |\n| `spt-daemon broker::tests::windows_session_is_zombie_sees_a_handle_held_corpse_as_dead` | X | . | . | X | . | . | . | . |\n| `spt-daemon livehost::tests::legacy_psyche_sweep_guard_is_id_specific_and_fail_safe` | . | . | . | . | X | X | X | . |\n| `spt-daemon shellhost::tests::kill_shell_at_still_kills_a_matching_pair` | . | . | . | X | . | . | . | . |\n| `spt-daemon shellwake::tests::kill_waker_at_still_kills_a_matching_pair` | . | X | X | X | . | . | . | . |\n| `spt-live digest::tests::extractor_timeout_errors` | X | X | . | X | . | . | . | . |\n| `spt-live history::tests::fetcher_timeout_errors` | X | X | . | . | . | . | . | . |\n| `spt-runtime runtime::tests::bounded_run_kills_on_timeout` | X | X | X | X | . | . | . | . |\n| `spt-store proc::tests::process_cmdline_reads_a_live_arg_marker` | . | . | . | . | X | X | X | X |\n| **leaky count** | 8 | 8 | 5 | 9 | 2 | 2 | 2 | 1 |\n\nUnion = 12 cells across 4 shas x 2 OSes. Present at EVERY Windows sha: 4. Present at every Linux sha: 1.\n\n#### Three readings, in increasing order of what they support\n\n**1. The churn is total and it is the whole point.** Windows counts run 8, 8, 5, 9 — the HIGHEST\nvalue is at `f3c8495b`, the tip carrying every fix F1-F16. Only **4 of 12** cells are present at\nevery Windows sha; only **1 of 2** at every Linux sha. Read as a quality signal the series says W2\nmade leaking worse, which is exactly as wrong as my retracted \"8 -> 5, favourable\" read and wrong\nfor the same reason. **A leaky count is not a signal in either direction.**\n\n**2. NEW, and I had not said it before building this table: the two OS sets are DISJOINT.** Ten\ncells leak only on Windows, two only on Linux, and **not one cell leaks on both**. Windows carries\n8-9 leaky cells per run against Linux's 1-2. So this is not one flaky population sampled twice —\nit is two populations with no overlap, and the Windows one is roughly five times larger. Any\nexplanation that treats \"leaky tests\" as a single phenomenon has to account for a clean partition\nby OS.\n\n**This is an OPEN QUESTION and the draft does not answer it. I do not have that explanation yet.**\nRecorded deliberately without a candidate cause: the partition is a measurement, and the temptation\nto pair a striking measurement with a plausible story is how the \"8 -> 5 is favourable\" reading got\ninto the record in the first place. Whoever takes this should arrive at a cause by reading, not by\ninheriting one from me.\n\n**SCOPED CAUSE, IN SOURCE, FOR ONE FAMILY ONLY (doyle ruled 10:22Z: source beats story; a source\ncause covering one family is a measurement and is filed as one).** The brainproc family leaks on\nWindows and not Linux because *its own fixture is asymmetric*: `long_child()` (brainproc.rs:1359)\nspawns `Command::new(\"cmd\").args([\"/C\",\"ping\",\"-n\",\"30\",\"127.0.0.1\"])` on Windows but\n`Command::new(\"sleep\").arg(\"30\")` on Unix — a shell wrapper on one box, a bare process on the other.\nThe Windows candidate the supervisor kills is `cmd`; the process burning 29 seconds is its child.\nThat is two lines of source, not an inference from the symptom. **And it is NOT the whole partition:**\n`process_cmdline_reads_a_live_arg_marker` uses a shell on BOTH arms (`sh -c \"sleep 30; : marker\"` /\n`cmd /C \"ping … & rem marker\"`) yet leaks on **Linux only** — the shell mechanism predicts it should\nleak on both boxes and it does not. So one family has a cause I can point at in the source, the\npartition as a whole remains OPEN, and the counterexample stands in this paragraph rather than a\nfootnote so no one carries the cause further than it goes.\n\n**THE PRODUCT PATH HAS NO INTERMEDIARY; THE FIXTURE DOES.** I chased the obvious escalation — if the\nreal supervisor also killed a shell wrapper, then \"never two live brains\"\n(REQ-HAZARD-BROKER-PROCESS-ISOLATION, the invariant this very cell guards) could be violated on\nWindows in production while the test stayed green. It cannot: `spawn_brain_child` (brainproc.rs:1224)\ndoes `Command::new(exe)` — the brain is spawned DIRECTLY, no shell, no grandchild, so a single-pid\nkill reaches it. **This is a test-fixture artifact, not a product defect**, and the fixture's shell\nis a Windows-only convenience for \"a process that blocks ~30s\" that introduced a layer the real path\ndoes not have. The negative is the useful half: it keeps the crashloop invariant out of IR-81 (a).\n\n**Why the cell passed review for as long as it did.** It asserts `pid != 0 && !pid_alive(pid)` before\nrollback, and that assertion is TRUE — `cmd` really is dead. The process still doing work is the one\nit never looks at. The leak and the green are not in tension; they are the same fact from two ends.\n**An assertion over a pid cannot see a tree.**\n\n**3. The invariant holds at 12 of 12, and it survived the population being shuffled three times.**\nEvery union member spawns a child process and then kills it, lets it time out, or inspects its\ncorpse — `trial_kills_alive`, `kill_shell_at`, `kill_waker_at`, `bounded_run_kills_on_timeout`,\n`extractor_timeout_errors`, `fetcher_timeout_errors`, `windows_session_is_zombie_..._corpse_as_dead`,\n`legacy_psyche_sweep_guard_...`, `process_cmdline_reads_a_live_arg_marker`, and the three brainproc\nspawn/promote/rollback cells. Membership churns freely across four shas and two OSes; the KIND of\ncell has not varied once. **This is the IR-80 headline** and it is better supported now than when it\nrested on a stable-looking five-cell cluster, precisely because the population underneath it has\nbeen reshuffled and the invariant did not move.\n\n#### A MECHANISM, read out of the source of the two Linux cells — calibrated, not generalized\n`process_cmdline_reads_a_live_arg_marker` spawns **`sh -c \"sleep 30; : marker\"`**, and the test's\nown comment says the trailing `; :` is deliberate — it keeps the shell RESIDENT so its\n`/proc/<pid>/cmdline` still carries the marker instead of being tail-exec-replaced by `sleep`. The\nteardown is `child.kill()` then `child.wait()`. **But `child` is the SHELL, and `sleep 30` is the\nshell's own child.** Killing the shell orphans the sleeper, which outlives the test by up to 30\nseconds — which is precisely what nextest reports as a LEAK. The Windows arm has the same shape:\n`cmd /C \"ping -n 30 127.0.0.1 >NUL & rem marker\"`, where `cmd` forks `ping`.\nSo the very construct that makes the test work (a resident shell, so the cmdline stays readable) is\nwhat guarantees a grandchild that a single-pid kill cannot reach.\n\n**What is verified and what is not, stated separately because the difference decides who owns this.**\nVERIFIED by reading source: this shape in BOTH Linux-only cells. CONSISTENT but not proven: the\nWindows family kills the same way — `kill_waker_at_still_kills_a_matching_pair` tears down with\n`kill_shell_pid(ours.id())`, a single-pid kill — so the mechanism is available to it, but I have not\nread every spawn helper. UNVERIFIED: the brainproc, broker and spt-live cells; those spawn real\nbrains and time out extractors, and may leak for unrelated reasons.\n\n**Why this matters beyond IR-80:** a single-pid kill that cannot reach a grandchild is exactly\n[[ir81]] arm (a) — identity and tree-awareness pushed into `kill_pid_tree`/`kill_pid` so no caller\ncan express the unreachable kill. If the mechanism above generalizes, IR-79 (rigs leaking daemons\non a failing assert), IR-80 (this) and IR-81 (kill scoping) are not three findings that share a\nseam, they are three FACES of one defect: **the codebase kills pids, and the things it needs dead\nare trees.** That is a claim worth testing, not asserting — and doyle's one-cell mechanism probe\nis still the right instrument, now with a sharper question: after the kill, is the surviving\nprocess the CHILD or the GRANDCHILD?\n\n---\n\n#### AMENDMENT 1 — \"a pid is not a tree\" has THREE faces, and only one of them is a kill\n\n*(hertz 2026-09-07, ruled by doyle 11:17Z: write this as an IR-80 amendment naming the three faces\nrather than three separate entries, so a reader hunting any one face lands on all three.)*\n\nThe register sentence this lane has been running on is doyle's: **a pid is not an identity and a pid\nis not a tree.** IR-80 and IR-81 were both filed against the KILL side, which made the sentence read\nlike a rule about killing. It is not. It is a rule about **which process you are talking about**, and\nkilling is only the face we happened to find first. Three faces are now measured, each found by a\ndifferent agent working a different problem:\n\n| face | the operation | what going one level too high produces | measured |\n|---|---|---|---|\n| **KILL** | `kill_pid(pid)` on a wrapper | the wrapper dies, the grandchild keeps working — the leak | IR-80's 12-cell union; `proc.rs:430`'s own doc states it |\n| **IDENTITY** | `kill_pid_tree(remembered_pid)` with no image read | you kill *a* process with that number, not the one you meant | IR-81 / #285, `broker.rs:8102` vs `servicehost.rs:651` |\n| **ENV READ** | `psutil.Process(child.pid).environ()` | the wrapper's env certifies a launch the battery would have failed | hertz 2026-09-07, self-test of `.github/bench/launch-battery.py` |\n\n**The third face, in full, because it is the newest and the least intuitive.** Reading back the\nenvironment of the process you spawned is the standard remedy for \"did my scrub/export actually\nland\" — it is what this project's own memory banked after the W0 perch-identity leak. It is\ninsufficient, and it fails in the flattering direction. A wrapper (`env VAR=x`, `cargo`, `nextest`,\n`bash -lc`) modifies the environment it hands the process **below** it, while its own `environ()`\nstill shows exactly what you passed in. So the read-back agrees with your intent, prints PROVEN, and\nsays nothing whatsoever about the process under test. Measured: the first version of\n`launch-battery.py` passed BOTH deliberately-negative tests. The corrected version walks descendants\nand, in the refusal, prints the wrapper as CLEAN beside the grandchild as VIOLATOR — that contrast\nis the face made visible in one line of output.\n\n**Why this belongs in IR-80 rather than in a new entry.** All three are the same error committed at\nthe same seam: an operation is aimed at a pid when the thing it needs to reach is a tree (or a\nspecific member of one). The remedies rhyme — walk the tree, read the identity, report the scope you\nactually covered — and a reader who finds any one face is one paragraph away from the other two.\nFiling them separately would have hidden that, which is the concrete cost doyle's ruling avoids.\n\n**What this amendment does NOT claim.** It does not widen IR-80's population: the 12-cell union\ntable and its Windows/Linux partition are unchanged, and the env face is not a test leak. It does\nnot add a remedy owner — the ENV face's fix is a tool (`.github/bench/launch-battery.py`), not product code, and the KILL and\nIDENTITY faces keep the owners they already have (#285 / todlando post-W2). It is a naming, and its\nwhole value is that the next instance of this error gets recognized as an instance instead of being\nfiled fresh.\n\n**Standing prediction, so this is falsifiable rather than tidy:** a fourth face exists wherever the\ncodebase asks a question *of* a pid that is really a question *about* a tree. The candidates I would\nlook at first are (a) liveness — `process_exists(pid)` answering \"is the work still running\" when\nthe work is a grandchild, and (b) resource attribution — reading a pid's handles/memory to decide\nwhether a lane is finished. Neither is measured; both are named so that finding one counts as\nconfirmation and finding none over the next few incidents counts against the generalization.\n\n### IR-81 — a process kill can be written scoped or machine-wide, and nothing makes the scoped form the only reachable one: both codebases carry the right pattern beside the wrong one\n\n- **Status:** OPEN, drafted by hertz 2026-09-07 08:38Z on doyle's dispatch (08:36Z), from the\n  fleet-daemon death on hfenduleam at 08:03:15Z ([[RCA-FLEET-DAEMON-14444]], cause still UNNAMED).\n  Census body: `docs/PID-KILL-CENSUS.md`. · **Origin:** doyle asked which sites kill a REMEMBERED\n  pid without re-verifying identity AT KILL TIME. The census answered that, and then answered a\n  better question nobody asked: **why the unguarded sites exist at all when the guarded ones sit\n  feet away.**\n- **⚠ THIS ENTRY IS NOT \"FIX THESE TWO SITES.\"** Both individual fixes are small and are dispatched\n  elsewhere (broker.rs:8102 → todlando's lane post-W2; live-relay-int.sh:78 → filed to perri). This\n  entry is about the thing that PRODUCED them and will produce the next one: the scoped form and the\n  machine-wide form are equally easy to write, equally plausible on review, and only one of them is\n  correct on a shared box.\n- **THE PAIRED EXHIBITS — same repo, same hand, feet apart.**\n\n  | | correct, and it says why | incorrect |\n  |---|---|---|\n  | **spt-core** | `spt-daemon/src/servicehost.rs:651` — `provably_gone` first, then `exe_path(pid)` compared to the parked image via `same_image`, then a FRESH post-kill read. Its comment IS the rule: *\"The pid is live. WHO is it? The image path decides — never the number.\"* | `spt-daemon/src/broker.rs:8102` — kills `spid`, a pid REMEMBERED off the session record, through `kill_pid_tree`. `zombie_verdict` consults liveness BY NUMBER (`process_exists`/`is_process_alive`), `adapter_labeled` (a property of the RECORD, not the live process), descendants and grace. **The live process's image is never read.** |\n  | **spt-claude-code** | `ci/launcher/bind-int.sh:50` — `wmic process where \"name='claude-spt.exe' and commandline like '%$ID%'\"`, scoped to this run's unique id, comment *\"never wall-a's\"*. Also `multi-subnet-bringup-int.sh:117` ($C3_ID) and `wake-survival-int.sh:64` (`-match '$PROBE'`). | `ci/psyche/live-relay-int.sh:78` — `for p in $(tasklist \\| grep -i claude-spt \\| awk '{print $2}'); do taskkill //PID \"$p\" //T //F; done` — **every** `claude-spt.exe` on the box, tree-force, no run-scoping. Comment: *\"by marker pid then name.\"* |\n\n  **The knowledge is not missing in either codebase. It is present, written down, and adjacent.**\n  Three correct sites to one wrong one in the adapter; a rule-stating comment in core. What is\n  missing is any mechanism that makes the wrong spelling hard to reach.\n- **Why \"just fix the sites\" is the wrong remedy:** it has already been tried implicitly — someone\n  wrote the scoped form three times, which is what a team looks like when it knows the rule and\n  still ships the exception. A fourth correct site does not prevent a fifth incorrect one. The\n  remedy has to change what is REACHABLE, not what is written.\n- **REMEDY — RULED 2026-09-07 08:40Z (doyle): (a) AND (b), not a choice between them. Two owners,\n  two lanes, and they cover different halves of the hazard.**\n  1. **(a) PRODUCT — push the identity requirement into the primitive.** `spt_store::proc::kill_pid_tree`\n     / `kill_pid` take an expected identity (image path, or a `same_image` closure) and refuse\n     without it, so a caller **cannot express** the unguarded kill; `servicehost.rs:651` stops being\n     the exception among callers and becomes the shape of all of them. **Owner: todlando, post-W2.**\n     ⇄ **This IS the fix shape of the `broker.rs:8102` board BUGFIX — that item and this entry\n     cross-reference each other; neither is complete alone.** Reaches Rust callers only.\n  2. **(b) GATE — `xtask check` refuses the unscoped spelling in CI scripts.** A `tasklist` /\n     `Get-Process` enumeration piped into a kill, or a bare `taskkill` with no\n     `commandline like` / `-match` scope in the same block, is a build failure. **Owner: hertz,\n     rides the IR-37 thin PR after W2 lands.** This is the half remedy (a) can NEVER reach — the\n     unguarded adapter site is a shell script, and no Rust signature constrains a shell script.\n  3. **(c) Fix the two sites and stop.** Recorded as CONSIDERED AND LOSING, not omitted: it has\n     already been tried implicitly — the adapter's author wrote the scoped form three times and\n     shipped the exception anyway — so a fourth correct site does not prevent a fifth wrong one.\n     It leaves the next instance free to appear.\n  **The (a)/(b) split is the entry's real content:** the hazard lives in two languages, and a remedy\n  in one of them is a half-measure that will read as a fix.\n- **STANDING LIMIT, so this entry is not overread as an incident cause:** none of these sites\n  explains the 08:03:15Z death. broker.rs:8102 would have been saved from firing by\n  `has_live_descendants` (the daemon had a live brain) — accidental protection, not deliberate —\n  and every claude-spt site enumerates `claude-spt.exe` while the dead process was `spt.exe`. The\n  census found a real hazard while looking for a different one. **Do not let this entry close the\n  incident.** The instrument at `C:\\Users\\decid\\.spt-watch\\daemon-watch.log` is what will answer\n  that, or fail to.\n- **Kin:** [[IR-79]] and [[IR-80]] (children outliving their cell; the leak family), the\n  [[RCA-FLEET-DAEMON-14444]] timeline, `servicehost.rs`'s own \"image path decides\" comment as the\n  in-tree statement of the rule, and the paired-exhibit method itself — a correct and an incorrect\n  site in one repo is stronger evidence about PROCESS than either site is about code.\n- **Ripe when:** the next touch of `spt-store/src/proc.rs` (for remedy 1) or of `xtask check`'s\n  gate family (for remedy 2). The adapter half is perri's, filed separately, and does not wait\n  on this.\n- **Size:** small for remedy 2, medium for remedy 1 (signature + every caller). The census that\n  justifies either is already written and does not need redoing.\n\n---\n\n#### ADAPTER-SIDE ARM: CLOSED (claude-spt, perri, 2026-09-07)\n\n**Status: closed in the consumer repo, test-only, does not close IR-81 here.**\n\n- **Commit `9c87372`** (spt-claude-code). Broad `tasklist | grep claude-spt | taskkill` replaced\n  with an **id-scoped wmic** call, **name-pinned so wmic cannot self-match**; the three\n  remembered-pid kills additionally got a **kill-time recheck**, covering the stale-identity face\n  as well as the unscoped-pattern face.\n- **Guard: `tests/ci-kill-scoping.sh`, traced as `REQ-HAZARD-CI-KILL-SCOPING`.** Gate green.\n  This is the check-shape arm (b) proposes for spt-core, already landed once — precedent, not\n  merely agreement.\n- **Scope: test/CI infrastructure only.** No product code changed. (doyle, 08:50Z.)\n- **`live-relay-int.sh:78` is retained as the historical RED exhibit** — the one genuinely\n  machine-wide kill found in the whole fleet census. It is the reason this hazard is written as a\n  hazard rather than a style note; do not quietly replace the exhibit with the fixed line.\n\n**Population lesson carried into arm (b)'s census.** I filed ONE site; perri confirmed **four**, and\nreports the idiom was already present in that repo **3x** before the filing. A filing that names one\nline under-counts its class by 3-4x in a single repo. **Census the ACT — any taskkill / pkill /\nwmic-delete reachable from a script root — never the literal string that led me to the first site.**\nState the walked roots in the check's own message, and give the gate a negative control that goes\nRED on a known-bad line before its green is trusted.\n\n**Still open here, unchanged:** arm (a), Rust-side identity pushed into `kill_pid_tree` / `kill_pid`\nso no Rust caller can express the unguarded kill (todlando, post-W2, cross-referenced with the\nbroker.rs:8102 board BUGFIX); and arm (b), the xtask script gate (mine, rides IR-37).\n\n---\n\n#### SCOPING ARM (a) — the product path has no intermediary; the fixture does\n*(hertz 2026-09-07, ruled by doyle 10:22Z off the IR-80 leak work.)*\n\n> **A pid is not an identity and a pid is not a tree. IR-80 needs CALLERS, not code.**\n> *(The register's sentence — doyle 10:23Z. Arm (a) fixes the identity half in\n> `kill_pid`/`kill_pid_tree`; the tree half needs no new machinery, because `kill_pid_tree` already\n> exists at proc.rs:430 with the defect stated in its own doc. This is why IR-79, IR-80 and IR-81\n> converge on one seam without collapsing into one finding.)*\n\nMeasured, not inferred: **`spawn_brain_child` (crates/spt-daemon/src/brainproc.rs:1224) does\n`Command::new(exe)`** — the real brain is spawned DIRECTLY, with no shell and no launcher between\nthe daemon and the process it supervises. So on the crashloop/rollback path a single-pid kill\n*does* reach the thing it aims at, and the \"orphaned grandchild\" mechanism found in the IR-80 leak\ncells is **a property of the TEST FIXTURE**, whose `long_child()` (brainproc.rs:1359) goes through\n`cmd /C` on Windows, not of the product.\n\n**What that scopes.** Arm (a) is NOT about the brain-supervision path and must not be sold as\nprotecting `REQ-HAZARD-BROKER-PROCESS-ISOLATION` (\"never two live brains\") — that invariant is not\nat risk here, and claiming it would be borrowing urgency this arm has not earned. Arm (a) stays\npointed at **the broker.rs:8102 reap, where the image is never read** — a kill aimed by pid alone\nat a process whose identity was never verified. That is the real unguarded form, and it is a\ndifferent failure (kill the wrong process) from the one IR-80 surfaced (fail to kill the right\none).\n\n**The two failures are different, which is why the drafts converge without collapsing.** Arm (a) is\n*kill the wrong process* (identity never read); IR-80 is *fail to kill the right one* (tree never\nwalked). The identity half is todlando's, post-W2. The tree half is already solved in-tree —\n`kill_pid_tree` at proc.rs:430, whose doc states the defect outright (\"a single-pid `kill_pid` leaves\nthe wrapper's harness children orphaned + running\") — so IR-80 ships callers, not machinery. See\n[[RIDER 4]] for the two test-side callers.\n\n### IR-82 — a daemon death leaves NO record of who died: autostart decides on a socket ping, says \"no daemon\", and the successor overwrites the only handle on the corpse\n\n- **Status:** RULED 2026-09-07 11:07Z (doyle), drafted by hertz 11:04Z on doyle's dispatch (11:03Z: *\"the autostart\n…\n  OBSERVABILITY, not in the death.\n…\n\n\n[Showing lines 4183-4593 of 6937. Use :4594 to continue]"}],"details":{"truncation":{"content":"\r\n### IR-80 — five leaky cells on ONE module (`brainproc` / `supervise_brain`), Windows only: a candidate PRODUCT leak on the promotion/rollback path, or a cluster of names — nobody has looked yet\r\n\r\n- **Status:** OPEN for the residual population, not an undiagnosed five-name product claim.\r\n  Later amendments identify the brainproc shell-wrapper fixture mechanism and distinguish\r\n  production's direct spawn; they do not classify all 12 union members. Historical opening\r\n  hypotheses below are not current causal conclusions. Filed by hertz 2026-09-07 07:40Z on\r\n  doyle's ruling that this retains its own identity, separate from IR-79.\r\n  **Origin:** noticed while measuring the #198 HEAVY scan-root gap ([[IR-37]] rider 2); the leak\r\n  roster was read out of the baseline golden log for an unrelated reason.\r\n- **⚠ WHAT THIS ENTRY IS, STATED FIRST SO IT IS NOT OVERREAD: a CLUSTER OF NAMES.** Five cells\r\n  that leaked share one module and one code path by their identifiers. Nothing has been measured\r\n  about WHAT is left alive, and a shared module is not a shared cause. Do not cite this as a\r\n  product defect until the census below has run.\r\n- **The observation, exact.** Golden run **34017906638**, sha `04e32c8c95cf`, both boxes, Phase A.\r\n  Windows (hfenduleam) reported **9 leaky** cells; Linux (kitsubito) **1** (`livehost::tests::\r\n  legacy_psyche_sweep_guard_is_id_specific_and_fail_safe`, unrelated). **Five of the Windows nine\r\n  are the same module:**\r\n\r\n  | cell | kind | time |\r\n  |---|---|---|\r\n  | `spt-daemon brainproc::tests::clear_before_spawn_defeats_exact_generation_stale_file` (:2200) | lib | 0.457s |\r\n  | `spt-daemon brainproc::tests::ready_but_old_gen_never_drains_does_not_promote_rolls_back` (:1834) | lib | 0.554s |\r\n  | `spt-daemon brainproc::tests::stale_generation_minus_one_ready_never_promotes` (:2155) | lib | 0.731s |\r\n  | `spt-daemon brainproc::tests::trial_kills_alive_never_ready_candidate_before_rollback` (:2109) | lib | 0.582s |\r\n  | `spt-daemon::false_promote ready_candidate_does_not_promote_until_the_wedged_old_gen_conn_drains` | int | 1.744s |\r\n\r\n  Denominator for the lib half: `brainproc`'s test module holds **26** `#[test]`/`#[tokio::test]`\r\n  cells, so **4 of 26 leaked, and all four are the trial/promote/rollback cells by name.** The\r\n  fifth is the integration rig that drives the same path.\r\n- **Why it is worth an entry even unmeasured:** four of the five are `kind(lib)`, so they run in\r\n  **`ci.yml` on every push**, not only in golden — if something really is left alive it is being\r\n  left alive on the shared Windows box many times a day. That is the same standing cost as\r\n  [[IR-79]]'s daemon face, arrived at from the opposite direction.\r\n- **HYPOTHESIS, labelled as such and NOT measured.** `supervise_brain` (:935) takes an injected\r\n  `spawn_child: impl FnMut(...) -> io::Result<Child>` (:941) and reaps candidates with bare\r\n  `let _ = child.kill();` at :998, :1015, :1055, :1071, :1081 — **`kill()` with no `wait()`.** On\r\n  Windows termination is asynchronous, and a killed-but-unreaped child can still hold the\r\n  inherited stdout/stderr pipe past the test's exit, which is exactly what nextest reports as\r\n  LEAK. The production spawner's own doc comment at :1190 states the intent — \"dies with no\r\n  orphaning. NOT `spawn_detached`\" — so if this is the mechanism, the code's intent and its\r\n  behaviour have diverged on one platform. **Every clause of this bullet is a reading of source,\r\n  not an observation of a live process. It may be entirely wrong.**\r\n- **FIRST MEASUREMENT — and doyle sharpened it 07:41Z from a census into a FALSIFIER, which is the\r\n  form to run:** on a free Windows box after W2, run\r\n  `trial_kills_alive_never_ready_candidate_before_rollback` **alone** and read one thing —\r\n  **is the killed pid still present, with the pipe handle open?** That is a yes/no against the\r\n  hypothesis above, not an open look at what happens to be running, and it is the difference\r\n  between a reading that settles the entry and a reading that produces more names. Capture pid,\r\n  image path and parent alongside the answer so a YES is immediately actionable, but the ANSWER is\r\n  the deliverable. One cell, one read. **Owner stays UNASSIGNED until it is taken** (doyle) — a\r\n  product path and a rig artifact are not distinguishable from here, and assigning before the read\r\n  would pick one by guess.\r\n- **Limits, so the entry cannot be overread:** nextest `LEAK` is **not a failure** — none of these\r\n  cells reds anything, and the run was green. Windows-only in **one** run; no trend established.\r\n  The clustering is by identifier and shared module, which is suggestive and is not causation.\r\n  I have not run any of these cells. Everything above is source plus one golden log — no box, no\r\n  build.\r\n- **Kin:** [[IR-79]] (children outliving the cell — the rig-teardown face of the same symptom, and\r\n  the reason doyle ruled these must stay SEPARATE: same symptom, different suspected owner),\r\n  [[IR-37]] rider 2 (the measurement that surfaced it), FLAKE-LEDGER's `resident_service_e2e` :664\r\n  teardown LEAK row.\r\n- **Ripe when:** the first free Windows box after W2 lands — it is a single-cell census, so it\r\n  fits any gap.\r\n- **Size:** unknown until the census. Tiny if it is a missing `wait()`; not tiny if the promotion\r\n  path leaves a real candidate brain alive on rollback.\r\n\r\n---\r\n\r\n#### THE LEAK SET IS NOISY — measured across three shas, 2026-09-07 (hertz)\r\n\r\n**This retracts the \"8 -> 5 leaky, direction favourable\" reading I flagged at 09:31Z.** It is not a\r\nfix and not an improvement; it is threshold noise, and the census this draft was built on inherits\r\nthat noise.\r\n\r\nWindows `ci` unit leg (`--workspace -E 'kind(lib) + kind(bin)'`), three consecutive shas:\r\n\r\n| cell | ff4b405d | e3bd53d4 | 401a19ad |\r\n|---|---|---|---|\r\n| brainproc::clear_before_spawn_defeats_exact_generation_stale_file | ● | ● | ● |\r\n| brainproc::ready_but_old_gen_never_drains_does_not_promote_rolls_back | ● | ● | ● |\r\n| brainproc::trial_kills_alive_never_ready_candidate_before_rollback | ● | ● | ● |\r\n| spt-runtime runtime::bounded_run_kills_on_timeout | ● | ● | ● |\r\n| brainproc::stale_generation_minus_one_ready_never_promotes | ● | ● | — |\r\n| spt-live digest::extractor_timeout_errors | ● | ● | — |\r\n| spt-live history::fetcher_timeout_errors | ● | ● | — |\r\n| spt-daemon broker::windows_session_is_zombie_sees_a_handle_held_corpse_as_dead | ● | — | — |\r\n| spt-daemon shellwake::kill_waker_at_still_kills_a_matching_pair | — | ● | ● |\r\n| **total** | **8** | **8** | **5** |\r\n\r\n**Causality check, which is what makes this a retraction rather than a hypothesis:** the three\r\ncommits between e3bd53d4 and 401a19ad touch **zero files** in brainproc, spt-live, spt-runtime,\r\nshellwake or broker (`git diff --name-only` over those paths returns nothing). The count fell by 3\r\nwith no change to any leaking module. So the drop cannot be a fix; the membership simply moves.\r\nNine cells appear in the union, only **four** are present at all three shas, and one\r\n(`shellwake::kill_waker_at`) *appeared* rather than vanished — a count that falls while a new member\r\njoins is the signature of a threshold, not of a repair.\r\n\r\n#### Three consequences for this draft\r\n\r\n1. **A count is not a quality signal here, in either direction.** Any future \"leaky went down\"\r\n   claim needs the NAME diff and a causality check against the changed files, or it is noise\r\n   reported as progress. I made exactly that error and it survived about twenty minutes.\r\n2. **The five-cell cluster is really \"three stable + one intermittent\".**\r\n   `stale_generation_minus_one_ready_never_promotes` is absent at 401a19ad. The cluster framing\r\n   still holds — three brainproc cells leak at every sha and they are all one module — but the\r\n   membership count must not be quoted as fixed.\r\n3. **doyle's falsifier beats my census, and this is the evidence.** The census (count the leaky\r\n   cells, name the cluster) is exactly what the noise destroys. His falsifier — *after\r\n   `trial_kills_alive_never_ready_candidate_before_rollback` on Windows, is the killed pid still\r\n   present with the pipe handle open?* — names ONE cell and probes a MECHANISM, and that cell is\r\n   **leaky at all three shas**, so it is the most stable target available. A mechanism probe is\r\n   immune to the threshold that moves the population. Owner stays UNASSIGNED until that read.\r\n\r\n#### One structural finding the noise does NOT touch\r\n**All nine union members spawn a child and then kill it, let it time out, or inspect its corpse** —\r\n`trial_kills_alive`, `kill_waker_at`, `bounded_run_kills_on_timeout`, `extractor_timeout_errors`,\r\n`fetcher_timeout_errors`, `windows_session_is_zombie_sees_a_handle_held_corpse_as_dead`, and the\r\nthree brainproc spawn/promote/rollback cells. Not one unrelated cell is in the set. Membership\r\nfluctuates; the *kind* of cell does not. That is a real signal about where child-process teardown\r\nis unreliable on Windows, and it is the same territory as [[ir79]] (rigs leaking daemons on a\r\nfailing assert) and [[ir81]] (kill scoping) — three drafts converging on one seam.\r\n\r\n---\r\n\r\n#### THE 12-CELL UNION — 4 shas x 2 OSes, membership beside the invariant (hertz, 2026-09-07 10:15Z)\r\n\r\nMachine-generated from the eight ci unit logs, not transcribed (a hand-typed 12x8 matrix is where\r\ntranscription errors live). `X` = reported LEAK at that sha on that box.\r\n\r\n| cell | W ff4b405d | W e3bd53d4 | W 401a19ad | W f3c8495b | L ff4b405d | L e3bd53d4 | L 401a19ad | L f3c8495b |\r\n|---|---|---|---|---|---|---|---|---|\r\n| `spt-daemon brainproc::tests::clear_before_spawn_defeats_exact_generation_stale_file` | X | X | X | X | . | . | . | . |\r\n| `spt-daemon brainproc::tests::ready_but_old_gen_never_drains_does_not_promote_rolls_back` | X | X | X | X | . | . | . | . |\r\n| `spt-daemon brainproc::tests::stale_generation_minus_one_ready_never_promotes` | X | X | . | X | . | . | . | . |\r\n| `spt-daemon brainproc::tests::trial_kills_alive_never_ready_candidate_before_rollback` | X | X | X | X | . | . | . | . |\r\n| `spt-daemon broker::tests::windows_session_is_zombie_sees_a_handle_held_corpse_as_dead` | X | . | . | X | . | . | . | . |\r\n| `spt-daemon livehost::tests::legacy_psyche_sweep_guard_is_id_specific_and_fail_safe` | . | . | . | . | X | X | X | . |\r\n| `spt-daemon shellhost::tests::kill_shell_at_still_kills_a_matching_pair` | . | . | . | X | . | . | . | . |\r\n| `spt-daemon shellwake::tests::kill_waker_at_still_kills_a_matching_pair` | . | X | X | X | . | . | . | . |\r\n| `spt-live digest::tests::extractor_timeout_errors` | X | X | . | X | . | . | . | . |\r\n| `spt-live history::tests::fetcher_timeout_errors` | X | X | . | . | . | . | . | . |\r\n| `spt-runtime runtime::tests::bounded_run_kills_on_timeout` | X | X | X | X | . | . | . | . |\r\n| `spt-store proc::tests::process_cmdline_reads_a_live_arg_marker` | . | . | . | . | X | X | X | X |\r\n| **leaky count** | 8 | 8 | 5 | 9 | 2 | 2 | 2 | 1 |\r\n\r\nUnion = 12 cells across 4 shas x 2 OSes. Present at EVERY Windows sha: 4. Present at every Linux sha: 1.\r\n\r\n#### Three readings, in increasing order of what they support\r\n\r\n**1. The churn is total and it is the whole point.** Windows counts run 8, 8, 5, 9 — the HIGHEST\r\nvalue is at `f3c8495b`, the tip carrying every fix F1-F16. Only **4 of 12** cells are present at\r\nevery Windows sha; only **1 of 2** at every Linux sha. Read as a quality signal the series says W2\r\nmade leaking worse, which is exactly as wrong as my retracted \"8 -> 5, favourable\" read and wrong\r\nfor the same reason. **A leaky count is not a signal in either direction.**\r\n\r\n**2. NEW, and I had not said it before building this table: the two OS sets are DISJOINT.** Ten\r\ncells leak only on Windows, two only on Linux, and **not one cell leaks on both**. Windows carries\r\n8-9 leaky cells per run against Linux's 1-2. So this is not one flaky population sampled twice —\r\nit is two populations with no overlap, and the Windows one is roughly five times larger. Any\r\nexplanation that treats \"leaky tests\" as a single phenomenon has to account for a clean partition\r\nby OS.\r\n\r\n**This is an OPEN QUESTION and the draft does not answer it. I do not have that explanation yet.**\r\nRecorded deliberately without a candidate cause: the partition is a measurement, and the temptation\r\nto pair a striking measurement with a plausible story is how the \"8 -> 5 is favourable\" reading got\r\ninto the record in the first place. Whoever takes this should arrive at a cause by reading, not by\r\ninheriting one from me.\r\n\r\n**SCOPED CAUSE, IN SOURCE, FOR ONE FAMILY ONLY (doyle ruled 10:22Z: source beats story; a source\r\ncause covering one family is a measurement and is filed as one).** The brainproc family leaks on\r\nWindows and not Linux because *its own fixture is asymmetric*: `long_child()` (brainproc.rs:1359)\r\nspawns `Command::new(\"cmd\").args([\"/C\",\"ping\",\"-n\",\"30\",\"127.0.0.1\"])` on Windows but\r\n`Command::new(\"sleep\").arg(\"30\")` on Unix — a shell wrapper on one box, a bare process on the other.\r\nThe Windows candidate the supervisor kills is `cmd`; the process burning 29 seconds is its child.\r\nThat is two lines of source, not an inference from the symptom. **And it is NOT the whole partition:**\r\n`process_cmdline_reads_a_live_arg_marker` uses a shell on BOTH arms (`sh -c \"sleep 30; : marker\"` /\r\n`cmd /C \"ping … & rem marker\"`) yet leaks on **Linux only** — the shell mechanism predicts it should\r\nleak on both boxes and it does not. So one family has a cause I can point at in the source, the\r\npartition as a whole remains OPEN, and the counterexample stands in this paragraph rather than a\r\nfootnote so no one carries the cause further than it goes.\r\n\r\n**THE PRODUCT PATH HAS NO INTERMEDIARY; THE FIXTURE DOES.** I chased the obvious escalation — if the\r\nreal supervisor also killed a shell wrapper, then \"never two live brains\"\r\n(REQ-HAZARD-BROKER-PROCESS-ISOLATION, the invariant this very cell guards) could be violated on\r\nWindows in production while the test stayed green. It cannot: `spawn_brain_child` (brainproc.rs:1224)\r\ndoes `Command::new(exe)` — the brain is spawned DIRECTLY, no shell, no grandchild, so a single-pid\r\nkill reaches it. **This is a test-fixture artifact, not a product defect**, and the fixture's shell\r\nis a Windows-only convenience for \"a process that blocks ~30s\" that introduced a layer the real path\r\ndoes not have. The negative is the useful half: it keeps the crashloop invariant out of IR-81 (a).\r\n\r\n**Why the cell passed review for as long as it did.** It asserts `pid != 0 && !pid_alive(pid)` before\r\nrollback, and that assertion is TRUE — `cmd` really is dead. The process still doing work is the one\r\nit never looks at. The leak and the green are not in tension; they are the same fact from two ends.\r\n**An assertion over a pid cannot see a tree.**\r\n\r\n**3. The invariant holds at 12 of 12, and it survived the population being shuffled three times.**\r\nEvery union member spawns a child process and then kills it, lets it time out, or inspects its\r\ncorpse — `trial_kills_alive`, `kill_shell_at`, `kill_waker_at`, `bounded_run_kills_on_timeout`,\r\n`extractor_timeout_errors`, `fetcher_timeout_errors`, `windows_session_is_zombie_..._corpse_as_dead`,\r\n`legacy_psyche_sweep_guard_...`, `process_cmdline_reads_a_live_arg_marker`, and the three brainproc\r\nspawn/promote/rollback cells. Membership churns freely across four shas and two OSes; the KIND of\r\ncell has not varied once. **This is the IR-80 headline** and it is better supported now than when it\r\nrested on a stable-looking five-cell cluster, precisely because the population underneath it has\r\nbeen reshuffled and the invariant did not move.\r\n\r\n#### A MECHANISM, read out of the source of the two Linux cells — calibrated, not generalized\r\n`process_cmdline_reads_a_live_arg_marker` spawns **`sh -c \"sleep 30; : marker\"`**, and the test's\r\nown comment says the trailing `; :` is deliberate — it keeps the shell RESIDENT so its\r\n`/proc/<pid>/cmdline` still carries the marker instead of being tail-exec-replaced by `sleep`. The\r\nteardown is `child.kill()` then `child.wait()`. **But `child` is the SHELL, and `sleep 30` is the\r\nshell's own child.** Killing the shell orphans the sleeper, which outlives the test by up to 30\r\nseconds — which is precisely what nextest reports as a LEAK. The Windows arm has the same shape:\r\n`cmd /C \"ping -n 30 127.0.0.1 >NUL & rem marker\"`, where `cmd` forks `ping`.\r\nSo the very construct that makes the test work (a resident shell, so the cmdline stays readable) is\r\nwhat guarantees a grandchild that a single-pid kill cannot reach.\r\n\r\n**What is verified and what is not, stated separately because the difference decides who owns this.**\r\nVERIFIED by reading source: this shape in BOTH Linux-only cells. CONSISTENT but not proven: the\r\nWindows family kills the same way — `kill_waker_at_still_kills_a_matching_pair` tears down with\r\n`kill_shell_pid(ours.id())`, a single-pid kill — so the mechanism is available to it, but I have not\r\nread every spawn helper. UNVERIFIED: the brainproc, broker and spt-live cells; those spawn real\r\nbrains and time out extractors, and may leak for unrelated reasons.\r\n\r\n**Why this matters beyond IR-80:** a single-pid kill that cannot reach a grandchild is exactly\r\n[[ir81]] arm (a) — identity and tree-awareness pushed into `kill_pid_tree`/`kill_pid` so no caller\r\ncan express the unreachable kill. If the mechanism above generalizes, IR-79 (rigs leaking daemons\r\non a failing assert), IR-80 (this) and IR-81 (kill scoping) are not three findings that share a\r\nseam, they are three FACES of one defect: **the codebase kills pids, and the things it needs dead\r\nare trees.** That is a claim worth testing, not asserting — and doyle's one-cell mechanism probe\r\nis still the right instrument, now with a sharper question: after the kill, is the surviving\r\nprocess the CHILD or the GRANDCHILD?\r\n\r\n---\r\n\r\n#### AMENDMENT 1 — \"a pid is not a tree\" has THREE faces, and only one of them is a kill\r\n\r\n*(hertz 2026-09-07, ruled by doyle 11:17Z: write this as an IR-80 amendment naming the three faces\r\nrather than three separate entries, so a reader hunting any one face lands on all three.)*\r\n\r\nThe register sentence this lane has been running on is doyle's: **a pid is not an identity and a pid\r\nis not a tree.** IR-80 and IR-81 were both filed against the KILL side, which made the sentence read\r\nlike a rule about killing. It is not. It is a rule about **which process you are talking about**, and\r\nkilling is only the face we happened to find first. Three faces are now measured, each found by a\r\ndifferent agent working a different problem:\r\n\r\n| face | the operation | what going one level too high produces | measured |\r\n|---|---|---|---|\r\n| **KILL** | `kill_pid(pid)` on a wrapper | the wrapper dies, the grandchild keeps working — the leak | IR-80's 12-cell union; `proc.rs:430`'s own doc states it |\r\n| **IDENTITY** | `kill_pid_tree(remembered_pid)` with no image read | you kill *a* process with that number, not the one you meant | IR-81 / #285, `broker.rs:8102` vs `servicehost.rs:651` |\r\n| **ENV READ** | `psutil.Process(child.pid).environ()` | the wrapper's env certifies a launch the battery would have failed | hertz 2026-09-07, self-test of `.github/bench/launch-battery.py` |\r\n\r\n**The third face, in full, because it is the newest and the least intuitive.** Reading back the\r\nenvironment of the process you spawned is the standard remedy for \"did my scrub/export actually\r\nland\" — it is what this project's own memory banked after the W0 perch-identity leak. It is\r\ninsufficient, and it fails in the flattering direction. A wrapper (`env VAR=x`, `cargo`, `nextest`,\r\n`bash -lc`) modifies the environment it hands the process **below** it, while its own `environ()`\r\nstill shows exactly what you passed in. So the read-back agrees with your intent, prints PROVEN, and\r\nsays nothing whatsoever about the process under test. Measured: the first version of\r\n`launch-battery.py` passed BOTH deliberately-negative tests. The corrected version walks descendants\r\nand, in the refusal, prints the wrapper as CLEAN beside the grandchild as VIOLATOR — that contrast\r\nis the face made visible in one line of output.\r\n\r\n**Why this belongs in IR-80 rather than in a new entry.** All three are the same error committed at\r\nthe same seam: an operation is aimed at a pid when the thing it needs to reach is a tree (or a\r\nspecific member of one). The remedies rhyme — walk the tree, read the identity, report the scope you\r\nactually covered — and a reader who finds any one face is one paragraph away from the other two.\r\nFiling them separately would have hidden that, which is the concrete cost doyle's ruling avoids.\r\n\r\n**What this amendment does NOT claim.** It does not widen IR-80's population: the 12-cell union\r\ntable and its Windows/Linux partition are unchanged, and the env face is not a test leak. It does\r\nnot add a remedy owner — the ENV face's fix is a tool (`.github/bench/launch-battery.py`), not product code, and the KILL and\r\nIDENTITY faces keep the owners they already have (#285 / todlando post-W2). It is a naming, and its\r\nwhole value is that the next instance of this error gets recognized as an instance instead of being\r\nfiled fresh.\r\n\r\n**Standing prediction, so this is falsifiable rather than tidy:** a fourth face exists wherever the\r\ncodebase asks a question *of* a pid that is really a question *about* a tree. The candidates I would\r\nlook at first are (a) liveness — `process_exists(pid)` answering \"is the work still running\" when\r\nthe work is a grandchild, and (b) resource attribution — reading a pid's handles/memory to decide\r\nwhether a lane is finished. Neither is measured; both are named so that finding one counts as\r\nconfirmation and finding none over the next few incidents counts against the generalization.\r\n\r\n### IR-81 — a process kill can be written scoped or machine-wide, and nothing makes the scoped form the only reachable one: both codebases carry the right pattern beside the wrong one\r\n\r\n- **Status:** OPEN, drafted by hertz 2026-09-07 08:38Z on doyle's dispatch (08:36Z), from the\r\n  fleet-daemon death on hfenduleam at 08:03:15Z ([[RCA-FLEET-DAEMON-14444]], cause still UNNAMED).\r\n  Census body: `docs/PID-KILL-CENSUS.md`. · **Origin:** doyle asked which sites kill a REMEMBERED\r\n  pid without re-verifying identity AT KILL TIME. The census answered that, and then answered a\r\n  better question nobody asked: **why the unguarded sites exist at all when the guarded ones sit\r\n  feet away.**\r\n- **⚠ THIS ENTRY IS NOT \"FIX THESE TWO SITES.\"** Both individual fixes are small and are dispatched\r\n  elsewhere (broker.rs:8102 → todlando's lane post-W2; live-relay-int.sh:78 → filed to perri). This\r\n  entry is about the thing that PRODUCED them and will produce the next one: the scoped form and the\r\n  machine-wide form are equally easy to write, equally plausible on review, and only one of them is\r\n  correct on a shared box.\r\n- **THE PAIRED EXHIBITS — same repo, same hand, feet apart.**\r\n\r\n  | | correct, and it says why | incorrect |\r\n  |---|---|---|\r\n  | **spt-core** | `spt-daemon/src/servicehost.rs:651` — `provably_gone` first, then `exe_path(pid)` compared to the parked image via `same_image`, then a FRESH post-kill read. Its comment IS the rule: *\"The pid is live. WHO is it? The image path decides — never the number.\"* | `spt-daemon/src/broker.rs:8102` — kills `spid`, a pid REMEMBERED off the session record, through `kill_pid_tree`. `zombie_verdict` consults liveness BY NUMBER (`process_exists`/`is_process_alive`), `adapter_labeled` (a property of the RECORD, not the live process), descendants and grace. **The live process's image is never read.** |\r\n  | **spt-claude-code** | `ci/launcher/bind-int.sh:50` — `wmic process where \"name='claude-spt.exe' and commandline like '%$ID%'\"`, scoped to this run's unique id, comment *\"never wall-a's\"*. Also `multi-subnet-bringup-int.sh:117` ($C3_ID) and `wake-survival-int.sh:64` (`-match '$PROBE'`). | `ci/psyche/live-relay-int.sh:78` — `for p in $(tasklist \\| grep -i claude-spt \\| awk '{print $2}'); do taskkill //PID \"$p\" //T //F; done` — **every** `claude-spt.exe` on the box, tree-force, no run-scoping. Comment: *\"by marker pid then name.\"* |\r\n\r\n  **The knowledge is not missing in either codebase. It is present, written down, and adjacent.**\r\n  Three correct sites to one wrong one in the adapter; a rule-stating comment in core. What is\r\n  missing is any mechanism that makes the wrong spelling hard to reach.\r\n- **Why \"just fix the sites\" is the wrong remedy:** it has already been tried implicitly — someone\r\n  wrote the scoped form three times, which is what a team looks like when it knows the rule and\r\n  still ships the exception. A fourth correct site does not prevent a fifth incorrect one. The\r\n  remedy has to change what is REACHABLE, not what is written.\r\n- **REMEDY — RULED 2026-09-07 08:40Z (doyle): (a) AND (b), not a choice between them. Two owners,\r\n  two lanes, and they cover different halves of the hazard.**\r\n  1. **(a) PRODUCT — push the identity requirement into the primitive.** `spt_store::proc::kill_pid_tree`\r\n     / `kill_pid` take an expected identity (image path, or a `same_image` closure) and refuse\r\n     without it, so a caller **cannot express** the unguarded kill; `servicehost.rs:651` stops being\r\n     the exception among callers and becomes the shape of all of them. **Owner: todlando, post-W2.**\r\n     ⇄ **This IS the fix shape of the `broker.rs:8102` board BUGFIX — that item and this entry\r\n     cross-reference each other; neither is complete alone.** Reaches Rust callers only.\r\n  2. **(b) GATE — `xtask check` refuses the unscoped spelling in CI scripts.** A `tasklist` /\r\n     `Get-Process` enumeration piped into a kill, or a bare `taskkill` with no\r\n     `commandline like` / `-match` scope in the same block, is a build failure. **Owner: hertz,\r\n     rides the IR-37 thin PR after W2 lands.** This is the half remedy (a) can NEVER reach — the\r\n     unguarded adapter site is a shell script, and no Rust signature constrains a shell script.\r\n  3. **(c) Fix the two sites and stop.** Recorded as CONSIDERED AND LOSING, not omitted: it has\r\n     already been tried implicitly — the adapter's author wrote the scoped form three times and\r\n     shipped the exception anyway — so a fourth correct site does not prevent a fifth wrong one.\r\n     It leaves the next instance free to appear.\r\n  **The (a)/(b) split is the entry's real content:** the hazard lives in two languages, and a remedy\r\n  in one of them is a half-measure that will read as a fix.\r\n- **STANDING LIMIT, so this entry is not overread as an incident cause:** none of these sites\r\n  explains the 08:03:15Z death. broker.rs:8102 would have been saved from firing by\r\n  `has_live_descendants` (the daemon had a live brain) — accidental protection, not deliberate —\r\n  and every claude-spt site enumerates `claude-spt.exe` while the dead process was `spt.exe`. The\r\n  census found a real hazard while looking for a different one. **Do not let this entry close the\r\n  incident.** The instrument at `C:\\Users\\decid\\.spt-watch\\daemon-watch.log` is what will answer\r\n  that, or fail to.\r\n- **Kin:** [[IR-79]] and [[IR-80]] (children outliving their cell; the leak family), the\r\n  [[RCA-FLEET-DAEMON-14444]] timeline, `servicehost.rs`'s own \"image path decides\" comment as the\r\n  in-tree statement of the rule, and the paired-exhibit method itself — a correct and an incorrect\r\n  site in one repo is stronger evidence about PROCESS than either site is about code.\r\n- **Ripe when:** the next touch of `spt-store/src/proc.rs` (for remedy 1) or of `xtask check`'s\r\n  gate family (for remedy 2). The adapter half is perri's, filed separately, and does not wait\r\n  on this.\r\n- **Size:** small for remedy 2, medium for remedy 1 (signature + every caller). The census that\r\n  justifies either is already written and does not need redoing.\r\n\r\n---\r\n\r\n#### ADAPTER-SIDE ARM: CLOSED (claude-spt, perri, 2026-09-07)\r\n\r\n**Status: closed in the consumer repo, test-only, does not close IR-81 here.**\r\n\r\n- **Commit `9c87372`** (spt-claude-code). Broad `tasklist | grep claude-spt | taskkill` replaced\r\n  with an **id-scoped wmic** call, **name-pinned so wmic cannot self-match**; the three\r\n  remembered-pid kills additionally got a **kill-time recheck**, covering the stale-identity face\r\n  as well as the unscoped-pattern face.\r\n- **Guard: `tests/ci-kill-scoping.sh`, traced as `REQ-HAZARD-CI-KILL-SCOPING`.** Gate green.\r\n  This is the check-shape arm (b) proposes for spt-core, already landed once — precedent, not\r\n  merely agreement.\r\n- **Scope: test/CI infrastructure only.** No product code changed. (doyle, 08:50Z.)\r\n- **`live-relay-int.sh:78` is retained as the historical RED exhibit** — the one genuinely\r\n  machine-wide kill found in the whole fleet census. It is the reason this hazard is written as a\r\n  hazard rather than a style note; do not quietly replace the exhibit with the fixed line.\r\n\r\n**Population lesson carried into arm (b)'s census.** I filed ONE site; perri confirmed **four**, and\r\nreports the idiom was already present in that repo **3x** before the filing. A filing that names one\r\nline under-counts its class by 3-4x in a single repo. **Census the ACT — any taskkill / pkill /\r\nwmic-delete reachable from a script root — never the literal string that led me to the first site.**\r\nState the walked roots in the check's own message, and give the gate a negative control that goes\r\nRED on a known-bad line before its green is trusted.\r\n\r\n**Still open here, unchanged:** arm (a), Rust-side identity pushed into `kill_pid_tree` / `kill_pid`\r\nso no Rust caller can express the unguarded kill (todlando, post-W2, cross-referenced with the\r\nbroker.rs:8102 board BUGFIX); and arm (b), the xtask script gate (mine, rides IR-37).\r\n\r\n---\r\n\r\n#### SCOPING ARM (a) — the product path has no intermediary; the fixture does\r\n*(hertz 2026-09-07, ruled by doyle 10:22Z off the IR-80 leak work.)*\r\n\r\n> **A pid is not an identity and a pid is not a tree. IR-80 needs CALLERS, not code.**\r\n> *(The register's sentence — doyle 10:23Z. Arm (a) fixes the identity half in\r\n> `kill_pid`/`kill_pid_tree`; the tree half needs no new machinery, because `kill_pid_tree` already\r\n> exists at proc.rs:430 with the defect stated in its own doc. This is why IR-79, IR-80 and IR-81\r\n> converge on one seam without collapsing into one finding.)*\r\n\r\nMeasured, not inferred: **`spawn_brain_child` (crates/spt-daemon/src/brainproc.rs:1224) does\r\n`Command::new(exe)`** — the real brain is spawned DIRECTLY, with no shell and no launcher between\r\nthe daemon and the process it supervises. So on the crashloop/rollback path a single-pid kill\r\n*does* reach the thing it aims at, and the \"orphaned grandchild\" mechanism found in the IR-80 leak\r\ncells is **a property of the TEST FIXTURE**, whose `long_child()` (brainproc.rs:1359) goes through\r\n`cmd /C` on Windows, not of the product.\r\n\r\n**What that scopes.** Arm (a) is NOT about the brain-supervision path and must not be sold as\r\nprotecting `REQ-HAZARD-BROKER-PROCESS-ISOLATION` (\"never two live brains\") — that invariant is not\r\nat risk here, and claiming it would be borrowing urgency this arm has not earned. Arm (a) stays\r\npointed at **the broker.rs:8102 reap, where the image is never read** — a kill aimed by pid alone\r\nat a process whose identity was never verified. That is the real unguarded form, and it is a\r\ndifferent failure (kill the wrong process) from the one IR-80 surfaced (fail to kill the right\r\none).\r\n\r\n**The two failures are different, which is why the drafts converge without collapsing.** Arm (a) is\r\n*kill the wrong process* (identity never read); IR-80 is *fail to kill the right one* (tree never\r\nwalked). The identity half is todlando's, post-W2. The tree half is already solved in-tree —\r\n`kill_pid_tree` at proc.rs:430, whose doc states the defect outright (\"a single-pid `kill_pid` leaves\r\nthe wrapper's harness children orphaned + running\") — so IR-80 ships callers, not machinery. See\r\n[[RIDER 4]] for the two test-side callers.\r\n\r\n### IR-82 — a daemon death leaves NO record of who died: autostart decides on a socket ping, says \"no daemon\", and the successor overwrites the only handle on the corpse\r\n\r\n- **Status:** RULED 2026-09-07 11:07Z (doyle), drafted by hertz 11:04Z on doyle's dispatch (11:03Z: *\"the autostart\r","truncated":true,"truncatedBy":"lines","totalLines":2755,"totalBytes":32629,"outputLines":411,"outputBytes":32629,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6937,"displayContent":{"text":"### IR-79 — 22 of the 31 rig binaries leak their daemon tree on a failing assert: teardown is a statement, not a guard\n…\n- **Status:** OPEN, filed by hertz 2026-09-07 on doyle's dispatch during PR #198's CI window,\n…\n- **Size:** medium — one guard in `common`, then 22 mechanical adoptions, each provable by\n…\n\r\n### IR-80 — five leaky cells on ONE module (`brainproc` / `supervise_brain`), Windows only: a candidate PRODUCT leak on the promotion/rollback path, or a cluster of names — nobody has looked yet\r\n\r\n- **Status:** OPEN for the residual population, not an undiagnosed five-name product claim.\r\n  Later amendments identify the brainproc shell-wrapper fixture mechanism and distinguish\r\n  production's direct spawn; they do not classify all 12 union members. Historical opening\r\n  hypotheses below are not current causal conclusions. Filed by hertz 2026-09-07 07:40Z on\r\n  doyle's ruling that this retains its own identity, separate from IR-79.\r\n  **Origin:** noticed while measuring the #198 HEAVY scan-root gap ([[IR-37]] rider 2); the leak\r\n  roster was read out of the baseline golden log for an unrelated reason.\r\n- **⚠ WHAT THIS ENTRY IS, STATED FIRST SO IT IS NOT OVERREAD: a CLUSTER OF NAMES.** Five cells\r\n  that leaked share one module and one code path by their identifiers. Nothing has been measured\r\n  about WHAT is left alive, and a shared module is not a shared cause. Do not cite this as a\r\n  product defect until the census below has run.\r\n- **The observation, exact.** Golden run **34017906638**, sha `04e32c8c95cf`, both boxes, Phase A.\r\n  Windows (hfenduleam) reported **9 leaky** cells; Linux (kitsubito) **1** (`livehost::tests::\r\n  legacy_psyche_sweep_guard_is_id_specific_and_fail_safe`, unrelated). **Five of the Windows nine\r\n  are the same module:**\r\n\r\n  | cell | kind | time |\r\n  |---|---|---|\r\n  | `spt-daemon brainproc::tests::clear_before_spawn_defeats_exact_generation_stale_file` (:2200) | lib | 0.457s |\r\n  | `spt-daemon brainproc::tests::ready_but_old_gen_never_drains_does_not_promote_rolls_back` (:1834) | lib | 0.554s |\r\n  | `spt-daemon brainproc::tests::stale_generation_minus_one_ready_never_promotes` (:2155) | lib | 0.731s |\r\n  | `spt-daemon brainproc::tests::trial_kills_alive_never_ready_candidate_before_rollback` (:2109) | lib | 0.582s |\r\n  | `spt-daemon::false_promote ready_candidate_does_not_promote_until_the_wedged_old_gen_conn_drains` | int | 1.744s |\r\n\r\n  Denominator for the lib half: `brainproc`'s test module holds **26** `#[test]`/`#[tokio::test]`\r\n  cells, so **4 of 26 leaked, and all four are the trial/promote/rollback cells by name.** The\r\n  fifth is the integration rig that drives the same path.\r\n- **Why it is worth an entry even unmeasured:** four of the five are `kind(lib)`, so they run in\r\n  **`ci.yml` on every push**, not only in golden — if something really is left alive it is being\r\n  left alive on the shared Windows box many times a day. That is the same standing cost as\r\n  [[IR-79]]'s daemon face, arrived at from the opposite direction.\r\n- **HYPOTHESIS, labelled as such and NOT measured.** `supervise_brain` (:935) takes an injected\r\n  `spawn_child: impl FnMut(...) -> io::Result<Child>` (:941) and reaps candidates with bare\r\n  `let _ = child.kill();` at :998, :1015, :1055, :1071, :1081 — **`kill()` with no `wait()`.** On\r\n  Windows termination is asynchronous, and a killed-but-unreaped child can still hold the\r\n  inherited stdout/stderr pipe past the test's exit, which is exactly what nextest reports as\r\n  LEAK. The production spawner's own doc comment at :1190 states the intent — \"dies with no\r\n  orphaning. NOT `spawn_detached`\" — so if this is the mechanism, the code's intent and its\r\n  behaviour have diverged on one platform. **Every clause of this bullet is a reading of source,\r\n  not an observation of a live process. It may be entirely wrong.**\r\n- **FIRST MEASUREMENT — and doyle sharpened it 07:41Z from a census into a FALSIFIER, which is the\r\n  form to run:** on a free Windows box after W2, run\r\n  `trial_kills_alive_never_ready_candidate_before_rollback` **alone** and read one thing —\r\n  **is the killed pid still present, with the pipe handle open?** That is a yes/no against the\r\n  hypothesis above, not an open look at what happens to be running, and it is the difference\r\n  between a reading that settles the entry and a reading that produces more names. Capture pid,\r\n  image path and parent alongside the answer so a YES is immediately actionable, but the ANSWER is\r\n  the deliverable. One cell, one read. **Owner stays UNASSIGNED until it is taken** (doyle) — a\r\n  product path and a rig artifact are not distinguishable from here, and assigning before the read\r\n  would pick one by guess.\r\n- **Limits, so the entry cannot be overread:** nextest `LEAK` is **not a failure** — none of these\r\n  cells reds anything, and the run was green. Windows-only in **one** run; no trend established.\r\n  The clustering is by identifier and shared module, which is suggestive and is not causation.\r\n  I have not run any of these cells. Everything above is source plus one golden log — no box, no\r\n  build.\r\n- **Kin:** [[IR-79]] (children outliving the cell — the rig-teardown face of the same symptom, and\r\n  the reason doyle ruled these must stay SEPARATE: same symptom, different suspected owner),\r\n  [[IR-37]] rider 2 (the measurement that surfaced it), FLAKE-LEDGER's `resident_service_e2e` :664\r\n  teardown LEAK row.\r\n- **Ripe when:** the first free Windows box after W2 lands — it is a single-cell census, so it\r\n  fits any gap.\r\n- **Size:** unknown until the census. Tiny if it is a missing `wait()`; not tiny if the promotion\r\n  path leaves a real candidate brain alive on rollback.\r\n\r\n---\r\n\r\n#### THE LEAK SET IS NOISY — measured across three shas, 2026-09-07 (hertz)\r\n\r\n**This retracts the \"8 -> 5 leaky, direction favourable\" reading I flagged at 09:31Z.** It is not a\r\nfix and not an improvement; it is threshold noise, and the census this draft was built on inherits\r\nthat noise.\r\n\r\nWindows `ci` unit leg (`--workspace -E 'kind(lib) + kind(bin)'`), three consecutive shas:\r\n\r\n| cell | ff4b405d | e3bd53d4 | 401a19ad |\r\n|---|---|---|---|\r\n| brainproc::clear_before_spawn_defeats_exact_generation_stale_file | ● | ● | ● |\r\n| brainproc::ready_but_old_gen_never_drains_does_not_promote_rolls_back | ● | ● | ● |\r\n| brainproc::trial_kills_alive_never_ready_candidate_before_rollback | ● | ● | ● |\r\n| spt-runtime runtime::bounded_run_kills_on_timeout | ● | ● | ● |\r\n| brainproc::stale_generation_minus_one_ready_never_promotes | ● | ● | — |\r\n| spt-live digest::extractor_timeout_errors | ● | ● | — |\r\n| spt-live history::fetcher_timeout_errors | ● | ● | — |\r\n| spt-daemon broker::windows_session_is_zombie_sees_a_handle_held_corpse_as_dead | ● | — | — |\r\n| spt-daemon shellwake::kill_waker_at_still_kills_a_matching_pair | — | ● | ● |\r\n| **total** | **8** | **8** | **5** |\r\n\r\n**Causality check, which is what makes this a retraction rather than a hypothesis:** the three\r\ncommits between e3bd53d4 and 401a19ad touch **zero files** in brainproc, spt-live, spt-runtime,\r\nshellwake or broker (`git diff --name-only` over those paths returns nothing). The count fell by 3\r\nwith no change to any leaking module. So the drop cannot be a fix; the membership simply moves.\r\nNine cells appear in the union, only **four** are present at all three shas, and one\r\n(`shellwake::kill_waker_at`) *appeared* rather than vanished — a count that falls while a new member\r\njoins is the signature of a threshold, not of a repair.\r\n\r\n#### Three consequences for this draft\r\n\r\n1. **A count is not a quality signal here, in either direction.** Any future \"leaky went down\"\r\n   claim needs the NAME diff and a causality check against the changed files, or it is noise\r\n   reported as progress. I made exactly that error and it survived about twenty minutes.\r\n2. **The five-cell cluster is really \"three stable + one intermittent\".**\r\n   `stale_generation_minus_one_ready_never_promotes` is absent at 401a19ad. The cluster framing\r\n   still holds — three brainproc cells leak at every sha and they are all one module — but the\r\n   membership count must not be quoted as fixed.\r\n3. **doyle's falsifier beats my census, and this is the evidence.** The census (count the leaky\r\n   cells, name the cluster) is exactly what the noise destroys. His falsifier — *after\r\n   `trial_kills_alive_never_ready_candidate_before_rollback` on Windows, is the killed pid still\r\n   present with the pipe handle open?* — names ONE cell and probes a MECHANISM, and that cell is\r\n   **leaky at all three shas**, so it is the most stable target available. A mechanism probe is\r\n   immune to the threshold that moves the population. Owner stays UNASSIGNED until that read.\r\n\r\n#### One structural finding the noise does NOT touch\r\n**All nine union members spawn a child and then kill it, let it time out, or inspect its corpse** —\r\n`trial_kills_alive`, `kill_waker_at`, `bounded_run_kills_on_timeout`, `extractor_timeout_errors`,\r\n`fetcher_timeout_errors`, `windows_session_is_zombie_sees_a_handle_held_corpse_as_dead`, and the\r\nthree brainproc spawn/promote/rollback cells. Not one unrelated cell is in the set. Membership\r\nfluctuates; the *kind* of cell does not. That is a real signal about where child-process teardown\r\nis unreliable on Windows, and it is the same territory as [[ir79]] (rigs leaking daemons on a\r\nfailing assert) and [[ir81]] (kill scoping) — three drafts converging on one seam.\r\n\r\n---\r\n\r\n#### THE 12-CELL UNION — 4 shas x 2 OSes, membership beside the invariant (hertz, 2026-09-07 10:15Z)\r\n\r\nMachine-generated from the eight ci unit logs, not transcribed (a hand-typed 12x8 matrix is where\r\ntranscription errors live). `X` = reported LEAK at that sha on that box.\r\n\r\n| cell | W ff4b405d | W e3bd53d4 | W 401a19ad | W f3c8495b | L ff4b405d | L e3bd53d4 | L 401a19ad | L f3c8495b |\r\n|---|---|---|---|---|---|---|---|---|\r\n| `spt-daemon brainproc::tests::clear_before_spawn_defeats_exact_generation_stale_file` | X | X | X | X | . | . | . | . |\r\n| `spt-daemon brainproc::tests::ready_but_old_gen_never_drains_does_not_promote_rolls_back` | X | X | X | X | . | . | . | . |\r\n| `spt-daemon brainproc::tests::stale_generation_minus_one_ready_never_promotes` | X | X | . | X | . | . | . | . |\r\n| `spt-daemon brainproc::tests::trial_kills_alive_never_ready_candidate_before_rollback` | X | X | X | X | . | . | . | . |\r\n| `spt-daemon broker::tests::windows_session_is_zombie_sees_a_handle_held_corpse_as_dead` | X | . | . | X | . | . | . | . |\r\n| `spt-daemon livehost::tests::legacy_psyche_sweep_guard_is_id_specific_and_fail_safe` | . | . | . | . | X | X | X | . |\r\n| `spt-daemon shellhost::tests::kill_shell_at_still_kills_a_matching_pair` | . | . | . | X | . | . | . | . |\r\n| `spt-daemon shellwake::tests::kill_waker_at_still_kills_a_matching_pair` | . | X | X | X | . | . | . | . |\r\n| `spt-live digest::tests::extractor_timeout_errors` | X | X | . | X | . | . | . | . |\r\n| `spt-live history::tests::fetcher_timeout_errors` | X | X | . | . | . | . | . | . |\r\n| `spt-runtime runtime::tests::bounded_run_kills_on_timeout` | X | X | X | X | . | . | . | . |\r\n| `spt-store proc::tests::process_cmdline_reads_a_live_arg_marker` | . | . | . | . | X | X | X | X |\r\n| **leaky count** | 8 | 8 | 5 | 9 | 2 | 2 | 2 | 1 |\r\n\r\nUnion = 12 cells across 4 shas x 2 OSes. Present at EVERY Windows sha: 4. Present at every Linux sha: 1.\r\n\r\n#### Three readings, in increasing order of what they support\r\n\r\n**1. The churn is total and it is the whole point.** Windows counts run 8, 8, 5, 9 — the HIGHEST\r\nvalue is at `f3c8495b`, the tip carrying every fix F1-F16. Only **4 of 12** cells are present at\r\nevery Windows sha; only **1 of 2** at every Linux sha. Read as a quality signal the series says W2\r\nmade leaking worse, which is exactly as wrong as my retracted \"8 -> 5, favourable\" read and wrong\r\nfor the same reason. **A leaky count is not a signal in either direction.**\r\n\r\n**2. NEW, and I had not said it before building this table: the two OS sets are DISJOINT.** Ten\r\ncells leak only on Windows, two only on Linux, and **not one cell leaks on both**. Windows carries\r\n8-9 leaky cells per run against Linux's 1-2. So this is not one flaky population sampled twice —\r\nit is two populations with no overlap, and the Windows one is roughly five times larger. Any\r\nexplanation that treats \"leaky tests\" as a single phenomenon has to account for a clean partition\r\nby OS.\r\n\r\n**This is an OPEN QUESTION and the draft does not answer it. I do not have that explanation yet.**\r\nRecorded deliberately without a candidate cause: the partition is a measurement, and the temptation\r\nto pair a striking measurement with a plausible story is how the \"8 -> 5 is favourable\" reading got\r\ninto the record in the first place. Whoever takes this should arrive at a cause by reading, not by\r\ninheriting one from me.\r\n\r\n**SCOPED CAUSE, IN SOURCE, FOR ONE FAMILY ONLY (doyle ruled 10:22Z: source beats story; a source\r\ncause covering one family is a measurement and is filed as one).** The brainproc family leaks on\r\nWindows and not Linux because *its own fixture is asymmetric*: `long_child()` (brainproc.rs:1359)\r\nspawns `Command::new(\"cmd\").args([\"/C\",\"ping\",\"-n\",\"30\",\"127.0.0.1\"])` on Windows but\r\n`Command::new(\"sleep\").arg(\"30\")` on Unix — a shell wrapper on one box, a bare process on the other.\r\nThe Windows candidate the supervisor kills is `cmd`; the process burning 29 seconds is its child.\r\nThat is two lines of source, not an inference from the symptom. **And it is NOT the whole partition:**\r\n`process_cmdline_reads_a_live_arg_marker` uses a shell on BOTH arms (`sh -c \"sleep 30; : marker\"` /\r\n`cmd /C \"ping … & rem marker\"`) yet leaks on **Linux only** — the shell mechanism predicts it should\r\nleak on both boxes and it does not. So one family has a cause I can point at in the source, the\r\npartition as a whole remains OPEN, and the counterexample stands in this paragraph rather than a\r\nfootnote so no one carries the cause further than it goes.\r\n\r\n**THE PRODUCT PATH HAS NO INTERMEDIARY; THE FIXTURE DOES.** I chased the obvious escalation — if the\r\nreal supervisor also killed a shell wrapper, then \"never two live brains\"\r\n(REQ-HAZARD-BROKER-PROCESS-ISOLATION, the invariant this very cell guards) could be violated on\r\nWindows in production while the test stayed green. It cannot: `spawn_brain_child` (brainproc.rs:1224)\r\ndoes `Command::new(exe)` — the brain is spawned DIRECTLY, no shell, no grandchild, so a single-pid\r\nkill reaches it. **This is a test-fixture artifact, not a product defect**, and the fixture's shell\r\nis a Windows-only convenience for \"a process that blocks ~30s\" that introduced a layer the real path\r\ndoes not have. The negative is the useful half: it keeps the crashloop invariant out of IR-81 (a).\r\n\r\n**Why the cell passed review for as long as it did.** It asserts `pid != 0 && !pid_alive(pid)` before\r\nrollback, and that assertion is TRUE — `cmd` really is dead. The process still doing work is the one\r\nit never looks at. The leak and the green are not in tension; they are the same fact from two ends.\r\n**An assertion over a pid cannot see a tree.**\r\n\r\n**3. The invariant holds at 12 of 12, and it survived the population being shuffled three times.**\r\nEvery union member spawns a child process and then kills it, lets it time out, or inspects its\r\ncorpse — `trial_kills_alive`, `kill_shell_at`, `kill_waker_at`, `bounded_run_kills_on_timeout`,\r\n`extractor_timeout_errors`, `fetcher_timeout_errors`, `windows_session_is_zombie_..._corpse_as_dead`,\r\n`legacy_psyche_sweep_guard_...`, `process_cmdline_reads_a_live_arg_marker`, and the three brainproc\r\nspawn/promote/rollback cells. Membership churns freely across four shas and two OSes; the KIND of\r\ncell has not varied once. **This is the IR-80 headline** and it is better supported now than when it\r\nrested on a stable-looking five-cell cluster, precisely because the population underneath it has\r\nbeen reshuffled and the invariant did not move.\r\n\r\n#### A MECHANISM, read out of the source of the two Linux cells — calibrated, not generalized\r\n`process_cmdline_reads_a_live_arg_marker` spawns **`sh -c \"sleep 30; : marker\"`**, and the test's\r\nown comment says the trailing `; :` is deliberate — it keeps the shell RESIDENT so its\r\n`/proc/<pid>/cmdline` still carries the marker instead of being tail-exec-replaced by `sleep`. The\r\nteardown is `child.kill()` then `child.wait()`. **But `child` is the SHELL, and `sleep 30` is the\r\nshell's own child.** Killing the shell orphans the sleeper, which outlives the test by up to 30\r\nseconds — which is precisely what nextest reports as a LEAK. The Windows arm has the same shape:\r\n`cmd /C \"ping -n 30 127.0.0.1 >NUL & rem marker\"`, where `cmd` forks `ping`.\r\nSo the very construct that makes the test work (a resident shell, so the cmdline stays readable) is\r\nwhat guarantees a grandchild that a single-pid kill cannot reach.\r\n\r\n**What is verified and what is not, stated separately because the difference decides who owns this.**\r\nVERIFIED by reading source: this shape in BOTH Linux-only cells. CONSISTENT but not proven: the\r\nWindows family kills the same way — `kill_waker_at_still_kills_a_matching_pair` tears down with\r\n`kill_shell_pid(ours.id())`, a single-pid kill — so the mechanism is available to it, but I have not\r\nread every spawn helper. UNVERIFIED: the brainproc, broker and spt-live cells; those spawn real\r\nbrains and time out extractors, and may leak for unrelated reasons.\r\n\r\n**Why this matters beyond IR-80:** a single-pid kill that cannot reach a grandchild is exactly\r\n[[ir81]] arm (a) — identity and tree-awareness pushed into `kill_pid_tree`/`kill_pid` so no caller\r\ncan express the unreachable kill. If the mechanism above generalizes, IR-79 (rigs leaking daemons\r\non a failing assert), IR-80 (this) and IR-81 (kill scoping) are not three findings that share a\r\nseam, they are three FACES of one defect: **the codebase kills pids, and the things it needs dead\r\nare trees.** That is a claim worth testing, not asserting — and doyle's one-cell mechanism probe\r\nis still the right instrument, now with a sharper question: after the kill, is the surviving\r\nprocess the CHILD or the GRANDCHILD?\r\n\r\n---\r\n\r\n#### AMENDMENT 1 — \"a pid is not a tree\" has THREE faces, and only one of them is a kill\r\n\r\n*(hertz 2026-09-07, ruled by doyle 11:17Z: write this as an IR-80 amendment naming the three faces\r\nrather than three separate entries, so a reader hunting any one face lands on all three.)*\r\n\r\nThe register sentence this lane has been running on is doyle's: **a pid is not an identity and a pid\r\nis not a tree.** IR-80 and IR-81 were both filed against the KILL side, which made the sentence read\r\nlike a rule about killing. It is not. It is a rule about **which process you are talking about**, and\r\nkilling is only the face we happened to find first. Three faces are now measured, each found by a\r\ndifferent agent working a different problem:\r\n\r\n| face | the operation | what going one level too high produces | measured |\r\n|---|---|---|---|\r\n| **KILL** | `kill_pid(pid)` on a wrapper | the wrapper dies, the grandchild keeps working — the leak | IR-80's 12-cell union; `proc.rs:430`'s own doc states it |\r\n| **IDENTITY** | `kill_pid_tree(remembered_pid)` with no image read | you kill *a* process with that number, not the one you meant | IR-81 / #285, `broker.rs:8102` vs `servicehost.rs:651` |\r\n| **ENV READ** | `psutil.Process(child.pid).environ()` | the wrapper's env certifies a launch the battery would have failed | hertz 2026-09-07, self-test of `.github/bench/launch-battery.py` |\r\n\r\n**The third face, in full, because it is the newest and the least intuitive.** Reading back the\r\nenvironment of the process you spawned is the standard remedy for \"did my scrub/export actually\r\nland\" — it is what this project's own memory banked after the W0 perch-identity leak. It is\r\ninsufficient, and it fails in the flattering direction. A wrapper (`env VAR=x`, `cargo`, `nextest`,\r\n`bash -lc`) modifies the environment it hands the process **below** it, while its own `environ()`\r\nstill shows exactly what you passed in. So the read-back agrees with your intent, prints PROVEN, and\r\nsays nothing whatsoever about the process under test. Measured: the first version of\r\n`launch-battery.py` passed BOTH deliberately-negative tests. The corrected version walks descendants\r\nand, in the refusal, prints the wrapper as CLEAN beside the grandchild as VIOLATOR — that contrast\r\nis the face made visible in one line of output.\r\n\r\n**Why this belongs in IR-80 rather than in a new entry.** All three are the same error committed at\r\nthe same seam: an operation is aimed at a pid when the thing it needs to reach is a tree (or a\r\nspecific member of one). The remedies rhyme — walk the tree, read the identity, report the scope you\r\nactually covered — and a reader who finds any one face is one paragraph away from the other two.\r\nFiling them separately would have hidden that, which is the concrete cost doyle's ruling avoids.\r\n\r\n**What this amendment does NOT claim.** It does not widen IR-80's population: the 12-cell union\r\ntable and its Windows/Linux partition are unchanged, and the env face is not a test leak. It does\r\nnot add a remedy owner — the ENV face's fix is a tool (`.github/bench/launch-battery.py`), not product code, and the KILL and\r\nIDENTITY faces keep the owners they already have (#285 / todlando post-W2). It is a naming, and its\r\nwhole value is that the next instance of this error gets recognized as an instance instead of being\r\nfiled fresh.\r\n\r\n**Standing prediction, so this is falsifiable rather than tidy:** a fourth face exists wherever the\r\ncodebase asks a question *of* a pid that is really a question *about* a tree. The candidates I would\r\nlook at first are (a) liveness — `process_exists(pid)` answering \"is the work still running\" when\r\nthe work is a grandchild, and (b) resource attribution — reading a pid's handles/memory to decide\r\nwhether a lane is finished. Neither is measured; both are named so that finding one counts as\r\nconfirmation and finding none over the next few incidents counts against the generalization.\r\n\r\n### IR-81 — a process kill can be written scoped or machine-wide, and nothing makes the scoped form the only reachable one: both codebases carry the right pattern beside the wrong one\r\n\r\n- **Status:** OPEN, drafted by hertz 2026-09-07 08:38Z on doyle's dispatch (08:36Z), from the\r\n  fleet-daemon death on hfenduleam at 08:03:15Z ([[RCA-FLEET-DAEMON-14444]], cause still UNNAMED).\r\n  Census body: `docs/PID-KILL-CENSUS.md`. · **Origin:** doyle asked which sites kill a REMEMBERED\r\n  pid without re-verifying identity AT KILL TIME. The census answered that, and then answered a\r\n  better question nobody asked: **why the unguarded sites exist at all when the guarded ones sit\r\n  feet away.**\r\n- **⚠ THIS ENTRY IS NOT \"FIX THESE TWO SITES.\"** Both individual fixes are small and are dispatched\r\n  elsewhere (broker.rs:8102 → todlando's lane post-W2; live-relay-int.sh:78 → filed to perri). This\r\n  entry is about the thing that PRODUCED them and will produce the next one: the scoped form and the\r\n  machine-wide form are equally easy to write, equally plausible on review, and only one of them is\r\n  correct on a shared box.\r\n- **THE PAIRED EXHIBITS — same repo, same hand, feet apart.**\r\n\r\n  | | correct, and it says why | incorrect |\r\n  |---|---|---|\r\n  | **spt-core** | `spt-daemon/src/servicehost.rs:651` — `provably_gone` first, then `exe_path(pid)` compared to the parked image via `same_image`, then a FRESH post-kill read. Its comment IS the rule: *\"The pid is live. WHO is it? The image path decides — never the number.\"* | `spt-daemon/src/broker.rs:8102` — kills `spid`, a pid REMEMBERED off the session record, through `kill_pid_tree`. `zombie_verdict` consults liveness BY NUMBER (`process_exists`/`is_process_alive`), `adapter_labeled` (a property of the RECORD, not the live process), descendants and grace. **The live process's image is never read.** |\r\n  | **spt-claude-code** | `ci/launcher/bind-int.sh:50` — `wmic process where \"name='claude-spt.exe' and commandline like '%$ID%'\"`, scoped to this run's unique id, comment *\"never wall-a's\"*. Also `multi-subnet-bringup-int.sh:117` ($C3_ID) and `wake-survival-int.sh:64` (`-match '$PROBE'`). | `ci/psyche/live-relay-int.sh:78` — `for p in $(tasklist \\| grep -i claude-spt \\| awk '{print $2}'); do taskkill //PID \"$p\" //T //F; done` — **every** `claude-spt.exe` on the box, tree-force, no run-scoping. Comment: *\"by marker pid then name.\"* |\r\n\r\n  **The knowledge is not missing in either codebase. It is present, written down, and adjacent.**\r\n  Three correct sites to one wrong one in the adapter; a rule-stating comment in core. What is\r\n  missing is any mechanism that makes the wrong spelling hard to reach.\r\n- **Why \"just fix the sites\" is the wrong remedy:** it has already been tried implicitly — someone\r\n  wrote the scoped form three times, which is what a team looks like when it knows the rule and\r\n  still ships the exception. A fourth correct site does not prevent a fifth incorrect one. The\r\n  remedy has to change what is REACHABLE, not what is written.\r\n- **REMEDY — RULED 2026-09-07 08:40Z (doyle): (a) AND (b), not a choice between them. Two owners,\r\n  two lanes, and they cover different halves of the hazard.**\r\n  1. **(a) PRODUCT — push the identity requirement into the primitive.** `spt_store::proc::kill_pid_tree`\r\n     / `kill_pid` take an expected identity (image path, or a `same_image` closure) and refuse\r\n     without it, so a caller **cannot express** the unguarded kill; `servicehost.rs:651` stops being\r\n     the exception among callers and becomes the shape of all of them. **Owner: todlando, post-W2.**\r\n     ⇄ **This IS the fix shape of the `broker.rs:8102` board BUGFIX — that item and this entry\r\n     cross-reference each other; neither is complete alone.** Reaches Rust callers only.\r\n  2. **(b) GATE — `xtask check` refuses the unscoped spelling in CI scripts.** A `tasklist` /\r\n     `Get-Process` enumeration piped into a kill, or a bare `taskkill` with no\r\n     `commandline like` / `-match` scope in the same block, is a build failure. **Owner: hertz,\r\n     rides the IR-37 thin PR after W2 lands.** This is the half remedy (a) can NEVER reach — the\r\n     unguarded adapter site is a shell script, and no Rust signature constrains a shell script.\r\n  3. **(c) Fix the two sites and stop.** Recorded as CONSIDERED AND LOSING, not omitted: it has\r\n     already been tried implicitly — the adapter's author wrote the scoped form three times and\r\n     shipped the exception anyway — so a fourth correct site does not prevent a fifth wrong one.\r\n     It leaves the next instance free to appear.\r\n  **The (a)/(b) split is the entry's real content:** the hazard lives in two languages, and a remedy\r\n  in one of them is a half-measure that will read as a fix.\r\n- **STANDING LIMIT, so this entry is not overread as an incident cause:** none of these sites\r\n  explains the 08:03:15Z death. broker.rs:8102 would have been saved from firing by\r\n  `has_live_descendants` (the daemon had a live brain) — accidental protection, not deliberate —\r\n  and every claude-spt site enumerates `claude-spt.exe` while the dead process was `spt.exe`. The\r\n  census found a real hazard while looking for a different one. **Do not let this entry close the\r\n  incident.** The instrument at `C:\\Users\\decid\\.spt-watch\\daemon-watch.log` is what will answer\r\n  that, or fail to.\r\n- **Kin:** [[IR-79]] and [[IR-80]] (children outliving their cell; the leak family), the\r\n  [[RCA-FLEET-DAEMON-14444]] timeline, `servicehost.rs`'s own \"image path decides\" comment as the\r\n  in-tree statement of the rule, and the paired-exhibit method itself — a correct and an incorrect\r\n  site in one repo is stronger evidence about PROCESS than either site is about code.\r\n- **Ripe when:** the next touch of `spt-store/src/proc.rs` (for remedy 1) or of `xtask check`'s\r\n  gate family (for remedy 2). The adapter half is perri's, filed separately, and does not wait\r\n  on this.\r\n- **Size:** small for remedy 2, medium for remedy 1 (signature + every caller). The census that\r\n  justifies either is already written and does not need redoing.\r\n\r\n---\r\n\r\n#### ADAPTER-SIDE ARM: CLOSED (claude-spt, perri, 2026-09-07)\r\n\r\n**Status: closed in the consumer repo, test-only, does not close IR-81 here.**\r\n\r\n- **Commit `9c87372`** (spt-claude-code). Broad `tasklist | grep claude-spt | taskkill` replaced\r\n  with an **id-scoped wmic** call, **name-pinned so wmic cannot self-match**; the three\r\n  remembered-pid kills additionally got a **kill-time recheck**, covering the stale-identity face\r\n  as well as the unscoped-pattern face.\r\n- **Guard: `tests/ci-kill-scoping.sh`, traced as `REQ-HAZARD-CI-KILL-SCOPING`.** Gate green.\r\n  This is the check-shape arm (b) proposes for spt-core, already landed once — precedent, not\r\n  merely agreement.\r\n- **Scope: test/CI infrastructure only.** No product code changed. (doyle, 08:50Z.)\r\n- **`live-relay-int.sh:78` is retained as the historical RED exhibit** — the one genuinely\r\n  machine-wide kill found in the whole fleet census. It is the reason this hazard is written as a\r\n  hazard rather than a style note; do not quietly replace the exhibit with the fixed line.\r\n\r\n**Population lesson carried into arm (b)'s census.** I filed ONE site; perri confirmed **four**, and\r\nreports the idiom was already present in that repo **3x** before the filing. A filing that names one\r\nline under-counts its class by 3-4x in a single repo. **Census the ACT — any taskkill / pkill /\r\nwmic-delete reachable from a script root — never the literal string that led me to the first site.**\r\nState the walked roots in the check's own message, and give the gate a negative control that goes\r\nRED on a known-bad line before its green is trusted.\r\n\r\n**Still open here, unchanged:** arm (a), Rust-side identity pushed into `kill_pid_tree` / `kill_pid`\r\nso no Rust caller can express the unguarded kill (todlando, post-W2, cross-referenced with the\r\nbroker.rs:8102 board BUGFIX); and arm (b), the xtask script gate (mine, rides IR-37).\r\n\r\n---\r\n\r\n#### SCOPING ARM (a) — the product path has no intermediary; the fixture does\r\n*(hertz 2026-09-07, ruled by doyle 10:22Z off the IR-80 leak work.)*\r\n\r\n> **A pid is not an identity and a pid is not a tree. IR-80 needs CALLERS, not code.**\r\n> *(The register's sentence — doyle 10:23Z. Arm (a) fixes the identity half in\r\n> `kill_pid`/`kill_pid_tree`; the tree half needs no new machinery, because `kill_pid_tree` already\r\n> exists at proc.rs:430 with the defect stated in its own doc. This is why IR-79, IR-80 and IR-81\r\n> converge on one seam without collapsing into one finding.)*\r\n\r\nMeasured, not inferred: **`spawn_brain_child` (crates/spt-daemon/src/brainproc.rs:1224) does\r\n`Command::new(exe)`** — the real brain is spawned DIRECTLY, with no shell and no launcher between\r\nthe daemon and the process it supervises. So on the crashloop/rollback path a single-pid kill\r\n*does* reach the thing it aims at, and the \"orphaned grandchild\" mechanism found in the IR-80 leak\r\ncells is **a property of the TEST FIXTURE**, whose `long_child()` (brainproc.rs:1359) goes through\r\n`cmd /C` on Windows, not of the product.\r\n\r\n**What that scopes.** Arm (a) is NOT about the brain-supervision path and must not be sold as\r\nprotecting `REQ-HAZARD-BROKER-PROCESS-ISOLATION` (\"never two live brains\") — that invariant is not\r\nat risk here, and claiming it would be borrowing urgency this arm has not earned. Arm (a) stays\r\npointed at **the broker.rs:8102 reap, where the image is never read** — a kill aimed by pid alone\r\nat a process whose identity was never verified. That is the real unguarded form, and it is a\r\ndifferent failure (kill the wrong process) from the one IR-80 surfaced (fail to kill the right\r\none).\r\n\r\n**The two failures are different, which is why the drafts converge without collapsing.** Arm (a) is\r\n*kill the wrong process* (identity never read); IR-80 is *fail to kill the right one* (tree never\r\nwalked). The identity half is todlando's, post-W2. The tree half is already solved in-tree —\r\n`kill_pid_tree` at proc.rs:430, whose doc states the defect outright (\"a single-pid `kill_pid` leaves\r\nthe wrapper's harness children orphaned + running\") — so IR-80 ships callers, not machinery. See\r\n[[RIDER 4]] for the two test-side callers.\r\n\r\n### IR-82 — a daemon death leaves NO record of who died: autostart decides on a socket ping, says \"no daemon\", and the successor overwrites the only handle on the corpse\r\n\r\n- **Status:** RULED 2026-09-07 11:07Z (doyle), drafted by hertz 11:04Z on doyle's dispatch (11:03Z: *\"the autostart\r\n…\n  OBSERVABILITY, not in the death.\n…\n","startLine":4103,"lineNumbers":[4103,null,4105,null,4181,null,4183,4184,4185,4186,4187,4188,4189,4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205,4206,4207,4208,4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223,4224,4225,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4238,4239,4240,4241,4242,4243,4244,4245,4246,4247,4248,4249,4250,4251,4252,4253,4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,4269,4270,4271,4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,4285,4286,4287,4288,4289,4290,4291,4292,4293,4294,4295,4296,4297,4298,4299,4300,4301,4302,4303,4304,4305,4306,4307,4308,4309,4310,4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326,4327,4328,4329,4330,4331,4332,4333,4334,4335,4336,4337,4338,4339,4340,4341,4342,4343,4344,4345,4346,4347,4348,4349,4350,4351,4352,4353,4354,4355,4356,4357,4358,4359,4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370,4371,4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387,4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417,4418,4419,4420,4421,4422,4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433,4434,4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448,4449,4450,4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463,4464,4465,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,4478,4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4493,4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,4519,4520,4521,4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,4539,4540,4541,4542,4543,4544,4545,4546,4547,4548,4549,4550,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567,4568,4569,4570,4571,4572,4573,4574,4575,4576,4577,4578,4579,4580,4581,4582,4583,4584,4585,4586,4587,4588,4589,4590,4591,4592,4593,null,4598,null,4696]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":6937,"totalBytes":32629,"outputLines":411,"outputBytes":32629,"shownRange":{"start":4183,"end":4593},"nextOffset":4594}}},"isError":false,"timestamp":1789483661696}}
{"type":"message","id":"fe74a92c","parentId":"c0d170f2","timestamp":"2026-09-15T14:47:41.702Z","message":{"role":"toolResult","toolCallId":"call_KHh6SESPu8iHaQIia3nO6g8X|fc_000c7cef03cac861016aa95a8d972487d1a927a2207ec8b414","toolName":"read","content":[{"type":"text","text":"### IR-81 — a process kill can be written scoped or machine-wide, and nothing makes the scoped form the only reachable one: both codebases carry the right pattern beside the wrong one\n…\n#### SCOPING ARM (a) — the product path has no intermediary; the fixture does\n…\n\n### IR-82 — a daemon death leaves NO record of who died: autostart decides on a socket ping, says \"no daemon\", and the successor overwrites the only handle on the corpse\n\n- **Status:** RULED 2026-09-07 11:07Z (doyle), drafted by hertz 11:04Z on doyle's dispatch (11:03Z: *\"the autostart\n  death-cause item is an IR, not a board item — mint it IR-82 in your thin PR\"*). Register on main\n  ends at IR-78; 79/80/81 are drafts in the same PR. · **Origin:** the fleet-daemon death on\n  hfenduleam at 08:03:14.87Z ([[RCA-FLEET-DAEMON-14444]]) whose cause is **still UNNAMED after a day\n  of measurement** — and the reason it is unnamed is this entry. Filed as a defect in\n  OBSERVABILITY, not in the death.\n- **⚠ THIS IS NOT \"find the killer.\"** The killer hunt is the RCA and stays open there. This entry\n  is about the fact that a killer hunt had to be run at all from a cold start, with a watcher script\n  written by hand after the event, because the product recorded nothing about the transition at the\n  moment it noticed it.\n\n- **THE MEASUREMENT — all four facts read at source, no build (gate was live on both boxes).**\n\n  1. **The daemon writes its pid.** `crates/spt-daemon/src/daemon.rs:471` —\n     `let _ = std::fs::write(daemon_pid_path(), std::process::id().to_string());`, into\n     `<spt_home>/daemon.pid` (`crates/spt-daemon/src/endpoint.rs:81`). Unconditional overwrite, no\n     read-before-write, no rotation, no history.\n  2. **Autostart never looks at it.** `ensure_running_outcome`\n     (`crates/spt-daemon/src/daemon.rs:686-724`) decides on `is_running()`, which is\n     `seedmap::ping(&seed_socket_name()).is_ok()` (`daemon.rs:598-600`) — **a socket ping and\n     nothing else.** The decision consults no pid, no mtime, no prior state.\n  3. **The breadcrumb it emits carries no identity.** `daemon.rs:721` —\n     `DAEMON_AUTOSTART: no daemon and no standing operator stop — starting one`. Deliberately\n     \"always-on, ids-free\" per its own comment, because its job is to be COUNTED (the convoy\n     serialization observable that `daemon_stop_convoy_e2e` asserts at :178/:237). That design is\n     correct for what it was built for and is exactly why it answers nothing here.\n  4. **Then the successor destroys the evidence.** The new daemon reaches :471 and overwrites\n     `daemon.pid` with its own pid. The dead pid, and the file mtime that bracketed its life, are\n     gone — overwritten by the very event that should have recorded them.\n\n- **THE SHARP FORM — the file is read ONLY in the state where it can tell you nothing.** The only\n  two readers of `daemon_pid_path()` in the tree are `crates/spt/src/cli.rs:8581` and `:8754` (both inside `cmd_daemon_status`, :8573), and\n  **both are gated on `running`** (`if running { let pid = read(...) }`). So `daemon.pid` is consulted\n  exclusively when a daemon is alive — when its contents are guaranteed fresh and merely restate\n  what the ping already proved — and is ignored in the one state where its staleness is the only\n  evidence anyone has. Its doc comment (`endpoint.rs:82-85`) says *\"a stale pid here is harmless\n  because callers probe the socket, never this file.\"* **That is true for LIVENESS and false for\n  FORENSICS**, and the entry is that the codebase has only ever considered the first reading.\n\n- **WHAT IT COST, concretely, on 2026-09-07.** Daemon pid 14444 died at 08:03:14.87Z inside the ci\n  Windows unit leg's nextest LIST phase; successor 48232 cold-started at 08:03:20Z and\n  `DAEMON_RESTART_RESUME`d every session, orphaning live agents' monitors and readers and handing at\n  least one agent a stale brief. Neither peer ran a kill. To get ANY signal at all I had to hand-write\n  an external watcher (`C:\\Users\\decid\\.spt-watch\\watch-daemon.ps1`, 1s cadence, identity re-verified\n  by image path AND creation time every poll) **after** the death, which by construction cannot\n  observe the event it was written for. 6600+ polls later the successor is alive and the original\n  death is still uncharacterized. A product-side record of the transition would have cost bytes.\n\n- **WHY THIS IS NOT THE CONVOY BREADCRUMB'S JOB, and must not be bolted onto it.**\n  `DAEMON_AUTOSTART` is load-bearing as a COUNTABLE line: `daemon_stop_convoy_e2e` asserts *exactly\n  one* appears under a storm (:178) and counts N under a deliberate race (:237). Adding identity\n  fields to that line risks the count and buries a forensic record inside a line whose contract is\n  its cardinality. **The record belongs in its own line and its own artifact.**\n\n- **REMEDY — RULED 2026-09-07 11:07Z (doyle), APPROVED as proposed with two refinements. Small,\n  product-side, no wire change.** doyle re-derived the census independently at `f3c8495b` (one\n  writer `daemon.rs:471`, two readers `cli.rs:8581` + `:8754`, both inside `if running`) before\n  ruling — the falsifiable claim below has been checked, not taken.\n  1. **Read before you clobber.** At `daemon.rs:471`, read the existing `daemon.pid` and its mtime\n     BEFORE the write; if it holds a pid that is not ours, emit a distinct, greppable line naming\n     the predecessor pid and how long ago the file was last touched — e.g.\n     `DAEMON_SUCCEEDS_PID: prior=<pid> prior_pidfile_age_ms=<n> reason=<socket-ping-failed>`. The\n     value is that the successor is the only process in the system that is guaranteed to run at\n     exactly the moment the question becomes askable.\n  2. **Keep one generation.** Rename the existing `daemon.pid` to `daemon.pid.prev` instead of\n     overwriting it (best-effort, same directory, same failure posture as today's `let _ =`). One\n     generation is enough to answer \"which pid did I replace, and when did it last write?\" and costs\n     no rotation policy.\n  3. **REFINED BY THE RULING — the discriminator is a FIELD, not a second line.** I proposed a\n     separate \"what the ping saw\" record; doyle collapsed it: `prior=<pid|none>` already separates\n     the two incidents, because `none` **is** the fresh-home case. One line, one field, no second\n     breadcrumb to keep in sync.\n  4. **ADDED BY THE RULING — `alive=<bool>`, from a by-number liveness READ at write time.** With\n     the prior pid in hand, read whether that number is still live and put the answer on the line.\n     It splits the two incidents that otherwise look identical: **`alive` prior = two daemons racing\n     the seed bind** (the convoy case), **dead prior = the corpse** (the 14444 case). This is a\n     READ, not a kill — #285's identity-before-kill rule binds kills and is not weakened here; a\n     by-number read that informs a log line commits no action on the pid.\n  5. **UNIT, specified by the ruling:** seed a pidfile with a fake pid and an aged mtime, run the\n     write path, assert the emitted fields (`prior`, `age_ms`, `alive`) AND the `daemon.pid.prev`\n     bytes. The `.prev` bytes are part of the assertion, not an afterthought — the generation kept\n     is the half that survives the process.\n  6. **NOT proposed, and the ruling kept it out:** a liveness change. `is_running()` must stay the socket ping — this entry does\n     not argue the pidfile should become a liveness signal, which is the exact mistake\n     `endpoint.rs:82-85` was written to prevent. The pidfile stays advisory; it just stops being\n     silently destroyed.\n\n- **LANE — SPLIT BY THE RULING, and the two halves ship separately.** The **IR-82 ENTRY** (this\n  text) rides hertz's IR-37 thin PR alongside IR-79/80/81. The **PRODUCT REMEDY** rides **#285's\n  lane** (todlando, post-W2) because it is the same pid-identity gate: #285 makes a kill read an\n  identity, this makes a successor read the identity it is about to erase. One lane, one owner,\n  one review of the pid-identity question. Do not implement the remedy in the thin PR.\n\n- **Kin:** [[RCA-FLEET-DAEMON-14444]] (the open incident this serves — IR-82 does not close it and\n  must not be read as closing it), [[IR-81]] (a pid is not an identity — the same lesson from the\n  KILL side; here it is the RECORD side), [[IR-80]]/[[IR-79]] (processes outliving what should have\n  accounted for them). The through-line doyle named at 10:22Z holds: *a pid is not an identity and a\n  pid is not a tree* — and IR-82 adds that **a pid nobody wrote down is not evidence.**\n\n- **Falsifiable claim, so it can be checked rather than believed:** at `f3c8495b` the tree contains\n  exactly ONE writer of `daemon_pid_path()` (`daemon.rs:471`) and exactly TWO readers\n  (`cli.rs:8581`, `cli.rs:8754`), both inside a `running` gate. If a future reader appears in an\n  unguarded path, this entry's premise weakens and it should be re-measured, not re-asserted.\n\n### IR-83 — a two-host rig addressed over the tailnet cannot receive INBOUND on Windows, and the whole rig population had only ever run the admitted direction\n\n- **Status:** OPEN, minted by hertz 2026-09-07 11:41Z on doyle's dispatch (11:40Z). **Provenance: the\n  mechanism below is DOYLE'S measurement, not mine** — eight probe arms, each with sender, listener\n  and output file, recorded in `GATE-W2-272-CHECKLIST.md` rows 11:36Z–11:39Z. I am off cargo on both\n  boxes and have re-measured none of it; this entry is the register form of his finding plus the\n  structural reading it supports. Board face: **F18**. Register slot: IR-83 (79/80/81/82 are the\n  same thin PR).\n- **2026-09-11 ruling:** the original universal \"LAN, never tailnet\" prescription below is\n  SUPERSEDED by IR-89's measured tailnet ACL + Windows Firewall remediation and successful\n  tailnet probes. Admit the actual transport at each layer and retain an independent reverse\n  direction witness. The operator-blocked box remedy is spent; durable witness enforcement\n  and its acceptance record remain separate, OPEN work. No new box changes authorized here.\n\n- **HALF ONE — the tailnet ACL is per-node and ONE-WAY.** `hfenduleam` admits 9 sources and\n  `kitsubito` is **not** among them; `kitsubito` admits `hfenduleam`. So a rig cell needing INBOUND\n  to the Windows box over `100.x` fails **at the receiver**, and it fails there **whatever the host\n  firewall says** — which is why a host-firewall investigation can be run to completion, come back\n  clean, and explain nothing.\n\n- **HALF TWO — Windows defaults `BlockInbound`, and a hash-named test exe has no rule.** Test\n  binaries are built with hash-suffixed names, so a rule written against the *program* is keyed to a\n  name that changes on the next build. The stale `spt_net-d037…` rule is the precedent already in\n  the tree: a rule that was correct once, is present, greps fine, and admits nothing. **The durable\n  form is PORT-scoped, not program-scoped:** ports `7480-7499`, `remoteip` = the peer's LAN address,\n  added by the operator.\n\n- **WHY IT SURFACED ONLY NOW, and this is the part that generalizes.** The W2 helper cell is the\n  **first cell in the entire rig population that ever needed `kitsubito -> hfenduleam` inbound.**\n  W1's four xbox cells and golden's old-twohost job are all `hfenduleam -> kitsubito` — the admitted\n  direction. So the population had a **direction monoculture**, and a one-way ACL is invisible to a\n  suite that only ever runs the admitted way. Every green in that population was consistent with the\n  ACL being wide open and equally consistent with it being one-way; the suite could not tell the\n  difference, and nobody had reason to ask. **A capability exercised in only one direction is not\n  covered, it is merely unexamined** — the same shape as an assertion that only ever sees the\n  passing arm.\n\n- **THE SECOND STRUCTURAL POINT — a rule keyed to a MUTABLE identity is the lane's own through-line.**\n  A per-hash program rule is an exception bound to an identity the build changes underneath it,\n  exactly as [[IR-81]] is about a kill bound to a pid the OS may reassign and IR-80 Amendment 1's ENV\n  READ face is about a read bound to a process identity `exec` can change. Port-scoping replaces a\n  mutable identity with a stable property. That is the same remedy shape as reading an image path\n  before a kill and reporting an environment in-band: **stop keying on the thing that moves.** I am\n  flagging the rhyme, not claiming a fourth face — this is infrastructure config, not a code path,\n  and the amendment's standing prediction is about pid-shaped questions.\n\n- **FALSIFIABLE CLAIM (doyle's, recorded verbatim as the entry's test):** with the rig on **LAN\n  addresses AND the port-scoped rule present**, the helper cell's owner raw carries `WEB_SERVE_FOR`;\n  with **either** missing, it carries none. Both arms matter — this is a conjunction, so a single\n  green with one of the two absent would refute it, and a red with both present would too.\n\n- **WHAT THIS ENTRY DOES NOT CLAIM.** It does not say the host firewall was ever misconfigured; the\n  ACL half fails at the receiver independently. It does not close F17 or explain the vacuous-green\n  run (that was the mid-flight script rewrite — different cause, different fix, and the two were\n  live in the same hour, which is precisely why each needed its own named mechanism rather than one\n  story). It proposes no product change: both halves are rig addressing and operator-added firewall\n  config.\n\n- **REMEDY.** (1) Rig-side: address peers by LAN in two-host rigs, and make the tailnet address\n  unreachable-by-construction rather than merely unused, so a future rig cannot quietly pick it up.\n  (2) Operator-side: the port-scoped inbound rule (`7480-7499`, `remoteip` = peer LAN), replacing\n  per-hash program rules; the stale `spt_net-d037…` rule should be removed in the same pass so it\n  stops reading as coverage. (3) Population-side — **RULED 11:42Z (doyle), with a precision that\n  changes the shape:** this is NOT a new cell. **The W2 helper cell IS the first reverse-direction\n  cell**, and on LAN it exercises `kitsubito -> hfenduleam` inbound for real once the rule exists.\n  The remedy is therefore to **keep at least one reverse cell in the xbox battery permanently and\n  NAME it as the direction witness**, so its role is a stated property rather than an accident of\n  what W2 happened to need. A suite that only runs one way cannot discover the next one-way ACL\n  either, and the way that recurs is not \"nobody wrote the cell\" but \"the cell that had it stopped\n  being run.\"\n\n  **The hazard that follows from naming it, stated here so the naming is not decorative:** a witness\n  cell that is SKIPPED stops being a witness while still reporting green — the exact confusion this\n  lane already paid for, where a must-skip `role_b` PASS was indistinguishable from four cells that\n  no-opped. So the direction witness needs its skip to be loud: if it is filtered out, phase-reclassed,\n  or short-circuits on a missing precondition, that must read as ABSENT COVERAGE and not as a pass.\n  Whoever names it owns that half too. **Concrete enforcement, doyle-ruled 11:44Z and written up\n  as the RIDER 5 ADDENDUM:** the xbox driver's HELPER WITNESS verdict line already refuses a\n  `0.0x s` helper PASS and a `b.raw` without `WEB_SERVE_FOR outcome=registered`; it must ALSO\n  print `NOT-A-WITNESS` when the cell is absent from the LIST leg. Those first two are\n  *ran-but-vacuous*; absence is *never-ran*, and a verdict built only from the first two passes\n  it by omission — every refusal condition evaluates against output that does not exist, finds\n  nothing to object to, and falls through to green.\n\n- **GATING CLAUSE — added 2026-09-07 12:56Z on doyle's dispatch (gate reshape, same minute).** An\n  inbound-to-Windows cell in a two-host rig is **gated on the port-scoped rule being present**, and\n  without it the cell must **SKIP LOUDLY**: it may not run, may not report PASS, and may not be\n  silently filtered — its absence must render as ABSENT COVERAGE in the verdict, on the RIDER 5\n  ADDENDUM's `NOT-A-WITNESS:NEVER-RAN` face. The precondition is machine-readable, so the driver\n  reads `netsh` at start and the gate is a measured fact rather than a remembered one; a cell whose\n  precondition is unmet and which therefore emits nothing is exactly the case a verdict assembled\n  only from ran-but-vacuous refusals passes by omission. **This clause is what stops the rule's\n  ABSENCE from reading as the rig's health.**\n\n  **How the reshaped W2 F17 gate applies it (doyle 12:56Z, recorded, not re-measured by me — I am\n  still off cargo on both boxes).** With the rule absent 75+ minutes and no operator activity, and\n  golden carrying no cross-box `twohost_web`, the shortfall is a **rig blocker, not a golden one**.\n  So the HELPER WITNESS was reshaped to the **ONE-BOX pair on BOTH OSes** — doyle's gate tree on\n  Windows, a kitsubito clone at the tip on Linux with the rig shipped as the frozen copy — on the\n  basis that the 03:31Z one-box run at `f3c8495b` reproduced F17 end to end (A `outcome=unanswered`,\n  B `DISPATCH:4:Unknown`), i.e. the one-box pair drives the real dispatcher on both roles.\n  Mutation D must turn the classify unit cell red **and** the one-box helper cell red\n  (owner `family=Unknown`>0, `registered`=0) while deny/fetch stay green; revert dirty 0. The\n  cross-box pair still runs as the A->B regression (deny/fetch must PASS), and while the rule is\n  absent its helper/range TIMEOUTs are classified **F18-INFRA** — becoming a witness automatically\n  if the rule lands before the run, because the driver reads `netsh` at start.\n  **The cross-box helper witness therefore stays an OPEN rider on the operator's rule, not a land\n  blocker.** Note the shape this preserves: the reshape moves the witness to a pair that CAN run,\n  and leaves the direction it cannot exercise named and open — it does not let the one-box green\n  stand in for the direction coverage that is still missing. A one-box pair proves the dispatcher;\n  it cannot prove an inbound ACL, and nothing here claims it does.\n\n  **PROBE RESOLUTION — doyle 12:59Z, ADOPTED INTO THIS GATE (not deferred to the rider).** The\n  precondition read is now THREE-VALUE in `gate-w2-f17.sh`: `Rule Name` in stdout -> PRESENT,\n  `No rules match` -> ABSENT, empty stdout or anything else -> PROBE-FAILED. **PROBE-FAILED\n  classifies the cross-box helper/range as `UNCLASSIFIED: this run cannot tell INFRA from a real\n  red` — never F18-INFRA** — and xbox-D's skip line names the state. The raw probe (exit code +\n  first 3 lines) is printed into the driver log, so the classification is auditable after the fact\n  rather than inferred from what got bucketed. Exercised standalone on all three arms: real\n  `netsh` = exit 1 + `No rules match` -> ABSENT; forced bad args -> PROBE-FAILED; empty stdout ->\n  PROBE-FAILED.\n\n  **Recorded because it corrects the asker (me), not the implementer:** I proposed the three-value\n  shape AND, in the same message, proposed discriminating on the exit code. doyle's standalone\n  exercise measured `netsh` exiting **1 on a clean ABSENT**, so an exit-code discriminator would\n  have classified every legitimately-absent rule as an instrument fault — turning the run's most\n  common honest state into PROBE-FAILED and, with it, `UNCLASSIFIED`. The discriminator that landed\n  is STDOUT CONTENT. The general form belongs in the entry because it is the reason the third arm\n  needed measuring at all: **a CLI's exit code is a claim about the QUERY, not about the ANSWER**,\n  and an empty-but-correct result is reported non-zero by a great many tools. A third value added\n  to a probe needs its own evidence, obtained by making all three arms fire on purpose — which is\n  this lane's standing rule that a tool whose success path has never been made to fail on purpose\n  is untested, applied to a tool's FAILURE path instead.\n\n- **Kin:** [[IR-81]] and IR-80 Amendment 1 (keying on a mutable identity), the F17 riders (a witness\n  that never executed the direction it certifies).\n\n### IR-84 — the one `PUMP_PEER_FAIL` arm the rigs actually fire was the only one carrying no clock, so the stall that produced it could be counted but never timed\n\n- **Status:** OPEN, filed by hertz 2026-09-09 with the instrument that closes its first half. ·\n  **Origin:** the 65 s two-host helper stall (design written before the run,\n  `docs/design/RIDER-65S-DESIGN.md`). The number was branch-claimed 2026-09-08 by name only — IR-85\n  records that it carried no entry text in any register file in any worktree — and this is that text.\n- **Symptom:** `two_host_web_helper_role_a` takes **61.956–69.096 s** across five runs while its\n  siblings in the same binary and the same run take **0.135–0.753 s**. Every ladder rig —\n  win-onebox, linux-onebox, cross-box — logs **exactly ONE**\n  `PUMP_PEER_FAIL:<node>:peer reply-read: no progress within budget — dropping peer (brain IPC read\n  deadline elapsed)` on B before completing. **3/3, one each, never on A** (doyle's GATE-W3 readout).\n- **Cause of the DIAGNOSTIC failure, which is what this entry is about:** that line is emitted from\n  the `Err(e)` arm of `peer_leg_outcome` (`crates/spt-daemon/src/pump/mod.rs`), and at\n  `b0b67aaa` it read `emit_line_err!(\"PUMP_PEER_FAIL:{peer_hex}:{e}\")` — **no timestamp**. Measured\n  at that sha rather than recalled: the file carries **four** `PUMP_PEER_FAIL` emit sites, **three**\n  of them stamped `wall_ms=… mono_ms=…` (the submit arm, the no-route arm, and the\n  `PRESENCE_DIAL_FAILED` arm), and this one was **the only unstamped site left**. It is also the\n  arm the rigs actually fire — a `PEER_REPLY_READ_BUDGET` expiry reclassified out of `TimedOut` by\n  `brain::reclassify_peer_reply_err` so it drops one peer rather than poisoning the round. **The\n  single arm a reader most needs to time was the single arm that could not be timed.**\n- **What that cost, stated as the open question it left:** the arithmetic does not close and this\n  entry does not close it. `PUMP_PEER_IO_TIMEOUT` is **30 s** (`:118`) and `SUPERVISE_BACKOFF_BASE`\n  is **5 s** (`:121`) — read as constants, not recalled — so one deadline plus one supervise floor\n  accounts for **35 s** against **61.956–69.096 s** observed. **~27–34 s is unaccounted**, itself\n  close to another 30, which is exactly the coincidence the design document warns against; and the\n  count of **exactly one** fail forbids the easy reading that two deadlines elapsed. Three candidates\n  stay open and are NOT ranked here: a first ~30 s burned before the deadline's clock starts; a\n  second budget stacking on the first; or the restart's re-prime costing materially more than its\n  5 s floor. **Separating them needs the deadline's own timestamps against the fail line** — which\n  is precisely what the log did not carry.\n- **⚠ WHAT THIS ENTRY DOES NOT CLAIM.** The instrument does not explain the stall, does not shorten\n  it, and changes no product behaviour: the same peer is dropped at the same instant with the same\n  backoff. It makes the stall **answerable from a log that already contains the failure**, instead of\n  requiring a rebuild to learn when the budget started. `PUMP_PEER_IO_TIMEOUT` is a hard const with\n  no env knob, so varying it costs a rebuild — deliberately deferred until the stamps say which half\n  of the arithmetic is missing.\n- **Kin and the recurrence that matters:** this is the **SECOND** time an unstamped\n  `PUMP_PEER_FAIL` cost a hunt. The `PRESENCE_DIAL_FAILED` arm carries a comment naming the\n  \"2026-07-14 `PUMP_PEER_FAIL`-unstamped seed, folded here\", and **REQ-PUMP-STAGE-TRUTH** already\n  requires every peer failure \"stamped (wall+mono) and peer-attributed\", explicitly subsuming that\n  seed. So the contract was written, three of four sites complied, and the fourth stayed silent for\n  eight weeks — **a convention enforced by no mechanism degrades one arm at a time, and every reader\n  of a complying arm reports the convention as held**, the same shape as the `validate_docs_dir`\n  refusal-arm rider in the same design document. Also kin: **IR-83** (the rig population had only\n  ever run the admitted direction), `REQ-HAZARD-PUMP-IPC-DEADLINE` (a `TimedOut` brain-IPC read is a\n  supervised restart, never a per-peer retry), ADR-0039 Decision 5.\n- **Ripe when:** now, and it lands with this entry — the stamp is one emit line, tagged\n  `impl->REQ-PUMP-STAGE-TRUTH` at the site. · **Size:** one emit line plus its comment.\n  **Follow-up, not this lane:** a cell that walks every `PUMP_PEER_FAIL` arm and asserts each one\n  stamps, so the fifth site added cannot be born silent.\n### IR-85 — the Windows self-hosted box runs its fs-heavy tests 3-4x slower than a week ago; two CI wall clocks were sized for the old box, and a red run kept hiding it\n\n- **Status:** OPEN, filed by hertz 2026-09-09 at the #272/v0.68.0 golden r3/r4 arc, on doyle's\n  dispatch. Number ruled by doyle from his own census of main@`a2f335f8` (register ended at IR-83;\n  IR-84 was branch-claimed by name only, with no entry text in any register file in any worktree —\n  that gap is now closed: **IR-84 was filed 2026-09-09 in PR #213**, so this sentence records the\n  state at `a2f335f8` and is no longer a reason to go looking for a missing entry).\n  **Absorbs two drafts:** doyle's `IR-DRAFT-windows-fs-heavy-slowdown-and-golden-wall` (his IR-A +\n  IR-B) and his earlier `IR-NEXT` (operator-desktop load), both retired by reference — this is the\n  single entry. Every job/step and per-test timing below is **doyle's**, read via the job/step API.\n  · **Origin:** #272 golden r3 attempt 2 was CANCELLED by a wall clock with both test phases green.\n- **⚠ THE CAP CHANGE IN `a2f335f8` IS NOT THE FIX AND MUST NOT BE READ AS ONE.** It bounds the run;\n  it repairs nothing. A future reader who finds an 80-minute wall and no entry here would reasonably\n  conclude the problem was solved. It was only made visible.\n\n- **A GREEN RUN COSTS MORE THAN A RED ONE, WHICH IS WHY THIS WENT UNSEEN.** A failing run\n  short-circuits past the wall a green run has to cross. r3 att1 finished in **48m39s only because\n  it FAILED at Phase B**; att2, green, hit 49m59s and was cancelled. Every earlier docs-drift skip\n  therefore presented as \"upstream failure\" — the wall was never the reported cause of anything, and\n  the surviving evidence systematically flattered the budget.\n\n- **THE WALL.** Windows golden `test` job (48 steps), fully GREEN: **30m53s** (2026-08-30, run\n  33296634901) and **33m21s** (2026-09-06, run 34017906638). At the v0.68.0 head against the\n  then-current 50-minute cap — **r3 att2**, job 102352551368 at `f6110c2a`: Phase A 17m14s, Phase B\n  20m25s, doctests 1m04s, clippy 3m31s, **CANCELLED at step 30 at 49m59s with everything green**;\n  steps 31-42 (installer, docs floor, both docs-drift gates, dormancy) never ran. r2 att1\n  (`25e60015`, 09-08 18:47Z) reached step 34 at 44m30s. Steps 30..39 cost ~3m30s on the 09-06 green\n  (notify 47s, installer 13s, docs-drift 1m54s). Predicted green need ~**56 min**; cap raised to\n  **80** (need + ~40% for day-to-day variance) in `a2f335f8`, ci unit 25 -> 40 in the same commit.\n- **r4, GREEN — the first complete measurement at the head: 54m35s** (07:12:26Z -> 08:07:01Z),\n  **25m25s** headroom under 80; docs-drift (step 38) 2m23s; Phase A 15m51s, Phase B 22m56s. The ~56\n  prediction held to within 1.5 min, so the cap is sized on evidence, not generosity. **What that\n  does NOT establish:** it was a sizing forecast, and its holding says nothing about the cause\n  diagnosis below. Nor are att2-vs-r4 per-phase deltas a trend — att2 was cancelled mid-run, so only\n  its phase legs are comparable at all, and the spread they sit in is the same variance the 40% is\n  there to absorb.\n\n- **THE SLOWDOWN, per test, same box, same tests.** `spt-daemon::sync` concurrent_writes\n  **22.4s -> 74.8s**, two_tier_sync 18.7 -> 67.4; `spt-store` monic clone_copies 17.7 -> 62.9,\n  different_monics 18.2 -> 64.9; syncmerge reconciled_write 27.3 -> 51.2. **~25 spt-store/spt-daemon\n  tests now exceed 30s on Windows Phase A at `f6110c2a`, against 1-2s each on kitsubito.**\n  Phase-level: Phase A nextest 170s (09-06) -> 642s (att1) -> 1034s (att2); Phase B 710s -> 1164s.\n  The suite did not get more expensive — Linux is unchanged.\n\n- **DATING SAYS ENVIRONMENT DOMINATES, AND BY HOW MUCH.** main's own ci Windows `unit` job:\n  11-12 min on 09-06 (runs 34040416870, 34041526195, 34043323577) -> 13-20 min on 09-07 -> 12-24 min\n  on 09-08, hitting **22 min at `e4444413`** (run 34261096301) three minutes under its own 25-minute\n  wall. **Gradual over days, under no single gate change, is the shape of an environment term, not a\n  commit's.** Head growth is real but MINOR: +138 Phase A tests, +20 Phase B, HEAVY 34 -> 35.\n\n- **THE BOX IS AN OPERATOR DESKTOP (folded in from the retired IR-NEXT), and that turns every fixed\n  wall-clock budget in the Windows suite into a coin.** From the r2 arc, three attempts at ONE sha\n  (run 34262154550 @ `25e60015`): Phase B red each time on a **different single cell or none** — a1\n  234/234 (job red on disk floors only), a2 `spt::webserve_attachment_e2e` arm 12, a3\n  `spt-daemon::mesh_recovery roster_route_survives_a_transient_dial_failure_with_discovery_disabled`\n  (15.0s `converge()` budget, cell 15.715s; the same cell 9.8s / 7.2s on a1/a2). Phase A — 3,346\n  spawn-dominated unit cells — slowed **monotonically 448.7 -> 495.1 -> 542.6s at that one sha**.\n  Per-cell a3/a2 over 73 Phase B cells >= 1s: median 1.05x, mean 1.34x, 19 cells >= 1.5x, worst 5.2x\n  (`endpoint_lifecycle poll_vs_reap` 1.1 -> 5.8s) — **BURSTY, not uniform**. A rotating single victim\n  across attempts at one sha is ONE environment cause; hardening victims one at a time never closes\n  it (paid before: `e2e-leaked-daemons-shared-box`). The budgets that lost were ~1.5x the fast\n  observation — inside the box's measured variance, so they were coins that had been landing right.\n- **Box census (doyle 01:13-01:19Z, no cargo/rustc/nextest running, CPU 31%, ~1.1 of 16 cores busy):**\n  `qbittorrent.exe` seeding since 09-08 10:20Z (box tx 21.3 MB/s over 5s); fleet `spt daemon brain`\n  with 516 GB read since 09-07 08:03Z (~3.5 MB/s steady); Defender real-time ON, `MsMpEng` at\n  67.8/62.8/48.9/32.2/12.2% of a core over 5s **on the idle box**; a fresh 35 MB exe pays\n  2092/994/1171/1043 ms on FIRST execution against 31/263/19/260 ms on the second — **and every CI\n  attempt rebuilds every test binary fresh.** At 06:45Z on 09-09, with the twohost legs running:\n  MsMpEng 89% CPU / 991 MB WS, qbittorrent pid 47056 holding 7817 CPU-seconds (2.2 h) since\n  09-08 03:20, free 134 GiB (275 -> 197 -> 131 across the three r3 dispatches).\n- **⚠ AN UNREADABLE ROW IS NOT AN ABSENT ONE.** The Defender exclusion list cannot be read\n  unelevated on this box: `Get-MpPreference` returns the literal string\n  `N/A: Must be an administrator to view exclusions` **as the ExclusionPath VALUE**, so a\n  `-contains` test reads ABSENT and is meaningless; the HKLM `Windows Defender\\Exclusions\\Paths`\n  read throws `SecurityException`. Nobody may report the runner directory as unexcluded from an\n  unelevated shell.\n\n- **HYPOTHESIS ALREADY KILLED, so nobody re-runs it:** the Windows-only `ADAPTER_WEB_PENDING`\n  reconcile failure (servehost nudge) **cannot** explain this — spt-store monic and contextstore\n  never touch that path.\n\n- **WHAT IS STILL NOT ESTABLISHED (labelled, so it is not inherited as fact).** The dating argument\n  establishes environment-DOMINANT and bounds head growth as the minor term. It does **not**\n  apportion the environment term itself: Defender vs the third-party torrent load vs the fleet\n  brain's steady read vs anything else is unsplit, and **\"MsMpEng at 89%\" remains a correlate\n  measured beside the slowdown, not a proven cause.** The discriminator lane below is what settles\n  head-vs-environment on evidence rather than on the shape of a drift curve.\n\n- **REMEDY — none landed. This entry is the debt, and its middle arms need an operator.** Sequence\n  matters; run them in this order:\n  1. **DISCRIMINATOR LANE (hertz, one box, ~1.5-2 h).** Run the five named tests at `04e32c8c` and\n     at `f6110c2a` on hfenduleam. **Same-slow at both = environment; slow only at the head = head\n     growth.** Cheap and decidable, and it must precede any operator ask — do not spend an elevation\n     request on a hypothesis a one-lane measurement can test. Design note, because it is the part\n     that makes the number trustworthy: the arms run **INTERLEAVED** (A/B/A/B/A/B, 3 reps each), not\n     all-A-then-all-B, so drift that hits the whole box cancels in the comparison instead of landing\n     on one arm. **A measurement that only works if everyone behaves is not a measurement** — the\n     torrent client and Defender are running throughout and are the thing under test, not noise\n     anyone gets to remove. Confounder already excluded: the three test-bearing files\n     (`spt-daemon/tests/sync.rs`, `spt-store/src/monic.rs`, `spt-store/src/syncmerge.rs`) are\n     **byte-identical blobs at both shas**, so a difference cannot be the tests changing; the two\n     crates around them are not (+11,388 lines over 48 files).\n  2. **Remove the third-party load first.** No torrent client on the CI box during golden windows.\n     It is the cheapest variable to remove, and removing it first makes arm 3's benefit measurable\n     instead of confounded.\n  3. **OPERATOR ASK — Defender path exclusions** for `C:\\actions-runner\\_work` and the gate pools,\n     read from an ADMIN shell first (see the unreadable-row warning above), then re-measure the\n     first-touch tax on a file **under that path** — the scratchpad measurement is outside the\n     runner dir, so it proves the mechanism's size, not the runner's exposure. Unsettable\n     unelevated; same shape as **IR-89**'s elevated firewall rule.\n  4. **CI census, cheap and durable:** print `Get-MpComputerStatus` RealTimeProtectionEnabled plus\n     the ExclusionPath read **verbatim, refusal text included**, in the Windows job's census step,\n     so a run's own record says what Defender it ran under.\n  5. **Re-measure both caps after any arm lands — the arm a future reader will skip, so it is loud\n     here.** A cap sized against a degraded box is correct only while the box stays degraded.\n     Leaving 80 in place after a repair silently restores the original hazard: a wall so generous it\n     no longer catches a wedged test, which is the job the golden cap was added to do in the first\n     place (the 2026-06-03 handoff.rs ConPTY stall, 22 unbounded hosted minutes).\n- **Kin:** [[IR-76]] (the golden runner IS the builders' box — the structural reason a desktop's\n  load reaches CI at all), [[IR-64]] (box-level facts only the operator can move), [[IR-89]] (the\n  other elevated box-rule ask), `defender-first-touch-tax-on-fresh-test-binaries` and\n  `e2e-leaked-daemons-shared-box` (memory).\n- **Ripe when:** arm 1 now; arms 2-4 on the operator's answer; arm 5 at the next `golden.yml` touch\n  after any of them. · **Size:** arm 1 a measurement, arm 4 one census line, arm 5 two literals.\n- **AMENDMENT 2026-09-09 (two terms this entry did not name when it landed at `d32d5c4c`).**\n  1. **`ci.yml`'s `changes` job runs `unit` on BOTH runners for every push to `main`.** The classify\n     step at `.github/workflows/ci.yml:49` emits `code=true` for every non-`pull_request` event, so\n     the docs-only skip that PR runs #206/#207 demonstrated is **`pull_request`-only** — read from\n     `ci.yml` at `main` by doyle, who names it his own error after twice ruling the opposite from the\n     PR runs alone. Consequence for this entry's wall clock: run **34337797758** (the ff of\n     `b66a9612`, a docs-only delta over golden-green `a2f335f8`) ran `unit (Windows)` 09:59:57Z →\n     10:40:48Z and was **CANCELLED at the 40-minute job wall** (job timeout; conclusion `cancelled`,\n     step 6 `Unit tests` 10:08:23 → 10:40:03) — a red on `main` at a sha whose content cannot fail a\n     unit test. It is an IR-85 face, not a flake row.\n  2. **A near-full volume is an environment term for the slowdown**, alongside the Defender\n     first-touch tax and the operator-desktop load already recorded. **Deliberately unquantified:**\n     the discriminator window that would have apportioned it was VOID, because the one leg that\n     completed ran under both a CI job and a falling disk. See **IR-90**.\n- **WHAT THE VOIDED DISCRIMINATOR ESTABLISHED, negatively (hertz, 2026-09-09).** The fs-heavy\n  slowdown REPRODUCES at `04e32c8c`, which predates the +11,388-line head growth: spt-daemon\n  `concurrent_writes` 105.420 s, `two_tier_sync` 58.362 s, spt-store `clone_copies` 65.657 s,\n  `different_monics` 73.967 s, `syncmerge reconciled_write` 86.765 s, against the 09-06 baseline of\n  22.4 / 18.7 / 17.7 / 18.2 / 27.3 s — **3.2x to 4.7x on all five, at the OLD sha**. So head growth\n  is **not NECESSARY** for the slowdown. That is the whole of it: it does NOT measure how much the\n  environment explains, and it is not evidence about the head arm at all — that leg ran inside run\n  34337797758's window and on a volume that reached 0.018 GiB free, and the head arm never produced\n  a comparable pair. **Arm 1 stays OPEN**, its re-run deferred until **IR-90**'s guard exists and a\n  window with no `main` push and no CI job on the box can be scheduled.\n\n- **AMENDMENT 2026-09-10 (hertz, on THIS ENTRY'S OWN arm-1 design note).** The note says the arms run\n  **INTERLEAVED** A/B/A/B so box drift cancels. It does not cancel: **B is always the later arm within\n  each pair**, so a monotone drift across the session lands on B every time and is read as an arm\n  effect. Alternate the PAIR ORDER — **A/B then B/A** — record per-leg timestamps and conditions, and\n  describe the result as **REDUCING order confounding, not eliminating it**. Second binding change,\n  from the releases#294 triage: **instrument, do not infer.** `cargo nextest run --success-output\n  immediate` retains stdout for PASSING tests (deployah), so a passing arm can still print poll\n  elapsed, iteration count, IPC time and producer progress — **a failing arm is not required** for a\n  margin measurement (todlando, correcting deployah's \"it has to fail to be informative\"). Arm 1 was\n  never re-run, so this lands before the measurement, not after it.\n\n### IR-86 — golden's 32 GiB floor is BELOW the measured 67.4 GiB Windows suite footprint, so a start floor passes a box that cannot finish\n\n- **Status:** OPEN, filed by doyle 2026-09-08 at the #272/v0.68.0 golden r2 triage. · **Origin:**\n…\n  25,284,501,504 B RED at 19:31:55Z -> `FLOOR_END` RED. Consumed in-job: 67.4 GiB.\n…\n- **Linux recurrence, 2026-09-15 (doyle, S4 golden `34946493637`, reported in `3HHHPWCR`).** Kitsubito's test job began with about **110.7 GB** free and reached about **29.3 GB** after its build and test sandbox consumed **81.4 GB**; the workload stages were green, then the floor gates red. `FLOOR_DOCS` and `FLOOR_END` run **before** test-temp-sandbox cleanup, deliberately ([[IR-46]]), so the job must retain the end-floor reserve while its own sandbox still exists. A generic **32 GiB** start admission does not establish that capacity.\n…\n\n\n[Showing lines 4590-5046 of 6937. Use :5047 to continue]"}],"details":{"truncation":{"content":"\r\n### IR-82 — a daemon death leaves NO record of who died: autostart decides on a socket ping, says \"no daemon\", and the successor overwrites the only handle on the corpse\r\n\r\n- **Status:** RULED 2026-09-07 11:07Z (doyle), drafted by hertz 11:04Z on doyle's dispatch (11:03Z: *\"the autostart\r\n  death-cause item is an IR, not a board item — mint it IR-82 in your thin PR\"*). Register on main\r\n  ends at IR-78; 79/80/81 are drafts in the same PR. · **Origin:** the fleet-daemon death on\r\n  hfenduleam at 08:03:14.87Z ([[RCA-FLEET-DAEMON-14444]]) whose cause is **still UNNAMED after a day\r\n  of measurement** — and the reason it is unnamed is this entry. Filed as a defect in\r\n  OBSERVABILITY, not in the death.\r\n- **⚠ THIS IS NOT \"find the killer.\"** The killer hunt is the RCA and stays open there. This entry\r\n  is about the fact that a killer hunt had to be run at all from a cold start, with a watcher script\r\n  written by hand after the event, because the product recorded nothing about the transition at the\r\n  moment it noticed it.\r\n\r\n- **THE MEASUREMENT — all four facts read at source, no build (gate was live on both boxes).**\r\n\r\n  1. **The daemon writes its pid.** `crates/spt-daemon/src/daemon.rs:471` —\r\n     `let _ = std::fs::write(daemon_pid_path(), std::process::id().to_string());`, into\r\n     `<spt_home>/daemon.pid` (`crates/spt-daemon/src/endpoint.rs:81`). Unconditional overwrite, no\r\n     read-before-write, no rotation, no history.\r\n  2. **Autostart never looks at it.** `ensure_running_outcome`\r\n     (`crates/spt-daemon/src/daemon.rs:686-724`) decides on `is_running()`, which is\r\n     `seedmap::ping(&seed_socket_name()).is_ok()` (`daemon.rs:598-600`) — **a socket ping and\r\n     nothing else.** The decision consults no pid, no mtime, no prior state.\r\n  3. **The breadcrumb it emits carries no identity.** `daemon.rs:721` —\r\n     `DAEMON_AUTOSTART: no daemon and no standing operator stop — starting one`. Deliberately\r\n     \"always-on, ids-free\" per its own comment, because its job is to be COUNTED (the convoy\r\n     serialization observable that `daemon_stop_convoy_e2e` asserts at :178/:237). That design is\r\n     correct for what it was built for and is exactly why it answers nothing here.\r\n  4. **Then the successor destroys the evidence.** The new daemon reaches :471 and overwrites\r\n     `daemon.pid` with its own pid. The dead pid, and the file mtime that bracketed its life, are\r\n     gone — overwritten by the very event that should have recorded them.\r\n\r\n- **THE SHARP FORM — the file is read ONLY in the state where it can tell you nothing.** The only\r\n  two readers of `daemon_pid_path()` in the tree are `crates/spt/src/cli.rs:8581` and `:8754` (both inside `cmd_daemon_status`, :8573), and\r\n  **both are gated on `running`** (`if running { let pid = read(...) }`). So `daemon.pid` is consulted\r\n  exclusively when a daemon is alive — when its contents are guaranteed fresh and merely restate\r\n  what the ping already proved — and is ignored in the one state where its staleness is the only\r\n  evidence anyone has. Its doc comment (`endpoint.rs:82-85`) says *\"a stale pid here is harmless\r\n  because callers probe the socket, never this file.\"* **That is true for LIVENESS and false for\r\n  FORENSICS**, and the entry is that the codebase has only ever considered the first reading.\r\n\r\n- **WHAT IT COST, concretely, on 2026-09-07.** Daemon pid 14444 died at 08:03:14.87Z inside the ci\r\n  Windows unit leg's nextest LIST phase; successor 48232 cold-started at 08:03:20Z and\r\n  `DAEMON_RESTART_RESUME`d every session, orphaning live agents' monitors and readers and handing at\r\n  least one agent a stale brief. Neither peer ran a kill. To get ANY signal at all I had to hand-write\r\n  an external watcher (`C:\\Users\\decid\\.spt-watch\\watch-daemon.ps1`, 1s cadence, identity re-verified\r\n  by image path AND creation time every poll) **after** the death, which by construction cannot\r\n  observe the event it was written for. 6600+ polls later the successor is alive and the original\r\n  death is still uncharacterized. A product-side record of the transition would have cost bytes.\r\n\r\n- **WHY THIS IS NOT THE CONVOY BREADCRUMB'S JOB, and must not be bolted onto it.**\r\n  `DAEMON_AUTOSTART` is load-bearing as a COUNTABLE line: `daemon_stop_convoy_e2e` asserts *exactly\r\n  one* appears under a storm (:178) and counts N under a deliberate race (:237). Adding identity\r\n  fields to that line risks the count and buries a forensic record inside a line whose contract is\r\n  its cardinality. **The record belongs in its own line and its own artifact.**\r\n\r\n- **REMEDY — RULED 2026-09-07 11:07Z (doyle), APPROVED as proposed with two refinements. Small,\r\n  product-side, no wire change.** doyle re-derived the census independently at `f3c8495b` (one\r\n  writer `daemon.rs:471`, two readers `cli.rs:8581` + `:8754`, both inside `if running`) before\r\n  ruling — the falsifiable claim below has been checked, not taken.\r\n  1. **Read before you clobber.** At `daemon.rs:471`, read the existing `daemon.pid` and its mtime\r\n     BEFORE the write; if it holds a pid that is not ours, emit a distinct, greppable line naming\r\n     the predecessor pid and how long ago the file was last touched — e.g.\r\n     `DAEMON_SUCCEEDS_PID: prior=<pid> prior_pidfile_age_ms=<n> reason=<socket-ping-failed>`. The\r\n     value is that the successor is the only process in the system that is guaranteed to run at\r\n     exactly the moment the question becomes askable.\r\n  2. **Keep one generation.** Rename the existing `daemon.pid` to `daemon.pid.prev` instead of\r\n     overwriting it (best-effort, same directory, same failure posture as today's `let _ =`). One\r\n     generation is enough to answer \"which pid did I replace, and when did it last write?\" and costs\r\n     no rotation policy.\r\n  3. **REFINED BY THE RULING — the discriminator is a FIELD, not a second line.** I proposed a\r\n     separate \"what the ping saw\" record; doyle collapsed it: `prior=<pid|none>` already separates\r\n     the two incidents, because `none` **is** the fresh-home case. One line, one field, no second\r\n     breadcrumb to keep in sync.\r\n  4. **ADDED BY THE RULING — `alive=<bool>`, from a by-number liveness READ at write time.** With\r\n     the prior pid in hand, read whether that number is still live and put the answer on the line.\r\n     It splits the two incidents that otherwise look identical: **`alive` prior = two daemons racing\r\n     the seed bind** (the convoy case), **dead prior = the corpse** (the 14444 case). This is a\r\n     READ, not a kill — #285's identity-before-kill rule binds kills and is not weakened here; a\r\n     by-number read that informs a log line commits no action on the pid.\r\n  5. **UNIT, specified by the ruling:** seed a pidfile with a fake pid and an aged mtime, run the\r\n     write path, assert the emitted fields (`prior`, `age_ms`, `alive`) AND the `daemon.pid.prev`\r\n     bytes. The `.prev` bytes are part of the assertion, not an afterthought — the generation kept\r\n     is the half that survives the process.\r\n  6. **NOT proposed, and the ruling kept it out:** a liveness change. `is_running()` must stay the socket ping — this entry does\r\n     not argue the pidfile should become a liveness signal, which is the exact mistake\r\n     `endpoint.rs:82-85` was written to prevent. The pidfile stays advisory; it just stops being\r\n     silently destroyed.\r\n\r\n- **LANE — SPLIT BY THE RULING, and the two halves ship separately.** The **IR-82 ENTRY** (this\r\n  text) rides hertz's IR-37 thin PR alongside IR-79/80/81. The **PRODUCT REMEDY** rides **#285's\r\n  lane** (todlando, post-W2) because it is the same pid-identity gate: #285 makes a kill read an\r\n  identity, this makes a successor read the identity it is about to erase. One lane, one owner,\r\n  one review of the pid-identity question. Do not implement the remedy in the thin PR.\r\n\r\n- **Kin:** [[RCA-FLEET-DAEMON-14444]] (the open incident this serves — IR-82 does not close it and\r\n  must not be read as closing it), [[IR-81]] (a pid is not an identity — the same lesson from the\r\n  KILL side; here it is the RECORD side), [[IR-80]]/[[IR-79]] (processes outliving what should have\r\n  accounted for them). The through-line doyle named at 10:22Z holds: *a pid is not an identity and a\r\n  pid is not a tree* — and IR-82 adds that **a pid nobody wrote down is not evidence.**\r\n\r\n- **Falsifiable claim, so it can be checked rather than believed:** at `f3c8495b` the tree contains\r\n  exactly ONE writer of `daemon_pid_path()` (`daemon.rs:471`) and exactly TWO readers\r\n  (`cli.rs:8581`, `cli.rs:8754`), both inside a `running` gate. If a future reader appears in an\r\n  unguarded path, this entry's premise weakens and it should be re-measured, not re-asserted.\r\n\r\n### IR-83 — a two-host rig addressed over the tailnet cannot receive INBOUND on Windows, and the whole rig population had only ever run the admitted direction\r\n\r\n- **Status:** OPEN, minted by hertz 2026-09-07 11:41Z on doyle's dispatch (11:40Z). **Provenance: the\r\n  mechanism below is DOYLE'S measurement, not mine** — eight probe arms, each with sender, listener\r\n  and output file, recorded in `GATE-W2-272-CHECKLIST.md` rows 11:36Z–11:39Z. I am off cargo on both\r\n  boxes and have re-measured none of it; this entry is the register form of his finding plus the\r\n  structural reading it supports. Board face: **F18**. Register slot: IR-83 (79/80/81/82 are the\r\n  same thin PR).\r\n- **2026-09-11 ruling:** the original universal \"LAN, never tailnet\" prescription below is\r\n  SUPERSEDED by IR-89's measured tailnet ACL + Windows Firewall remediation and successful\r\n  tailnet probes. Admit the actual transport at each layer and retain an independent reverse\r\n  direction witness. The operator-blocked box remedy is spent; durable witness enforcement\r\n  and its acceptance record remain separate, OPEN work. No new box changes authorized here.\r\n\r\n- **HALF ONE — the tailnet ACL is per-node and ONE-WAY.** `hfenduleam` admits 9 sources and\r\n  `kitsubito` is **not** among them; `kitsubito` admits `hfenduleam`. So a rig cell needing INBOUND\r\n  to the Windows box over `100.x` fails **at the receiver**, and it fails there **whatever the host\r\n  firewall says** — which is why a host-firewall investigation can be run to completion, come back\r\n  clean, and explain nothing.\r\n\r\n- **HALF TWO — Windows defaults `BlockInbound`, and a hash-named test exe has no rule.** Test\r\n  binaries are built with hash-suffixed names, so a rule written against the *program* is keyed to a\r\n  name that changes on the next build. The stale `spt_net-d037…` rule is the precedent already in\r\n  the tree: a rule that was correct once, is present, greps fine, and admits nothing. **The durable\r\n  form is PORT-scoped, not program-scoped:** ports `7480-7499`, `remoteip` = the peer's LAN address,\r\n  added by the operator.\r\n\r\n- **WHY IT SURFACED ONLY NOW, and this is the part that generalizes.** The W2 helper cell is the\r\n  **first cell in the entire rig population that ever needed `kitsubito -> hfenduleam` inbound.**\r\n  W1's four xbox cells and golden's old-twohost job are all `hfenduleam -> kitsubito` — the admitted\r\n  direction. So the population had a **direction monoculture**, and a one-way ACL is invisible to a\r\n  suite that only ever runs the admitted way. Every green in that population was consistent with the\r\n  ACL being wide open and equally consistent with it being one-way; the suite could not tell the\r\n  difference, and nobody had reason to ask. **A capability exercised in only one direction is not\r\n  covered, it is merely unexamined** — the same shape as an assertion that only ever sees the\r\n  passing arm.\r\n\r\n- **THE SECOND STRUCTURAL POINT — a rule keyed to a MUTABLE identity is the lane's own through-line.**\r\n  A per-hash program rule is an exception bound to an identity the build changes underneath it,\r\n  exactly as [[IR-81]] is about a kill bound to a pid the OS may reassign and IR-80 Amendment 1's ENV\r\n  READ face is about a read bound to a process identity `exec` can change. Port-scoping replaces a\r\n  mutable identity with a stable property. That is the same remedy shape as reading an image path\r\n  before a kill and reporting an environment in-band: **stop keying on the thing that moves.** I am\r\n  flagging the rhyme, not claiming a fourth face — this is infrastructure config, not a code path,\r\n  and the amendment's standing prediction is about pid-shaped questions.\r\n\r\n- **FALSIFIABLE CLAIM (doyle's, recorded verbatim as the entry's test):** with the rig on **LAN\r\n  addresses AND the port-scoped rule present**, the helper cell's owner raw carries `WEB_SERVE_FOR`;\r\n  with **either** missing, it carries none. Both arms matter — this is a conjunction, so a single\r\n  green with one of the two absent would refute it, and a red with both present would too.\r\n\r\n- **WHAT THIS ENTRY DOES NOT CLAIM.** It does not say the host firewall was ever misconfigured; the\r\n  ACL half fails at the receiver independently. It does not close F17 or explain the vacuous-green\r\n  run (that was the mid-flight script rewrite — different cause, different fix, and the two were\r\n  live in the same hour, which is precisely why each needed its own named mechanism rather than one\r\n  story). It proposes no product change: both halves are rig addressing and operator-added firewall\r\n  config.\r\n\r\n- **REMEDY.** (1) Rig-side: address peers by LAN in two-host rigs, and make the tailnet address\r\n  unreachable-by-construction rather than merely unused, so a future rig cannot quietly pick it up.\r\n  (2) Operator-side: the port-scoped inbound rule (`7480-7499`, `remoteip` = peer LAN), replacing\r\n  per-hash program rules; the stale `spt_net-d037…` rule should be removed in the same pass so it\r\n  stops reading as coverage. (3) Population-side — **RULED 11:42Z (doyle), with a precision that\r\n  changes the shape:** this is NOT a new cell. **The W2 helper cell IS the first reverse-direction\r\n  cell**, and on LAN it exercises `kitsubito -> hfenduleam` inbound for real once the rule exists.\r\n  The remedy is therefore to **keep at least one reverse cell in the xbox battery permanently and\r\n  NAME it as the direction witness**, so its role is a stated property rather than an accident of\r\n  what W2 happened to need. A suite that only runs one way cannot discover the next one-way ACL\r\n  either, and the way that recurs is not \"nobody wrote the cell\" but \"the cell that had it stopped\r\n  being run.\"\r\n\r\n  **The hazard that follows from naming it, stated here so the naming is not decorative:** a witness\r\n  cell that is SKIPPED stops being a witness while still reporting green — the exact confusion this\r\n  lane already paid for, where a must-skip `role_b` PASS was indistinguishable from four cells that\r\n  no-opped. So the direction witness needs its skip to be loud: if it is filtered out, phase-reclassed,\r\n  or short-circuits on a missing precondition, that must read as ABSENT COVERAGE and not as a pass.\r\n  Whoever names it owns that half too. **Concrete enforcement, doyle-ruled 11:44Z and written up\r\n  as the RIDER 5 ADDENDUM:** the xbox driver's HELPER WITNESS verdict line already refuses a\r\n  `0.0x s` helper PASS and a `b.raw` without `WEB_SERVE_FOR outcome=registered`; it must ALSO\r\n  print `NOT-A-WITNESS` when the cell is absent from the LIST leg. Those first two are\r\n  *ran-but-vacuous*; absence is *never-ran*, and a verdict built only from the first two passes\r\n  it by omission — every refusal condition evaluates against output that does not exist, finds\r\n  nothing to object to, and falls through to green.\r\n\r\n- **GATING CLAUSE — added 2026-09-07 12:56Z on doyle's dispatch (gate reshape, same minute).** An\r\n  inbound-to-Windows cell in a two-host rig is **gated on the port-scoped rule being present**, and\r\n  without it the cell must **SKIP LOUDLY**: it may not run, may not report PASS, and may not be\r\n  silently filtered — its absence must render as ABSENT COVERAGE in the verdict, on the RIDER 5\r\n  ADDENDUM's `NOT-A-WITNESS:NEVER-RAN` face. The precondition is machine-readable, so the driver\r\n  reads `netsh` at start and the gate is a measured fact rather than a remembered one; a cell whose\r\n  precondition is unmet and which therefore emits nothing is exactly the case a verdict assembled\r\n  only from ran-but-vacuous refusals passes by omission. **This clause is what stops the rule's\r\n  ABSENCE from reading as the rig's health.**\r\n\r\n  **How the reshaped W2 F17 gate applies it (doyle 12:56Z, recorded, not re-measured by me — I am\r\n  still off cargo on both boxes).** With the rule absent 75+ minutes and no operator activity, and\r\n  golden carrying no cross-box `twohost_web`, the shortfall is a **rig blocker, not a golden one**.\r\n  So the HELPER WITNESS was reshaped to the **ONE-BOX pair on BOTH OSes** — doyle's gate tree on\r\n  Windows, a kitsubito clone at the tip on Linux with the rig shipped as the frozen copy — on the\r\n  basis that the 03:31Z one-box run at `f3c8495b` reproduced F17 end to end (A `outcome=unanswered`,\r\n  B `DISPATCH:4:Unknown`), i.e. the one-box pair drives the real dispatcher on both roles.\r\n  Mutation D must turn the classify unit cell red **and** the one-box helper cell red\r\n  (owner `family=Unknown`>0, `registered`=0) while deny/fetch stay green; revert dirty 0. The\r\n  cross-box pair still runs as the A->B regression (deny/fetch must PASS), and while the rule is\r\n  absent its helper/range TIMEOUTs are classified **F18-INFRA** — becoming a witness automatically\r\n  if the rule lands before the run, because the driver reads `netsh` at start.\r\n  **The cross-box helper witness therefore stays an OPEN rider on the operator's rule, not a land\r\n  blocker.** Note the shape this preserves: the reshape moves the witness to a pair that CAN run,\r\n  and leaves the direction it cannot exercise named and open — it does not let the one-box green\r\n  stand in for the direction coverage that is still missing. A one-box pair proves the dispatcher;\r\n  it cannot prove an inbound ACL, and nothing here claims it does.\r\n\r\n  **PROBE RESOLUTION — doyle 12:59Z, ADOPTED INTO THIS GATE (not deferred to the rider).** The\r\n  precondition read is now THREE-VALUE in `gate-w2-f17.sh`: `Rule Name` in stdout -> PRESENT,\r\n  `No rules match` -> ABSENT, empty stdout or anything else -> PROBE-FAILED. **PROBE-FAILED\r\n  classifies the cross-box helper/range as `UNCLASSIFIED: this run cannot tell INFRA from a real\r\n  red` — never F18-INFRA** — and xbox-D's skip line names the state. The raw probe (exit code +\r\n  first 3 lines) is printed into the driver log, so the classification is auditable after the fact\r\n  rather than inferred from what got bucketed. Exercised standalone on all three arms: real\r\n  `netsh` = exit 1 + `No rules match` -> ABSENT; forced bad args -> PROBE-FAILED; empty stdout ->\r\n  PROBE-FAILED.\r\n\r\n  **Recorded because it corrects the asker (me), not the implementer:** I proposed the three-value\r\n  shape AND, in the same message, proposed discriminating on the exit code. doyle's standalone\r\n  exercise measured `netsh` exiting **1 on a clean ABSENT**, so an exit-code discriminator would\r\n  have classified every legitimately-absent rule as an instrument fault — turning the run's most\r\n  common honest state into PROBE-FAILED and, with it, `UNCLASSIFIED`. The discriminator that landed\r\n  is STDOUT CONTENT. The general form belongs in the entry because it is the reason the third arm\r\n  needed measuring at all: **a CLI's exit code is a claim about the QUERY, not about the ANSWER**,\r\n  and an empty-but-correct result is reported non-zero by a great many tools. A third value added\r\n  to a probe needs its own evidence, obtained by making all three arms fire on purpose — which is\r\n  this lane's standing rule that a tool whose success path has never been made to fail on purpose\r\n  is untested, applied to a tool's FAILURE path instead.\r\n\r\n- **Kin:** [[IR-81]] and IR-80 Amendment 1 (keying on a mutable identity), the F17 riders (a witness\r\n  that never executed the direction it certifies).\r\n\r\n### IR-84 — the one `PUMP_PEER_FAIL` arm the rigs actually fire was the only one carrying no clock, so the stall that produced it could be counted but never timed\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-09 with the instrument that closes its first half. ·\r\n  **Origin:** the 65 s two-host helper stall (design written before the run,\r\n  `docs/design/RIDER-65S-DESIGN.md`). The number was branch-claimed 2026-09-08 by name only — IR-85\r\n  records that it carried no entry text in any register file in any worktree — and this is that text.\r\n- **Symptom:** `two_host_web_helper_role_a` takes **61.956–69.096 s** across five runs while its\r\n  siblings in the same binary and the same run take **0.135–0.753 s**. Every ladder rig —\r\n  win-onebox, linux-onebox, cross-box — logs **exactly ONE**\r\n  `PUMP_PEER_FAIL:<node>:peer reply-read: no progress within budget — dropping peer (brain IPC read\r\n  deadline elapsed)` on B before completing. **3/3, one each, never on A** (doyle's GATE-W3 readout).\r\n- **Cause of the DIAGNOSTIC failure, which is what this entry is about:** that line is emitted from\r\n  the `Err(e)` arm of `peer_leg_outcome` (`crates/spt-daemon/src/pump/mod.rs`), and at\r\n  `b0b67aaa` it read `emit_line_err!(\"PUMP_PEER_FAIL:{peer_hex}:{e}\")` — **no timestamp**. Measured\r\n  at that sha rather than recalled: the file carries **four** `PUMP_PEER_FAIL` emit sites, **three**\r\n  of them stamped `wall_ms=… mono_ms=…` (the submit arm, the no-route arm, and the\r\n  `PRESENCE_DIAL_FAILED` arm), and this one was **the only unstamped site left**. It is also the\r\n  arm the rigs actually fire — a `PEER_REPLY_READ_BUDGET` expiry reclassified out of `TimedOut` by\r\n  `brain::reclassify_peer_reply_err` so it drops one peer rather than poisoning the round. **The\r\n  single arm a reader most needs to time was the single arm that could not be timed.**\r\n- **What that cost, stated as the open question it left:** the arithmetic does not close and this\r\n  entry does not close it. `PUMP_PEER_IO_TIMEOUT` is **30 s** (`:118`) and `SUPERVISE_BACKOFF_BASE`\r\n  is **5 s** (`:121`) — read as constants, not recalled — so one deadline plus one supervise floor\r\n  accounts for **35 s** against **61.956–69.096 s** observed. **~27–34 s is unaccounted**, itself\r\n  close to another 30, which is exactly the coincidence the design document warns against; and the\r\n  count of **exactly one** fail forbids the easy reading that two deadlines elapsed. Three candidates\r\n  stay open and are NOT ranked here: a first ~30 s burned before the deadline's clock starts; a\r\n  second budget stacking on the first; or the restart's re-prime costing materially more than its\r\n  5 s floor. **Separating them needs the deadline's own timestamps against the fail line** — which\r\n  is precisely what the log did not carry.\r\n- **⚠ WHAT THIS ENTRY DOES NOT CLAIM.** The instrument does not explain the stall, does not shorten\r\n  it, and changes no product behaviour: the same peer is dropped at the same instant with the same\r\n  backoff. It makes the stall **answerable from a log that already contains the failure**, instead of\r\n  requiring a rebuild to learn when the budget started. `PUMP_PEER_IO_TIMEOUT` is a hard const with\r\n  no env knob, so varying it costs a rebuild — deliberately deferred until the stamps say which half\r\n  of the arithmetic is missing.\r\n- **Kin and the recurrence that matters:** this is the **SECOND** time an unstamped\r\n  `PUMP_PEER_FAIL` cost a hunt. The `PRESENCE_DIAL_FAILED` arm carries a comment naming the\r\n  \"2026-07-14 `PUMP_PEER_FAIL`-unstamped seed, folded here\", and **REQ-PUMP-STAGE-TRUTH** already\r\n  requires every peer failure \"stamped (wall+mono) and peer-attributed\", explicitly subsuming that\r\n  seed. So the contract was written, three of four sites complied, and the fourth stayed silent for\r\n  eight weeks — **a convention enforced by no mechanism degrades one arm at a time, and every reader\r\n  of a complying arm reports the convention as held**, the same shape as the `validate_docs_dir`\r\n  refusal-arm rider in the same design document. Also kin: **IR-83** (the rig population had only\r\n  ever run the admitted direction), `REQ-HAZARD-PUMP-IPC-DEADLINE` (a `TimedOut` brain-IPC read is a\r\n  supervised restart, never a per-peer retry), ADR-0039 Decision 5.\r\n- **Ripe when:** now, and it lands with this entry — the stamp is one emit line, tagged\r\n  `impl->REQ-PUMP-STAGE-TRUTH` at the site. · **Size:** one emit line plus its comment.\r\n  **Follow-up, not this lane:** a cell that walks every `PUMP_PEER_FAIL` arm and asserts each one\r\n  stamps, so the fifth site added cannot be born silent.\r\n### IR-85 — the Windows self-hosted box runs its fs-heavy tests 3-4x slower than a week ago; two CI wall clocks were sized for the old box, and a red run kept hiding it\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-09 at the #272/v0.68.0 golden r3/r4 arc, on doyle's\r\n  dispatch. Number ruled by doyle from his own census of main@`a2f335f8` (register ended at IR-83;\r\n  IR-84 was branch-claimed by name only, with no entry text in any register file in any worktree —\r\n  that gap is now closed: **IR-84 was filed 2026-09-09 in PR #213**, so this sentence records the\r\n  state at `a2f335f8` and is no longer a reason to go looking for a missing entry).\r\n  **Absorbs two drafts:** doyle's `IR-DRAFT-windows-fs-heavy-slowdown-and-golden-wall` (his IR-A +\r\n  IR-B) and his earlier `IR-NEXT` (operator-desktop load), both retired by reference — this is the\r\n  single entry. Every job/step and per-test timing below is **doyle's**, read via the job/step API.\r\n  · **Origin:** #272 golden r3 attempt 2 was CANCELLED by a wall clock with both test phases green.\r\n- **⚠ THE CAP CHANGE IN `a2f335f8` IS NOT THE FIX AND MUST NOT BE READ AS ONE.** It bounds the run;\r\n  it repairs nothing. A future reader who finds an 80-minute wall and no entry here would reasonably\r\n  conclude the problem was solved. It was only made visible.\r\n\r\n- **A GREEN RUN COSTS MORE THAN A RED ONE, WHICH IS WHY THIS WENT UNSEEN.** A failing run\r\n  short-circuits past the wall a green run has to cross. r3 att1 finished in **48m39s only because\r\n  it FAILED at Phase B**; att2, green, hit 49m59s and was cancelled. Every earlier docs-drift skip\r\n  therefore presented as \"upstream failure\" — the wall was never the reported cause of anything, and\r\n  the surviving evidence systematically flattered the budget.\r\n\r\n- **THE WALL.** Windows golden `test` job (48 steps), fully GREEN: **30m53s** (2026-08-30, run\r\n  33296634901) and **33m21s** (2026-09-06, run 34017906638). At the v0.68.0 head against the\r\n  then-current 50-minute cap — **r3 att2**, job 102352551368 at `f6110c2a`: Phase A 17m14s, Phase B\r\n  20m25s, doctests 1m04s, clippy 3m31s, **CANCELLED at step 30 at 49m59s with everything green**;\r\n  steps 31-42 (installer, docs floor, both docs-drift gates, dormancy) never ran. r2 att1\r\n  (`25e60015`, 09-08 18:47Z) reached step 34 at 44m30s. Steps 30..39 cost ~3m30s on the 09-06 green\r\n  (notify 47s, installer 13s, docs-drift 1m54s). Predicted green need ~**56 min**; cap raised to\r\n  **80** (need + ~40% for day-to-day variance) in `a2f335f8`, ci unit 25 -> 40 in the same commit.\r\n- **r4, GREEN — the first complete measurement at the head: 54m35s** (07:12:26Z -> 08:07:01Z),\r\n  **25m25s** headroom under 80; docs-drift (step 38) 2m23s; Phase A 15m51s, Phase B 22m56s. The ~56\r\n  prediction held to within 1.5 min, so the cap is sized on evidence, not generosity. **What that\r\n  does NOT establish:** it was a sizing forecast, and its holding says nothing about the cause\r\n  diagnosis below. Nor are att2-vs-r4 per-phase deltas a trend — att2 was cancelled mid-run, so only\r\n  its phase legs are comparable at all, and the spread they sit in is the same variance the 40% is\r\n  there to absorb.\r\n\r\n- **THE SLOWDOWN, per test, same box, same tests.** `spt-daemon::sync` concurrent_writes\r\n  **22.4s -> 74.8s**, two_tier_sync 18.7 -> 67.4; `spt-store` monic clone_copies 17.7 -> 62.9,\r\n  different_monics 18.2 -> 64.9; syncmerge reconciled_write 27.3 -> 51.2. **~25 spt-store/spt-daemon\r\n  tests now exceed 30s on Windows Phase A at `f6110c2a`, against 1-2s each on kitsubito.**\r\n  Phase-level: Phase A nextest 170s (09-06) -> 642s (att1) -> 1034s (att2); Phase B 710s -> 1164s.\r\n  The suite did not get more expensive — Linux is unchanged.\r\n\r\n- **DATING SAYS ENVIRONMENT DOMINATES, AND BY HOW MUCH.** main's own ci Windows `unit` job:\r\n  11-12 min on 09-06 (runs 34040416870, 34041526195, 34043323577) -> 13-20 min on 09-07 -> 12-24 min\r\n  on 09-08, hitting **22 min at `e4444413`** (run 34261096301) three minutes under its own 25-minute\r\n  wall. **Gradual over days, under no single gate change, is the shape of an environment term, not a\r\n  commit's.** Head growth is real but MINOR: +138 Phase A tests, +20 Phase B, HEAVY 34 -> 35.\r\n\r\n- **THE BOX IS AN OPERATOR DESKTOP (folded in from the retired IR-NEXT), and that turns every fixed\r\n  wall-clock budget in the Windows suite into a coin.** From the r2 arc, three attempts at ONE sha\r\n  (run 34262154550 @ `25e60015`): Phase B red each time on a **different single cell or none** — a1\r\n  234/234 (job red on disk floors only), a2 `spt::webserve_attachment_e2e` arm 12, a3\r\n  `spt-daemon::mesh_recovery roster_route_survives_a_transient_dial_failure_with_discovery_disabled`\r\n  (15.0s `converge()` budget, cell 15.715s; the same cell 9.8s / 7.2s on a1/a2). Phase A — 3,346\r\n  spawn-dominated unit cells — slowed **monotonically 448.7 -> 495.1 -> 542.6s at that one sha**.\r\n  Per-cell a3/a2 over 73 Phase B cells >= 1s: median 1.05x, mean 1.34x, 19 cells >= 1.5x, worst 5.2x\r\n  (`endpoint_lifecycle poll_vs_reap` 1.1 -> 5.8s) — **BURSTY, not uniform**. A rotating single victim\r\n  across attempts at one sha is ONE environment cause; hardening victims one at a time never closes\r\n  it (paid before: `e2e-leaked-daemons-shared-box`). The budgets that lost were ~1.5x the fast\r\n  observation — inside the box's measured variance, so they were coins that had been landing right.\r\n- **Box census (doyle 01:13-01:19Z, no cargo/rustc/nextest running, CPU 31%, ~1.1 of 16 cores busy):**\r\n  `qbittorrent.exe` seeding since 09-08 10:20Z (box tx 21.3 MB/s over 5s); fleet `spt daemon brain`\r\n  with 516 GB read since 09-07 08:03Z (~3.5 MB/s steady); Defender real-time ON, `MsMpEng` at\r\n  67.8/62.8/48.9/32.2/12.2% of a core over 5s **on the idle box**; a fresh 35 MB exe pays\r\n  2092/994/1171/1043 ms on FIRST execution against 31/263/19/260 ms on the second — **and every CI\r\n  attempt rebuilds every test binary fresh.** At 06:45Z on 09-09, with the twohost legs running:\r\n  MsMpEng 89% CPU / 991 MB WS, qbittorrent pid 47056 holding 7817 CPU-seconds (2.2 h) since\r\n  09-08 03:20, free 134 GiB (275 -> 197 -> 131 across the three r3 dispatches).\r\n- **⚠ AN UNREADABLE ROW IS NOT AN ABSENT ONE.** The Defender exclusion list cannot be read\r\n  unelevated on this box: `Get-MpPreference` returns the literal string\r\n  `N/A: Must be an administrator to view exclusions` **as the ExclusionPath VALUE**, so a\r\n  `-contains` test reads ABSENT and is meaningless; the HKLM `Windows Defender\\Exclusions\\Paths`\r\n  read throws `SecurityException`. Nobody may report the runner directory as unexcluded from an\r\n  unelevated shell.\r\n\r\n- **HYPOTHESIS ALREADY KILLED, so nobody re-runs it:** the Windows-only `ADAPTER_WEB_PENDING`\r\n  reconcile failure (servehost nudge) **cannot** explain this — spt-store monic and contextstore\r\n  never touch that path.\r\n\r\n- **WHAT IS STILL NOT ESTABLISHED (labelled, so it is not inherited as fact).** The dating argument\r\n  establishes environment-DOMINANT and bounds head growth as the minor term. It does **not**\r\n  apportion the environment term itself: Defender vs the third-party torrent load vs the fleet\r\n  brain's steady read vs anything else is unsplit, and **\"MsMpEng at 89%\" remains a correlate\r\n  measured beside the slowdown, not a proven cause.** The discriminator lane below is what settles\r\n  head-vs-environment on evidence rather than on the shape of a drift curve.\r\n\r\n- **REMEDY — none landed. This entry is the debt, and its middle arms need an operator.** Sequence\r\n  matters; run them in this order:\r\n  1. **DISCRIMINATOR LANE (hertz, one box, ~1.5-2 h).** Run the five named tests at `04e32c8c` and\r\n     at `f6110c2a` on hfenduleam. **Same-slow at both = environment; slow only at the head = head\r\n     growth.** Cheap and decidable, and it must precede any operator ask — do not spend an elevation\r\n     request on a hypothesis a one-lane measurement can test. Design note, because it is the part\r\n     that makes the number trustworthy: the arms run **INTERLEAVED** (A/B/A/B/A/B, 3 reps each), not\r\n     all-A-then-all-B, so drift that hits the whole box cancels in the comparison instead of landing\r\n     on one arm. **A measurement that only works if everyone behaves is not a measurement** — the\r\n     torrent client and Defender are running throughout and are the thing under test, not noise\r\n     anyone gets to remove. Confounder already excluded: the three test-bearing files\r\n     (`spt-daemon/tests/sync.rs`, `spt-store/src/monic.rs`, `spt-store/src/syncmerge.rs`) are\r\n     **byte-identical blobs at both shas**, so a difference cannot be the tests changing; the two\r\n     crates around them are not (+11,388 lines over 48 files).\r\n  2. **Remove the third-party load first.** No torrent client on the CI box during golden windows.\r\n     It is the cheapest variable to remove, and removing it first makes arm 3's benefit measurable\r\n     instead of confounded.\r\n  3. **OPERATOR ASK — Defender path exclusions** for `C:\\actions-runner\\_work` and the gate pools,\r\n     read from an ADMIN shell first (see the unreadable-row warning above), then re-measure the\r\n     first-touch tax on a file **under that path** — the scratchpad measurement is outside the\r\n     runner dir, so it proves the mechanism's size, not the runner's exposure. Unsettable\r\n     unelevated; same shape as **IR-89**'s elevated firewall rule.\r\n  4. **CI census, cheap and durable:** print `Get-MpComputerStatus` RealTimeProtectionEnabled plus\r\n     the ExclusionPath read **verbatim, refusal text included**, in the Windows job's census step,\r\n     so a run's own record says what Defender it ran under.\r\n  5. **Re-measure both caps after any arm lands — the arm a future reader will skip, so it is loud\r\n     here.** A cap sized against a degraded box is correct only while the box stays degraded.\r\n     Leaving 80 in place after a repair silently restores the original hazard: a wall so generous it\r\n     no longer catches a wedged test, which is the job the golden cap was added to do in the first\r\n     place (the 2026-06-03 handoff.rs ConPTY stall, 22 unbounded hosted minutes).\r\n- **Kin:** [[IR-76]] (the golden runner IS the builders' box — the structural reason a desktop's\r\n  load reaches CI at all), [[IR-64]] (box-level facts only the operator can move), [[IR-89]] (the\r\n  other elevated box-rule ask), `defender-first-touch-tax-on-fresh-test-binaries` and\r\n  `e2e-leaked-daemons-shared-box` (memory).\r\n- **Ripe when:** arm 1 now; arms 2-4 on the operator's answer; arm 5 at the next `golden.yml` touch\r\n  after any of them. · **Size:** arm 1 a measurement, arm 4 one census line, arm 5 two literals.\r\n- **AMENDMENT 2026-09-09 (two terms this entry did not name when it landed at `d32d5c4c`).**\r\n  1. **`ci.yml`'s `changes` job runs `unit` on BOTH runners for every push to `main`.** The classify\r\n     step at `.github/workflows/ci.yml:49` emits `code=true` for every non-`pull_request` event, so\r\n     the docs-only skip that PR runs #206/#207 demonstrated is **`pull_request`-only** — read from\r\n     `ci.yml` at `main` by doyle, who names it his own error after twice ruling the opposite from the\r\n     PR runs alone. Consequence for this entry's wall clock: run **34337797758** (the ff of\r\n     `b66a9612`, a docs-only delta over golden-green `a2f335f8`) ran `unit (Windows)` 09:59:57Z →\r\n     10:40:48Z and was **CANCELLED at the 40-minute job wall** (job timeout; conclusion `cancelled`,\r\n     step 6 `Unit tests` 10:08:23 → 10:40:03) — a red on `main` at a sha whose content cannot fail a\r\n     unit test. It is an IR-85 face, not a flake row.\r\n  2. **A near-full volume is an environment term for the slowdown**, alongside the Defender\r\n     first-touch tax and the operator-desktop load already recorded. **Deliberately unquantified:**\r\n     the discriminator window that would have apportioned it was VOID, because the one leg that\r\n     completed ran under both a CI job and a falling disk. See **IR-90**.\r\n- **WHAT THE VOIDED DISCRIMINATOR ESTABLISHED, negatively (hertz, 2026-09-09).** The fs-heavy\r\n  slowdown REPRODUCES at `04e32c8c`, which predates the +11,388-line head growth: spt-daemon\r\n  `concurrent_writes` 105.420 s, `two_tier_sync` 58.362 s, spt-store `clone_copies` 65.657 s,\r\n  `different_monics` 73.967 s, `syncmerge reconciled_write` 86.765 s, against the 09-06 baseline of\r\n  22.4 / 18.7 / 17.7 / 18.2 / 27.3 s — **3.2x to 4.7x on all five, at the OLD sha**. So head growth\r\n  is **not NECESSARY** for the slowdown. That is the whole of it: it does NOT measure how much the\r\n  environment explains, and it is not evidence about the head arm at all — that leg ran inside run\r\n  34337797758's window and on a volume that reached 0.018 GiB free, and the head arm never produced\r\n  a comparable pair. **Arm 1 stays OPEN**, its re-run deferred until **IR-90**'s guard exists and a\r\n  window with no `main` push and no CI job on the box can be scheduled.\r\n\r\n- **AMENDMENT 2026-09-10 (hertz, on THIS ENTRY'S OWN arm-1 design note).** The note says the arms run\r\n  **INTERLEAVED** A/B/A/B so box drift cancels. It does not cancel: **B is always the later arm within\r\n  each pair**, so a monotone drift across the session lands on B every time and is read as an arm\r\n  effect. Alternate the PAIR ORDER — **A/B then B/A** — record per-leg timestamps and conditions, and\r\n  describe the result as **REDUCING order confounding, not eliminating it**. Second binding change,\r\n  from the releases#294 triage: **instrument, do not infer.** `cargo nextest run --success-output\r\n  immediate` retains stdout for PASSING tests (deployah), so a passing arm can still print poll\r\n  elapsed, iteration count, IPC time and producer progress — **a failing arm is not required** for a\r\n  margin measurement (todlando, correcting deployah's \"it has to fail to be informative\"). Arm 1 was\r\n  never re-run, so this lands before the measurement, not after it.\r\n\r\n### IR-86 — golden's 32 GiB floor is BELOW the measured 67.4 GiB Windows suite footprint, so a start floor passes a box that cannot finish\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-08 at the #272/v0.68.0 golden r2 triage. · **Origin:**\r","truncated":true,"truncatedBy":"lines","totalLines":2348,"totalBytes":39037,"outputLines":457,"outputBytes":39037,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6937,"displayContent":{"text":"### IR-81 — a process kill can be written scoped or machine-wide, and nothing makes the scoped form the only reachable one: both codebases carry the right pattern beside the wrong one\n…\n#### SCOPING ARM (a) — the product path has no intermediary; the fixture does\n…\n\r\n### IR-82 — a daemon death leaves NO record of who died: autostart decides on a socket ping, says \"no daemon\", and the successor overwrites the only handle on the corpse\r\n\r\n- **Status:** RULED 2026-09-07 11:07Z (doyle), drafted by hertz 11:04Z on doyle's dispatch (11:03Z: *\"the autostart\r\n  death-cause item is an IR, not a board item — mint it IR-82 in your thin PR\"*). Register on main\r\n  ends at IR-78; 79/80/81 are drafts in the same PR. · **Origin:** the fleet-daemon death on\r\n  hfenduleam at 08:03:14.87Z ([[RCA-FLEET-DAEMON-14444]]) whose cause is **still UNNAMED after a day\r\n  of measurement** — and the reason it is unnamed is this entry. Filed as a defect in\r\n  OBSERVABILITY, not in the death.\r\n- **⚠ THIS IS NOT \"find the killer.\"** The killer hunt is the RCA and stays open there. This entry\r\n  is about the fact that a killer hunt had to be run at all from a cold start, with a watcher script\r\n  written by hand after the event, because the product recorded nothing about the transition at the\r\n  moment it noticed it.\r\n\r\n- **THE MEASUREMENT — all four facts read at source, no build (gate was live on both boxes).**\r\n\r\n  1. **The daemon writes its pid.** `crates/spt-daemon/src/daemon.rs:471` —\r\n     `let _ = std::fs::write(daemon_pid_path(), std::process::id().to_string());`, into\r\n     `<spt_home>/daemon.pid` (`crates/spt-daemon/src/endpoint.rs:81`). Unconditional overwrite, no\r\n     read-before-write, no rotation, no history.\r\n  2. **Autostart never looks at it.** `ensure_running_outcome`\r\n     (`crates/spt-daemon/src/daemon.rs:686-724`) decides on `is_running()`, which is\r\n     `seedmap::ping(&seed_socket_name()).is_ok()` (`daemon.rs:598-600`) — **a socket ping and\r\n     nothing else.** The decision consults no pid, no mtime, no prior state.\r\n  3. **The breadcrumb it emits carries no identity.** `daemon.rs:721` —\r\n     `DAEMON_AUTOSTART: no daemon and no standing operator stop — starting one`. Deliberately\r\n     \"always-on, ids-free\" per its own comment, because its job is to be COUNTED (the convoy\r\n     serialization observable that `daemon_stop_convoy_e2e` asserts at :178/:237). That design is\r\n     correct for what it was built for and is exactly why it answers nothing here.\r\n  4. **Then the successor destroys the evidence.** The new daemon reaches :471 and overwrites\r\n     `daemon.pid` with its own pid. The dead pid, and the file mtime that bracketed its life, are\r\n     gone — overwritten by the very event that should have recorded them.\r\n\r\n- **THE SHARP FORM — the file is read ONLY in the state where it can tell you nothing.** The only\r\n  two readers of `daemon_pid_path()` in the tree are `crates/spt/src/cli.rs:8581` and `:8754` (both inside `cmd_daemon_status`, :8573), and\r\n  **both are gated on `running`** (`if running { let pid = read(...) }`). So `daemon.pid` is consulted\r\n  exclusively when a daemon is alive — when its contents are guaranteed fresh and merely restate\r\n  what the ping already proved — and is ignored in the one state where its staleness is the only\r\n  evidence anyone has. Its doc comment (`endpoint.rs:82-85`) says *\"a stale pid here is harmless\r\n  because callers probe the socket, never this file.\"* **That is true for LIVENESS and false for\r\n  FORENSICS**, and the entry is that the codebase has only ever considered the first reading.\r\n\r\n- **WHAT IT COST, concretely, on 2026-09-07.** Daemon pid 14444 died at 08:03:14.87Z inside the ci\r\n  Windows unit leg's nextest LIST phase; successor 48232 cold-started at 08:03:20Z and\r\n  `DAEMON_RESTART_RESUME`d every session, orphaning live agents' monitors and readers and handing at\r\n  least one agent a stale brief. Neither peer ran a kill. To get ANY signal at all I had to hand-write\r\n  an external watcher (`C:\\Users\\decid\\.spt-watch\\watch-daemon.ps1`, 1s cadence, identity re-verified\r\n  by image path AND creation time every poll) **after** the death, which by construction cannot\r\n  observe the event it was written for. 6600+ polls later the successor is alive and the original\r\n  death is still uncharacterized. A product-side record of the transition would have cost bytes.\r\n\r\n- **WHY THIS IS NOT THE CONVOY BREADCRUMB'S JOB, and must not be bolted onto it.**\r\n  `DAEMON_AUTOSTART` is load-bearing as a COUNTABLE line: `daemon_stop_convoy_e2e` asserts *exactly\r\n  one* appears under a storm (:178) and counts N under a deliberate race (:237). Adding identity\r\n  fields to that line risks the count and buries a forensic record inside a line whose contract is\r\n  its cardinality. **The record belongs in its own line and its own artifact.**\r\n\r\n- **REMEDY — RULED 2026-09-07 11:07Z (doyle), APPROVED as proposed with two refinements. Small,\r\n  product-side, no wire change.** doyle re-derived the census independently at `f3c8495b` (one\r\n  writer `daemon.rs:471`, two readers `cli.rs:8581` + `:8754`, both inside `if running`) before\r\n  ruling — the falsifiable claim below has been checked, not taken.\r\n  1. **Read before you clobber.** At `daemon.rs:471`, read the existing `daemon.pid` and its mtime\r\n     BEFORE the write; if it holds a pid that is not ours, emit a distinct, greppable line naming\r\n     the predecessor pid and how long ago the file was last touched — e.g.\r\n     `DAEMON_SUCCEEDS_PID: prior=<pid> prior_pidfile_age_ms=<n> reason=<socket-ping-failed>`. The\r\n     value is that the successor is the only process in the system that is guaranteed to run at\r\n     exactly the moment the question becomes askable.\r\n  2. **Keep one generation.** Rename the existing `daemon.pid` to `daemon.pid.prev` instead of\r\n     overwriting it (best-effort, same directory, same failure posture as today's `let _ =`). One\r\n     generation is enough to answer \"which pid did I replace, and when did it last write?\" and costs\r\n     no rotation policy.\r\n  3. **REFINED BY THE RULING — the discriminator is a FIELD, not a second line.** I proposed a\r\n     separate \"what the ping saw\" record; doyle collapsed it: `prior=<pid|none>` already separates\r\n     the two incidents, because `none` **is** the fresh-home case. One line, one field, no second\r\n     breadcrumb to keep in sync.\r\n  4. **ADDED BY THE RULING — `alive=<bool>`, from a by-number liveness READ at write time.** With\r\n     the prior pid in hand, read whether that number is still live and put the answer on the line.\r\n     It splits the two incidents that otherwise look identical: **`alive` prior = two daemons racing\r\n     the seed bind** (the convoy case), **dead prior = the corpse** (the 14444 case). This is a\r\n     READ, not a kill — #285's identity-before-kill rule binds kills and is not weakened here; a\r\n     by-number read that informs a log line commits no action on the pid.\r\n  5. **UNIT, specified by the ruling:** seed a pidfile with a fake pid and an aged mtime, run the\r\n     write path, assert the emitted fields (`prior`, `age_ms`, `alive`) AND the `daemon.pid.prev`\r\n     bytes. The `.prev` bytes are part of the assertion, not an afterthought — the generation kept\r\n     is the half that survives the process.\r\n  6. **NOT proposed, and the ruling kept it out:** a liveness change. `is_running()` must stay the socket ping — this entry does\r\n     not argue the pidfile should become a liveness signal, which is the exact mistake\r\n     `endpoint.rs:82-85` was written to prevent. The pidfile stays advisory; it just stops being\r\n     silently destroyed.\r\n\r\n- **LANE — SPLIT BY THE RULING, and the two halves ship separately.** The **IR-82 ENTRY** (this\r\n  text) rides hertz's IR-37 thin PR alongside IR-79/80/81. The **PRODUCT REMEDY** rides **#285's\r\n  lane** (todlando, post-W2) because it is the same pid-identity gate: #285 makes a kill read an\r\n  identity, this makes a successor read the identity it is about to erase. One lane, one owner,\r\n  one review of the pid-identity question. Do not implement the remedy in the thin PR.\r\n\r\n- **Kin:** [[RCA-FLEET-DAEMON-14444]] (the open incident this serves — IR-82 does not close it and\r\n  must not be read as closing it), [[IR-81]] (a pid is not an identity — the same lesson from the\r\n  KILL side; here it is the RECORD side), [[IR-80]]/[[IR-79]] (processes outliving what should have\r\n  accounted for them). The through-line doyle named at 10:22Z holds: *a pid is not an identity and a\r\n  pid is not a tree* — and IR-82 adds that **a pid nobody wrote down is not evidence.**\r\n\r\n- **Falsifiable claim, so it can be checked rather than believed:** at `f3c8495b` the tree contains\r\n  exactly ONE writer of `daemon_pid_path()` (`daemon.rs:471`) and exactly TWO readers\r\n  (`cli.rs:8581`, `cli.rs:8754`), both inside a `running` gate. If a future reader appears in an\r\n  unguarded path, this entry's premise weakens and it should be re-measured, not re-asserted.\r\n\r\n### IR-83 — a two-host rig addressed over the tailnet cannot receive INBOUND on Windows, and the whole rig population had only ever run the admitted direction\r\n\r\n- **Status:** OPEN, minted by hertz 2026-09-07 11:41Z on doyle's dispatch (11:40Z). **Provenance: the\r\n  mechanism below is DOYLE'S measurement, not mine** — eight probe arms, each with sender, listener\r\n  and output file, recorded in `GATE-W2-272-CHECKLIST.md` rows 11:36Z–11:39Z. I am off cargo on both\r\n  boxes and have re-measured none of it; this entry is the register form of his finding plus the\r\n  structural reading it supports. Board face: **F18**. Register slot: IR-83 (79/80/81/82 are the\r\n  same thin PR).\r\n- **2026-09-11 ruling:** the original universal \"LAN, never tailnet\" prescription below is\r\n  SUPERSEDED by IR-89's measured tailnet ACL + Windows Firewall remediation and successful\r\n  tailnet probes. Admit the actual transport at each layer and retain an independent reverse\r\n  direction witness. The operator-blocked box remedy is spent; durable witness enforcement\r\n  and its acceptance record remain separate, OPEN work. No new box changes authorized here.\r\n\r\n- **HALF ONE — the tailnet ACL is per-node and ONE-WAY.** `hfenduleam` admits 9 sources and\r\n  `kitsubito` is **not** among them; `kitsubito` admits `hfenduleam`. So a rig cell needing INBOUND\r\n  to the Windows box over `100.x` fails **at the receiver**, and it fails there **whatever the host\r\n  firewall says** — which is why a host-firewall investigation can be run to completion, come back\r\n  clean, and explain nothing.\r\n\r\n- **HALF TWO — Windows defaults `BlockInbound`, and a hash-named test exe has no rule.** Test\r\n  binaries are built with hash-suffixed names, so a rule written against the *program* is keyed to a\r\n  name that changes on the next build. The stale `spt_net-d037…` rule is the precedent already in\r\n  the tree: a rule that was correct once, is present, greps fine, and admits nothing. **The durable\r\n  form is PORT-scoped, not program-scoped:** ports `7480-7499`, `remoteip` = the peer's LAN address,\r\n  added by the operator.\r\n\r\n- **WHY IT SURFACED ONLY NOW, and this is the part that generalizes.** The W2 helper cell is the\r\n  **first cell in the entire rig population that ever needed `kitsubito -> hfenduleam` inbound.**\r\n  W1's four xbox cells and golden's old-twohost job are all `hfenduleam -> kitsubito` — the admitted\r\n  direction. So the population had a **direction monoculture**, and a one-way ACL is invisible to a\r\n  suite that only ever runs the admitted way. Every green in that population was consistent with the\r\n  ACL being wide open and equally consistent with it being one-way; the suite could not tell the\r\n  difference, and nobody had reason to ask. **A capability exercised in only one direction is not\r\n  covered, it is merely unexamined** — the same shape as an assertion that only ever sees the\r\n  passing arm.\r\n\r\n- **THE SECOND STRUCTURAL POINT — a rule keyed to a MUTABLE identity is the lane's own through-line.**\r\n  A per-hash program rule is an exception bound to an identity the build changes underneath it,\r\n  exactly as [[IR-81]] is about a kill bound to a pid the OS may reassign and IR-80 Amendment 1's ENV\r\n  READ face is about a read bound to a process identity `exec` can change. Port-scoping replaces a\r\n  mutable identity with a stable property. That is the same remedy shape as reading an image path\r\n  before a kill and reporting an environment in-band: **stop keying on the thing that moves.** I am\r\n  flagging the rhyme, not claiming a fourth face — this is infrastructure config, not a code path,\r\n  and the amendment's standing prediction is about pid-shaped questions.\r\n\r\n- **FALSIFIABLE CLAIM (doyle's, recorded verbatim as the entry's test):** with the rig on **LAN\r\n  addresses AND the port-scoped rule present**, the helper cell's owner raw carries `WEB_SERVE_FOR`;\r\n  with **either** missing, it carries none. Both arms matter — this is a conjunction, so a single\r\n  green with one of the two absent would refute it, and a red with both present would too.\r\n\r\n- **WHAT THIS ENTRY DOES NOT CLAIM.** It does not say the host firewall was ever misconfigured; the\r\n  ACL half fails at the receiver independently. It does not close F17 or explain the vacuous-green\r\n  run (that was the mid-flight script rewrite — different cause, different fix, and the two were\r\n  live in the same hour, which is precisely why each needed its own named mechanism rather than one\r\n  story). It proposes no product change: both halves are rig addressing and operator-added firewall\r\n  config.\r\n\r\n- **REMEDY.** (1) Rig-side: address peers by LAN in two-host rigs, and make the tailnet address\r\n  unreachable-by-construction rather than merely unused, so a future rig cannot quietly pick it up.\r\n  (2) Operator-side: the port-scoped inbound rule (`7480-7499`, `remoteip` = peer LAN), replacing\r\n  per-hash program rules; the stale `spt_net-d037…` rule should be removed in the same pass so it\r\n  stops reading as coverage. (3) Population-side — **RULED 11:42Z (doyle), with a precision that\r\n  changes the shape:** this is NOT a new cell. **The W2 helper cell IS the first reverse-direction\r\n  cell**, and on LAN it exercises `kitsubito -> hfenduleam` inbound for real once the rule exists.\r\n  The remedy is therefore to **keep at least one reverse cell in the xbox battery permanently and\r\n  NAME it as the direction witness**, so its role is a stated property rather than an accident of\r\n  what W2 happened to need. A suite that only runs one way cannot discover the next one-way ACL\r\n  either, and the way that recurs is not \"nobody wrote the cell\" but \"the cell that had it stopped\r\n  being run.\"\r\n\r\n  **The hazard that follows from naming it, stated here so the naming is not decorative:** a witness\r\n  cell that is SKIPPED stops being a witness while still reporting green — the exact confusion this\r\n  lane already paid for, where a must-skip `role_b` PASS was indistinguishable from four cells that\r\n  no-opped. So the direction witness needs its skip to be loud: if it is filtered out, phase-reclassed,\r\n  or short-circuits on a missing precondition, that must read as ABSENT COVERAGE and not as a pass.\r\n  Whoever names it owns that half too. **Concrete enforcement, doyle-ruled 11:44Z and written up\r\n  as the RIDER 5 ADDENDUM:** the xbox driver's HELPER WITNESS verdict line already refuses a\r\n  `0.0x s` helper PASS and a `b.raw` without `WEB_SERVE_FOR outcome=registered`; it must ALSO\r\n  print `NOT-A-WITNESS` when the cell is absent from the LIST leg. Those first two are\r\n  *ran-but-vacuous*; absence is *never-ran*, and a verdict built only from the first two passes\r\n  it by omission — every refusal condition evaluates against output that does not exist, finds\r\n  nothing to object to, and falls through to green.\r\n\r\n- **GATING CLAUSE — added 2026-09-07 12:56Z on doyle's dispatch (gate reshape, same minute).** An\r\n  inbound-to-Windows cell in a two-host rig is **gated on the port-scoped rule being present**, and\r\n  without it the cell must **SKIP LOUDLY**: it may not run, may not report PASS, and may not be\r\n  silently filtered — its absence must render as ABSENT COVERAGE in the verdict, on the RIDER 5\r\n  ADDENDUM's `NOT-A-WITNESS:NEVER-RAN` face. The precondition is machine-readable, so the driver\r\n  reads `netsh` at start and the gate is a measured fact rather than a remembered one; a cell whose\r\n  precondition is unmet and which therefore emits nothing is exactly the case a verdict assembled\r\n  only from ran-but-vacuous refusals passes by omission. **This clause is what stops the rule's\r\n  ABSENCE from reading as the rig's health.**\r\n\r\n  **How the reshaped W2 F17 gate applies it (doyle 12:56Z, recorded, not re-measured by me — I am\r\n  still off cargo on both boxes).** With the rule absent 75+ minutes and no operator activity, and\r\n  golden carrying no cross-box `twohost_web`, the shortfall is a **rig blocker, not a golden one**.\r\n  So the HELPER WITNESS was reshaped to the **ONE-BOX pair on BOTH OSes** — doyle's gate tree on\r\n  Windows, a kitsubito clone at the tip on Linux with the rig shipped as the frozen copy — on the\r\n  basis that the 03:31Z one-box run at `f3c8495b` reproduced F17 end to end (A `outcome=unanswered`,\r\n  B `DISPATCH:4:Unknown`), i.e. the one-box pair drives the real dispatcher on both roles.\r\n  Mutation D must turn the classify unit cell red **and** the one-box helper cell red\r\n  (owner `family=Unknown`>0, `registered`=0) while deny/fetch stay green; revert dirty 0. The\r\n  cross-box pair still runs as the A->B regression (deny/fetch must PASS), and while the rule is\r\n  absent its helper/range TIMEOUTs are classified **F18-INFRA** — becoming a witness automatically\r\n  if the rule lands before the run, because the driver reads `netsh` at start.\r\n  **The cross-box helper witness therefore stays an OPEN rider on the operator's rule, not a land\r\n  blocker.** Note the shape this preserves: the reshape moves the witness to a pair that CAN run,\r\n  and leaves the direction it cannot exercise named and open — it does not let the one-box green\r\n  stand in for the direction coverage that is still missing. A one-box pair proves the dispatcher;\r\n  it cannot prove an inbound ACL, and nothing here claims it does.\r\n\r\n  **PROBE RESOLUTION — doyle 12:59Z, ADOPTED INTO THIS GATE (not deferred to the rider).** The\r\n  precondition read is now THREE-VALUE in `gate-w2-f17.sh`: `Rule Name` in stdout -> PRESENT,\r\n  `No rules match` -> ABSENT, empty stdout or anything else -> PROBE-FAILED. **PROBE-FAILED\r\n  classifies the cross-box helper/range as `UNCLASSIFIED: this run cannot tell INFRA from a real\r\n  red` — never F18-INFRA** — and xbox-D's skip line names the state. The raw probe (exit code +\r\n  first 3 lines) is printed into the driver log, so the classification is auditable after the fact\r\n  rather than inferred from what got bucketed. Exercised standalone on all three arms: real\r\n  `netsh` = exit 1 + `No rules match` -> ABSENT; forced bad args -> PROBE-FAILED; empty stdout ->\r\n  PROBE-FAILED.\r\n\r\n  **Recorded because it corrects the asker (me), not the implementer:** I proposed the three-value\r\n  shape AND, in the same message, proposed discriminating on the exit code. doyle's standalone\r\n  exercise measured `netsh` exiting **1 on a clean ABSENT**, so an exit-code discriminator would\r\n  have classified every legitimately-absent rule as an instrument fault — turning the run's most\r\n  common honest state into PROBE-FAILED and, with it, `UNCLASSIFIED`. The discriminator that landed\r\n  is STDOUT CONTENT. The general form belongs in the entry because it is the reason the third arm\r\n  needed measuring at all: **a CLI's exit code is a claim about the QUERY, not about the ANSWER**,\r\n  and an empty-but-correct result is reported non-zero by a great many tools. A third value added\r\n  to a probe needs its own evidence, obtained by making all three arms fire on purpose — which is\r\n  this lane's standing rule that a tool whose success path has never been made to fail on purpose\r\n  is untested, applied to a tool's FAILURE path instead.\r\n\r\n- **Kin:** [[IR-81]] and IR-80 Amendment 1 (keying on a mutable identity), the F17 riders (a witness\r\n  that never executed the direction it certifies).\r\n\r\n### IR-84 — the one `PUMP_PEER_FAIL` arm the rigs actually fire was the only one carrying no clock, so the stall that produced it could be counted but never timed\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-09 with the instrument that closes its first half. ·\r\n  **Origin:** the 65 s two-host helper stall (design written before the run,\r\n  `docs/design/RIDER-65S-DESIGN.md`). The number was branch-claimed 2026-09-08 by name only — IR-85\r\n  records that it carried no entry text in any register file in any worktree — and this is that text.\r\n- **Symptom:** `two_host_web_helper_role_a` takes **61.956–69.096 s** across five runs while its\r\n  siblings in the same binary and the same run take **0.135–0.753 s**. Every ladder rig —\r\n  win-onebox, linux-onebox, cross-box — logs **exactly ONE**\r\n  `PUMP_PEER_FAIL:<node>:peer reply-read: no progress within budget — dropping peer (brain IPC read\r\n  deadline elapsed)` on B before completing. **3/3, one each, never on A** (doyle's GATE-W3 readout).\r\n- **Cause of the DIAGNOSTIC failure, which is what this entry is about:** that line is emitted from\r\n  the `Err(e)` arm of `peer_leg_outcome` (`crates/spt-daemon/src/pump/mod.rs`), and at\r\n  `b0b67aaa` it read `emit_line_err!(\"PUMP_PEER_FAIL:{peer_hex}:{e}\")` — **no timestamp**. Measured\r\n  at that sha rather than recalled: the file carries **four** `PUMP_PEER_FAIL` emit sites, **three**\r\n  of them stamped `wall_ms=… mono_ms=…` (the submit arm, the no-route arm, and the\r\n  `PRESENCE_DIAL_FAILED` arm), and this one was **the only unstamped site left**. It is also the\r\n  arm the rigs actually fire — a `PEER_REPLY_READ_BUDGET` expiry reclassified out of `TimedOut` by\r\n  `brain::reclassify_peer_reply_err` so it drops one peer rather than poisoning the round. **The\r\n  single arm a reader most needs to time was the single arm that could not be timed.**\r\n- **What that cost, stated as the open question it left:** the arithmetic does not close and this\r\n  entry does not close it. `PUMP_PEER_IO_TIMEOUT` is **30 s** (`:118`) and `SUPERVISE_BACKOFF_BASE`\r\n  is **5 s** (`:121`) — read as constants, not recalled — so one deadline plus one supervise floor\r\n  accounts for **35 s** against **61.956–69.096 s** observed. **~27–34 s is unaccounted**, itself\r\n  close to another 30, which is exactly the coincidence the design document warns against; and the\r\n  count of **exactly one** fail forbids the easy reading that two deadlines elapsed. Three candidates\r\n  stay open and are NOT ranked here: a first ~30 s burned before the deadline's clock starts; a\r\n  second budget stacking on the first; or the restart's re-prime costing materially more than its\r\n  5 s floor. **Separating them needs the deadline's own timestamps against the fail line** — which\r\n  is precisely what the log did not carry.\r\n- **⚠ WHAT THIS ENTRY DOES NOT CLAIM.** The instrument does not explain the stall, does not shorten\r\n  it, and changes no product behaviour: the same peer is dropped at the same instant with the same\r\n  backoff. It makes the stall **answerable from a log that already contains the failure**, instead of\r\n  requiring a rebuild to learn when the budget started. `PUMP_PEER_IO_TIMEOUT` is a hard const with\r\n  no env knob, so varying it costs a rebuild — deliberately deferred until the stamps say which half\r\n  of the arithmetic is missing.\r\n- **Kin and the recurrence that matters:** this is the **SECOND** time an unstamped\r\n  `PUMP_PEER_FAIL` cost a hunt. The `PRESENCE_DIAL_FAILED` arm carries a comment naming the\r\n  \"2026-07-14 `PUMP_PEER_FAIL`-unstamped seed, folded here\", and **REQ-PUMP-STAGE-TRUTH** already\r\n  requires every peer failure \"stamped (wall+mono) and peer-attributed\", explicitly subsuming that\r\n  seed. So the contract was written, three of four sites complied, and the fourth stayed silent for\r\n  eight weeks — **a convention enforced by no mechanism degrades one arm at a time, and every reader\r\n  of a complying arm reports the convention as held**, the same shape as the `validate_docs_dir`\r\n  refusal-arm rider in the same design document. Also kin: **IR-83** (the rig population had only\r\n  ever run the admitted direction), `REQ-HAZARD-PUMP-IPC-DEADLINE` (a `TimedOut` brain-IPC read is a\r\n  supervised restart, never a per-peer retry), ADR-0039 Decision 5.\r\n- **Ripe when:** now, and it lands with this entry — the stamp is one emit line, tagged\r\n  `impl->REQ-PUMP-STAGE-TRUTH` at the site. · **Size:** one emit line plus its comment.\r\n  **Follow-up, not this lane:** a cell that walks every `PUMP_PEER_FAIL` arm and asserts each one\r\n  stamps, so the fifth site added cannot be born silent.\r\n### IR-85 — the Windows self-hosted box runs its fs-heavy tests 3-4x slower than a week ago; two CI wall clocks were sized for the old box, and a red run kept hiding it\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-09 at the #272/v0.68.0 golden r3/r4 arc, on doyle's\r\n  dispatch. Number ruled by doyle from his own census of main@`a2f335f8` (register ended at IR-83;\r\n  IR-84 was branch-claimed by name only, with no entry text in any register file in any worktree —\r\n  that gap is now closed: **IR-84 was filed 2026-09-09 in PR #213**, so this sentence records the\r\n  state at `a2f335f8` and is no longer a reason to go looking for a missing entry).\r\n  **Absorbs two drafts:** doyle's `IR-DRAFT-windows-fs-heavy-slowdown-and-golden-wall` (his IR-A +\r\n  IR-B) and his earlier `IR-NEXT` (operator-desktop load), both retired by reference — this is the\r\n  single entry. Every job/step and per-test timing below is **doyle's**, read via the job/step API.\r\n  · **Origin:** #272 golden r3 attempt 2 was CANCELLED by a wall clock with both test phases green.\r\n- **⚠ THE CAP CHANGE IN `a2f335f8` IS NOT THE FIX AND MUST NOT BE READ AS ONE.** It bounds the run;\r\n  it repairs nothing. A future reader who finds an 80-minute wall and no entry here would reasonably\r\n  conclude the problem was solved. It was only made visible.\r\n\r\n- **A GREEN RUN COSTS MORE THAN A RED ONE, WHICH IS WHY THIS WENT UNSEEN.** A failing run\r\n  short-circuits past the wall a green run has to cross. r3 att1 finished in **48m39s only because\r\n  it FAILED at Phase B**; att2, green, hit 49m59s and was cancelled. Every earlier docs-drift skip\r\n  therefore presented as \"upstream failure\" — the wall was never the reported cause of anything, and\r\n  the surviving evidence systematically flattered the budget.\r\n\r\n- **THE WALL.** Windows golden `test` job (48 steps), fully GREEN: **30m53s** (2026-08-30, run\r\n  33296634901) and **33m21s** (2026-09-06, run 34017906638). At the v0.68.0 head against the\r\n  then-current 50-minute cap — **r3 att2**, job 102352551368 at `f6110c2a`: Phase A 17m14s, Phase B\r\n  20m25s, doctests 1m04s, clippy 3m31s, **CANCELLED at step 30 at 49m59s with everything green**;\r\n  steps 31-42 (installer, docs floor, both docs-drift gates, dormancy) never ran. r2 att1\r\n  (`25e60015`, 09-08 18:47Z) reached step 34 at 44m30s. Steps 30..39 cost ~3m30s on the 09-06 green\r\n  (notify 47s, installer 13s, docs-drift 1m54s). Predicted green need ~**56 min**; cap raised to\r\n  **80** (need + ~40% for day-to-day variance) in `a2f335f8`, ci unit 25 -> 40 in the same commit.\r\n- **r4, GREEN — the first complete measurement at the head: 54m35s** (07:12:26Z -> 08:07:01Z),\r\n  **25m25s** headroom under 80; docs-drift (step 38) 2m23s; Phase A 15m51s, Phase B 22m56s. The ~56\r\n  prediction held to within 1.5 min, so the cap is sized on evidence, not generosity. **What that\r\n  does NOT establish:** it was a sizing forecast, and its holding says nothing about the cause\r\n  diagnosis below. Nor are att2-vs-r4 per-phase deltas a trend — att2 was cancelled mid-run, so only\r\n  its phase legs are comparable at all, and the spread they sit in is the same variance the 40% is\r\n  there to absorb.\r\n\r\n- **THE SLOWDOWN, per test, same box, same tests.** `spt-daemon::sync` concurrent_writes\r\n  **22.4s -> 74.8s**, two_tier_sync 18.7 -> 67.4; `spt-store` monic clone_copies 17.7 -> 62.9,\r\n  different_monics 18.2 -> 64.9; syncmerge reconciled_write 27.3 -> 51.2. **~25 spt-store/spt-daemon\r\n  tests now exceed 30s on Windows Phase A at `f6110c2a`, against 1-2s each on kitsubito.**\r\n  Phase-level: Phase A nextest 170s (09-06) -> 642s (att1) -> 1034s (att2); Phase B 710s -> 1164s.\r\n  The suite did not get more expensive — Linux is unchanged.\r\n\r\n- **DATING SAYS ENVIRONMENT DOMINATES, AND BY HOW MUCH.** main's own ci Windows `unit` job:\r\n  11-12 min on 09-06 (runs 34040416870, 34041526195, 34043323577) -> 13-20 min on 09-07 -> 12-24 min\r\n  on 09-08, hitting **22 min at `e4444413`** (run 34261096301) three minutes under its own 25-minute\r\n  wall. **Gradual over days, under no single gate change, is the shape of an environment term, not a\r\n  commit's.** Head growth is real but MINOR: +138 Phase A tests, +20 Phase B, HEAVY 34 -> 35.\r\n\r\n- **THE BOX IS AN OPERATOR DESKTOP (folded in from the retired IR-NEXT), and that turns every fixed\r\n  wall-clock budget in the Windows suite into a coin.** From the r2 arc, three attempts at ONE sha\r\n  (run 34262154550 @ `25e60015`): Phase B red each time on a **different single cell or none** — a1\r\n  234/234 (job red on disk floors only), a2 `spt::webserve_attachment_e2e` arm 12, a3\r\n  `spt-daemon::mesh_recovery roster_route_survives_a_transient_dial_failure_with_discovery_disabled`\r\n  (15.0s `converge()` budget, cell 15.715s; the same cell 9.8s / 7.2s on a1/a2). Phase A — 3,346\r\n  spawn-dominated unit cells — slowed **monotonically 448.7 -> 495.1 -> 542.6s at that one sha**.\r\n  Per-cell a3/a2 over 73 Phase B cells >= 1s: median 1.05x, mean 1.34x, 19 cells >= 1.5x, worst 5.2x\r\n  (`endpoint_lifecycle poll_vs_reap` 1.1 -> 5.8s) — **BURSTY, not uniform**. A rotating single victim\r\n  across attempts at one sha is ONE environment cause; hardening victims one at a time never closes\r\n  it (paid before: `e2e-leaked-daemons-shared-box`). The budgets that lost were ~1.5x the fast\r\n  observation — inside the box's measured variance, so they were coins that had been landing right.\r\n- **Box census (doyle 01:13-01:19Z, no cargo/rustc/nextest running, CPU 31%, ~1.1 of 16 cores busy):**\r\n  `qbittorrent.exe` seeding since 09-08 10:20Z (box tx 21.3 MB/s over 5s); fleet `spt daemon brain`\r\n  with 516 GB read since 09-07 08:03Z (~3.5 MB/s steady); Defender real-time ON, `MsMpEng` at\r\n  67.8/62.8/48.9/32.2/12.2% of a core over 5s **on the idle box**; a fresh 35 MB exe pays\r\n  2092/994/1171/1043 ms on FIRST execution against 31/263/19/260 ms on the second — **and every CI\r\n  attempt rebuilds every test binary fresh.** At 06:45Z on 09-09, with the twohost legs running:\r\n  MsMpEng 89% CPU / 991 MB WS, qbittorrent pid 47056 holding 7817 CPU-seconds (2.2 h) since\r\n  09-08 03:20, free 134 GiB (275 -> 197 -> 131 across the three r3 dispatches).\r\n- **⚠ AN UNREADABLE ROW IS NOT AN ABSENT ONE.** The Defender exclusion list cannot be read\r\n  unelevated on this box: `Get-MpPreference` returns the literal string\r\n  `N/A: Must be an administrator to view exclusions` **as the ExclusionPath VALUE**, so a\r\n  `-contains` test reads ABSENT and is meaningless; the HKLM `Windows Defender\\Exclusions\\Paths`\r\n  read throws `SecurityException`. Nobody may report the runner directory as unexcluded from an\r\n  unelevated shell.\r\n\r\n- **HYPOTHESIS ALREADY KILLED, so nobody re-runs it:** the Windows-only `ADAPTER_WEB_PENDING`\r\n  reconcile failure (servehost nudge) **cannot** explain this — spt-store monic and contextstore\r\n  never touch that path.\r\n\r\n- **WHAT IS STILL NOT ESTABLISHED (labelled, so it is not inherited as fact).** The dating argument\r\n  establishes environment-DOMINANT and bounds head growth as the minor term. It does **not**\r\n  apportion the environment term itself: Defender vs the third-party torrent load vs the fleet\r\n  brain's steady read vs anything else is unsplit, and **\"MsMpEng at 89%\" remains a correlate\r\n  measured beside the slowdown, not a proven cause.** The discriminator lane below is what settles\r\n  head-vs-environment on evidence rather than on the shape of a drift curve.\r\n\r\n- **REMEDY — none landed. This entry is the debt, and its middle arms need an operator.** Sequence\r\n  matters; run them in this order:\r\n  1. **DISCRIMINATOR LANE (hertz, one box, ~1.5-2 h).** Run the five named tests at `04e32c8c` and\r\n     at `f6110c2a` on hfenduleam. **Same-slow at both = environment; slow only at the head = head\r\n     growth.** Cheap and decidable, and it must precede any operator ask — do not spend an elevation\r\n     request on a hypothesis a one-lane measurement can test. Design note, because it is the part\r\n     that makes the number trustworthy: the arms run **INTERLEAVED** (A/B/A/B/A/B, 3 reps each), not\r\n     all-A-then-all-B, so drift that hits the whole box cancels in the comparison instead of landing\r\n     on one arm. **A measurement that only works if everyone behaves is not a measurement** — the\r\n     torrent client and Defender are running throughout and are the thing under test, not noise\r\n     anyone gets to remove. Confounder already excluded: the three test-bearing files\r\n     (`spt-daemon/tests/sync.rs`, `spt-store/src/monic.rs`, `spt-store/src/syncmerge.rs`) are\r\n     **byte-identical blobs at both shas**, so a difference cannot be the tests changing; the two\r\n     crates around them are not (+11,388 lines over 48 files).\r\n  2. **Remove the third-party load first.** No torrent client on the CI box during golden windows.\r\n     It is the cheapest variable to remove, and removing it first makes arm 3's benefit measurable\r\n     instead of confounded.\r\n  3. **OPERATOR ASK — Defender path exclusions** for `C:\\actions-runner\\_work` and the gate pools,\r\n     read from an ADMIN shell first (see the unreadable-row warning above), then re-measure the\r\n     first-touch tax on a file **under that path** — the scratchpad measurement is outside the\r\n     runner dir, so it proves the mechanism's size, not the runner's exposure. Unsettable\r\n     unelevated; same shape as **IR-89**'s elevated firewall rule.\r\n  4. **CI census, cheap and durable:** print `Get-MpComputerStatus` RealTimeProtectionEnabled plus\r\n     the ExclusionPath read **verbatim, refusal text included**, in the Windows job's census step,\r\n     so a run's own record says what Defender it ran under.\r\n  5. **Re-measure both caps after any arm lands — the arm a future reader will skip, so it is loud\r\n     here.** A cap sized against a degraded box is correct only while the box stays degraded.\r\n     Leaving 80 in place after a repair silently restores the original hazard: a wall so generous it\r\n     no longer catches a wedged test, which is the job the golden cap was added to do in the first\r\n     place (the 2026-06-03 handoff.rs ConPTY stall, 22 unbounded hosted minutes).\r\n- **Kin:** [[IR-76]] (the golden runner IS the builders' box — the structural reason a desktop's\r\n  load reaches CI at all), [[IR-64]] (box-level facts only the operator can move), [[IR-89]] (the\r\n  other elevated box-rule ask), `defender-first-touch-tax-on-fresh-test-binaries` and\r\n  `e2e-leaked-daemons-shared-box` (memory).\r\n- **Ripe when:** arm 1 now; arms 2-4 on the operator's answer; arm 5 at the next `golden.yml` touch\r\n  after any of them. · **Size:** arm 1 a measurement, arm 4 one census line, arm 5 two literals.\r\n- **AMENDMENT 2026-09-09 (two terms this entry did not name when it landed at `d32d5c4c`).**\r\n  1. **`ci.yml`'s `changes` job runs `unit` on BOTH runners for every push to `main`.** The classify\r\n     step at `.github/workflows/ci.yml:49` emits `code=true` for every non-`pull_request` event, so\r\n     the docs-only skip that PR runs #206/#207 demonstrated is **`pull_request`-only** — read from\r\n     `ci.yml` at `main` by doyle, who names it his own error after twice ruling the opposite from the\r\n     PR runs alone. Consequence for this entry's wall clock: run **34337797758** (the ff of\r\n     `b66a9612`, a docs-only delta over golden-green `a2f335f8`) ran `unit (Windows)` 09:59:57Z →\r\n     10:40:48Z and was **CANCELLED at the 40-minute job wall** (job timeout; conclusion `cancelled`,\r\n     step 6 `Unit tests` 10:08:23 → 10:40:03) — a red on `main` at a sha whose content cannot fail a\r\n     unit test. It is an IR-85 face, not a flake row.\r\n  2. **A near-full volume is an environment term for the slowdown**, alongside the Defender\r\n     first-touch tax and the operator-desktop load already recorded. **Deliberately unquantified:**\r\n     the discriminator window that would have apportioned it was VOID, because the one leg that\r\n     completed ran under both a CI job and a falling disk. See **IR-90**.\r\n- **WHAT THE VOIDED DISCRIMINATOR ESTABLISHED, negatively (hertz, 2026-09-09).** The fs-heavy\r\n  slowdown REPRODUCES at `04e32c8c`, which predates the +11,388-line head growth: spt-daemon\r\n  `concurrent_writes` 105.420 s, `two_tier_sync` 58.362 s, spt-store `clone_copies` 65.657 s,\r\n  `different_monics` 73.967 s, `syncmerge reconciled_write` 86.765 s, against the 09-06 baseline of\r\n  22.4 / 18.7 / 17.7 / 18.2 / 27.3 s — **3.2x to 4.7x on all five, at the OLD sha**. So head growth\r\n  is **not NECESSARY** for the slowdown. That is the whole of it: it does NOT measure how much the\r\n  environment explains, and it is not evidence about the head arm at all — that leg ran inside run\r\n  34337797758's window and on a volume that reached 0.018 GiB free, and the head arm never produced\r\n  a comparable pair. **Arm 1 stays OPEN**, its re-run deferred until **IR-90**'s guard exists and a\r\n  window with no `main` push and no CI job on the box can be scheduled.\r\n\r\n- **AMENDMENT 2026-09-10 (hertz, on THIS ENTRY'S OWN arm-1 design note).** The note says the arms run\r\n  **INTERLEAVED** A/B/A/B so box drift cancels. It does not cancel: **B is always the later arm within\r\n  each pair**, so a monotone drift across the session lands on B every time and is read as an arm\r\n  effect. Alternate the PAIR ORDER — **A/B then B/A** — record per-leg timestamps and conditions, and\r\n  describe the result as **REDUCING order confounding, not eliminating it**. Second binding change,\r\n  from the releases#294 triage: **instrument, do not infer.** `cargo nextest run --success-output\r\n  immediate` retains stdout for PASSING tests (deployah), so a passing arm can still print poll\r\n  elapsed, iteration count, IPC time and producer progress — **a failing arm is not required** for a\r\n  margin measurement (todlando, correcting deployah's \"it has to fail to be informative\"). Arm 1 was\r\n  never re-run, so this lands before the measurement, not after it.\r\n\r\n### IR-86 — golden's 32 GiB floor is BELOW the measured 67.4 GiB Windows suite footprint, so a start floor passes a box that cannot finish\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-08 at the #272/v0.68.0 golden r2 triage. · **Origin:**\r\n…\n  25,284,501,504 B RED at 19:31:55Z -> `FLOOR_END` RED. Consumed in-job: 67.4 GiB.\n…\n- **Linux recurrence, 2026-09-15 (doyle, S4 golden `34946493637`, reported in `3HHHPWCR`).** Kitsubito's test job began with about **110.7 GB** free and reached about **29.3 GB** after its build and test sandbox consumed **81.4 GB**; the workload stages were green, then the floor gates red. `FLOOR_DOCS` and `FLOOR_END` run **before** test-temp-sandbox cleanup, deliberately ([[IR-46]]), so the job must retain the end-floor reserve while its own sandbox still exists. A generic **32 GiB** start admission does not establish that capacity.\n…\n","startLine":4466,"lineNumbers":[4466,null,4560,null,4590,4591,4592,4593,4594,4595,4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611,4612,4613,4614,4615,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626,4627,4628,4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,4644,4645,4646,4647,4648,4649,4650,4651,4652,4653,4654,4655,4656,4657,4658,4659,4660,4661,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672,4673,4674,4675,4676,4677,4678,4679,4680,4681,4682,4683,4684,4685,4686,4687,4688,4689,4690,4691,4692,4693,4694,4695,4696,4697,4698,4699,4700,4701,4702,4703,4704,4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718,4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731,4732,4733,4734,4735,4736,4737,4738,4739,4740,4741,4742,4743,4744,4745,4746,4747,4748,4749,4750,4751,4752,4753,4754,4755,4756,4757,4758,4759,4760,4761,4762,4763,4764,4765,4766,4767,4768,4769,4770,4771,4772,4773,4774,4775,4776,4777,4778,4779,4780,4781,4782,4783,4784,4785,4786,4787,4788,4789,4790,4791,4792,4793,4794,4795,4796,4797,4798,4799,4800,4801,4802,4803,4804,4805,4806,4807,4808,4809,4810,4811,4812,4813,4814,4815,4816,4817,4818,4819,4820,4821,4822,4823,4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,4854,4855,4856,4857,4858,4859,4860,4861,4862,4863,4864,4865,4866,4867,4868,4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879,4880,4881,4882,4883,4884,4885,4886,4887,4888,4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909,4910,4911,4912,4913,4914,4915,4916,4917,4918,4919,4920,4921,4922,4923,4924,4925,4926,4927,4928,4929,4930,4931,4932,4933,4934,4935,4936,4937,4938,4939,4940,4941,4942,4943,4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954,4955,4956,4957,4958,4959,4960,4961,4962,4963,4964,4965,4966,4967,4968,4969,4970,4971,4972,4973,4974,4975,4976,4977,4978,4979,4980,4981,4982,4983,4984,4985,4986,4987,4988,4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999,5000,5001,5002,5003,5004,5005,5006,5007,5008,5009,5010,5011,5012,5013,5014,5015,5016,5017,5018,5019,5020,5021,5022,5023,5024,5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,5040,5041,5042,5043,5044,5045,5046,null,5050,null,5082,null,5092]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":6937,"totalBytes":39037,"outputLines":457,"outputBytes":39037,"shownRange":{"start":4590,"end":5046},"nextOffset":5047}}},"isError":false,"timestamp":1789483661702}}
{"type":"message","id":"3cb4e931","parentId":"fe74a92c","timestamp":"2026-09-15T14:47:41.708Z","message":{"role":"toolResult","toolCallId":"call_5ZpeIsZcdlrtUTY8rOlOBEmP|fc_000c7cef03cac861016aa95a8d972c87d1a02d85ce62f5523c","toolName":"read","content":[{"type":"text","text":"### IR-85 — the Windows self-hosted box runs its fs-heavy tests 3-4x slower than a week ago; two CI wall clocks were sized for the old box, and a red run kept hiding it\n…\n- **Status:** OPEN, filed by hertz 2026-09-09 at the #272/v0.68.0 golden r3/r4 arc, on doyle's\n…\n- **AMENDMENT 2026-09-10 (hertz, on THIS ENTRY'S OWN arm-1 design note).** The note says the arms run\n…\n\n### IR-86 — golden's 32 GiB floor is BELOW the measured 67.4 GiB Windows suite footprint, so a start floor passes a box that cannot finish\n\n- **Status:** OPEN, filed by doyle 2026-09-08 at the #272/v0.68.0 golden r2 triage. · **Origin:**\n  run 34262154550 @ `25e60015` (shaped on `e4444413`), Windows test job 102182665033: every product\n  step green (Phase A 3346/3346, Phase B 234/234, Summary 2, FAIL 0), the ONLY reds were the two\n  in-job floor gates. `FLOOR_START` 97,649,786,880 B PASS at 18:47:23Z -> `FLOOR_DOCS`\n  25,284,501,504 B RED at 19:31:55Z -> `FLOOR_END` RED. Consumed in-job: 67.4 GiB.\n- **Mechanism:** `golden.yml` derives 32 GiB as \"the observed tens-of-GB full-suite footprint\n  rounded up to the next binary boundary, preserving headroom for one complete run\" (comment\n  above the Windows start floor). The measured footprint is 67.4 GiB, so a start reading anywhere\n  in [32, ~100) GiB passes and the job then walks under the floor by construction: box baseline\n  91 GiB minus 67.4 = 23.5 < 32. This is a shortfall of the DERIVATION, not a rate, not a product\n  red, and not the instant-vs-sustained face IR-46 files (that face is fixed by the FLOOR_DOCS\n  re-read, which is what caught it). The start floor must be footprint + end-floor (~100 GiB) or\n  it asserts nothing about finishing.\n- **Coverage consequence (the load-bearing part):** the Windows `Docs drift gate (CLI ref + llms\n  links)` step is sequenced BEHIND `FLOOR_DOCS`, so it SKIPPED and r2 held NO Windows CLI-ref\n  axis at that sha until the rerun. A floor red that skips a gate is a coverage hole wearing a\n  disk red.\n- **Kin:** [[IR-46]] (a floor asserts an instant), [[IR-59]] (pool arithmetic, LNK-class reds\n  that name no disk), [[IR-64]] (the operator-payload reservoir that sets the box baseline; its\n  ripe-when arm — a golden that dies at the floor despite adopted pool discipline — FIRED here\n  in the in-job form), [[IR-73]] (second half BUILT: the within-job re-read exists and is what\n  produced the FLOOR_DOCS reading), REQ-CI-FREE-SPACE-PREFLIGHT.\n- **Coupling (deployah 23:54Z, from `golden.yml` at `25e60015`):** the Windows `DISK docs floor`\n  (:616) and `Docs drift gate — windows` (:629) carry only `if: runner.os == 'Windows'`, no\n  `always()`, while `DISK end floor` does (`always() && runner.os == 'Windows'`, ~:705). Actions'\n  default is \"previous steps succeeded\", so ANY Phase B red skips the docs axis by construction —\n  observed three times at this sha (floor red, ttl cell, ttl cell). The docs gate is therefore never\n  independent evidence: it can only be banked when Phase B is green in the same job. Remedy line:\n  gate the two docs steps on `!cancelled()` plus the success of the steps they actually depend on\n  (checkout/build), not on Phase B — a rig change, new sha, hertz workflow rider slot.\n- **Remedy shape:** re-derive the start floor from the measured footprint (67.4 GiB Windows,\n  Linux to be measured) plus the 32 GiB end floor, print the footprint (start minus end free)\n  on every run so the number re-measures itself, and keep the 32 GiB literal only for\n  `FLOOR_END`.\n- **Ripe when:** next `golden.yml` touch (hertz workflow rider slot). · **Size:** small — one\n  literal per start-floor site + one printed subtraction.\n- **Linux recurrence, 2026-09-15 (doyle, S4 golden `34946493637`, reported in `3HHHPWCR`).** Kitsubito's test job began with about **110.7 GB** free and reached about **29.3 GB** after its build and test sandbox consumed **81.4 GB**; the workload stages were green, then the floor gates red. `FLOOR_DOCS` and `FLOOR_END` run **before** test-temp-sandbox cleanup, deliberately ([[IR-46]]), so the job must retain the end-floor reserve while its own sandbox still exists. A generic **32 GiB** start admission does not establish that capacity.\n<!-- [doc->REQ-CI-FREE-SPACE-PREFLIGHT] -->\n- **Linux sizing decision, 2026-09-15 (2NLUDSQA).** Golden's Linux **test-job** start allowance is now **130,000,000,000 bytes (130 decimal GB)**. The rounded measurements imply about **115.8 GB** minimum (81.4 GB working set + 32 GiB reserve); the allowance includes about **14.24 GB** margin, not a newly measured peak. `FLOOR_DOCS` and `FLOOR_END` retain **34,359,738,368 bytes (32 GiB)** and their pre-cleanup placement. Admission remains after checkout and before expensive work. Only this job/OS start value changes; other jobs, Windows admission, step conditions and cleanup order are untouched. Moving guards after cleanup would certify a different state and was not chosen.\n- **Linux verification.** Executed the actual YAML shell bodies on kitsubito with controlled `df` readings: the historical 110.7 GB start passes the predecessor and is refused by the successor; 130 GB minus one byte refuses, exactly 130 GB passes; native `df` failure23 propagates. Both docs/end bodies still refuse one byte below 32 GiB and pass exactly at the reserve. An unmodified native `df` sample passed at **246,886,174,720 bytes** free. All **9 successor probes** matched their expected exits; temporary probe workspace removed. Parsed workflow comparison confirms only the Linux test admission body differs, with all other executable steps/conditions/order unchanged. Evidence: `.spt/preserved/hertz-ir86-linux-floor/{predecessor,successor,workflow-scope}.js…\n<!-- [doc->REQ-CI-FREE-SPACE-PREFLIGHT] -->\n- **Windows source and derivation, 2026-09-15 (FRNOZMV4 / 2G5X324J / WNMSYL52).** Primary runner log: `.spt/preserved/hertz-ir86-windows-floor/job102182665033.log`, SHA256 **`8b1167ab4de3d474df4dde19f0a623d03beb820400cd19907b996cc2ab7bf91d`**, recovered from GitHub job **102182665033**, run **34262154550**, hfenduleam, source SHA **`25e6001585ed0cd495a72c7634dded9dd207bdae`**. Its actual `FLOOR_START` at line138 / 18:47:23.3668896Z reads **97,649,786,880 bytes**; `FLOOR_END` at line5223 / 19:31:56.6941352Z reads **25,284,497,408 bytes**, both on2026-09-08. Net movement is **72,365,289,472 bytes (67.395 GiB)**. Add the retained32GiB reserve: **106,725,027,840 bytes (99.395 GiB)**; round up to the next binary boundary for **128 GiB (137,438,953,472 bytes)** ad…\n- **Windows admission scope.** Only golden's Windows **test-job** start floor changes (`128GB` in PowerShell means128GiB). Docs/end remain32GiB before teardown; checkout still precedes admission, expensive work follows it, and every other step/condition/order remains unchanged. Linux retains its separately derived130decimalGB allowance.\n- **Reclamation is load-bearing (WNMSYL52).** Today's pre-reap hfenduleam sample **91,890,798,592 bytes (~92 GB)** would have been REFUSED by this admission floor. Reaping classified, owned retired targets is therefore a prerequisite for golden admission from that box state, not optional housekeeping. The authorized S3/S5 target removal left **201,837,236,224 bytes** free; source `.spt/preserved/hertz-retire-QD54OM7S/retirement-result.json` records both samples and their concurrent-CI attribution caveat. Re-sample after reclamation; no stale free-space reading grants a run. The unchanged refusal diagnostic names **`RESOURCE=disk`**, drive, free bytes and floor: classify it as **capacity REFUSED / workload UNTESTED**, not a product-test failure. The CI job st…\n- **Windows verification.** Executed the actual YAML PowerShell bodies under pwsh7.6.6. The historical97.65GB input passes the predecessor and refuses under the successor; today's pre-reap91.89GB also refuses with `RESOURCE=disk`. Admission-minus-one-byte refuses, exactly128GiB passes; an unreadable workspace fails before any PASS token. Docs/end each refuse reserve-minus-one-byte and pass exactly32GiB. A native workspace read passed at **264,109,211,648 bytes** free. All **10 successor probes** matched expected exits; no script files, build, pool claim, or suite execution. Parsed workflow comparison confirms only the Windows test admission body changed. Evidence: `.spt/preserved/hertz-ir86-windows-floor/{consumption-source,predecessor,successor,workflow-sco…\n- **Remaining IR-86 scope.** Both OS admission-sizing slices are implemented; automated start-minus-end reporting remains separate work, so the whole entry stays open. Existing raw-byte START/DOCS/END readings remain available for capacity analysis and are instantaneous shared-volume samples, not exclusive workload attribution.\n\n### IR-87 — two-host ceremony halves are INDEPENDENT jobs on DIFFERENT runners (A Windows/hfenduleam, B Linux/kitsubito); B's 900 s budget runs on B's own clock, so any older queued Windows job starves A and reds B deterministically, and the panic text blames pairing\n\n- **Status:** OPEN, filed by doyle 2026-09-08 at the #272 golden r2 triage. · **Origin:**\n  run 34262154550, twohost-b job 102207296960 (log 81,692 B, sha256 67403f04…8030): role B built,\n  rostered, polled PAIR_MEET_UP every 30 s from 19:34:30Z, and hit the rig_wait barrier\n  \"pairing: A rostered via the daemon-hosted responder\" at its 900 s deadline 19:49:17Z\n  (`crates/spt-daemon/tests/twohost.rs`, exit 101, 2 passed 1 failed). twohost-a (102207296985)\n  was QUEUED from 19:32:13Z with no runner: the Windows runner went to thin ci run 34261096301\n  (post-merge on main @ `e4444413`) the second the golden test job released it at 19:31:56Z.\n- **Mechanism:** `golden.yml` sequences twohost-a and twohost-b after `test`, but they are two\n  jobs on two runners (measured 2026-09-08 20:56Z via the jobs API `runner_name`: twohost-a on\n  hfenduleam, twohost-b on kitsubito), and GitHub's queue does not honour a workflow's intra-run\n  job ordering against a FOREIGN run on either runner. B starts, its whole budget ticks against a partner that has not been\n  scheduled, and `rig_wait` panics `never converged on the rig: {what}` — a text that reads as a\n  pairing defect. The lanes were not at fault, and twohost-a's outcome was predetermined once B\n  exited (a later A pass would be vacuous).\n- **Kin:** [[IR-76]] (hfenduleam is golden runner AND builders' box; the job-start census cannot\n  see a competing GitHub run either), [[IR-62]] (rig collisions on shared runners), the W1 two-host\n  rig, `a-barrier-cannot-ride-a-carrier-its-sender-outlives` (memory, same family: a barrier needs\n  the receiver's own answer).\n- **Remedy shape (pick at rider time):** (1) start barrier on B keyed to A's job having STARTED\n  (a run-scoped artifact or a `needs`+matrix collapse into ONE job that spawns both roles), or\n  (2) B's deadline clock starts at first A-rostered signal with a separate, longer \"A never\n  appeared\" budget, or (3) the panic names the missing partner's job state so triage does not\n  chase pairing. Any option: the two-host halves must never share a runner queue with a foreign\n  run while one half waits.\n- **Ripe when:** next `golden.yml`/twohost rig touch. · **Size:** small-medium (job shape or\n  barrier rework + panic text).\n\n- **AMENDMENT 2026-09-10 (releases#294, golden 34445961595 att1 @ `a9e786b2`) — THE STARVING RUN CAN\n  BE GOLDEN'S OWN PR, which makes this self-inflicted and recurrent on every golden run with a PR\n  open.** Measured timeline: **07:18:59Z** golden `test (Windows)` completes and releases hfenduleam;\n  **07:18:59Z** twohost-a queued; **07:19:01Z** PR run **34446095808** job `unit (Windows,\n  hfenduleam)` SEIZES the runner; **07:19:02Z** twohost-b starts on the free kitsubito; **07:36:16Z**\n  twohost-b fails at **900.41s** — `never converged on the rig: pairing: A rostered via the\n  daemon-hosted responder`. The origin case (2026-09-08) was a post-merge push on `main`: a run\n  belonging to someone else. **Here the starving run is the `pull_request` run of the very PR carrying\n  the golden head**, so opening the golden PR arms the starvation of that same head's twohost pair.\n  **Consequence for the remedy shape above: any option that only de-conflicts against OTHER lanes'\n  runs does not reach this case.** The golden head's own PR has to be excluded from the Windows\n  runner for the duration of the golden run (or the pair collapsed into one job, option 1).\n- **SECOND-ORDER FACE (deployah, same run): starvation does not merely red B — it desynchronises the\n  pair past repair.** twohost-b was TERMINAL at 07:36:16Z; twohost-a did not start until **07:48:07Z**\n  — the two halves never overlapped for a single second, so twohost-a's outcome is uninformative\n  **whatever it says**, and a red there must not be counted as a second product failure. Recorded\n  honestly at deployah's own insistence: **VOID is his SCORING interpretation, not a fact about the\n  run** — the release record carries GitHub's raw `conclusion` for both jobs beside the scoring, not\n  laundered into it.\n- **⚠ ITS WALL CLOCK IS INDISTINGUISHABLE FROM [[IR-89]]'s.** A 900 s twohost red whose panel blames\n  pairing is ALSO the exact signature of the banked Windows-firewall hazard. The panel alone cannot\n  separate them; **the job TIMELINE can**. Check the schedule before accepting the firewall hazard for\n  any 900 s twohost red — this one fit that signature perfectly and was not it.\n\n### IR-88 — `pool-release` via `cargo run -p xtask` REBUILDS xtask INTO the pool it is releasing, so a reaped pool regrows ~2.8 GB in silence\n\n- **Status:** OPEN, filed by doyle 2026-09-08 from hertz's reap report (20:00Z) during the #272\n  golden r2 repair. · **Origin:** hertz reaped hertz-lane4 / hertz-repin / hertz-percell-id target\n  subtrees (Length-sum upper bounds 68.16 / 47.11 / 8.79 GB) and then ran `cargo run -p xtask --\n  pool-release …` from each worktree: cargo rebuilt xtask into the just-reaped `target/` (2.8 GB\n  back in lane4, partial in repin), nothing printed said so, and the descendancy stopper killed\n  the second before it finished. Removed by hand afterwards; the post-reap free reading on the\n  record (275.95 GiB at 19:55:51Z) predates the regrowth.\n- **Mechanism:** the documented verb (AGENTS.md: \"drop it with `pool-release`\") is a `cargo run`,\n  and cargo's default target for that run IS the pool being released. The verb's own success path\n  recreates the state the operator just measured away; a teardown step that runs it AFTER a reap\n  undoes part of the reap and leaves the recorded free reading stale.\n- **Remedy shape:** either (a) `pool-release` documented and scripted as a PREBUILT `xtask.exe`\n  invoked against `--pool <dir>` from another pool, or (b) the verb refuses when its own\n  `CARGO_TARGET_DIR`/default target equals `--pool` and prints the prebuilt form, or (c) the reap\n  recipe orders release BEFORE the subtree delete. Memory banked 2026-09-08\n  (`pool-release-rebuilds-xtask-into-the-pool-you-just-reaped`); this entry is the durable home.\n- **POSITIVE CONTROL (hertz, 2026-09-09, ruling-3 gate-r3 teardown):** the same release run\n  from a PREBUILT `xtask.exe` invoked from outside the pool regrew NOTHING — the pool's own\n  `xtask.exe` still carried its original 21:00:42 mtime afterwards, and the reap that followed\n  reclaimed 63.71 GiB (132.03 -> 195.74 GiB free) against a 64.88 GiB Length-sum. So the\n  regrowth is a property of the `cargo run` VEHICLE, not of the verb, and remedy (a) is proven\n  rather than merely proposed.\n- **Kin:** [[IR-31]] (pool budgeting), [[IR-56]] (pool-claim identity from CWD — same verb\n  family, same \"the tool acts on where it stands\" shape), releases#103.\n- **Ripe when:** next xtask pool-verb touch or the teardown runbook edit. · **Size:** tiny —\n  one guard or one doc line.\n- **Amendment 2026-09-11 (hertz measured, doyle accepted):** the release-before-delete recipe as\n  written (\"keep the built test binaries, drop deps\") is NOT runnable — the workspace builds runtime\n  dylibs into the same `deps` dir (three `iroh_relay-*.dll` beside `daemon_stop_convoy_e2e-*.exe`\n  in the measured pool), so a retained exe with its dlls deleted is a keepsake. The recipe now reads:\n  retain the test exe set AND the runtime dll set, then EXECUTE one retained exe from the\n  post-deletion state before claiming the set is runnable; otherwise the disposition is archival and\n  exe retention is optional. `.pdb` is not needed to run but costs symbolised failure output — decide\n  that deliberately, not by size.\n\n### IR-89 — hfenduleam's Windows Firewall drops cold inbound UDP to the runner-built test exes, so the two-host rig's first B→A claim (W2 helper) reds for its whole 900 s budget and the panic blames A\n\n- **Status:** BOX HALF **APPLIED** 2026-09-08; WORKFLOW HALF **BUILT** 2026-09-09 — PR #211\n  (`9b96d7e7` + this amendment), **LANDED, exact golden-step acceptance unreconciled**.\n  Subsequent goldens have run: \"until the next golden\" is no longer a future trigger.\n  This sweep does not infer probe execution from a run's existence or overall conclusion;\n  retain the step-specific exercised/skipped/failed evidence before closing. Filed by doyle 2026-09-08\n  at the #272 golden r2 terminal triage; the operator-blocked flag is retired here, because\n  the operator acted.\n  The operator applied BOTH layers that evening — the Windows inbound rule (~23:41Z) and the\n  tailnet ACL grant (~23:56Z) — and the re-probe with the same rule-less pwsh listener read\n  **3/3 over Tailscale on 7483 AND 3/3 on 7489 at 23:57:50Z** from `100.98.197.12`, with a\n  post-terminal probe 3/3 on both ports at attempt 4. v0.68.0 then shipped at `a2f335f8` with\n  both two-host legs GREEN on golden r4, so the box half is closed by measurement and not by\n  assertion. **Durable half BUILT, acceptance reconciliation OPEN:** the pre-ceremony B→A\n  probe and its corrections are documented below. Do not redispatch a workflow guard that\n  already landed, or reopen the spent operator permission. The next box/ACL reset remains a\n  recheck trigger. · **Origin:** run 34262154550 @ `25e60015`, twohost-a 102229928746\n  (`two_host_web_helper_role_a`, :968, 900.40 s) and twohost-b 102229928689\n  (`two_host_web_role_b`, :559, 910.20 s): B logged 75 × \"A not ready … broker QUIC op exceeded\n  the 10s bound (peer unresponsive)\" from 20:49:49Z to 21:04:37Z and was never ADMITTED. Ladder\n  green both sides; both halves started 20:41:23Z on their own runners (not IR-87's starvation).\n- **Mechanism (MEASURED 21:11Z):** the box's firewall policy is `BlockInbound,AllowOutbound` on\n  all three profiles (Ethernet and Tailscale both Private). Inbound allow rules exist only for\n  exes under `Documents\\projects\\spt-core\\target` (interactive Allow clicks) and under the DEAD\n  pre-rename runner path `_work\\spt-core\\spt-core`; exactly ONE under `_work\\spt-bs-core` (its\n  `target\\debug\\spt.exe`, the CLI, not the binder — deployah's count, mine had said zero), none for\n  any `twohost_web-*.exe`. `Get-NetFirewallProfile` shows `DefaultInboundAction = NotConfigured`,\n  whose effective default IS block: the block is Windows' default, not a configured policy, so there\n  is no policy to \"restore\". The runner is a service (`.\\decid`), so the Allow dialog that minted the\n  old rules cannot appear. A's helper cell 3 bound `broker udp 7483` inside\n  `_work\\spt-bs-core\\spt-bs-core\\target\\debug\\deps\\twohost_web-f73bc44be13353fb.exe`; B dialled\n  `100.68.35.65:7483` cold. Probe: a rule-less pwsh UDP listener on hfenduleam:7483 received 0 of\n  3 datagrams from kitsubito `100.98.197.12`; the reverse control (python listener on\n  kitsubito:7483) received 3 of 3 from hfenduleam.\n- **Why three faces from one cause:** the shared-key rig (pre-`e4444413`) reached A only through\n  holes A's OUT-dialling cells (7480–7482) had opened for `id_a` — six 10 s bounds until B's\n  magicsock fell onto one of those paths, then ADMITTED (the 63 s stall, helper-stall memory), or\n  onto a live same-key sibling that never replied (the 21 min hang in 34239258523). Per-cell A\n  identity (`id_a_for`, `e4444413`) removed the accidental route by construction, leaving only\n  the cold path, which the firewall drops. hertz's one-box discriminator \"vanishes\" was true on\n  one box because one box never crosses the firewall. Product and rig are both exonerated; the\n  rig's `a_addr` comment already names W2 as the first A-ward claim.\n- **Remedy (two halves):** (1) BOX, operator-owned, elevated on hfenduleam:\n  `New-NetFirewallRule -DisplayName \"spt-ci two-host rig UDP-In (kitsubito only)\" -Direction Inbound -Action Allow -Protocol UDP -LocalPort 7460-7499 -RemoteAddress 100.98.197.12 -Profile Any`\n  (rig ports at the sha: ladder 7460/7461; web `PORT_OFFSET` 20 → A cells 7480–7483, B 7481; the\n  A-ward surface today is exactly UDP 7480–7483 — deployah's tighter range — and the whole range\n  moves with any `SPT_TWO_HOST_PORT_A` override, so the rule must move with it);\n  program-path rules are the wrong shape because the exe hash changes per build. Verify with the\n  same probe (3/3) before any rerun. (2) WORKFLOW, hertz: a B→A UDP probe step in the twohost\n  jobs before the ceremony, so this reds in 10 s with its own name instead of 900 s blaming\n  pairing; and retire the dead `_work\\spt-core` rules note in the runner runbook.\n- **Kin:** [[IR-83]] (the tailnet-ACL face of a cross-box inbound block — KIN, **NOT the same\n  finding**: that entry is the tailnet policy layer, this one is the Windows firewall layer, and\n  the SECOND LAYER note below is exactly the measurement that separates them), [[IR-87]] (the\n  other way a half waits 900 s on a partner), [[IR-76]] (golden runner\n  is the operator's box), [[IR-64]] (box-level facts only the operator can move),\n  `twohost-web-helper-stall-shared-a-identity-stale-path` (memory; its CONFIRMED arm is re-read\n  by this entry).\n- **AMENDMENT 2026-09-09 — the WORKFLOW half is BUILT and FIELD-MEASURED; it is LANDED-pending-golden\n  (hertz).** The guard is two cells in `twohost_web.rs` plus a step per half in `golden.yml`, and it\n  grew four design corrections that are worth more than the guard itself, because each one is a way a\n  probe can certify the fault it exists to catch.\n  1. **A FIXED SYMMETRIC WINDOW ADDS A THIRD CAUSE THAT LOOKS LIKE THE OTHER TWO.** The step boundary\n     orders the probe on ONE host; it does not align two, and after the ladder each half pays its own\n     wrapper and `cargo test` (on Windows a fingerprint scan plus Defender's first touch of a fresh\n     exe). MEASURED: the first hand-run in the A=kitsubito direction (13:14:13 → 13:14:51Z) redded\n     `INBOUND_BLOCKED` at 10.24 s with text asserting \"a BOX rule, not a product or rig fault\" — and\n     the cause was `cargo`'s start-up on the SENDER putting its first datagram after the receiver's\n     10 s window closed. An innocent box, the guard's own words against it. What stopped it being\n     filed as a kitsubito block was that the box facts contradicted the text (`tailscale debug\n     netmap` on kitsubito lists `100.68.35.65/32` among its permitted inbound sources, and `ufw` is\n     inactive) — a failure text that contradicts a measured box is the text's defect. So the\n     rendezvous is DATA: A listens up to the rig budget and beacons once a second; B binds first,\n     waits for a beacon, and only then starts a ten-second clock, so B's red has already excluded\n     \"A is not up\". That is a FOURTH outcome with its own name, `PROBE_NO_BEACON`, never\n     `INBOUND_BLOCKED`.\n  2. **THE LISTENING SOCKET MUST NEVER SEND.** Any outbound datagram from the measured port opens\n     stateful return state for it, so B's probe then arrives SOLICITED and crosses under both layers\n     — this entry's own \"solicited return traffic works under either fault\" applied to the guard\n     rather than to the ceremony. MEASURED: with the beacon sharing A's listening socket, the\n     out-of-grant control went **GREEN at 13:28Z** on a port a listen-only run had measured BLOCKED\n     at 13:20Z; a further green at 13:31Z with the beacon moved but the ack still leaving that socket\n     was residual state from 13:28 — true BY ELIMINATION rather than by assertion: nothing in the\n     13:31 run sent from 7509 before the first arrival, so the only outbound that could have opened\n     that port's return state belongs to the previous run. Beacon and ack both leave an ephemeral socket now, and B sends\n     from an ephemeral port too, so no run repeats a 4-tuple a previous run opened.\n  3. **THE ACK IS ADDRESSED TO B'S RIG PORT, not to the probe's source port.** MEASURED: acking to\n     `from` produced a run that CONTRADICTED ITSELF — A said `INBOUND OK` and B said\n     `INBOUND_BLOCKED`, same run, 13:41:33 → 13:41:50Z — because A's ack leaves its ephemeral\n     socket, is therefore not return traffic of the flow B opened, and a receiver whose inbound rule\n     is a port RANGE drops it. The rig port is the only address either host is reachable on cold.\n  4. **THE FALSIFIER, and it is the operator's own rule used as an instrument.** Forcing the probe\n     port to **7509** (`SPT_TWO_HOST_PORT_A=7480`), one port outside the granted udp 7460-7499, reds\n     the guard on demand with no elevation and no policy edit. Run TWICE BACK TO BACK at the final\n     code, 13:43:41 → 13:44:23Z and 13:44:25 → 13:45:07Z: **RED, RED** — A after 40 s having sent\n     39 beacons, B in its ten seconds having sent 48 and 47 datagrams with no ack, both exit 101.\n     One red would only prove a state timeout expired; two consecutive reds prove the design writes\n     none. The grant boundary is therefore measured from inside the test binary: 7489 crosses, 7509\n     does not, same hosts, same binary, one env var apart.\n  5. **ONE ACK IS NOT ENOUGH — the same split verdict arrives by packet loss** (doyle, reviewing the\n     built lane). A acking ONCE and breaking leaves B's red resting on a single unrepeated UDP\n     datagram: lose it and A prints `INBOUND OK` while B reds `INBOUND_BLOCKED`, blaming a firewall\n     for ordinary loss — correction 3's defect reached by a different road. A now keeps draining for\n     a short window after its own verdict is already settled and acks EVERY probe in it, while B\n     stops on the first ack. The A-side assertion is unchanged: it was decided by the first datagram.\n  6. **THE PROBE STEPS CARRY THEIR OWN BUDGET, 300 s, set EXPLICITLY** beside ceremony steps that say\n     900. It bounds RENDEZVOUS skew, not pairing, so a blocked link costs 300 s ONCE instead of 900\n     per cell per half. Left unset it would have been `from_env`'s invisible default sitting next to\n     a visible 900 on the step below — a number the next reader would have inferred wrongly, which is\n     this entry's whole failure mode in miniature.\n- **FIELD PROOF, 2026-09-09, and it is the ONLY proof this guard has:** `dir 1` (A=hfenduleam,\n  B=kitsubito) 13:45:14 → 13:45:18Z and `dir 2` (A=kitsubito, B=hfenduleam) 13:45:41 → 13:45:58Z,\n  both GREEN with the ack after ONE datagram, both exits 0, both hosts running byte-identical source\n  (md5 `f31779339266f8034dcd72917c56a37e`, checked on both sides). Free space 174.38 GiB, flat across\n  all four arms.\n  ⚠ **THE `golden.yml` STEPS THEMSELVES ARE UNEXERCISED UNTIL THE NEXT GOLDEN RUN.** Thin CI\n  compiles the cells and SKIPS them — `Rig::from_env` returns `None` without `SPT_TWO_HOST`, so a\n  green thin run says the code builds and nothing about the steps. The wall times above are the field\n  proof; treat the workflow half as landed-pending-golden and not as verified by its own PR.\n- **Ripe when:** the next GOLDEN run, which is the first thing that exercises the steps — the\n  code half is built and field-measured (PR #211). (The box half was ripe \"now\" against\n  `25e60015` and is done; #272 golden acceptance is no longer blocked by it.) · **Size:** one\n  workflow step remaining; the elevated command is spent.\n- **SECOND LAYER (measured 23:41–23:50Z, after the operator applied the Windows rule exactly as\n  asked and the re-probe STILL read 0/3):** the tailnet ACL. The same `python.exe` listener (own\n  program rule) received 3/3 from kitsubito over the LAN (`192.168.1.168 → 192.168.1.81:7483`) and\n  0/3 over Tailscale (`100.98.197.12 → 100.68.35.65`), TCP connect over Tailscale times out too,\n  solicited return over Tailscale works, ShieldsUp false both ends. `tailscale debug netmap` on\n  hfenduleam: one PacketFilter rule, 18 permitted inbound sources, kitsubito ABSENT; kitsubito is\n  `tag:eye-tracking-resource` owned by a different tailnet user, and its own filter DOES permit\n  hfenduleam. Asymmetric policy: member device → tagged resource allowed, reverse denied. The\n  Windows rule was NECESSARY (rule-less exe, LAN probe 0/2 earlier) and NOT SUFFICIENT. Remedy\n  half (1) gains an ACL grant, operator-owned in the admin console:\n  `{\"action\":\"accept\",\"src\":[\"tag:eye-tracking-resource\"],\"dst\":[\"hfenduleam:7460-7499\"],\"proto\":\"udp\"}`.\n  Rider 4's failure text names both layers and the LAN-vs-Tailscale probe as the discriminator.\n  Lesson for the entry: a cross-box \"unresponsive\" has at least THREE layers (Windows rule, tailnet\n  policy, the exe's own bind); probe through the SAME path the rig uses, and re-probe after every\n  single change — the first fix reading as \"applied\" is not the probe reading 3/3.\n- **Corroboration + reading traps (deployah 23:50Z, from the box):** Windows rule found present by\n  FILTER search (`netsh advfirewall firewall show rule name=all dir=in verbose`), not by name — the\n  operator's name is hyphenated \"two-host\" and a `twohost` grep reads it ABSENT. Netmap: the single\n  filter permits ALL ports and ALL protocols from its 18 sources, so the grant is SOURCE-scoped, not\n  port-scoped — \"this peer is not a permitted source at all\", which is why TCP timed out beside UDP.\n  Two permitted sources (100.98.213.33, 100.98.214.87) share kitsubito's 100.98/16 and read as hits\n  to an eyeball scan for \"100.98.\"; test membership of the full /32, never a prefix. His first netmap\n  read extracted a non-existent field (`SrcIPs`; the real key is `Srcs`), printed an empty list and\n  minted a confident \"ABSENT\" — an empty extraction cannot witness absence; the 18-count is from the\n  corrected read. Prefs on the box: ShieldsUp false, NoStatefulFiltering true, RouteAll true,\n  NetfilterMode 2 — nothing there explains the drop.\n- **Probe-rider design rule (hertz, d882297f):** the pre-ceremony probe reds `INBOUND_BLOCKED` for\n  EITHER layer and does not pretend to know which — its job is \"the box cannot receive, stop triaging\n  the product\"; the layer is named only by the one measurement that decides it (same listener, LAN\n  vs Tailscale), which the failure text prints as a recipe. A guard that names a cause it did not\n  measure is the defect class this whole entry documents.\n\n### IR-90 — a full disk on the self-hosted box reds a rig as a PRODUCT refusal, not a build error, and no rig or gate records the free space that would falsify it\n\n- **Status:** OPEN, filed by hertz 2026-09-09 from the disk-full incident on hfenduleam. ·\n  **Origin:** the IR-85 discriminator lane's head arm, killed by the volume rather than by the code\n  under test.\n- **Symptom:** `spt-daemon::sync concurrent_writes_reconcile_on_elected_node_and_converge` FAILED at\n  67.588 s with a panic in our own test at `crates\\spt-daemon\\tests\\sync.rs:198`:\n  `pull: Custom { kind: Other, error: \"sync refused: bundle failed: git -C <tmp>\\tracked-b\\.seed.git\n  bundle create <tmp>\\scratch\\serve\\serve-pull-6.bundle ^d12a7134... a-doyle failed (exit Some(1)):\n  fatal: sha1 file '<stdout>' write error. Out of diskspace\\nerror: pack-objects died\" }`, then a\n  second panic at `:213` (`pull thread: Any { .. }`) as the harness thread unwound.\n- **Cause:** `C:` was at **0.018 GiB free of 1862.02 GiB (0.00%)** at that instant\n  (`Win32_LogicalDisk`, 10:57Z). `git bundle create` could not write; the daemon's serve path turned\n  that into its real product refusal string `sync refused: bundle failed`; the test asserted on the\n  refusal. **Every layer behaved correctly, and the report reads as a sync regression at the sha\n  under test.**\n- **Why it is worse than the disk faces already known:** the two banked faces\n  (`disk-full-reds-as-lnk1318-pdb-error`) are TOOLCHAIN costumes — `LNK1318` at link, and rustc\n  I/O before any link — and both route a reader to \"the box is sick\". This one routes to a CODE\n  OWNER: it names our file, our line and our refusal string, and the disk word sits in the FOURTH\n  nested clause behind a git exit code. It arrived mid-discriminator with an old sha and a new sha\n  side by side, where the cheapest reading — \"the head arm failed, the old arm passed\" — is a\n  head regression that does not exist.\n- **Blast radius, same incident:** the volume also carried a live `unit (self-hosted, Windows,\n  hfenduleam)` job (run 34341010297) compiling into it, which completed FAILURE on its own and was\n  ruled VOID after the fact. doyle's cancel of THAT run returned `Cannot cancel a workflow run that\n  is completed` — recorded because a register that credits a controlled action nobody performed\n  teaches the next reader that the box was under control. (The earlier run 34337797758, in\n  **IR-85**'s amendment, is a different run with a different ending: CANCELLED at the job wall. One\n  register putting one cancel string on the wrong run is the same defect, one run over.) `spt daemon status` went to peer pump last tick 185 s with 24 brain\n  subscribers stall-evicted (last evict 10:51:22Z, inside the disk window), with an operator restart\n  under consideration — a restart that risks the releases#287 shell stranding and that, had it\n  appeared to help, would have taught everyone the wrong cause.\n- **⚠ Two things that looked like disk fallout and are NOT**, recorded so this entry does not\n  overclaim. (a) `serve list` returning `SERVE_UNCONFIRMED`: doyle read it from source —\n  `servehost.rs` and `KIND_SERVE_REQUEST` are ABSENT at 0.67.0/0.67.1 and were minted by 0.68.0, and\n  the resident broker is still the 0.67.0 image after the brain-only flip, so the CLI's 10 s bound\n  times out **by design** against an older daemon. (b) `peer reachability: DEGRADED, 4 of 7 peers\n  unreachable for 882775 s` — 10.2 days, predating the incident entirely. Even the pump term is\n  claimed as CONCURRENT, not caused: hertz called the pump recovered off ONE post-reclaim sample\n  (54 s) and doyle falsified it two minutes later (133 s), because a single reading of a monotonic\n  \"last tick N s ago\" counter cannot separate STILL TICKING from TICKED ONCE, and a fresh project\n  index proves the coordinator loop, not the pump.\n- **Remedy — one guard, two placements, and it REFUSES rather than runs:**\n  1. **Rig start.** For the two-host rig and any test rig that shells out to `git bundle` or writes a\n     store: read free space on the volume holding the rig's temp root and `target`, and under a floor\n     fail immediately with a message that says DISK and prints the number — never enter the\n     ceremony. Floor: start at **10 GiB**, above the largest single artifact these rigs write and far\n     below any healthy state of this box; tune only with a measurement.\n  2. **Failure text**, for the case where space runs out MID-run and no start check can catch it:\n     when a shelled-out git/store operation fails, append the current free space to the error before\n     it becomes a product refusal string, so the panic that reaches a human already carries the\n     falsifier.\n- **WHY BOTH, measured rather than argued (hertz, 2026-09-09, the #209 lane):** a floor read ONCE at\n  rig start would have PASSED that run and the run still ended nearly empty — `cargo check` started\n  at **136.32 GiB** free, the test-profile build of 221 binaries took it to **40.18 GiB in ten\n  minutes**, the legs finished at **16.24 GiB**, and it read **12.27 GiB** ninety seconds later. A\n  start-only guard is a guard against yesterday's disk. That last ~4 GiB fell with those legs already\n  terminal; the candidates are the runner's CI job and its `_work` tree, unsampled and therefore\n  UNATTRIBUTED.\n- **The record itself, and the only one that caught the dip (hertz, 2026-09-09):**\n  `.spt/preserved/hertz-leak-670-legs/disk-full-trace.log` — **139 samples, 11:52:46Z–13:57:07Z, one\n  per minute**, max **238.41 GiB** @12:45:20Z, min **12.53 GiB** @12:12:45Z. Two samples fall under\n  15 GiB — **14.85** @12:12:11Z and **12.53** @12:12:45Z — both inside the #209 leak lane's\n  build-and-teardown window, i.e. AFTER a start floor would have passed the run at **136.15 GiB**\n  (the window's first sample). Two caveats, both binding on any reading of it: **the true minimum is\n  unbounded below 12.53 — the sampler cannot see between its samples**, and **it attributes nothing:\n  hertz's own legs and the runner's CI job are indistinguishable in it.** It is the SECOND instrument\n  on this incident and the only one covering the dip: doyle's 30 s trace, preserved at\n  `.spt/preserved/ir90-free-space-trace-2026-09-09/free-sampler-12-13Z-to-12-28Z.txt`, runs\n  12:15:37Z–12:31:10Z and so begins after hertz's reap — it records the RECOVERY, this one records\n  the FALL. sha256 `d58ce838b677e62d4a017e77524f899fda81e7bacf73a0e2a05a1192e60abaf2`\n  (doyle's, `8bdae01bc151597070d7011443a2cdc74614232dbc962faec1b1b1833c71f22a`).\n- **Explicitly NOT the remedy:** a bigger disk, or a reap schedule. ~195 GiB of headroom was consumed\n  by ordinary work, ACCRUED across a ~45-minute build phase; **no reading bounds a rate** — the\n  free-space observations either side are endpoints of an accrual, and a rate derived from them\n  retargets a hunt (deployah's went to runaway logs, VSS and torrent preallocation on the strength of\n  a `>150 MB/s` derived that way, while the measured live box-wide write rate was ~1.5 MB/s). What\n  consumed it: two `cargo nextest run -E <5-test filter>` lanes at **82.88** and **64.44 GiB** — a\n  filter narrows the RUN, never the BUILD, and both built 221 test binaries under the `test` profile\n  — plus 40.93 GiB of `C:\\actions-runner\\_work` and 9.8 GiB of `%TEMP%`. Any headroom this box\n  has is two cold pools away from gone, so the guard must be a REFUSAL, not a budget.\n- **Kin:** **IR-85** (the same box's fs-heavy slowdown; a near-full volume is now a named environment\n  term there), **IR-86** (a start floor that passes a box which cannot finish — the same defect one\n  layer up, and this entry is its mid-run half), **IR-76** (the golden runner is the operator's\n  desktop), `disk-full-reds-as-lnk1318-pdb-error` (memory; this is its third face and its standing\n  gap), `test-profile-pool-outgrows-the-disk-floor`, `free-space-floor-blocks-golden`.\n- **Ripe when:** now. · **Size:** one assertion plus one error-context append, both test-side.\n\n### IR-91 — 561 untracked files sat at the repo root, 18 of them cited by tracked files, and the census that classified them used a corpus that made the discriminator invisible\n\n- **Status:** CLOSED by the lane that filed it (the root-scratch classify PR), hertz 2026-09-09 on\n  doyle's census and rulings. · **Origin:** the `.spt/` ignore lane (PR #212) named 561 untracked\n  root files as explicitly out of scope; this is that half.\n- **The population, measured at `2037bcb8`:** `git status --porcelain --untracked-files=all` = **561\n  `??` rows, all at the repo root, zero in subdirectories**, 50,034,994 bytes (47.7 MiB). By\n  extension: 268 `.raw`, 184 `.exit`, 87 `.md`, 7 `.out`, 4 `.log`, 4 `.done`, 2 `.txt`,\n  2 `.stackdump`, 2 `.sh`, 1 `.py`. **A `git add -A` at the root staged every one of them**, which\n  is the same landmine `.spt/` carried before #212 and the reason this is one arc in two lanes.\n- **⚠ THE FINDING, and it is about the CENSUS, not the files:** the first classification put two\n  cited files in the \"bury\" class. `W3-196-CENSUS.md` and `WEBSERVE-272-JIT.md` were recorded as\n  \"cited only from other root scratch\" — citing files `W3-196-JIT.md` and `W3-272-MEASUREMENTS.md`,\n  which are **TRACKED**. The census corpus was tracked-only, so **every hit it produced was a\n  tracked citation by construction**; the two were then relabelled by their PATH, because a `.md`\n  sitting at the repo root reads as scratch. **The discriminator is TRACKED-OR-NOT, never\n  ROOT-OR-NOT** — and a corpus that can only return tracked hits cannot tell you which of its own\n  hits are tracked, because it has already thrown away the distinction. Burying those two would have\n  left two tracked files citing paths that no longer existed: the `launch-battery.py` mechanism from\n  **IR-90**'s sibling lane with the sides swapped, caught here only because the burial list was\n  re-verified against the corpus a second time by a different reader.\n- **The second finding, which withdrew the lane's own destinations:** the repo root **already holds\n  140 tracked files, 134 of them `.md`, 25 with `JIT` in the name** — `IDLE-EDGE-JIT.md`,\n  `W3-196-JIT.md`, `WEBSERVE-272-W2-JIT.md`, every `M*-PLAN.md`, `MESH-D*-PLAN.md`,\n  `RESTORATION-D*-PLAN.md`. **The house convention is measured, not assumed: a plan or record lives\n  at the repo root and is TRACKED.** The first ruling would have relocated the cited files into\n  `docs/intake/`, `docs/design/` and `docs/gate-records/` — splitting siblings across two homes\n  (`WEBSERVE-272-W2-JIT.md` at root, `WEBSERVE-272-W3-DRIFT-RIDERS.md` in `docs/intake/`) and\n  repointing 18 citation lines to buy that split. **Destinations withdrawn; the 18 are tracked where\n  they are.** Zero moves, zero repoints, zero sha-transfer risk. A lane that tidies against a\n  measured convention is not tidying.\n- **THE RULE, which is what this entry is for:** *a plan or record cited from a tracked file is\n  itself tracked, at the path the citation already names.* The root is a legal home. What decides a\n  file's fate is whether the repo points at it — not where it sits, not what it is called, and not\n  whether it looks like scratch.\n- **What the lane did:** **18 Class A** files `git add`ed in place. **473 Class B** gate legs\n  (`.raw`/`.exit`/`.done`/`.log`/`.out`/`.stackdump`/`.sh`/`.txt`, zero tracked citations, each\n  word-bounded against the whole 911-file tracked corpus) **MOVED — not deleted** — to\n  `.spt/preserved/root-gate-legs-2026-09-09/` with a sha256 manifest, every file hashed before and\n  after the move. **70 Class C** uncited `.md` likewise to `.spt/preserved/root-md-2026-09-09/`.\n  Then five **root-anchored** ignore lines: `/*.raw` `/*.exit` `/*.done` `/*.out` `/*.stackdump`.\n- **Why those five and not more.** Legs are the one class whose FUTURE instances are scratch **by\n  construction**, so ignoring them institutionalizes no loss. `/*.md`, `/*.log`, `/*.sh` and\n  `/*.txt` are deliberately NOT ignored: a plan or script dropped at the root must keep showing as\n  `??` so the next census classifies it — **that is exactly the pattern that produced this repo's\n  140-file tracked root corpus**, and an ignore line there would hide the next one. The anchoring is\n  load-bearing and was proved with a negative control: `crates/probe.raw` is **not** ignored, which\n  an unanchored `*.raw` would have swallowed.\n- **Kin:** the `.spt/` ignore lane (PR #212 — same arc, and its `launch-battery.py` case is why\n  nothing here was deleted), **IR-90** (a citation into `.spt/preserved/` is machine-bound evidence,\n  never a repo path), `ignoring-a-directory-buries-what-the-repo-cites-in-it` (memory).\n- **Ripe when:** landed with this entry. · **Size:** one `.gitignore` stanza, 18 adds, 543\n  preserved files, no deletions.\n\n### IR-92 — the message that WAKES an idle spt-hosted endpoint rides a delivery leg that never publishes MSG_IN, so a woken agent's own funnel holds none of the messages that woke it\n\n- **Status:** OPEN — filed doyle 2026-09-09 from hertz's census, probe and proposed text (his by\n…\n  the chase exposed that neither agent's io-events log held the messages that woke it.\n…\n\n\n[Showing lines 5043-5484 of 6937. Use :5485 to continue. Some lines truncated to 768 chars]"}],"details":{"truncation":{"content":"\r\n### IR-86 — golden's 32 GiB floor is BELOW the measured 67.4 GiB Windows suite footprint, so a start floor passes a box that cannot finish\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-08 at the #272/v0.68.0 golden r2 triage. · **Origin:**\r\n  run 34262154550 @ `25e60015` (shaped on `e4444413`), Windows test job 102182665033: every product\r\n  step green (Phase A 3346/3346, Phase B 234/234, Summary 2, FAIL 0), the ONLY reds were the two\r\n  in-job floor gates. `FLOOR_START` 97,649,786,880 B PASS at 18:47:23Z -> `FLOOR_DOCS`\r\n  25,284,501,504 B RED at 19:31:55Z -> `FLOOR_END` RED. Consumed in-job: 67.4 GiB.\r\n- **Mechanism:** `golden.yml` derives 32 GiB as \"the observed tens-of-GB full-suite footprint\r\n  rounded up to the next binary boundary, preserving headroom for one complete run\" (comment\r\n  above the Windows start floor). The measured footprint is 67.4 GiB, so a start reading anywhere\r\n  in [32, ~100) GiB passes and the job then walks under the floor by construction: box baseline\r\n  91 GiB minus 67.4 = 23.5 < 32. This is a shortfall of the DERIVATION, not a rate, not a product\r\n  red, and not the instant-vs-sustained face IR-46 files (that face is fixed by the FLOOR_DOCS\r\n  re-read, which is what caught it). The start floor must be footprint + end-floor (~100 GiB) or\r\n  it asserts nothing about finishing.\r\n- **Coverage consequence (the load-bearing part):** the Windows `Docs drift gate (CLI ref + llms\r\n  links)` step is sequenced BEHIND `FLOOR_DOCS`, so it SKIPPED and r2 held NO Windows CLI-ref\r\n  axis at that sha until the rerun. A floor red that skips a gate is a coverage hole wearing a\r\n  disk red.\r\n- **Kin:** [[IR-46]] (a floor asserts an instant), [[IR-59]] (pool arithmetic, LNK-class reds\r\n  that name no disk), [[IR-64]] (the operator-payload reservoir that sets the box baseline; its\r\n  ripe-when arm — a golden that dies at the floor despite adopted pool discipline — FIRED here\r\n  in the in-job form), [[IR-73]] (second half BUILT: the within-job re-read exists and is what\r\n  produced the FLOOR_DOCS reading), REQ-CI-FREE-SPACE-PREFLIGHT.\r\n- **Coupling (deployah 23:54Z, from `golden.yml` at `25e60015`):** the Windows `DISK docs floor`\r\n  (:616) and `Docs drift gate — windows` (:629) carry only `if: runner.os == 'Windows'`, no\r\n  `always()`, while `DISK end floor` does (`always() && runner.os == 'Windows'`, ~:705). Actions'\r\n  default is \"previous steps succeeded\", so ANY Phase B red skips the docs axis by construction —\r\n  observed three times at this sha (floor red, ttl cell, ttl cell). The docs gate is therefore never\r\n  independent evidence: it can only be banked when Phase B is green in the same job. Remedy line:\r\n  gate the two docs steps on `!cancelled()` plus the success of the steps they actually depend on\r\n  (checkout/build), not on Phase B — a rig change, new sha, hertz workflow rider slot.\r\n- **Remedy shape:** re-derive the start floor from the measured footprint (67.4 GiB Windows,\r\n  Linux to be measured) plus the 32 GiB end floor, print the footprint (start minus end free)\r\n  on every run so the number re-measures itself, and keep the 32 GiB literal only for\r\n  `FLOOR_END`.\r\n- **Ripe when:** next `golden.yml` touch (hertz workflow rider slot). · **Size:** small — one\r\n  literal per start-floor site + one printed subtraction.\r\n- **Linux recurrence, 2026-09-15 (doyle, S4 golden `34946493637`, reported in `3HHHPWCR`).** Kitsubito's test job began with about **110.7 GB** free and reached about **29.3 GB** after its build and test sandbox consumed **81.4 GB**; the workload stages were green, then the floor gates red. `FLOOR_DOCS` and `FLOOR_END` run **before** test-temp-sandbox cleanup, deliberately ([[IR-46]]), so the job must retain the end-floor reserve while its own sandbox still exists. A generic **32 GiB** start admission does not establish that capacity.\r\n<!-- [doc->REQ-CI-FREE-SPACE-PREFLIGHT] -->\r\n- **Linux sizing decision, 2026-09-15 (2NLUDSQA).** Golden's Linux **test-job** start allowance is now **130,000,000,000 bytes (130 decimal GB)**. The rounded measurements imply about **115.8 GB** minimum (81.4 GB working set + 32 GiB reserve); the allowance includes about **14.24 GB** margin, not a newly measured peak. `FLOOR_DOCS` and `FLOOR_END` retain **34,359,738,368 bytes (32 GiB)** and their pre-cleanup placement. Admission remains after checkout and before expensive work. Only this job/OS start value changes; other jobs, Windows admission, step conditions and cleanup order are untouched. Moving guards after cleanup would certify a different state and was not chosen.\r\n- **Linux verification.** Executed the actual YAML shell bodies on kitsubito with controlled `df` readings: the historical 110.7 GB start passes the predecessor and is refused by the successor; 130 GB minus one byte refuses, exactly 130 GB passes; native `df` failure23 propagates. Both docs/end bodies still refuse one byte below 32 GiB and pass exactly at the reserve. An unmodified native `df` sample passed at **246,886,174,720 bytes** free. All **9 successor probes** matched their expected exits; temporary probe workspace removed. Parsed workflow comparison confirms only the Linux test admission body differs, with all other executable steps/conditions/order unchanged. Evidence: `.spt/preserved/hertz-ir86-linux-floor/{predecessor,successor,workflow-scope}.js…\n<!-- [doc->REQ-CI-FREE-SPACE-PREFLIGHT] -->\r\n- **Windows source and derivation, 2026-09-15 (FRNOZMV4 / 2G5X324J / WNMSYL52).** Primary runner log: `.spt/preserved/hertz-ir86-windows-floor/job102182665033.log`, SHA256 **`8b1167ab4de3d474df4dde19f0a623d03beb820400cd19907b996cc2ab7bf91d`**, recovered from GitHub job **102182665033**, run **34262154550**, hfenduleam, source SHA **`25e6001585ed0cd495a72c7634dded9dd207bdae`**. Its actual `FLOOR_START` at line138 / 18:47:23.3668896Z reads **97,649,786,880 bytes**; `FLOOR_END` at line5223 / 19:31:56.6941352Z reads **25,284,497,408 bytes**, both on2026-09-08. Net movement is **72,365,289,472 bytes (67.395 GiB)**. Add the retained32GiB reserve: **106,725,027,840 bytes (99.395 GiB)**; round up to the next binary boundary for **128 GiB (137,438,953,472 bytes)** ad…\n- **Windows admission scope.** Only golden's Windows **test-job** start floor changes (`128GB` in PowerShell means128GiB). Docs/end remain32GiB before teardown; checkout still precedes admission, expensive work follows it, and every other step/condition/order remains unchanged. Linux retains its separately derived130decimalGB allowance.\r\n- **Reclamation is load-bearing (WNMSYL52).** Today's pre-reap hfenduleam sample **91,890,798,592 bytes (~92 GB)** would have been REFUSED by this admission floor. Reaping classified, owned retired targets is therefore a prerequisite for golden admission from that box state, not optional housekeeping. The authorized S3/S5 target removal left **201,837,236,224 bytes** free; source `.spt/preserved/hertz-retire-QD54OM7S/retirement-result.json` records both samples and their concurrent-CI attribution caveat. Re-sample after reclamation; no stale free-space reading grants a run. The unchanged refusal diagnostic names **`RESOURCE=disk`**, drive, free bytes and floor: classify it as **capacity REFUSED / workload UNTESTED**, not a product-test failure. The CI job st…\n- **Windows verification.** Executed the actual YAML PowerShell bodies under pwsh7.6.6. The historical97.65GB input passes the predecessor and refuses under the successor; today's pre-reap91.89GB also refuses with `RESOURCE=disk`. Admission-minus-one-byte refuses, exactly128GiB passes; an unreadable workspace fails before any PASS token. Docs/end each refuse reserve-minus-one-byte and pass exactly32GiB. A native workspace read passed at **264,109,211,648 bytes** free. All **10 successor probes** matched expected exits; no script files, build, pool claim, or suite execution. Parsed workflow comparison confirms only the Windows test admission body changed. Evidence: `.spt/preserved/hertz-ir86-windows-floor/{consumption-source,predecessor,successor,workflow-sco…\n- **Remaining IR-86 scope.** Both OS admission-sizing slices are implemented; automated start-minus-end reporting remains separate work, so the whole entry stays open. Existing raw-byte START/DOCS/END readings remain available for capacity analysis and are instantaneous shared-volume samples, not exclusive workload attribution.\r\n\r\n### IR-87 — two-host ceremony halves are INDEPENDENT jobs on DIFFERENT runners (A Windows/hfenduleam, B Linux/kitsubito); B's 900 s budget runs on B's own clock, so any older queued Windows job starves A and reds B deterministically, and the panic text blames pairing\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-08 at the #272 golden r2 triage. · **Origin:**\r\n  run 34262154550, twohost-b job 102207296960 (log 81,692 B, sha256 67403f04…8030): role B built,\r\n  rostered, polled PAIR_MEET_UP every 30 s from 19:34:30Z, and hit the rig_wait barrier\r\n  \"pairing: A rostered via the daemon-hosted responder\" at its 900 s deadline 19:49:17Z\r\n  (`crates/spt-daemon/tests/twohost.rs`, exit 101, 2 passed 1 failed). twohost-a (102207296985)\r\n  was QUEUED from 19:32:13Z with no runner: the Windows runner went to thin ci run 34261096301\r\n  (post-merge on main @ `e4444413`) the second the golden test job released it at 19:31:56Z.\r\n- **Mechanism:** `golden.yml` sequences twohost-a and twohost-b after `test`, but they are two\r\n  jobs on two runners (measured 2026-09-08 20:56Z via the jobs API `runner_name`: twohost-a on\r\n  hfenduleam, twohost-b on kitsubito), and GitHub's queue does not honour a workflow's intra-run\r\n  job ordering against a FOREIGN run on either runner. B starts, its whole budget ticks against a partner that has not been\r\n  scheduled, and `rig_wait` panics `never converged on the rig: {what}` — a text that reads as a\r\n  pairing defect. The lanes were not at fault, and twohost-a's outcome was predetermined once B\r\n  exited (a later A pass would be vacuous).\r\n- **Kin:** [[IR-76]] (hfenduleam is golden runner AND builders' box; the job-start census cannot\r\n  see a competing GitHub run either), [[IR-62]] (rig collisions on shared runners), the W1 two-host\r\n  rig, `a-barrier-cannot-ride-a-carrier-its-sender-outlives` (memory, same family: a barrier needs\r\n  the receiver's own answer).\r\n- **Remedy shape (pick at rider time):** (1) start barrier on B keyed to A's job having STARTED\r\n  (a run-scoped artifact or a `needs`+matrix collapse into ONE job that spawns both roles), or\r\n  (2) B's deadline clock starts at first A-rostered signal with a separate, longer \"A never\r\n  appeared\" budget, or (3) the panic names the missing partner's job state so triage does not\r\n  chase pairing. Any option: the two-host halves must never share a runner queue with a foreign\r\n  run while one half waits.\r\n- **Ripe when:** next `golden.yml`/twohost rig touch. · **Size:** small-medium (job shape or\r\n  barrier rework + panic text).\r\n\r\n- **AMENDMENT 2026-09-10 (releases#294, golden 34445961595 att1 @ `a9e786b2`) — THE STARVING RUN CAN\r\n  BE GOLDEN'S OWN PR, which makes this self-inflicted and recurrent on every golden run with a PR\r\n  open.** Measured timeline: **07:18:59Z** golden `test (Windows)` completes and releases hfenduleam;\r\n  **07:18:59Z** twohost-a queued; **07:19:01Z** PR run **34446095808** job `unit (Windows,\r\n  hfenduleam)` SEIZES the runner; **07:19:02Z** twohost-b starts on the free kitsubito; **07:36:16Z**\r\n  twohost-b fails at **900.41s** — `never converged on the rig: pairing: A rostered via the\r\n  daemon-hosted responder`. The origin case (2026-09-08) was a post-merge push on `main`: a run\r\n  belonging to someone else. **Here the starving run is the `pull_request` run of the very PR carrying\r\n  the golden head**, so opening the golden PR arms the starvation of that same head's twohost pair.\r\n  **Consequence for the remedy shape above: any option that only de-conflicts against OTHER lanes'\r\n  runs does not reach this case.** The golden head's own PR has to be excluded from the Windows\r\n  runner for the duration of the golden run (or the pair collapsed into one job, option 1).\r\n- **SECOND-ORDER FACE (deployah, same run): starvation does not merely red B — it desynchronises the\r\n  pair past repair.** twohost-b was TERMINAL at 07:36:16Z; twohost-a did not start until **07:48:07Z**\r\n  — the two halves never overlapped for a single second, so twohost-a's outcome is uninformative\r\n  **whatever it says**, and a red there must not be counted as a second product failure. Recorded\r\n  honestly at deployah's own insistence: **VOID is his SCORING interpretation, not a fact about the\r\n  run** — the release record carries GitHub's raw `conclusion` for both jobs beside the scoring, not\r\n  laundered into it.\r\n- **⚠ ITS WALL CLOCK IS INDISTINGUISHABLE FROM [[IR-89]]'s.** A 900 s twohost red whose panel blames\r\n  pairing is ALSO the exact signature of the banked Windows-firewall hazard. The panel alone cannot\r\n  separate them; **the job TIMELINE can**. Check the schedule before accepting the firewall hazard for\r\n  any 900 s twohost red — this one fit that signature perfectly and was not it.\r\n\r\n### IR-88 — `pool-release` via `cargo run -p xtask` REBUILDS xtask INTO the pool it is releasing, so a reaped pool regrows ~2.8 GB in silence\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-08 from hertz's reap report (20:00Z) during the #272\r\n  golden r2 repair. · **Origin:** hertz reaped hertz-lane4 / hertz-repin / hertz-percell-id target\r\n  subtrees (Length-sum upper bounds 68.16 / 47.11 / 8.79 GB) and then ran `cargo run -p xtask --\r\n  pool-release …` from each worktree: cargo rebuilt xtask into the just-reaped `target/` (2.8 GB\r\n  back in lane4, partial in repin), nothing printed said so, and the descendancy stopper killed\r\n  the second before it finished. Removed by hand afterwards; the post-reap free reading on the\r\n  record (275.95 GiB at 19:55:51Z) predates the regrowth.\r\n- **Mechanism:** the documented verb (AGENTS.md: \"drop it with `pool-release`\") is a `cargo run`,\r\n  and cargo's default target for that run IS the pool being released. The verb's own success path\r\n  recreates the state the operator just measured away; a teardown step that runs it AFTER a reap\r\n  undoes part of the reap and leaves the recorded free reading stale.\r\n- **Remedy shape:** either (a) `pool-release` documented and scripted as a PREBUILT `xtask.exe`\r\n  invoked against `--pool <dir>` from another pool, or (b) the verb refuses when its own\r\n  `CARGO_TARGET_DIR`/default target equals `--pool` and prints the prebuilt form, or (c) the reap\r\n  recipe orders release BEFORE the subtree delete. Memory banked 2026-09-08\r\n  (`pool-release-rebuilds-xtask-into-the-pool-you-just-reaped`); this entry is the durable home.\r\n- **POSITIVE CONTROL (hertz, 2026-09-09, ruling-3 gate-r3 teardown):** the same release run\r\n  from a PREBUILT `xtask.exe` invoked from outside the pool regrew NOTHING — the pool's own\r\n  `xtask.exe` still carried its original 21:00:42 mtime afterwards, and the reap that followed\r\n  reclaimed 63.71 GiB (132.03 -> 195.74 GiB free) against a 64.88 GiB Length-sum. So the\r\n  regrowth is a property of the `cargo run` VEHICLE, not of the verb, and remedy (a) is proven\r\n  rather than merely proposed.\r\n- **Kin:** [[IR-31]] (pool budgeting), [[IR-56]] (pool-claim identity from CWD — same verb\r\n  family, same \"the tool acts on where it stands\" shape), releases#103.\r\n- **Ripe when:** next xtask pool-verb touch or the teardown runbook edit. · **Size:** tiny —\r\n  one guard or one doc line.\r\n- **Amendment 2026-09-11 (hertz measured, doyle accepted):** the release-before-delete recipe as\r\n  written (\"keep the built test binaries, drop deps\") is NOT runnable — the workspace builds runtime\r\n  dylibs into the same `deps` dir (three `iroh_relay-*.dll` beside `daemon_stop_convoy_e2e-*.exe`\r\n  in the measured pool), so a retained exe with its dlls deleted is a keepsake. The recipe now reads:\r\n  retain the test exe set AND the runtime dll set, then EXECUTE one retained exe from the\r\n  post-deletion state before claiming the set is runnable; otherwise the disposition is archival and\r\n  exe retention is optional. `.pdb` is not needed to run but costs symbolised failure output — decide\r\n  that deliberately, not by size.\r\n\r\n### IR-89 — hfenduleam's Windows Firewall drops cold inbound UDP to the runner-built test exes, so the two-host rig's first B→A claim (W2 helper) reds for its whole 900 s budget and the panic blames A\r\n\r\n- **Status:** BOX HALF **APPLIED** 2026-09-08; WORKFLOW HALF **BUILT** 2026-09-09 — PR #211\r\n  (`9b96d7e7` + this amendment), **LANDED, exact golden-step acceptance unreconciled**.\r\n  Subsequent goldens have run: \"until the next golden\" is no longer a future trigger.\r\n  This sweep does not infer probe execution from a run's existence or overall conclusion;\r\n  retain the step-specific exercised/skipped/failed evidence before closing. Filed by doyle 2026-09-08\r\n  at the #272 golden r2 terminal triage; the operator-blocked flag is retired here, because\r\n  the operator acted.\r\n  The operator applied BOTH layers that evening — the Windows inbound rule (~23:41Z) and the\r\n  tailnet ACL grant (~23:56Z) — and the re-probe with the same rule-less pwsh listener read\r\n  **3/3 over Tailscale on 7483 AND 3/3 on 7489 at 23:57:50Z** from `100.98.197.12`, with a\r\n  post-terminal probe 3/3 on both ports at attempt 4. v0.68.0 then shipped at `a2f335f8` with\r\n  both two-host legs GREEN on golden r4, so the box half is closed by measurement and not by\r\n  assertion. **Durable half BUILT, acceptance reconciliation OPEN:** the pre-ceremony B→A\r\n  probe and its corrections are documented below. Do not redispatch a workflow guard that\r\n  already landed, or reopen the spent operator permission. The next box/ACL reset remains a\r\n  recheck trigger. · **Origin:** run 34262154550 @ `25e60015`, twohost-a 102229928746\r\n  (`two_host_web_helper_role_a`, :968, 900.40 s) and twohost-b 102229928689\r\n  (`two_host_web_role_b`, :559, 910.20 s): B logged 75 × \"A not ready … broker QUIC op exceeded\r\n  the 10s bound (peer unresponsive)\" from 20:49:49Z to 21:04:37Z and was never ADMITTED. Ladder\r\n  green both sides; both halves started 20:41:23Z on their own runners (not IR-87's starvation).\r\n- **Mechanism (MEASURED 21:11Z):** the box's firewall policy is `BlockInbound,AllowOutbound` on\r\n  all three profiles (Ethernet and Tailscale both Private). Inbound allow rules exist only for\r\n  exes under `Documents\\projects\\spt-core\\target` (interactive Allow clicks) and under the DEAD\r\n  pre-rename runner path `_work\\spt-core\\spt-core`; exactly ONE under `_work\\spt-bs-core` (its\r\n  `target\\debug\\spt.exe`, the CLI, not the binder — deployah's count, mine had said zero), none for\r\n  any `twohost_web-*.exe`. `Get-NetFirewallProfile` shows `DefaultInboundAction = NotConfigured`,\r\n  whose effective default IS block: the block is Windows' default, not a configured policy, so there\r\n  is no policy to \"restore\". The runner is a service (`.\\decid`), so the Allow dialog that minted the\r\n  old rules cannot appear. A's helper cell 3 bound `broker udp 7483` inside\r\n  `_work\\spt-bs-core\\spt-bs-core\\target\\debug\\deps\\twohost_web-f73bc44be13353fb.exe`; B dialled\r\n  `100.68.35.65:7483` cold. Probe: a rule-less pwsh UDP listener on hfenduleam:7483 received 0 of\r\n  3 datagrams from kitsubito `100.98.197.12`; the reverse control (python listener on\r\n  kitsubito:7483) received 3 of 3 from hfenduleam.\r\n- **Why three faces from one cause:** the shared-key rig (pre-`e4444413`) reached A only through\r\n  holes A's OUT-dialling cells (7480–7482) had opened for `id_a` — six 10 s bounds until B's\r\n  magicsock fell onto one of those paths, then ADMITTED (the 63 s stall, helper-stall memory), or\r\n  onto a live same-key sibling that never replied (the 21 min hang in 34239258523). Per-cell A\r\n  identity (`id_a_for`, `e4444413`) removed the accidental route by construction, leaving only\r\n  the cold path, which the firewall drops. hertz's one-box discriminator \"vanishes\" was true on\r\n  one box because one box never crosses the firewall. Product and rig are both exonerated; the\r\n  rig's `a_addr` comment already names W2 as the first A-ward claim.\r\n- **Remedy (two halves):** (1) BOX, operator-owned, elevated on hfenduleam:\r\n  `New-NetFirewallRule -DisplayName \"spt-ci two-host rig UDP-In (kitsubito only)\" -Direction Inbound -Action Allow -Protocol UDP -LocalPort 7460-7499 -RemoteAddress 100.98.197.12 -Profile Any`\r\n  (rig ports at the sha: ladder 7460/7461; web `PORT_OFFSET` 20 → A cells 7480–7483, B 7481; the\r\n  A-ward surface today is exactly UDP 7480–7483 — deployah's tighter range — and the whole range\r\n  moves with any `SPT_TWO_HOST_PORT_A` override, so the rule must move with it);\r\n  program-path rules are the wrong shape because the exe hash changes per build. Verify with the\r\n  same probe (3/3) before any rerun. (2) WORKFLOW, hertz: a B→A UDP probe step in the twohost\r\n  jobs before the ceremony, so this reds in 10 s with its own name instead of 900 s blaming\r\n  pairing; and retire the dead `_work\\spt-core` rules note in the runner runbook.\r\n- **Kin:** [[IR-83]] (the tailnet-ACL face of a cross-box inbound block — KIN, **NOT the same\r\n  finding**: that entry is the tailnet policy layer, this one is the Windows firewall layer, and\r\n  the SECOND LAYER note below is exactly the measurement that separates them), [[IR-87]] (the\r\n  other way a half waits 900 s on a partner), [[IR-76]] (golden runner\r\n  is the operator's box), [[IR-64]] (box-level facts only the operator can move),\r\n  `twohost-web-helper-stall-shared-a-identity-stale-path` (memory; its CONFIRMED arm is re-read\r\n  by this entry).\r\n- **AMENDMENT 2026-09-09 — the WORKFLOW half is BUILT and FIELD-MEASURED; it is LANDED-pending-golden\r\n  (hertz).** The guard is two cells in `twohost_web.rs` plus a step per half in `golden.yml`, and it\r\n  grew four design corrections that are worth more than the guard itself, because each one is a way a\r\n  probe can certify the fault it exists to catch.\r\n  1. **A FIXED SYMMETRIC WINDOW ADDS A THIRD CAUSE THAT LOOKS LIKE THE OTHER TWO.** The step boundary\r\n     orders the probe on ONE host; it does not align two, and after the ladder each half pays its own\r\n     wrapper and `cargo test` (on Windows a fingerprint scan plus Defender's first touch of a fresh\r\n     exe). MEASURED: the first hand-run in the A=kitsubito direction (13:14:13 → 13:14:51Z) redded\r\n     `INBOUND_BLOCKED` at 10.24 s with text asserting \"a BOX rule, not a product or rig fault\" — and\r\n     the cause was `cargo`'s start-up on the SENDER putting its first datagram after the receiver's\r\n     10 s window closed. An innocent box, the guard's own words against it. What stopped it being\r\n     filed as a kitsubito block was that the box facts contradicted the text (`tailscale debug\r\n     netmap` on kitsubito lists `100.68.35.65/32` among its permitted inbound sources, and `ufw` is\r\n     inactive) — a failure text that contradicts a measured box is the text's defect. So the\r\n     rendezvous is DATA: A listens up to the rig budget and beacons once a second; B binds first,\r\n     waits for a beacon, and only then starts a ten-second clock, so B's red has already excluded\r\n     \"A is not up\". That is a FOURTH outcome with its own name, `PROBE_NO_BEACON`, never\r\n     `INBOUND_BLOCKED`.\r\n  2. **THE LISTENING SOCKET MUST NEVER SEND.** Any outbound datagram from the measured port opens\r\n     stateful return state for it, so B's probe then arrives SOLICITED and crosses under both layers\r\n     — this entry's own \"solicited return traffic works under either fault\" applied to the guard\r\n     rather than to the ceremony. MEASURED: with the beacon sharing A's listening socket, the\r\n     out-of-grant control went **GREEN at 13:28Z** on a port a listen-only run had measured BLOCKED\r\n     at 13:20Z; a further green at 13:31Z with the beacon moved but the ack still leaving that socket\r\n     was residual state from 13:28 — true BY ELIMINATION rather than by assertion: nothing in the\r\n     13:31 run sent from 7509 before the first arrival, so the only outbound that could have opened\r\n     that port's return state belongs to the previous run. Beacon and ack both leave an ephemeral socket now, and B sends\r\n     from an ephemeral port too, so no run repeats a 4-tuple a previous run opened.\r\n  3. **THE ACK IS ADDRESSED TO B'S RIG PORT, not to the probe's source port.** MEASURED: acking to\r\n     `from` produced a run that CONTRADICTED ITSELF — A said `INBOUND OK` and B said\r\n     `INBOUND_BLOCKED`, same run, 13:41:33 → 13:41:50Z — because A's ack leaves its ephemeral\r\n     socket, is therefore not return traffic of the flow B opened, and a receiver whose inbound rule\r\n     is a port RANGE drops it. The rig port is the only address either host is reachable on cold.\r\n  4. **THE FALSIFIER, and it is the operator's own rule used as an instrument.** Forcing the probe\r\n     port to **7509** (`SPT_TWO_HOST_PORT_A=7480`), one port outside the granted udp 7460-7499, reds\r\n     the guard on demand with no elevation and no policy edit. Run TWICE BACK TO BACK at the final\r\n     code, 13:43:41 → 13:44:23Z and 13:44:25 → 13:45:07Z: **RED, RED** — A after 40 s having sent\r\n     39 beacons, B in its ten seconds having sent 48 and 47 datagrams with no ack, both exit 101.\r\n     One red would only prove a state timeout expired; two consecutive reds prove the design writes\r\n     none. The grant boundary is therefore measured from inside the test binary: 7489 crosses, 7509\r\n     does not, same hosts, same binary, one env var apart.\r\n  5. **ONE ACK IS NOT ENOUGH — the same split verdict arrives by packet loss** (doyle, reviewing the\r\n     built lane). A acking ONCE and breaking leaves B's red resting on a single unrepeated UDP\r\n     datagram: lose it and A prints `INBOUND OK` while B reds `INBOUND_BLOCKED`, blaming a firewall\r\n     for ordinary loss — correction 3's defect reached by a different road. A now keeps draining for\r\n     a short window after its own verdict is already settled and acks EVERY probe in it, while B\r\n     stops on the first ack. The A-side assertion is unchanged: it was decided by the first datagram.\r\n  6. **THE PROBE STEPS CARRY THEIR OWN BUDGET, 300 s, set EXPLICITLY** beside ceremony steps that say\r\n     900. It bounds RENDEZVOUS skew, not pairing, so a blocked link costs 300 s ONCE instead of 900\r\n     per cell per half. Left unset it would have been `from_env`'s invisible default sitting next to\r\n     a visible 900 on the step below — a number the next reader would have inferred wrongly, which is\r\n     this entry's whole failure mode in miniature.\r\n- **FIELD PROOF, 2026-09-09, and it is the ONLY proof this guard has:** `dir 1` (A=hfenduleam,\r\n  B=kitsubito) 13:45:14 → 13:45:18Z and `dir 2` (A=kitsubito, B=hfenduleam) 13:45:41 → 13:45:58Z,\r\n  both GREEN with the ack after ONE datagram, both exits 0, both hosts running byte-identical source\r\n  (md5 `f31779339266f8034dcd72917c56a37e`, checked on both sides). Free space 174.38 GiB, flat across\r\n  all four arms.\r\n  ⚠ **THE `golden.yml` STEPS THEMSELVES ARE UNEXERCISED UNTIL THE NEXT GOLDEN RUN.** Thin CI\r\n  compiles the cells and SKIPS them — `Rig::from_env` returns `None` without `SPT_TWO_HOST`, so a\r\n  green thin run says the code builds and nothing about the steps. The wall times above are the field\r\n  proof; treat the workflow half as landed-pending-golden and not as verified by its own PR.\r\n- **Ripe when:** the next GOLDEN run, which is the first thing that exercises the steps — the\r\n  code half is built and field-measured (PR #211). (The box half was ripe \"now\" against\r\n  `25e60015` and is done; #272 golden acceptance is no longer blocked by it.) · **Size:** one\r\n  workflow step remaining; the elevated command is spent.\r\n- **SECOND LAYER (measured 23:41–23:50Z, after the operator applied the Windows rule exactly as\r\n  asked and the re-probe STILL read 0/3):** the tailnet ACL. The same `python.exe` listener (own\r\n  program rule) received 3/3 from kitsubito over the LAN (`192.168.1.168 → 192.168.1.81:7483`) and\r\n  0/3 over Tailscale (`100.98.197.12 → 100.68.35.65`), TCP connect over Tailscale times out too,\r\n  solicited return over Tailscale works, ShieldsUp false both ends. `tailscale debug netmap` on\r\n  hfenduleam: one PacketFilter rule, 18 permitted inbound sources, kitsubito ABSENT; kitsubito is\r\n  `tag:eye-tracking-resource` owned by a different tailnet user, and its own filter DOES permit\r\n  hfenduleam. Asymmetric policy: member device → tagged resource allowed, reverse denied. The\r\n  Windows rule was NECESSARY (rule-less exe, LAN probe 0/2 earlier) and NOT SUFFICIENT. Remedy\r\n  half (1) gains an ACL grant, operator-owned in the admin console:\r\n  `{\"action\":\"accept\",\"src\":[\"tag:eye-tracking-resource\"],\"dst\":[\"hfenduleam:7460-7499\"],\"proto\":\"udp\"}`.\r\n  Rider 4's failure text names both layers and the LAN-vs-Tailscale probe as the discriminator.\r\n  Lesson for the entry: a cross-box \"unresponsive\" has at least THREE layers (Windows rule, tailnet\r\n  policy, the exe's own bind); probe through the SAME path the rig uses, and re-probe after every\r\n  single change — the first fix reading as \"applied\" is not the probe reading 3/3.\r\n- **Corroboration + reading traps (deployah 23:50Z, from the box):** Windows rule found present by\r\n  FILTER search (`netsh advfirewall firewall show rule name=all dir=in verbose`), not by name — the\r\n  operator's name is hyphenated \"two-host\" and a `twohost` grep reads it ABSENT. Netmap: the single\r\n  filter permits ALL ports and ALL protocols from its 18 sources, so the grant is SOURCE-scoped, not\r\n  port-scoped — \"this peer is not a permitted source at all\", which is why TCP timed out beside UDP.\r\n  Two permitted sources (100.98.213.33, 100.98.214.87) share kitsubito's 100.98/16 and read as hits\r\n  to an eyeball scan for \"100.98.\"; test membership of the full /32, never a prefix. His first netmap\r\n  read extracted a non-existent field (`SrcIPs`; the real key is `Srcs`), printed an empty list and\r\n  minted a confident \"ABSENT\" — an empty extraction cannot witness absence; the 18-count is from the\r\n  corrected read. Prefs on the box: ShieldsUp false, NoStatefulFiltering true, RouteAll true,\r\n  NetfilterMode 2 — nothing there explains the drop.\r\n- **Probe-rider design rule (hertz, d882297f):** the pre-ceremony probe reds `INBOUND_BLOCKED` for\r\n  EITHER layer and does not pretend to know which — its job is \"the box cannot receive, stop triaging\r\n  the product\"; the layer is named only by the one measurement that decides it (same listener, LAN\r\n  vs Tailscale), which the failure text prints as a recipe. A guard that names a cause it did not\r\n  measure is the defect class this whole entry documents.\r\n\r\n### IR-90 — a full disk on the self-hosted box reds a rig as a PRODUCT refusal, not a build error, and no rig or gate records the free space that would falsify it\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-09 from the disk-full incident on hfenduleam. ·\r\n  **Origin:** the IR-85 discriminator lane's head arm, killed by the volume rather than by the code\r\n  under test.\r\n- **Symptom:** `spt-daemon::sync concurrent_writes_reconcile_on_elected_node_and_converge` FAILED at\r\n  67.588 s with a panic in our own test at `crates\\spt-daemon\\tests\\sync.rs:198`:\r\n  `pull: Custom { kind: Other, error: \"sync refused: bundle failed: git -C <tmp>\\tracked-b\\.seed.git\r\n  bundle create <tmp>\\scratch\\serve\\serve-pull-6.bundle ^d12a7134... a-doyle failed (exit Some(1)):\r\n  fatal: sha1 file '<stdout>' write error. Out of diskspace\\nerror: pack-objects died\" }`, then a\r\n  second panic at `:213` (`pull thread: Any { .. }`) as the harness thread unwound.\r\n- **Cause:** `C:` was at **0.018 GiB free of 1862.02 GiB (0.00%)** at that instant\r\n  (`Win32_LogicalDisk`, 10:57Z). `git bundle create` could not write; the daemon's serve path turned\r\n  that into its real product refusal string `sync refused: bundle failed`; the test asserted on the\r\n  refusal. **Every layer behaved correctly, and the report reads as a sync regression at the sha\r\n  under test.**\r\n- **Why it is worse than the disk faces already known:** the two banked faces\r\n  (`disk-full-reds-as-lnk1318-pdb-error`) are TOOLCHAIN costumes — `LNK1318` at link, and rustc\r\n  I/O before any link — and both route a reader to \"the box is sick\". This one routes to a CODE\r\n  OWNER: it names our file, our line and our refusal string, and the disk word sits in the FOURTH\r\n  nested clause behind a git exit code. It arrived mid-discriminator with an old sha and a new sha\r\n  side by side, where the cheapest reading — \"the head arm failed, the old arm passed\" — is a\r\n  head regression that does not exist.\r\n- **Blast radius, same incident:** the volume also carried a live `unit (self-hosted, Windows,\r\n  hfenduleam)` job (run 34341010297) compiling into it, which completed FAILURE on its own and was\r\n  ruled VOID after the fact. doyle's cancel of THAT run returned `Cannot cancel a workflow run that\r\n  is completed` — recorded because a register that credits a controlled action nobody performed\r\n  teaches the next reader that the box was under control. (The earlier run 34337797758, in\r\n  **IR-85**'s amendment, is a different run with a different ending: CANCELLED at the job wall. One\r\n  register putting one cancel string on the wrong run is the same defect, one run over.) `spt daemon status` went to peer pump last tick 185 s with 24 brain\r\n  subscribers stall-evicted (last evict 10:51:22Z, inside the disk window), with an operator restart\r\n  under consideration — a restart that risks the releases#287 shell stranding and that, had it\r\n  appeared to help, would have taught everyone the wrong cause.\r\n- **⚠ Two things that looked like disk fallout and are NOT**, recorded so this entry does not\r\n  overclaim. (a) `serve list` returning `SERVE_UNCONFIRMED`: doyle read it from source —\r\n  `servehost.rs` and `KIND_SERVE_REQUEST` are ABSENT at 0.67.0/0.67.1 and were minted by 0.68.0, and\r\n  the resident broker is still the 0.67.0 image after the brain-only flip, so the CLI's 10 s bound\r\n  times out **by design** against an older daemon. (b) `peer reachability: DEGRADED, 4 of 7 peers\r\n  unreachable for 882775 s` — 10.2 days, predating the incident entirely. Even the pump term is\r\n  claimed as CONCURRENT, not caused: hertz called the pump recovered off ONE post-reclaim sample\r\n  (54 s) and doyle falsified it two minutes later (133 s), because a single reading of a monotonic\r\n  \"last tick N s ago\" counter cannot separate STILL TICKING from TICKED ONCE, and a fresh project\r\n  index proves the coordinator loop, not the pump.\r\n- **Remedy — one guard, two placements, and it REFUSES rather than runs:**\r\n  1. **Rig start.** For the two-host rig and any test rig that shells out to `git bundle` or writes a\r\n     store: read free space on the volume holding the rig's temp root and `target`, and under a floor\r\n     fail immediately with a message that says DISK and prints the number — never enter the\r\n     ceremony. Floor: start at **10 GiB**, above the largest single artifact these rigs write and far\r\n     below any healthy state of this box; tune only with a measurement.\r\n  2. **Failure text**, for the case where space runs out MID-run and no start check can catch it:\r\n     when a shelled-out git/store operation fails, append the current free space to the error before\r\n     it becomes a product refusal string, so the panic that reaches a human already carries the\r\n     falsifier.\r\n- **WHY BOTH, measured rather than argued (hertz, 2026-09-09, the #209 lane):** a floor read ONCE at\r\n  rig start would have PASSED that run and the run still ended nearly empty — `cargo check` started\r\n  at **136.32 GiB** free, the test-profile build of 221 binaries took it to **40.18 GiB in ten\r\n  minutes**, the legs finished at **16.24 GiB**, and it read **12.27 GiB** ninety seconds later. A\r\n  start-only guard is a guard against yesterday's disk. That last ~4 GiB fell with those legs already\r\n  terminal; the candidates are the runner's CI job and its `_work` tree, unsampled and therefore\r\n  UNATTRIBUTED.\r\n- **The record itself, and the only one that caught the dip (hertz, 2026-09-09):**\r\n  `.spt/preserved/hertz-leak-670-legs/disk-full-trace.log` — **139 samples, 11:52:46Z–13:57:07Z, one\r\n  per minute**, max **238.41 GiB** @12:45:20Z, min **12.53 GiB** @12:12:45Z. Two samples fall under\r\n  15 GiB — **14.85** @12:12:11Z and **12.53** @12:12:45Z — both inside the #209 leak lane's\r\n  build-and-teardown window, i.e. AFTER a start floor would have passed the run at **136.15 GiB**\r\n  (the window's first sample). Two caveats, both binding on any reading of it: **the true minimum is\r\n  unbounded below 12.53 — the sampler cannot see between its samples**, and **it attributes nothing:\r\n  hertz's own legs and the runner's CI job are indistinguishable in it.** It is the SECOND instrument\r\n  on this incident and the only one covering the dip: doyle's 30 s trace, preserved at\r\n  `.spt/preserved/ir90-free-space-trace-2026-09-09/free-sampler-12-13Z-to-12-28Z.txt`, runs\r\n  12:15:37Z–12:31:10Z and so begins after hertz's reap — it records the RECOVERY, this one records\r\n  the FALL. sha256 `d58ce838b677e62d4a017e77524f899fda81e7bacf73a0e2a05a1192e60abaf2`\r\n  (doyle's, `8bdae01bc151597070d7011443a2cdc74614232dbc962faec1b1b1833c71f22a`).\r\n- **Explicitly NOT the remedy:** a bigger disk, or a reap schedule. ~195 GiB of headroom was consumed\r\n  by ordinary work, ACCRUED across a ~45-minute build phase; **no reading bounds a rate** — the\r\n  free-space observations either side are endpoints of an accrual, and a rate derived from them\r\n  retargets a hunt (deployah's went to runaway logs, VSS and torrent preallocation on the strength of\r\n  a `>150 MB/s` derived that way, while the measured live box-wide write rate was ~1.5 MB/s). What\r\n  consumed it: two `cargo nextest run -E <5-test filter>` lanes at **82.88** and **64.44 GiB** — a\r\n  filter narrows the RUN, never the BUILD, and both built 221 test binaries under the `test` profile\r\n  — plus 40.93 GiB of `C:\\actions-runner\\_work` and 9.8 GiB of `%TEMP%`. Any headroom this box\r\n  has is two cold pools away from gone, so the guard must be a REFUSAL, not a budget.\r\n- **Kin:** **IR-85** (the same box's fs-heavy slowdown; a near-full volume is now a named environment\r\n  term there), **IR-86** (a start floor that passes a box which cannot finish — the same defect one\r\n  layer up, and this entry is its mid-run half), **IR-76** (the golden runner is the operator's\r\n  desktop), `disk-full-reds-as-lnk1318-pdb-error` (memory; this is its third face and its standing\r\n  gap), `test-profile-pool-outgrows-the-disk-floor`, `free-space-floor-blocks-golden`.\r\n- **Ripe when:** now. · **Size:** one assertion plus one error-context append, both test-side.\r\n\r\n### IR-91 — 561 untracked files sat at the repo root, 18 of them cited by tracked files, and the census that classified them used a corpus that made the discriminator invisible\r\n\r\n- **Status:** CLOSED by the lane that filed it (the root-scratch classify PR), hertz 2026-09-09 on\r\n  doyle's census and rulings. · **Origin:** the `.spt/` ignore lane (PR #212) named 561 untracked\r\n  root files as explicitly out of scope; this is that half.\r\n- **The population, measured at `2037bcb8`:** `git status --porcelain --untracked-files=all` = **561\r\n  `??` rows, all at the repo root, zero in subdirectories**, 50,034,994 bytes (47.7 MiB). By\r\n  extension: 268 `.raw`, 184 `.exit`, 87 `.md`, 7 `.out`, 4 `.log`, 4 `.done`, 2 `.txt`,\r\n  2 `.stackdump`, 2 `.sh`, 1 `.py`. **A `git add -A` at the root staged every one of them**, which\r\n  is the same landmine `.spt/` carried before #212 and the reason this is one arc in two lanes.\r\n- **⚠ THE FINDING, and it is about the CENSUS, not the files:** the first classification put two\r\n  cited files in the \"bury\" class. `W3-196-CENSUS.md` and `WEBSERVE-272-JIT.md` were recorded as\r\n  \"cited only from other root scratch\" — citing files `W3-196-JIT.md` and `W3-272-MEASUREMENTS.md`,\r\n  which are **TRACKED**. The census corpus was tracked-only, so **every hit it produced was a\r\n  tracked citation by construction**; the two were then relabelled by their PATH, because a `.md`\r\n  sitting at the repo root reads as scratch. **The discriminator is TRACKED-OR-NOT, never\r\n  ROOT-OR-NOT** — and a corpus that can only return tracked hits cannot tell you which of its own\r\n  hits are tracked, because it has already thrown away the distinction. Burying those two would have\r\n  left two tracked files citing paths that no longer existed: the `launch-battery.py` mechanism from\r\n  **IR-90**'s sibling lane with the sides swapped, caught here only because the burial list was\r\n  re-verified against the corpus a second time by a different reader.\r\n- **The second finding, which withdrew the lane's own destinations:** the repo root **already holds\r\n  140 tracked files, 134 of them `.md`, 25 with `JIT` in the name** — `IDLE-EDGE-JIT.md`,\r\n  `W3-196-JIT.md`, `WEBSERVE-272-W2-JIT.md`, every `M*-PLAN.md`, `MESH-D*-PLAN.md`,\r\n  `RESTORATION-D*-PLAN.md`. **The house convention is measured, not assumed: a plan or record lives\r\n  at the repo root and is TRACKED.** The first ruling would have relocated the cited files into\r\n  `docs/intake/`, `docs/design/` and `docs/gate-records/` — splitting siblings across two homes\r\n  (`WEBSERVE-272-W2-JIT.md` at root, `WEBSERVE-272-W3-DRIFT-RIDERS.md` in `docs/intake/`) and\r\n  repointing 18 citation lines to buy that split. **Destinations withdrawn; the 18 are tracked where\r\n  they are.** Zero moves, zero repoints, zero sha-transfer risk. A lane that tidies against a\r\n  measured convention is not tidying.\r\n- **THE RULE, which is what this entry is for:** *a plan or record cited from a tracked file is\r\n  itself tracked, at the path the citation already names.* The root is a legal home. What decides a\r\n  file's fate is whether the repo points at it — not where it sits, not what it is called, and not\r\n  whether it looks like scratch.\r\n- **What the lane did:** **18 Class A** files `git add`ed in place. **473 Class B** gate legs\r\n  (`.raw`/`.exit`/`.done`/`.log`/`.out`/`.stackdump`/`.sh`/`.txt`, zero tracked citations, each\r\n  word-bounded against the whole 911-file tracked corpus) **MOVED — not deleted** — to\r\n  `.spt/preserved/root-gate-legs-2026-09-09/` with a sha256 manifest, every file hashed before and\r\n  after the move. **70 Class C** uncited `.md` likewise to `.spt/preserved/root-md-2026-09-09/`.\r\n  Then five **root-anchored** ignore lines: `/*.raw` `/*.exit` `/*.done` `/*.out` `/*.stackdump`.\r\n- **Why those five and not more.** Legs are the one class whose FUTURE instances are scratch **by\r\n  construction**, so ignoring them institutionalizes no loss. `/*.md`, `/*.log`, `/*.sh` and\r\n  `/*.txt` are deliberately NOT ignored: a plan or script dropped at the root must keep showing as\r\n  `??` so the next census classifies it — **that is exactly the pattern that produced this repo's\r\n  140-file tracked root corpus**, and an ignore line there would hide the next one. The anchoring is\r\n  load-bearing and was proved with a negative control: `crates/probe.raw` is **not** ignored, which\r\n  an unanchored `*.raw` would have swallowed.\r\n- **Kin:** the `.spt/` ignore lane (PR #212 — same arc, and its `launch-battery.py` case is why\r\n  nothing here was deleted), **IR-90** (a citation into `.spt/preserved/` is machine-bound evidence,\r\n  never a repo path), `ignoring-a-directory-buries-what-the-repo-cites-in-it` (memory).\r\n- **Ripe when:** landed with this entry. · **Size:** one `.gitignore` stanza, 18 adds, 543\r\n  preserved files, no deletions.\r\n\r\n### IR-92 — the message that WAKES an idle spt-hosted endpoint rides a delivery leg that never publishes MSG_IN, so a woken agent's own funnel holds none of the messages that woke it\r\n\r\n- **Status:** OPEN — filed doyle 2026-09-09 from hertz's census, probe and proposed text (his by\r","truncated":true,"truncatedBy":"lines","totalLines":1895,"totalBytes":44591,"outputLines":442,"outputBytes":44591,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6937,"displayContent":{"text":"### IR-85 — the Windows self-hosted box runs its fs-heavy tests 3-4x slower than a week ago; two CI wall clocks were sized for the old box, and a red run kept hiding it\n…\n- **Status:** OPEN, filed by hertz 2026-09-09 at the #272/v0.68.0 golden r3/r4 arc, on doyle's\n…\n- **AMENDMENT 2026-09-10 (hertz, on THIS ENTRY'S OWN arm-1 design note).** The note says the arms run\n…\n\r\n### IR-86 — golden's 32 GiB floor is BELOW the measured 67.4 GiB Windows suite footprint, so a start floor passes a box that cannot finish\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-08 at the #272/v0.68.0 golden r2 triage. · **Origin:**\r\n  run 34262154550 @ `25e60015` (shaped on `e4444413`), Windows test job 102182665033: every product\r\n  step green (Phase A 3346/3346, Phase B 234/234, Summary 2, FAIL 0), the ONLY reds were the two\r\n  in-job floor gates. `FLOOR_START` 97,649,786,880 B PASS at 18:47:23Z -> `FLOOR_DOCS`\r\n  25,284,501,504 B RED at 19:31:55Z -> `FLOOR_END` RED. Consumed in-job: 67.4 GiB.\r\n- **Mechanism:** `golden.yml` derives 32 GiB as \"the observed tens-of-GB full-suite footprint\r\n  rounded up to the next binary boundary, preserving headroom for one complete run\" (comment\r\n  above the Windows start floor). The measured footprint is 67.4 GiB, so a start reading anywhere\r\n  in [32, ~100) GiB passes and the job then walks under the floor by construction: box baseline\r\n  91 GiB minus 67.4 = 23.5 < 32. This is a shortfall of the DERIVATION, not a rate, not a product\r\n  red, and not the instant-vs-sustained face IR-46 files (that face is fixed by the FLOOR_DOCS\r\n  re-read, which is what caught it). The start floor must be footprint + end-floor (~100 GiB) or\r\n  it asserts nothing about finishing.\r\n- **Coverage consequence (the load-bearing part):** the Windows `Docs drift gate (CLI ref + llms\r\n  links)` step is sequenced BEHIND `FLOOR_DOCS`, so it SKIPPED and r2 held NO Windows CLI-ref\r\n  axis at that sha until the rerun. A floor red that skips a gate is a coverage hole wearing a\r\n  disk red.\r\n- **Kin:** [[IR-46]] (a floor asserts an instant), [[IR-59]] (pool arithmetic, LNK-class reds\r\n  that name no disk), [[IR-64]] (the operator-payload reservoir that sets the box baseline; its\r\n  ripe-when arm — a golden that dies at the floor despite adopted pool discipline — FIRED here\r\n  in the in-job form), [[IR-73]] (second half BUILT: the within-job re-read exists and is what\r\n  produced the FLOOR_DOCS reading), REQ-CI-FREE-SPACE-PREFLIGHT.\r\n- **Coupling (deployah 23:54Z, from `golden.yml` at `25e60015`):** the Windows `DISK docs floor`\r\n  (:616) and `Docs drift gate — windows` (:629) carry only `if: runner.os == 'Windows'`, no\r\n  `always()`, while `DISK end floor` does (`always() && runner.os == 'Windows'`, ~:705). Actions'\r\n  default is \"previous steps succeeded\", so ANY Phase B red skips the docs axis by construction —\r\n  observed three times at this sha (floor red, ttl cell, ttl cell). The docs gate is therefore never\r\n  independent evidence: it can only be banked when Phase B is green in the same job. Remedy line:\r\n  gate the two docs steps on `!cancelled()` plus the success of the steps they actually depend on\r\n  (checkout/build), not on Phase B — a rig change, new sha, hertz workflow rider slot.\r\n- **Remedy shape:** re-derive the start floor from the measured footprint (67.4 GiB Windows,\r\n  Linux to be measured) plus the 32 GiB end floor, print the footprint (start minus end free)\r\n  on every run so the number re-measures itself, and keep the 32 GiB literal only for\r\n  `FLOOR_END`.\r\n- **Ripe when:** next `golden.yml` touch (hertz workflow rider slot). · **Size:** small — one\r\n  literal per start-floor site + one printed subtraction.\r\n- **Linux recurrence, 2026-09-15 (doyle, S4 golden `34946493637`, reported in `3HHHPWCR`).** Kitsubito's test job began with about **110.7 GB** free and reached about **29.3 GB** after its build and test sandbox consumed **81.4 GB**; the workload stages were green, then the floor gates red. `FLOOR_DOCS` and `FLOOR_END` run **before** test-temp-sandbox cleanup, deliberately ([[IR-46]]), so the job must retain the end-floor reserve while its own sandbox still exists. A generic **32 GiB** start admission does not establish that capacity.\r\n<!-- [doc->REQ-CI-FREE-SPACE-PREFLIGHT] -->\r\n- **Linux sizing decision, 2026-09-15 (2NLUDSQA).** Golden's Linux **test-job** start allowance is now **130,000,000,000 bytes (130 decimal GB)**. The rounded measurements imply about **115.8 GB** minimum (81.4 GB working set + 32 GiB reserve); the allowance includes about **14.24 GB** margin, not a newly measured peak. `FLOOR_DOCS` and `FLOOR_END` retain **34,359,738,368 bytes (32 GiB)** and their pre-cleanup placement. Admission remains after checkout and before expensive work. Only this job/OS start value changes; other jobs, Windows admission, step conditions and cleanup order are untouched. Moving guards after cleanup would certify a different state and was not chosen.\r\n- **Linux verification.** Executed the actual YAML shell bodies on kitsubito with controlled `df` readings: the historical 110.7 GB start passes the predecessor and is refused by the successor; 130 GB minus one byte refuses, exactly 130 GB passes; native `df` failure23 propagates. Both docs/end bodies still refuse one byte below 32 GiB and pass exactly at the reserve. An unmodified native `df` sample passed at **246,886,174,720 bytes** free. All **9 successor probes** matched their expected exits; temporary probe workspace removed. Parsed workflow comparison confirms only the Linux test admission body differs, with all other executable steps/conditions/order unchanged. Evidence: `.spt/preserved/hertz-ir86-linux-floor/{predecessor,successor,workflow-scope}.js…\n<!-- [doc->REQ-CI-FREE-SPACE-PREFLIGHT] -->\r\n- **Windows source and derivation, 2026-09-15 (FRNOZMV4 / 2G5X324J / WNMSYL52).** Primary runner log: `.spt/preserved/hertz-ir86-windows-floor/job102182665033.log`, SHA256 **`8b1167ab4de3d474df4dde19f0a623d03beb820400cd19907b996cc2ab7bf91d`**, recovered from GitHub job **102182665033**, run **34262154550**, hfenduleam, source SHA **`25e6001585ed0cd495a72c7634dded9dd207bdae`**. Its actual `FLOOR_START` at line138 / 18:47:23.3668896Z reads **97,649,786,880 bytes**; `FLOOR_END` at line5223 / 19:31:56.6941352Z reads **25,284,497,408 bytes**, both on2026-09-08. Net movement is **72,365,289,472 bytes (67.395 GiB)**. Add the retained32GiB reserve: **106,725,027,840 bytes (99.395 GiB)**; round up to the next binary boundary for **128 GiB (137,438,953,472 bytes)** ad…\n- **Windows admission scope.** Only golden's Windows **test-job** start floor changes (`128GB` in PowerShell means128GiB). Docs/end remain32GiB before teardown; checkout still precedes admission, expensive work follows it, and every other step/condition/order remains unchanged. Linux retains its separately derived130decimalGB allowance.\r\n- **Reclamation is load-bearing (WNMSYL52).** Today's pre-reap hfenduleam sample **91,890,798,592 bytes (~92 GB)** would have been REFUSED by this admission floor. Reaping classified, owned retired targets is therefore a prerequisite for golden admission from that box state, not optional housekeeping. The authorized S3/S5 target removal left **201,837,236,224 bytes** free; source `.spt/preserved/hertz-retire-QD54OM7S/retirement-result.json` records both samples and their concurrent-CI attribution caveat. Re-sample after reclamation; no stale free-space reading grants a run. The unchanged refusal diagnostic names **`RESOURCE=disk`**, drive, free bytes and floor: classify it as **capacity REFUSED / workload UNTESTED**, not a product-test failure. The CI job st…\n- **Windows verification.** Executed the actual YAML PowerShell bodies under pwsh7.6.6. The historical97.65GB input passes the predecessor and refuses under the successor; today's pre-reap91.89GB also refuses with `RESOURCE=disk`. Admission-minus-one-byte refuses, exactly128GiB passes; an unreadable workspace fails before any PASS token. Docs/end each refuse reserve-minus-one-byte and pass exactly32GiB. A native workspace read passed at **264,109,211,648 bytes** free. All **10 successor probes** matched expected exits; no script files, build, pool claim, or suite execution. Parsed workflow comparison confirms only the Windows test admission body changed. Evidence: `.spt/preserved/hertz-ir86-windows-floor/{consumption-source,predecessor,successor,workflow-sco…\n- **Remaining IR-86 scope.** Both OS admission-sizing slices are implemented; automated start-minus-end reporting remains separate work, so the whole entry stays open. Existing raw-byte START/DOCS/END readings remain available for capacity analysis and are instantaneous shared-volume samples, not exclusive workload attribution.\r\n\r\n### IR-87 — two-host ceremony halves are INDEPENDENT jobs on DIFFERENT runners (A Windows/hfenduleam, B Linux/kitsubito); B's 900 s budget runs on B's own clock, so any older queued Windows job starves A and reds B deterministically, and the panic text blames pairing\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-08 at the #272 golden r2 triage. · **Origin:**\r\n  run 34262154550, twohost-b job 102207296960 (log 81,692 B, sha256 67403f04…8030): role B built,\r\n  rostered, polled PAIR_MEET_UP every 30 s from 19:34:30Z, and hit the rig_wait barrier\r\n  \"pairing: A rostered via the daemon-hosted responder\" at its 900 s deadline 19:49:17Z\r\n  (`crates/spt-daemon/tests/twohost.rs`, exit 101, 2 passed 1 failed). twohost-a (102207296985)\r\n  was QUEUED from 19:32:13Z with no runner: the Windows runner went to thin ci run 34261096301\r\n  (post-merge on main @ `e4444413`) the second the golden test job released it at 19:31:56Z.\r\n- **Mechanism:** `golden.yml` sequences twohost-a and twohost-b after `test`, but they are two\r\n  jobs on two runners (measured 2026-09-08 20:56Z via the jobs API `runner_name`: twohost-a on\r\n  hfenduleam, twohost-b on kitsubito), and GitHub's queue does not honour a workflow's intra-run\r\n  job ordering against a FOREIGN run on either runner. B starts, its whole budget ticks against a partner that has not been\r\n  scheduled, and `rig_wait` panics `never converged on the rig: {what}` — a text that reads as a\r\n  pairing defect. The lanes were not at fault, and twohost-a's outcome was predetermined once B\r\n  exited (a later A pass would be vacuous).\r\n- **Kin:** [[IR-76]] (hfenduleam is golden runner AND builders' box; the job-start census cannot\r\n  see a competing GitHub run either), [[IR-62]] (rig collisions on shared runners), the W1 two-host\r\n  rig, `a-barrier-cannot-ride-a-carrier-its-sender-outlives` (memory, same family: a barrier needs\r\n  the receiver's own answer).\r\n- **Remedy shape (pick at rider time):** (1) start barrier on B keyed to A's job having STARTED\r\n  (a run-scoped artifact or a `needs`+matrix collapse into ONE job that spawns both roles), or\r\n  (2) B's deadline clock starts at first A-rostered signal with a separate, longer \"A never\r\n  appeared\" budget, or (3) the panic names the missing partner's job state so triage does not\r\n  chase pairing. Any option: the two-host halves must never share a runner queue with a foreign\r\n  run while one half waits.\r\n- **Ripe when:** next `golden.yml`/twohost rig touch. · **Size:** small-medium (job shape or\r\n  barrier rework + panic text).\r\n\r\n- **AMENDMENT 2026-09-10 (releases#294, golden 34445961595 att1 @ `a9e786b2`) — THE STARVING RUN CAN\r\n  BE GOLDEN'S OWN PR, which makes this self-inflicted and recurrent on every golden run with a PR\r\n  open.** Measured timeline: **07:18:59Z** golden `test (Windows)` completes and releases hfenduleam;\r\n  **07:18:59Z** twohost-a queued; **07:19:01Z** PR run **34446095808** job `unit (Windows,\r\n  hfenduleam)` SEIZES the runner; **07:19:02Z** twohost-b starts on the free kitsubito; **07:36:16Z**\r\n  twohost-b fails at **900.41s** — `never converged on the rig: pairing: A rostered via the\r\n  daemon-hosted responder`. The origin case (2026-09-08) was a post-merge push on `main`: a run\r\n  belonging to someone else. **Here the starving run is the `pull_request` run of the very PR carrying\r\n  the golden head**, so opening the golden PR arms the starvation of that same head's twohost pair.\r\n  **Consequence for the remedy shape above: any option that only de-conflicts against OTHER lanes'\r\n  runs does not reach this case.** The golden head's own PR has to be excluded from the Windows\r\n  runner for the duration of the golden run (or the pair collapsed into one job, option 1).\r\n- **SECOND-ORDER FACE (deployah, same run): starvation does not merely red B — it desynchronises the\r\n  pair past repair.** twohost-b was TERMINAL at 07:36:16Z; twohost-a did not start until **07:48:07Z**\r\n  — the two halves never overlapped for a single second, so twohost-a's outcome is uninformative\r\n  **whatever it says**, and a red there must not be counted as a second product failure. Recorded\r\n  honestly at deployah's own insistence: **VOID is his SCORING interpretation, not a fact about the\r\n  run** — the release record carries GitHub's raw `conclusion` for both jobs beside the scoring, not\r\n  laundered into it.\r\n- **⚠ ITS WALL CLOCK IS INDISTINGUISHABLE FROM [[IR-89]]'s.** A 900 s twohost red whose panel blames\r\n  pairing is ALSO the exact signature of the banked Windows-firewall hazard. The panel alone cannot\r\n  separate them; **the job TIMELINE can**. Check the schedule before accepting the firewall hazard for\r\n  any 900 s twohost red — this one fit that signature perfectly and was not it.\r\n\r\n### IR-88 — `pool-release` via `cargo run -p xtask` REBUILDS xtask INTO the pool it is releasing, so a reaped pool regrows ~2.8 GB in silence\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-08 from hertz's reap report (20:00Z) during the #272\r\n  golden r2 repair. · **Origin:** hertz reaped hertz-lane4 / hertz-repin / hertz-percell-id target\r\n  subtrees (Length-sum upper bounds 68.16 / 47.11 / 8.79 GB) and then ran `cargo run -p xtask --\r\n  pool-release …` from each worktree: cargo rebuilt xtask into the just-reaped `target/` (2.8 GB\r\n  back in lane4, partial in repin), nothing printed said so, and the descendancy stopper killed\r\n  the second before it finished. Removed by hand afterwards; the post-reap free reading on the\r\n  record (275.95 GiB at 19:55:51Z) predates the regrowth.\r\n- **Mechanism:** the documented verb (AGENTS.md: \"drop it with `pool-release`\") is a `cargo run`,\r\n  and cargo's default target for that run IS the pool being released. The verb's own success path\r\n  recreates the state the operator just measured away; a teardown step that runs it AFTER a reap\r\n  undoes part of the reap and leaves the recorded free reading stale.\r\n- **Remedy shape:** either (a) `pool-release` documented and scripted as a PREBUILT `xtask.exe`\r\n  invoked against `--pool <dir>` from another pool, or (b) the verb refuses when its own\r\n  `CARGO_TARGET_DIR`/default target equals `--pool` and prints the prebuilt form, or (c) the reap\r\n  recipe orders release BEFORE the subtree delete. Memory banked 2026-09-08\r\n  (`pool-release-rebuilds-xtask-into-the-pool-you-just-reaped`); this entry is the durable home.\r\n- **POSITIVE CONTROL (hertz, 2026-09-09, ruling-3 gate-r3 teardown):** the same release run\r\n  from a PREBUILT `xtask.exe` invoked from outside the pool regrew NOTHING — the pool's own\r\n  `xtask.exe` still carried its original 21:00:42 mtime afterwards, and the reap that followed\r\n  reclaimed 63.71 GiB (132.03 -> 195.74 GiB free) against a 64.88 GiB Length-sum. So the\r\n  regrowth is a property of the `cargo run` VEHICLE, not of the verb, and remedy (a) is proven\r\n  rather than merely proposed.\r\n- **Kin:** [[IR-31]] (pool budgeting), [[IR-56]] (pool-claim identity from CWD — same verb\r\n  family, same \"the tool acts on where it stands\" shape), releases#103.\r\n- **Ripe when:** next xtask pool-verb touch or the teardown runbook edit. · **Size:** tiny —\r\n  one guard or one doc line.\r\n- **Amendment 2026-09-11 (hertz measured, doyle accepted):** the release-before-delete recipe as\r\n  written (\"keep the built test binaries, drop deps\") is NOT runnable — the workspace builds runtime\r\n  dylibs into the same `deps` dir (three `iroh_relay-*.dll` beside `daemon_stop_convoy_e2e-*.exe`\r\n  in the measured pool), so a retained exe with its dlls deleted is a keepsake. The recipe now reads:\r\n  retain the test exe set AND the runtime dll set, then EXECUTE one retained exe from the\r\n  post-deletion state before claiming the set is runnable; otherwise the disposition is archival and\r\n  exe retention is optional. `.pdb` is not needed to run but costs symbolised failure output — decide\r\n  that deliberately, not by size.\r\n\r\n### IR-89 — hfenduleam's Windows Firewall drops cold inbound UDP to the runner-built test exes, so the two-host rig's first B→A claim (W2 helper) reds for its whole 900 s budget and the panic blames A\r\n\r\n- **Status:** BOX HALF **APPLIED** 2026-09-08; WORKFLOW HALF **BUILT** 2026-09-09 — PR #211\r\n  (`9b96d7e7` + this amendment), **LANDED, exact golden-step acceptance unreconciled**.\r\n  Subsequent goldens have run: \"until the next golden\" is no longer a future trigger.\r\n  This sweep does not infer probe execution from a run's existence or overall conclusion;\r\n  retain the step-specific exercised/skipped/failed evidence before closing. Filed by doyle 2026-09-08\r\n  at the #272 golden r2 terminal triage; the operator-blocked flag is retired here, because\r\n  the operator acted.\r\n  The operator applied BOTH layers that evening — the Windows inbound rule (~23:41Z) and the\r\n  tailnet ACL grant (~23:56Z) — and the re-probe with the same rule-less pwsh listener read\r\n  **3/3 over Tailscale on 7483 AND 3/3 on 7489 at 23:57:50Z** from `100.98.197.12`, with a\r\n  post-terminal probe 3/3 on both ports at attempt 4. v0.68.0 then shipped at `a2f335f8` with\r\n  both two-host legs GREEN on golden r4, so the box half is closed by measurement and not by\r\n  assertion. **Durable half BUILT, acceptance reconciliation OPEN:** the pre-ceremony B→A\r\n  probe and its corrections are documented below. Do not redispatch a workflow guard that\r\n  already landed, or reopen the spent operator permission. The next box/ACL reset remains a\r\n  recheck trigger. · **Origin:** run 34262154550 @ `25e60015`, twohost-a 102229928746\r\n  (`two_host_web_helper_role_a`, :968, 900.40 s) and twohost-b 102229928689\r\n  (`two_host_web_role_b`, :559, 910.20 s): B logged 75 × \"A not ready … broker QUIC op exceeded\r\n  the 10s bound (peer unresponsive)\" from 20:49:49Z to 21:04:37Z and was never ADMITTED. Ladder\r\n  green both sides; both halves started 20:41:23Z on their own runners (not IR-87's starvation).\r\n- **Mechanism (MEASURED 21:11Z):** the box's firewall policy is `BlockInbound,AllowOutbound` on\r\n  all three profiles (Ethernet and Tailscale both Private). Inbound allow rules exist only for\r\n  exes under `Documents\\projects\\spt-core\\target` (interactive Allow clicks) and under the DEAD\r\n  pre-rename runner path `_work\\spt-core\\spt-core`; exactly ONE under `_work\\spt-bs-core` (its\r\n  `target\\debug\\spt.exe`, the CLI, not the binder — deployah's count, mine had said zero), none for\r\n  any `twohost_web-*.exe`. `Get-NetFirewallProfile` shows `DefaultInboundAction = NotConfigured`,\r\n  whose effective default IS block: the block is Windows' default, not a configured policy, so there\r\n  is no policy to \"restore\". The runner is a service (`.\\decid`), so the Allow dialog that minted the\r\n  old rules cannot appear. A's helper cell 3 bound `broker udp 7483` inside\r\n  `_work\\spt-bs-core\\spt-bs-core\\target\\debug\\deps\\twohost_web-f73bc44be13353fb.exe`; B dialled\r\n  `100.68.35.65:7483` cold. Probe: a rule-less pwsh UDP listener on hfenduleam:7483 received 0 of\r\n  3 datagrams from kitsubito `100.98.197.12`; the reverse control (python listener on\r\n  kitsubito:7483) received 3 of 3 from hfenduleam.\r\n- **Why three faces from one cause:** the shared-key rig (pre-`e4444413`) reached A only through\r\n  holes A's OUT-dialling cells (7480–7482) had opened for `id_a` — six 10 s bounds until B's\r\n  magicsock fell onto one of those paths, then ADMITTED (the 63 s stall, helper-stall memory), or\r\n  onto a live same-key sibling that never replied (the 21 min hang in 34239258523). Per-cell A\r\n  identity (`id_a_for`, `e4444413`) removed the accidental route by construction, leaving only\r\n  the cold path, which the firewall drops. hertz's one-box discriminator \"vanishes\" was true on\r\n  one box because one box never crosses the firewall. Product and rig are both exonerated; the\r\n  rig's `a_addr` comment already names W2 as the first A-ward claim.\r\n- **Remedy (two halves):** (1) BOX, operator-owned, elevated on hfenduleam:\r\n  `New-NetFirewallRule -DisplayName \"spt-ci two-host rig UDP-In (kitsubito only)\" -Direction Inbound -Action Allow -Protocol UDP -LocalPort 7460-7499 -RemoteAddress 100.98.197.12 -Profile Any`\r\n  (rig ports at the sha: ladder 7460/7461; web `PORT_OFFSET` 20 → A cells 7480–7483, B 7481; the\r\n  A-ward surface today is exactly UDP 7480–7483 — deployah's tighter range — and the whole range\r\n  moves with any `SPT_TWO_HOST_PORT_A` override, so the rule must move with it);\r\n  program-path rules are the wrong shape because the exe hash changes per build. Verify with the\r\n  same probe (3/3) before any rerun. (2) WORKFLOW, hertz: a B→A UDP probe step in the twohost\r\n  jobs before the ceremony, so this reds in 10 s with its own name instead of 900 s blaming\r\n  pairing; and retire the dead `_work\\spt-core` rules note in the runner runbook.\r\n- **Kin:** [[IR-83]] (the tailnet-ACL face of a cross-box inbound block — KIN, **NOT the same\r\n  finding**: that entry is the tailnet policy layer, this one is the Windows firewall layer, and\r\n  the SECOND LAYER note below is exactly the measurement that separates them), [[IR-87]] (the\r\n  other way a half waits 900 s on a partner), [[IR-76]] (golden runner\r\n  is the operator's box), [[IR-64]] (box-level facts only the operator can move),\r\n  `twohost-web-helper-stall-shared-a-identity-stale-path` (memory; its CONFIRMED arm is re-read\r\n  by this entry).\r\n- **AMENDMENT 2026-09-09 — the WORKFLOW half is BUILT and FIELD-MEASURED; it is LANDED-pending-golden\r\n  (hertz).** The guard is two cells in `twohost_web.rs` plus a step per half in `golden.yml`, and it\r\n  grew four design corrections that are worth more than the guard itself, because each one is a way a\r\n  probe can certify the fault it exists to catch.\r\n  1. **A FIXED SYMMETRIC WINDOW ADDS A THIRD CAUSE THAT LOOKS LIKE THE OTHER TWO.** The step boundary\r\n     orders the probe on ONE host; it does not align two, and after the ladder each half pays its own\r\n     wrapper and `cargo test` (on Windows a fingerprint scan plus Defender's first touch of a fresh\r\n     exe). MEASURED: the first hand-run in the A=kitsubito direction (13:14:13 → 13:14:51Z) redded\r\n     `INBOUND_BLOCKED` at 10.24 s with text asserting \"a BOX rule, not a product or rig fault\" — and\r\n     the cause was `cargo`'s start-up on the SENDER putting its first datagram after the receiver's\r\n     10 s window closed. An innocent box, the guard's own words against it. What stopped it being\r\n     filed as a kitsubito block was that the box facts contradicted the text (`tailscale debug\r\n     netmap` on kitsubito lists `100.68.35.65/32` among its permitted inbound sources, and `ufw` is\r\n     inactive) — a failure text that contradicts a measured box is the text's defect. So the\r\n     rendezvous is DATA: A listens up to the rig budget and beacons once a second; B binds first,\r\n     waits for a beacon, and only then starts a ten-second clock, so B's red has already excluded\r\n     \"A is not up\". That is a FOURTH outcome with its own name, `PROBE_NO_BEACON`, never\r\n     `INBOUND_BLOCKED`.\r\n  2. **THE LISTENING SOCKET MUST NEVER SEND.** Any outbound datagram from the measured port opens\r\n     stateful return state for it, so B's probe then arrives SOLICITED and crosses under both layers\r\n     — this entry's own \"solicited return traffic works under either fault\" applied to the guard\r\n     rather than to the ceremony. MEASURED: with the beacon sharing A's listening socket, the\r\n     out-of-grant control went **GREEN at 13:28Z** on a port a listen-only run had measured BLOCKED\r\n     at 13:20Z; a further green at 13:31Z with the beacon moved but the ack still leaving that socket\r\n     was residual state from 13:28 — true BY ELIMINATION rather than by assertion: nothing in the\r\n     13:31 run sent from 7509 before the first arrival, so the only outbound that could have opened\r\n     that port's return state belongs to the previous run. Beacon and ack both leave an ephemeral socket now, and B sends\r\n     from an ephemeral port too, so no run repeats a 4-tuple a previous run opened.\r\n  3. **THE ACK IS ADDRESSED TO B'S RIG PORT, not to the probe's source port.** MEASURED: acking to\r\n     `from` produced a run that CONTRADICTED ITSELF — A said `INBOUND OK` and B said\r\n     `INBOUND_BLOCKED`, same run, 13:41:33 → 13:41:50Z — because A's ack leaves its ephemeral\r\n     socket, is therefore not return traffic of the flow B opened, and a receiver whose inbound rule\r\n     is a port RANGE drops it. The rig port is the only address either host is reachable on cold.\r\n  4. **THE FALSIFIER, and it is the operator's own rule used as an instrument.** Forcing the probe\r\n     port to **7509** (`SPT_TWO_HOST_PORT_A=7480`), one port outside the granted udp 7460-7499, reds\r\n     the guard on demand with no elevation and no policy edit. Run TWICE BACK TO BACK at the final\r\n     code, 13:43:41 → 13:44:23Z and 13:44:25 → 13:45:07Z: **RED, RED** — A after 40 s having sent\r\n     39 beacons, B in its ten seconds having sent 48 and 47 datagrams with no ack, both exit 101.\r\n     One red would only prove a state timeout expired; two consecutive reds prove the design writes\r\n     none. The grant boundary is therefore measured from inside the test binary: 7489 crosses, 7509\r\n     does not, same hosts, same binary, one env var apart.\r\n  5. **ONE ACK IS NOT ENOUGH — the same split verdict arrives by packet loss** (doyle, reviewing the\r\n     built lane). A acking ONCE and breaking leaves B's red resting on a single unrepeated UDP\r\n     datagram: lose it and A prints `INBOUND OK` while B reds `INBOUND_BLOCKED`, blaming a firewall\r\n     for ordinary loss — correction 3's defect reached by a different road. A now keeps draining for\r\n     a short window after its own verdict is already settled and acks EVERY probe in it, while B\r\n     stops on the first ack. The A-side assertion is unchanged: it was decided by the first datagram.\r\n  6. **THE PROBE STEPS CARRY THEIR OWN BUDGET, 300 s, set EXPLICITLY** beside ceremony steps that say\r\n     900. It bounds RENDEZVOUS skew, not pairing, so a blocked link costs 300 s ONCE instead of 900\r\n     per cell per half. Left unset it would have been `from_env`'s invisible default sitting next to\r\n     a visible 900 on the step below — a number the next reader would have inferred wrongly, which is\r\n     this entry's whole failure mode in miniature.\r\n- **FIELD PROOF, 2026-09-09, and it is the ONLY proof this guard has:** `dir 1` (A=hfenduleam,\r\n  B=kitsubito) 13:45:14 → 13:45:18Z and `dir 2` (A=kitsubito, B=hfenduleam) 13:45:41 → 13:45:58Z,\r\n  both GREEN with the ack after ONE datagram, both exits 0, both hosts running byte-identical source\r\n  (md5 `f31779339266f8034dcd72917c56a37e`, checked on both sides). Free space 174.38 GiB, flat across\r\n  all four arms.\r\n  ⚠ **THE `golden.yml` STEPS THEMSELVES ARE UNEXERCISED UNTIL THE NEXT GOLDEN RUN.** Thin CI\r\n  compiles the cells and SKIPS them — `Rig::from_env` returns `None` without `SPT_TWO_HOST`, so a\r\n  green thin run says the code builds and nothing about the steps. The wall times above are the field\r\n  proof; treat the workflow half as landed-pending-golden and not as verified by its own PR.\r\n- **Ripe when:** the next GOLDEN run, which is the first thing that exercises the steps — the\r\n  code half is built and field-measured (PR #211). (The box half was ripe \"now\" against\r\n  `25e60015` and is done; #272 golden acceptance is no longer blocked by it.) · **Size:** one\r\n  workflow step remaining; the elevated command is spent.\r\n- **SECOND LAYER (measured 23:41–23:50Z, after the operator applied the Windows rule exactly as\r\n  asked and the re-probe STILL read 0/3):** the tailnet ACL. The same `python.exe` listener (own\r\n  program rule) received 3/3 from kitsubito over the LAN (`192.168.1.168 → 192.168.1.81:7483`) and\r\n  0/3 over Tailscale (`100.98.197.12 → 100.68.35.65`), TCP connect over Tailscale times out too,\r\n  solicited return over Tailscale works, ShieldsUp false both ends. `tailscale debug netmap` on\r\n  hfenduleam: one PacketFilter rule, 18 permitted inbound sources, kitsubito ABSENT; kitsubito is\r\n  `tag:eye-tracking-resource` owned by a different tailnet user, and its own filter DOES permit\r\n  hfenduleam. Asymmetric policy: member device → tagged resource allowed, reverse denied. The\r\n  Windows rule was NECESSARY (rule-less exe, LAN probe 0/2 earlier) and NOT SUFFICIENT. Remedy\r\n  half (1) gains an ACL grant, operator-owned in the admin console:\r\n  `{\"action\":\"accept\",\"src\":[\"tag:eye-tracking-resource\"],\"dst\":[\"hfenduleam:7460-7499\"],\"proto\":\"udp\"}`.\r\n  Rider 4's failure text names both layers and the LAN-vs-Tailscale probe as the discriminator.\r\n  Lesson for the entry: a cross-box \"unresponsive\" has at least THREE layers (Windows rule, tailnet\r\n  policy, the exe's own bind); probe through the SAME path the rig uses, and re-probe after every\r\n  single change — the first fix reading as \"applied\" is not the probe reading 3/3.\r\n- **Corroboration + reading traps (deployah 23:50Z, from the box):** Windows rule found present by\r\n  FILTER search (`netsh advfirewall firewall show rule name=all dir=in verbose`), not by name — the\r\n  operator's name is hyphenated \"two-host\" and a `twohost` grep reads it ABSENT. Netmap: the single\r\n  filter permits ALL ports and ALL protocols from its 18 sources, so the grant is SOURCE-scoped, not\r\n  port-scoped — \"this peer is not a permitted source at all\", which is why TCP timed out beside UDP.\r\n  Two permitted sources (100.98.213.33, 100.98.214.87) share kitsubito's 100.98/16 and read as hits\r\n  to an eyeball scan for \"100.98.\"; test membership of the full /32, never a prefix. His first netmap\r\n  read extracted a non-existent field (`SrcIPs`; the real key is `Srcs`), printed an empty list and\r\n  minted a confident \"ABSENT\" — an empty extraction cannot witness absence; the 18-count is from the\r\n  corrected read. Prefs on the box: ShieldsUp false, NoStatefulFiltering true, RouteAll true,\r\n  NetfilterMode 2 — nothing there explains the drop.\r\n- **Probe-rider design rule (hertz, d882297f):** the pre-ceremony probe reds `INBOUND_BLOCKED` for\r\n  EITHER layer and does not pretend to know which — its job is \"the box cannot receive, stop triaging\r\n  the product\"; the layer is named only by the one measurement that decides it (same listener, LAN\r\n  vs Tailscale), which the failure text prints as a recipe. A guard that names a cause it did not\r\n  measure is the defect class this whole entry documents.\r\n\r\n### IR-90 — a full disk on the self-hosted box reds a rig as a PRODUCT refusal, not a build error, and no rig or gate records the free space that would falsify it\r\n\r\n- **Status:** OPEN, filed by hertz 2026-09-09 from the disk-full incident on hfenduleam. ·\r\n  **Origin:** the IR-85 discriminator lane's head arm, killed by the volume rather than by the code\r\n  under test.\r\n- **Symptom:** `spt-daemon::sync concurrent_writes_reconcile_on_elected_node_and_converge` FAILED at\r\n  67.588 s with a panic in our own test at `crates\\spt-daemon\\tests\\sync.rs:198`:\r\n  `pull: Custom { kind: Other, error: \"sync refused: bundle failed: git -C <tmp>\\tracked-b\\.seed.git\r\n  bundle create <tmp>\\scratch\\serve\\serve-pull-6.bundle ^d12a7134... a-doyle failed (exit Some(1)):\r\n  fatal: sha1 file '<stdout>' write error. Out of diskspace\\nerror: pack-objects died\" }`, then a\r\n  second panic at `:213` (`pull thread: Any { .. }`) as the harness thread unwound.\r\n- **Cause:** `C:` was at **0.018 GiB free of 1862.02 GiB (0.00%)** at that instant\r\n  (`Win32_LogicalDisk`, 10:57Z). `git bundle create` could not write; the daemon's serve path turned\r\n  that into its real product refusal string `sync refused: bundle failed`; the test asserted on the\r\n  refusal. **Every layer behaved correctly, and the report reads as a sync regression at the sha\r\n  under test.**\r\n- **Why it is worse than the disk faces already known:** the two banked faces\r\n  (`disk-full-reds-as-lnk1318-pdb-error`) are TOOLCHAIN costumes — `LNK1318` at link, and rustc\r\n  I/O before any link — and both route a reader to \"the box is sick\". This one routes to a CODE\r\n  OWNER: it names our file, our line and our refusal string, and the disk word sits in the FOURTH\r\n  nested clause behind a git exit code. It arrived mid-discriminator with an old sha and a new sha\r\n  side by side, where the cheapest reading — \"the head arm failed, the old arm passed\" — is a\r\n  head regression that does not exist.\r\n- **Blast radius, same incident:** the volume also carried a live `unit (self-hosted, Windows,\r\n  hfenduleam)` job (run 34341010297) compiling into it, which completed FAILURE on its own and was\r\n  ruled VOID after the fact. doyle's cancel of THAT run returned `Cannot cancel a workflow run that\r\n  is completed` — recorded because a register that credits a controlled action nobody performed\r\n  teaches the next reader that the box was under control. (The earlier run 34337797758, in\r\n  **IR-85**'s amendment, is a different run with a different ending: CANCELLED at the job wall. One\r\n  register putting one cancel string on the wrong run is the same defect, one run over.) `spt daemon status` went to peer pump last tick 185 s with 24 brain\r\n  subscribers stall-evicted (last evict 10:51:22Z, inside the disk window), with an operator restart\r\n  under consideration — a restart that risks the releases#287 shell stranding and that, had it\r\n  appeared to help, would have taught everyone the wrong cause.\r\n- **⚠ Two things that looked like disk fallout and are NOT**, recorded so this entry does not\r\n  overclaim. (a) `serve list` returning `SERVE_UNCONFIRMED`: doyle read it from source —\r\n  `servehost.rs` and `KIND_SERVE_REQUEST` are ABSENT at 0.67.0/0.67.1 and were minted by 0.68.0, and\r\n  the resident broker is still the 0.67.0 image after the brain-only flip, so the CLI's 10 s bound\r\n  times out **by design** against an older daemon. (b) `peer reachability: DEGRADED, 4 of 7 peers\r\n  unreachable for 882775 s` — 10.2 days, predating the incident entirely. Even the pump term is\r\n  claimed as CONCURRENT, not caused: hertz called the pump recovered off ONE post-reclaim sample\r\n  (54 s) and doyle falsified it two minutes later (133 s), because a single reading of a monotonic\r\n  \"last tick N s ago\" counter cannot separate STILL TICKING from TICKED ONCE, and a fresh project\r\n  index proves the coordinator loop, not the pump.\r\n- **Remedy — one guard, two placements, and it REFUSES rather than runs:**\r\n  1. **Rig start.** For the two-host rig and any test rig that shells out to `git bundle` or writes a\r\n     store: read free space on the volume holding the rig's temp root and `target`, and under a floor\r\n     fail immediately with a message that says DISK and prints the number — never enter the\r\n     ceremony. Floor: start at **10 GiB**, above the largest single artifact these rigs write and far\r\n     below any healthy state of this box; tune only with a measurement.\r\n  2. **Failure text**, for the case where space runs out MID-run and no start check can catch it:\r\n     when a shelled-out git/store operation fails, append the current free space to the error before\r\n     it becomes a product refusal string, so the panic that reaches a human already carries the\r\n     falsifier.\r\n- **WHY BOTH, measured rather than argued (hertz, 2026-09-09, the #209 lane):** a floor read ONCE at\r\n  rig start would have PASSED that run and the run still ended nearly empty — `cargo check` started\r\n  at **136.32 GiB** free, the test-profile build of 221 binaries took it to **40.18 GiB in ten\r\n  minutes**, the legs finished at **16.24 GiB**, and it read **12.27 GiB** ninety seconds later. A\r\n  start-only guard is a guard against yesterday's disk. That last ~4 GiB fell with those legs already\r\n  terminal; the candidates are the runner's CI job and its `_work` tree, unsampled and therefore\r\n  UNATTRIBUTED.\r\n- **The record itself, and the only one that caught the dip (hertz, 2026-09-09):**\r\n  `.spt/preserved/hertz-leak-670-legs/disk-full-trace.log` — **139 samples, 11:52:46Z–13:57:07Z, one\r\n  per minute**, max **238.41 GiB** @12:45:20Z, min **12.53 GiB** @12:12:45Z. Two samples fall under\r\n  15 GiB — **14.85** @12:12:11Z and **12.53** @12:12:45Z — both inside the #209 leak lane's\r\n  build-and-teardown window, i.e. AFTER a start floor would have passed the run at **136.15 GiB**\r\n  (the window's first sample). Two caveats, both binding on any reading of it: **the true minimum is\r\n  unbounded below 12.53 — the sampler cannot see between its samples**, and **it attributes nothing:\r\n  hertz's own legs and the runner's CI job are indistinguishable in it.** It is the SECOND instrument\r\n  on this incident and the only one covering the dip: doyle's 30 s trace, preserved at\r\n  `.spt/preserved/ir90-free-space-trace-2026-09-09/free-sampler-12-13Z-to-12-28Z.txt`, runs\r\n  12:15:37Z–12:31:10Z and so begins after hertz's reap — it records the RECOVERY, this one records\r\n  the FALL. sha256 `d58ce838b677e62d4a017e77524f899fda81e7bacf73a0e2a05a1192e60abaf2`\r\n  (doyle's, `8bdae01bc151597070d7011443a2cdc74614232dbc962faec1b1b1833c71f22a`).\r\n- **Explicitly NOT the remedy:** a bigger disk, or a reap schedule. ~195 GiB of headroom was consumed\r\n  by ordinary work, ACCRUED across a ~45-minute build phase; **no reading bounds a rate** — the\r\n  free-space observations either side are endpoints of an accrual, and a rate derived from them\r\n  retargets a hunt (deployah's went to runaway logs, VSS and torrent preallocation on the strength of\r\n  a `>150 MB/s` derived that way, while the measured live box-wide write rate was ~1.5 MB/s). What\r\n  consumed it: two `cargo nextest run -E <5-test filter>` lanes at **82.88** and **64.44 GiB** — a\r\n  filter narrows the RUN, never the BUILD, and both built 221 test binaries under the `test` profile\r\n  — plus 40.93 GiB of `C:\\actions-runner\\_work` and 9.8 GiB of `%TEMP%`. Any headroom this box\r\n  has is two cold pools away from gone, so the guard must be a REFUSAL, not a budget.\r\n- **Kin:** **IR-85** (the same box's fs-heavy slowdown; a near-full volume is now a named environment\r\n  term there), **IR-86** (a start floor that passes a box which cannot finish — the same defect one\r\n  layer up, and this entry is its mid-run half), **IR-76** (the golden runner is the operator's\r\n  desktop), `disk-full-reds-as-lnk1318-pdb-error` (memory; this is its third face and its standing\r\n  gap), `test-profile-pool-outgrows-the-disk-floor`, `free-space-floor-blocks-golden`.\r\n- **Ripe when:** now. · **Size:** one assertion plus one error-context append, both test-side.\r\n\r\n### IR-91 — 561 untracked files sat at the repo root, 18 of them cited by tracked files, and the census that classified them used a corpus that made the discriminator invisible\r\n\r\n- **Status:** CLOSED by the lane that filed it (the root-scratch classify PR), hertz 2026-09-09 on\r\n  doyle's census and rulings. · **Origin:** the `.spt/` ignore lane (PR #212) named 561 untracked\r\n  root files as explicitly out of scope; this is that half.\r\n- **The population, measured at `2037bcb8`:** `git status --porcelain --untracked-files=all` = **561\r\n  `??` rows, all at the repo root, zero in subdirectories**, 50,034,994 bytes (47.7 MiB). By\r\n  extension: 268 `.raw`, 184 `.exit`, 87 `.md`, 7 `.out`, 4 `.log`, 4 `.done`, 2 `.txt`,\r\n  2 `.stackdump`, 2 `.sh`, 1 `.py`. **A `git add -A` at the root staged every one of them**, which\r\n  is the same landmine `.spt/` carried before #212 and the reason this is one arc in two lanes.\r\n- **⚠ THE FINDING, and it is about the CENSUS, not the files:** the first classification put two\r\n  cited files in the \"bury\" class. `W3-196-CENSUS.md` and `WEBSERVE-272-JIT.md` were recorded as\r\n  \"cited only from other root scratch\" — citing files `W3-196-JIT.md` and `W3-272-MEASUREMENTS.md`,\r\n  which are **TRACKED**. The census corpus was tracked-only, so **every hit it produced was a\r\n  tracked citation by construction**; the two were then relabelled by their PATH, because a `.md`\r\n  sitting at the repo root reads as scratch. **The discriminator is TRACKED-OR-NOT, never\r\n  ROOT-OR-NOT** — and a corpus that can only return tracked hits cannot tell you which of its own\r\n  hits are tracked, because it has already thrown away the distinction. Burying those two would have\r\n  left two tracked files citing paths that no longer existed: the `launch-battery.py` mechanism from\r\n  **IR-90**'s sibling lane with the sides swapped, caught here only because the burial list was\r\n  re-verified against the corpus a second time by a different reader.\r\n- **The second finding, which withdrew the lane's own destinations:** the repo root **already holds\r\n  140 tracked files, 134 of them `.md`, 25 with `JIT` in the name** — `IDLE-EDGE-JIT.md`,\r\n  `W3-196-JIT.md`, `WEBSERVE-272-W2-JIT.md`, every `M*-PLAN.md`, `MESH-D*-PLAN.md`,\r\n  `RESTORATION-D*-PLAN.md`. **The house convention is measured, not assumed: a plan or record lives\r\n  at the repo root and is TRACKED.** The first ruling would have relocated the cited files into\r\n  `docs/intake/`, `docs/design/` and `docs/gate-records/` — splitting siblings across two homes\r\n  (`WEBSERVE-272-W2-JIT.md` at root, `WEBSERVE-272-W3-DRIFT-RIDERS.md` in `docs/intake/`) and\r\n  repointing 18 citation lines to buy that split. **Destinations withdrawn; the 18 are tracked where\r\n  they are.** Zero moves, zero repoints, zero sha-transfer risk. A lane that tidies against a\r\n  measured convention is not tidying.\r\n- **THE RULE, which is what this entry is for:** *a plan or record cited from a tracked file is\r\n  itself tracked, at the path the citation already names.* The root is a legal home. What decides a\r\n  file's fate is whether the repo points at it — not where it sits, not what it is called, and not\r\n  whether it looks like scratch.\r\n- **What the lane did:** **18 Class A** files `git add`ed in place. **473 Class B** gate legs\r\n  (`.raw`/`.exit`/`.done`/`.log`/`.out`/`.stackdump`/`.sh`/`.txt`, zero tracked citations, each\r\n  word-bounded against the whole 911-file tracked corpus) **MOVED — not deleted** — to\r\n  `.spt/preserved/root-gate-legs-2026-09-09/` with a sha256 manifest, every file hashed before and\r\n  after the move. **70 Class C** uncited `.md` likewise to `.spt/preserved/root-md-2026-09-09/`.\r\n  Then five **root-anchored** ignore lines: `/*.raw` `/*.exit` `/*.done` `/*.out` `/*.stackdump`.\r\n- **Why those five and not more.** Legs are the one class whose FUTURE instances are scratch **by\r\n  construction**, so ignoring them institutionalizes no loss. `/*.md`, `/*.log`, `/*.sh` and\r\n  `/*.txt` are deliberately NOT ignored: a plan or script dropped at the root must keep showing as\r\n  `??` so the next census classifies it — **that is exactly the pattern that produced this repo's\r\n  140-file tracked root corpus**, and an ignore line there would hide the next one. The anchoring is\r\n  load-bearing and was proved with a negative control: `crates/probe.raw` is **not** ignored, which\r\n  an unanchored `*.raw` would have swallowed.\r\n- **Kin:** the `.spt/` ignore lane (PR #212 — same arc, and its `launch-battery.py` case is why\r\n  nothing here was deleted), **IR-90** (a citation into `.spt/preserved/` is machine-bound evidence,\r\n  never a repo path), `ignoring-a-directory-buries-what-the-repo-cites-in-it` (memory).\r\n- **Ripe when:** landed with this entry. · **Size:** one `.gitignore` stanza, 18 adds, 543\r\n  preserved files, no deletions.\r\n\r\n### IR-92 — the message that WAKES an idle spt-hosted endpoint rides a delivery leg that never publishes MSG_IN, so a woken agent's own funnel holds none of the messages that woke it\r\n\r\n- **Status:** OPEN — filed doyle 2026-09-09 from hertz's census, probe and proposed text (his by\r\n…\n  the chase exposed that neither agent's io-events log held the messages that woke it.\n…\n","startLine":4884,"lineNumbers":[4884,null,4886,null,5033,null,5043,5044,5045,5046,5047,5048,5049,5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,5070,5071,5072,5073,5074,5075,5076,5077,5078,5079,5080,5081,5082,5083,5084,5085,5086,5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102,5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,5113,5114,5115,5116,5117,5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133,5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149,5150,5151,5152,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164,5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,5176,5177,5178,5179,5180,5181,5182,5183,5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,5199,5200,5201,5202,5203,5204,5205,5206,5207,5208,5209,5210,5211,5212,5213,5214,5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243,5244,5245,5246,5247,5248,5249,5250,5251,5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283,5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347,5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,null,5488,null,5613]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":6937,"totalBytes":44591,"outputLines":442,"outputBytes":44591,"shownRange":{"start":5043,"end":5484},"nextOffset":5485},"limits":{"columnTruncated":{"maxColumn":768}}}},"isError":false,"timestamp":1789483661708}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_tfmPJAXoEB45zBmrjWL2T3O9|fc_000c7cef03cac861016aa95a95281087d1a48345c416f1ca59","toolName":"read","startedAt":"2026-09-15T14:47:49.290Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:5482-5927"},"intent":"Reading messaging through timeout amendments"},"id":"da90b310","parentId":"3cb4e931","timestamp":"2026-09-15T14:47:49.290Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Str3WkuDknjM3SZXXaQTQMCX|fc_000c7cef03cac861016aa95a95282487d1950d6423ddc7c130","toolName":"read","startedAt":"2026-09-15T14:47:49.290Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:5928-6366"},"intent":"Reading discipline and fixture entries"},"id":"30c6cf8e","parentId":"da90b310","timestamp":"2026-09-15T14:47:49.290Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_l6I7d56NfalytdGlREVyYtWf|fc_000c7cef03cac861016aa95a95282c87d18bbe240cbfa3c273","toolName":"read","startedAt":"2026-09-15T14:47:49.290Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6367-6768"},"intent":"Reading remaining rig dispositions"},"id":"399563e3","parentId":"30c6cf8e","timestamp":"2026-09-15T14:47:49.290Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_fKsgbmNm0t8sArrjynyjUTCz|fc_000c7cef03cac861016aa95a95283487d18c59a8cf5696216b","toolName":"read","startedAt":"2026-09-15T14:47:49.291Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6769-6937:raw"},"intent":"Reading final rig amendments"},"id":"9bb57cde","parentId":"399563e3","timestamp":"2026-09-15T14:47:49.291Z"}
{"type":"message","id":"2be37315","parentId":"9bb57cde","timestamp":"2026-09-15T14:47:49.291Z","message":{"role":"assistant","content":[{"type":"toolCall","id":"call_tfmPJAXoEB45zBmrjWL2T3O9|fc_000c7cef03cac861016aa95a95281087d1a48345c416f1ca59","name":"read","arguments":{"i":"Reading messaging through timeout amendments","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:5482-5927"},"intent":"Reading messaging through timeout amendments"},{"type":"toolCall","id":"call_Str3WkuDknjM3SZXXaQTQMCX|fc_000c7cef03cac861016aa95a95282487d1950d6423ddc7c130","name":"read","arguments":{"i":"Reading discipline and fixture entries","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:5928-6366"},"intent":"Reading discipline and fixture entries"},{"type":"toolCall","id":"call_l6I7d56NfalytdGlREVyYtWf|fc_000c7cef03cac861016aa95a95282c87d18bbe240cbfa3c273","name":"read","arguments":{"i":"Reading remaining rig dispositions","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6367-6768"},"intent":"Reading remaining rig dispositions"},{"type":"toolCall","id":"call_fKsgbmNm0t8sArrjynyjUTCz|fc_000c7cef03cac861016aa95a95283487d18c59a8cf5696216b","name":"read","arguments":{"i":"Reading final rig amendments","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6769-6937:raw"},"intent":"Reading final rig amendments"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":39161,"output":196,"cacheRead":21376,"cacheWrite":0,"totalTokens":60733,"cost":{"input":0.39161,"output":0.0098,"cacheRead":0.021376,"cacheWrite":0,"total":0.422786}},"stopReason":"toolUse","timestamp":1789483661749,"responseId":"resp_000c7cef03cac861016aa95a8e17e487d1b2534b818b293ed2","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"fc_000c7cef03cac861016aa95a95281087d1a48345c416f1ca59","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading messaging through timeout amendments\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:5482-5927\"}","call_id":"call_tfmPJAXoEB45zBmrjWL2T3O9","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95a95282487d1950d6423ddc7c130","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading discipline and fixture entries\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:5928-6366\"}","call_id":"call_Str3WkuDknjM3SZXXaQTQMCX","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95a95282c87d18bbe240cbfa3c273","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading remaining rig dispositions\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6367-6768\"}","call_id":"call_l6I7d56NfalytdGlREVyYtWf","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95a95283487d18c59a8cf5696216b","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading final rig amendments\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6769-6937:raw\"}","call_id":"call_fKsgbmNm0t8sArrjynyjUTCz","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}}]},"duration":7536.184599995613,"ttft":7461.126599997282,"completedAt":1789483669288,"contextSnapshot":{"promptTokens":60537,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"message","id":"28b4373a","parentId":"2be37315","timestamp":"2026-09-15T14:47:49.305Z","message":{"role":"toolResult","toolCallId":"call_tfmPJAXoEB45zBmrjWL2T3O9|fc_000c7cef03cac861016aa95a95281087d1a48345c416f1ca59","toolName":"read","content":[{"type":"text","text":"### IR-91 — 561 untracked files sat at the repo root, 18 of them cited by tracked files, and the census that classified them used a corpus that made the discriminator invisible\n…\n- **Status:** CLOSED by the lane that filed it (the root-scratch classify PR), hertz 2026-09-09 on\n…\n- **Ripe when:** landed with this entry. · **Size:** one `.gitignore` stanza, 18 adds, 543\n…\n\n### IR-92 — the message that WAKES an idle spt-hosted endpoint rides a delivery leg that never publishes MSG_IN, so a woken agent's own funnel holds none of the messages that woke it\n\n- **Status:** OPEN — filed doyle 2026-09-09 from hertz's census, probe and proposed text (his by\n  role; the recorder read and the REQ reading are doyle's). Fix lane unassigned: product change in\n  `spt-daemon` (todlando), test-side legs (hertz). · **Origin:** a 22:35Z empty `<msg from=\"hertz\"/>`\n  turn trigger after the #292 daemon restart, chased for its body; the body was in a spill file, and\n  the chase exposed that neither agent's io-events log held the messages that woke it.\n- **Release reconciliation, 2026-09-11 (source read at `e5a2fed9`):** core PR **#215 is\n  DOCS-ONLY**. Its merge and v0.69.0 ship-fact record (comment 5628532753) discharge the\n  **register rider**, not this product remedy. Core #217 is the separate #293 brain-read\n  census, not an inject-edge fix. `try_spt_hosted_inject` still returns the result of\n  `brain.inject_endpoint` without publishing `MSG_IN`. **IR-92 stays OPEN.** Carry the\n  observation-only chokepoint remedy into the next product intake (todlando product ownership,\n  hertz test ownership); neither offline owner's execution is implied by that assignment.\n- **THE TWO PUBLISH SITES ORDER THEMSELVES OPPOSITELY — read at `de5a44bc`, 2026-09-10, from the\n  bare-baseline red on `io_events_undriven_kinds_e2e` (golden 34467873057, Linux Phase A).** The\n  count below is right and the ORDERING is what this entry was missing:\n  · **PATH A, hook poll** (`delivery.rs`): `poll_drain()` publishes EVERY delivered row (`:757`) and\n    RETURNS them; its only caller `cmd_poll` (`:660`) then loops `emit_event` over the returned rows.\n    **Publication happens-before presentation**, strictly. An immediate log read after observed\n    presentation is CONTRACT-CORRECT here, and a bounded retry on this path WOULD conceal a real\n    violation. **Leave Path A alone.**\n  · **PATH B, the relay** (`startup.rs:1057`, the `deliver` closure): `emit(id, from, body)` — the\n    presentation — runs, and `publish_msg_io(...MSG_IN...)` runs AFTER it, per message, in the same\n    closure; the closure's own comment records that \"Both backlog (after notif validity) and live TCP\n    reach this edge.\" **Presentation happens-before publication.**\n  A test that detects presentation by reading the listener child's STDOUT through a pipe and then\n  reads the io-events log immediately is therefore **racy BY CONTRACT on Path B** — publication for\n  that message runs after its emit, in the child, and the pipe read can win. A bounded wait on the\n  log is permitted on Path B: **it does not weaken any publication-before-presentation guarantee\n  there, because there is none** (hertz's and todlando's narrowing — NOT \"conceals nothing\": the\n  wait still DEFINES WHICH PUBLICATION DELAYS THE TEST ACCEPTS, and it does not establish why any\n  given execution missed a row). A timeout would establish \"not published within the bound\", never\n  \"never publishes\", and cannot alone identify this entry's defect.\n- **A SECOND, INDEPENDENT DEFECT IN THAT CELL'S ASSERTION, true regardless of the above.**\n  `io_events_undriven_kinds_e2e.rs:818` asserts exact-once as\n  `vec![(\"MSG_IN\", Some(AUTHOR)), (\"MSG_IN\", Some(AUTHOR))]` — a `(kind, author)` pair per row, and\n  **both rows are identical**, so the assertion cannot tell the backlog row from the live row and\n  **two BACKLOG rows would satisfy it**. The identities exist and are already stamped:\n  `publish_msg_io_local` carries `.with_msg_id(msg_id_of(body))` — the short ID the failing panel\n  itself printed. Exact-once belongs per MESSAGE ID, not per author.\n  **AND IT CUTS BACKWARDS, WEAKENING EVERY GREEN THIS CELL HAS EVER RETURNED (deployah, on\n  arm-comparability grounds — the point nobody else had drawn):** the three PASSING executions of\n  this cell in the instrumented pair (base linux 3.612 s, head linux 2.343 s, head windows 16.411 s)\n  did **NOT** establish that both relay arms published. They established that two rows matching\n  `(MSG_IN, alice)` were present at read time. A green here is a WEAKER fact than it reads as — the\n  verdict stands in for a measurement the assertion never made. So \"both Linux legs were green\n  across the instrumented pair\" does not become FALSE, it becomes NARROWER than it was being used\n  for: it is a statement about the ASSERTION's outcome, not about publication. It does **not** make\n  the bare red likelier to be a product defect, does not classify anything, and does not separate\n  the race from non-publication — it removes a comparison the RCA was implicitly leaning on.\n  (Raised independently by hertz and todlando as an assertion defect; its backwards consequence for\n  the greens is deployah's.)\n- **Status of that red: UNEXPLAINED between DELAYED and ABSENT publication.** Path B makes the race\n  MECHANICALLY AVAILABLE, which is more than \"not excluded\" — but availability is not occurrence,\n  and one observation does not separate them. Kinship to this entry stays a HYPOTHESIS. The cell is\n  in neither `docs/FLAKE-LEDGER.md` nor this register (0 hits each): an unregistered signature.\n- **The mechanism, read at `de5a44bc`:** `MSG_IN` has exactly two publish sites in the tree —\n  `crates/spt/src/api/delivery.rs:757` (`publish_msg_io_local`, reached only from `poll_drain`, the\n  hook-poll leg, `TakerLeg::HookPoll`) and `crates/spt/src/api/startup.rs:1064` (`publish_msg_io`\n  inside the `api listen` relay's `deliver` sink — the Monitor-stream surface a hook-hosted session\n  never uses). **The spt-hosted inject leg reaches neither.** `crates/spt-daemon/src/inject.rs:75`\n  `try_spt_hosted_inject` renders the envelope and hands it to `brain.inject_endpoint`; the file has\n  zero `publish_msg_io` / `iobus` / `IO_KIND_MSG_IN` references in 343 lines (control: `TakerAudit`\n  / `claim_idle_edge_at` hit, so the grep is live). Every caller delivers through it unobserved:\n  `cli.rs:11739` send-time direct inject when the broker reports the target IDLE (the sender is\n  answered `SENT`), `cli.rs:11684` `--force-native`, `inject.rs:168` `drain_spool_offering` (the\n  idle-EDGE drain `delivery.rs:801`, the send-time already-idle re-offer, the pulse-tick belt, and the\n  native ER-briefing arm), and `wan.rs:822` / `:1173` WAN ingress. Two more drain edges are silent by\n  the same shape and did not fire here: `cmd_poll_shell` (`delivery.rs:705`, shell surface) and\n  `cmd_worker_poll` (`worker.rs:138`, worker surface). A call-site grep would have marked `relay.rs`\n  silent too — it publishes through its sink one crate up — so \"does this edge observe\" is answered\n  by following the row to a bus, never by grepping the edge.\n- **The rule it produces (hertz's refinement, measured across both logs):** for a hook-hosted live\n  agent (`is_spt_hosted_no_relay`), **`SENT` to an idle peer → direct inject → NEVER recorded on\n  the peer** (deterministic). **`QUEUED` → recorded IFF the hook poll takes the row.** One stamped\n  census, **as of 23:04Z 2026-09-09** (the counts grow with every message, so an unstamped figure is\n  stale on arrival): SENT-to-idle unrecorded on the receiver **12/12** (hertz’s five to doyle, doyle’s\n  seven to hertz — the seventh being the message that announced this filing, delivered by the defect\n  it named); QUEUED recorded **8/8**, every one drained mid-tool. Each side’s absence census matched\n  the other side’s verdict log without either seeing the other’s data.\n  by the caller census a spooled row can also be taken by the send-time already-idle re-offer or the\n  pulse-tick belt (`inject.rs:168`, unrecorded), so a `QUEUED` row’s fate is decided by the TAKER,\n  not the verdict — that arm was not observed tonight and stays a prediction.\n- **Measured, hfenduleam 2026-09-09, both full streams read end to end, same 23:04Z stamp:** hertz’s\n  log (through seq 1812): the messages that arrived as turn triggers (`UserPromptSubmit`, idle) — **7/7\n  unlogged**; those that arrived mid-tool (`PreToolUse`, busy) — **4/4 logged**, msg-id present,\n  `<LAST_MSGS>` clock moved (doyle's 22:55Z probe was `QUEUED`, drained mid-Bash, logged as 1804).\n  His \"zero `MSG_IN` since 14:02:34Z\" was **not a state change**: 1633 at 14:02 was the last message\n  that happened to catch him inside a tool call; everything after found him idle. doyle's log (1,121\n  events): PACER-0 **7 received / 6 logged**, the missing one `G4NK5FFT` being the row that woke the\n  session; hertz’s five `SENT` wake messages **absent entirely** and his four `QUEUED` ones **present\n  4/4**, each drained mid-tool; riders in the same spill (1856/1857 beside the promoted 1855;\n  `3NGTHQHN` beside a task-notification trigger) logged. One variable moved.\n- **Scope, corrected once (hertz struck his own \"bilateral\" clause on doyle's control):**\n  receiver-side only. The sender's `MSG_OUT` rows are intact on both sides, so an exchange IS\n  reconstructible from the **peer's** log — but not from the woken agent's own, which is the surface\n  a post-reset agent reads. hertz re-grounded his 22:36 session off seq 1786 of a log that holds his\n  half of every exchange since 14:02 and none of doyle's; a replay of an idle-woken agent shows its\n  own outbound answering nothing, and the last-received clock skips exactly the moments the peer was\n  talking, which reads as \"peer gone quiet\".\n- **Against the requirement's own words:** `REQ-IO-MSG-EDGES` (activated, `doc`/`impl`/`unit`)\n  states that \"MSG_IN publishes where core **delivers or injects** an inbound one, so the funnel\n  observes the edges rather than growing a parallel notion of what a message is\". This is not a case\n  the requirement failed to anticipate: **its own second clause is unimplemented** while `impl` and\n  `unit` read green on the first. The inject edge was never given a publisher when F-023 (idle-edge\n  drain), W5 (parked re-offer) and the WAN ingress added takers; the unit cell at `delivery.rs:1251`\n  pins the poll leg only, so the coverage the registry reports is green on two edges and vacuous on\n  the one the requirement names by verb.\n- **Remedy, and where it must sit:** publish `MSG_IN` **inside `try_spt_hosted_inject` on\n  `Some((true, _))`** — the one chokepoint all four callers share — so no caller can deliver\n  unobserved; a fix placed in `drain_spool_offering` would leave the send-time direct inject and WAN\n  ingress silent. Keep it observation-only (REQ-IO-EVENT-BUS): the inject verdict must not depend on\n  the bus. The unit cell to add mirrors `delivery.rs:1251`: an injected row owes exactly one\n  `MSG_IN`, a refused inject owes none. Post-hoc census of what was lost: spooled rows carry\n  `TakerLeg::IdleInject` / `NativeInject` in the audit column (REQ-SPOOL-TAKE-AUDIT); direct injects\n  never spooled and are enumerable only from the sender's `MSG_OUT`.\n- **OPEN, unranked, not smoothed:** doyle's pre-clear 1855 got a **bodiless** `USER_INPUT msg\n  from=\"hertz\"` row (the `api state busy` payload path, `delivery.rs:115` `state_io_kind`) while his\n  post-clear five got **no row at all**. Both are wake-delivered; the difference is downstream of\n  this gap, in what the adapter passed as the state payload, and is not this entry's mechanism.\n  Also out of scope, perri's surface: the claude-spt overflow notice names spills of the CURRENT\n  session id only, so the last spill before a `/clear` is never named again (how the 22:35Z body\n  went unread in the first place).\n- **Kin:** `REQ-IO-MSG-EDGES`, `REQ-MSG-IDLE-EDGE-DRAIN`, `REQ-IDLE-PARKED-DELIVERY`,\n  `REQ-SPOOL-TAKE-AUDIT`, **IR-84** (the arm the rigs fire was the only one without a clock — same\n  shape: the leg that fires most is the one the instrument never covered), releases#287 (shells after\n  a restart), memory `an-empty-msg-from-tag-is-a-turn-trigger-whose-body-lives-in-the-spill`.\n- **Ripe when:** any lane touches `spt-daemon::inject` or the IO funnel; small enough to ride the\n  next product batch. · **Size:** one publish call at one chokepoint, one unit cell, one `int` leg\n  (a hook-hosted receiver woken by a `SENT`, then `io-events` replayed for the msg-id).\n\n### IR-93 — no PDB ships beside the installed `spt` binary, so the one non-invasive read of a wedged production daemon comes back without a single named frame\n\n- **Status:** OPEN, filed by doyle 2026-09-10. **The number was reserved by NAME on 2026-09-09** at\n  the #293 mechanism read (\"PDB ask -> IR-93 at next sweep\") and this entry closes that claim — a\n  name-only IR with no entry text is the exact gap [[IR-85]]'s status line had to spend a paragraph\n  explaining about IR-84, and it is not being left open a second time. · **Origin:** the #293 pump\n  wedge on hfenduleam.\n- **What was actually paid.** With the daemon wedged and unrecoverable, hertz's `cdb -pv -p 31856`\n  dump (2026-09-09 23:23:26-31Z, 4.79 s suspend, 35 threads, preserved at\n  `.spt/preserved/293-brain-stacks-20260909T232326Z/`) was the ONLY direct observation available of\n  the live wedged process — the pump had already stopped, so the suspend cost the fleet nothing it\n  still had. It came back **with NO SYMBOLS: there is no PDB beside the installed exe.** Both\n  pump-ipc-reader threads were visible in `SleepEx` and all 32 brain threads in Wait, but the frames\n  are addresses.\n- **The cost, stated at the strength it holds.** The mechanism was named anyway — from SOURCE reading\n  (`Brain::read_event()` unbounded at `brain.rs:1025-1027`, 17 in-brain loopers), not from the dump.\n  What the dump could not do is say **WHICH call site parked THAT instance**, and that remains NOT\n  ESTABLISHED. A symbolised dump is the one artifact that answers it directly, and the next wedge\n  will present the same choice with the same empty answer.\n- **Remedy:** retain and ship the PDB beside the installed binary (or publish a symbol store the\n  debugger can resolve against) so a production dump names frames. **Weigh it honestly at rider\n  time:** this is a packaging/size decision, and a release profile that emits no debug info is a\n  deliberate choice someone made — this entry is the bill for it, not a claim it was wrong.\n- **Kin:** [[IR-82]] (a daemon death leaves no record of who died — same family: the corpse is the\n  evidence and nothing preserves it), [[IR-84]] (the arm with no clock), [[IR-95]] (a budget that\n  cannot say how much it burned).\n- **Ripe when:** next installer / release-packaging touch. · **Size:** packaging (profile + install\n  layout), no product code.\n\n### IR-94 — xtask's brainread deadline gate cannot SEE `serve_sync`: its registry is three hand-listed files and its predicate is a name shape, so a stream server outside both got the reply form and the gate stayed green\n\n- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 / v0.69.0 golden RED triage. **This\n  is an INDEPENDENT gate finding, not the cause of that red** — it was found while reading the\n  milestone's diff and stands whatever Finding 1 turns out to be. · **Origin:**\n  `xtask/src/brainread.rs`, new this milestone (the #293 fix's zero-call-site guard).\n- **Mechanism, read at source.** The gate's REACH is two hand-authored narrowings stacked:\n  **registry = exactly three files** (`dispatch.rs`, `attach.rs`, `brain.rs`) and **predicate = a name\n  shape** (`starts_with(\"serve_\") && ends_with(\"_feed\")` or `== \"serve_attach\"`). `serve_sync` is a\n  stream server that lives in **no registry file** and whose name **escapes the pattern**, so it is\n  invisible on both axes at once. It therefore carries the **REPLY form — the exact form this gate\n  REJECTS for every stream server it can see — and the gate is GREEN.** An enforcement whose\n  population is enumerated by hand reports compliance over the set it can see, which is not the set\n  that matters.\n- **Why it is inert TODAY and why that is not reassuring.** The production carrier is unbounded:\n  `dispatch::connect()` (`dispatch.rs:898`) uses `Brain::cold_start` with `io_timeout: None`, so\n  `call_deadline()` is `None` and the read is unbounded regardless of which form the server carries.\n  **It becomes LATENT the day `serve_sync` rides a pump carrier** — which is precisely the direction\n  the #293 fix is moving the codebase. The guard will still be green on that day.\n- **Owned:** todlando has taken that his migration/census missed `serve_sync`'s lifetime semantics.\n  Recorded because the entry is about the GATE's reach, not about who missed it.\n- **Remedy shape:** derive the population from the **behaviour** (a fn that serves a stream) rather\n  than from the file it sits in or the name it happens to carry, and make the gate **FAIL on a server\n  it cannot classify instead of skipping it**. Add a census leg that PRINTS the population checked —\n  a count is what would have exposed a three-file registry at a glance.\n- **Kin:** [[IR-84]], `unbounded-brain-carrier-cannot-be-bounded` (memory — the carrier question that\n  makes this inert today), `REQ-BRAIN-READ-BOUNDED-PER-CALL`.\n- **Ripe when:** next `brainread`/xtask touch, **and mandatorily BEFORE `serve_sync` is migrated to a\n  bounded carrier.** · **Size:** small.\n\n### IR-95 — a burned polling budget names WHAT it wanted and never HOW LONG it waited, so no run, green or red, can say how close it came\n\n- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 golden RED, where it cost this\n  triage most of a morning and four agents. · **Origin:** the two Windows Phase A failures at\n  `a9e786b2`, both polling budgets burned rather than value mismatches.\n- **The two sites, read at source.** They are not even the same KIND of budget, which is the first\n  thing no reader can tell from the panel:\n  · `crates/spt/tests/contract_e2e.rs:393-407` — a **WALL** deadline,\n  `let deadline = Instant::now() + Duration::from_secs(30)`, panicking\n  `\"the brain pulse must ingest the commune into the live context tier\"`. **No elapsed.**\n  · `crates/spt-daemon/tests/sync.rs:98-110` — an **ITERATION** budget, `for _ in 0..400 {\n  net_streams(); sleep(25ms) }`, panicking `\"sync stream never appeared at the responder's broker\"`.\n  **No elapsed, no iteration count** — and its own comment calls it a \"10s budget\", which is a\n  NOMINAL sum of sleeps, not a wall bound: each `net_streams()` IPC call adds to it (hertz), so on a\n  loaded box the wall it grants is unknown and larger.\n- **Four costs MEASURED in this one triage, each traceable to the missing clock:**\n  1. **The panic reads as a CONTENT claim.** `contract_e2e.rs:403`'s message is what a 30 s DEADLINE\n     EXPIRY prints, and doyle relayed it to three peers as \"a clean content assert, not a stall\"\n     before opening the source.\n  2. **History cannot supply margins at all.** nextest suppresses passing output by default, so\n     **eight consecutive goldens** of this cell's Windows durations exist and **not one carries an\n     internal margin**. (`--success-output immediate` retains it — so this is recoverable going\n     forward, and was not, going back.)\n  3. **A whole-test total cannot locate the poll inside the test.** This conflation was committed\n     **five times in forty minutes by three different agents** — deployah twice (retracted both),\n     doyle once *in the message correcting deployah for it*, and it was caught each time by todlando\n     and hertz. A defect that costs three careful agents five errors in one morning is not a people\n     problem; the number they needed was not printed anywhere.\n  4. **A FAIL and a PASS are not the same quantity.** `wait_for_stream_except` is called at\n     `sync.rs:201`, with `serve_sync`, the puller join and every assertion AFTER it — so a failing\n     run **truncates** there. This cell FAILED at 58.77 s and PASSED at 61.304 s, and that 2.5 s gap\n     carries no information in either direction. It was read as an anomaly (\"it took LESS time and\n     still failed\") until the call site was opened.\n- **Remedy:** on expiry, print **elapsed, the budget, and iterations consumed**; where the poll waits\n  on another party, print that party's **PRODUCER PROGRESS** too — a watcher's own timings cannot\n  separate a slow watcher from a slow producer (hertz, todlando), which is the single fact this\n  triage most needed and could not get. Keep the content sentence; it is the panic's `{what}`, not\n  its whole body.\n- **Population CENSUSED 2026-09-10 (doyle), discharging the census this entry declared OWED — 323\n  poll sites detected, 304 of them classified blind. SUPERSEDED 2026-09-10 by the validation\n  below: 317 blind of a 321-site population, and the census's own coverage measured.** Read-only, run beside golden diagnostic 34458491560\n  without dispatching anything to either runner. Preserved with its method, its raw classification\n  and its discarded first attempt at `.spt/preserved/ir95-poll-census-20260910/`.\n- **Method, deliberately WORDING-INDEPENDENT.** Over the 212 tracked `*.rs` files under\n  `**/tests/**` plus `xtask/`, take every loop by SHAPE — `for _ in 0..N`, `while Instant::now() <\n  deadline`, `while <x>.elapsed() < budget`, bare `loop {` — keep it only if it SLEEPS (a poll, not\n  a spin) and can FAIL (`panic!`/`assert!`/`expect(`/`bail!` on its exit path), then ask whether its\n  failure path emits a MEASURED VALUE (`.elapsed()`, `.as_millis()`, an iteration counter). **String\n  literals are stripped before that question is asked**, so the word \"budget\" inside a panic message\n  cannot credit itself with a clock. **Result: 323 sites, 19 apparently clocked, 304 blind.**\n- **304 of 323 DETECTED CANDIDATES CLASSIFIED BLIND — a classifier count, NOT a proven floor.**\n  Stated at that strength on hertz's and todlando's correction of a stronger form this entry\n  briefly carried. What was actually spot-checked is the CLOCK bucket, and both errors found there\n  ran the same direction, undercounting blindness: `brain_read_deadline.rs:87` was credited from\n  elsewhere in the read window while its real failure path is `panic!(\"whole-carrier brain never\n  connected to {name}\")`, carrying no clock at all; `er_briefing_presented_e2e.rs:310` returns\n  `Some(started.elapsed())` on SUCCESS and a bare `None` on expiry.\n- **What that does NOT license.** Finding only false-CLOCK errors does not exclude false-BLIND ones,\n  and nothing here establishes POPULATION COVERAGE — whether the four loop shapes catch every poll\n  in the corpus is unvalidated, so a poll expressed as a helper, a retry combinator or an iterator\n  chain is uncounted and unmeasured. **No repository-wide `>= 94%` claim is made and none should be\n  repeated from this entry.** The honest sentence is: 304 classified BLIND among 323 detected\n  candidates, with the checked errors so far undercounting blindness. Validating both buckets and\n  the population is owed before any bound is asserted.\n- **VALIDATED 2026-09-10 (doyle) — all three owed checks discharged; the headline figure MOVES to\n  317 blind of 321.** Preserved as `VALIDATION.md` beside the census (machine-bound per [[IR-90]]).\n  (1) **The CLOCK bucket is now adjudicated EXHAUSTIVELY, not spot-checked**: of 19, only **4** emit\n  a measured value on their own expiry path, **13 were FALSE CLOCKs** and move to BLIND, and **2 are\n  not poll-failure sites at all**. Two mechanisms cover all 13, neither of them a wording problem:\n  **window bleed** (7 — four credited by a `const CONVERGE_BUDGET: Duration = …as_millis()…`\n  *declaration* 20-25 lines BELOW a bare `panic!(\"brain could not connect\")`, one by a different\n  loop 57 lines away, two by an unrelated `now_ms()` helper) and **condition-use, not emission** (6 —\n  `assert!(started.elapsed() < Duration::from_secs(30), \"…viewer_count={count:?}\")` reads the clock\n  in the PREDICATE and omits it from the MESSAGE). Stripping string literals stopped a message\n  crediting itself; it does not stop CODE crediting a site whose message stays silent.\n  (2) **False-BLINDs checked at last — a seeded 30-site random sample of the BLIND bucket\n  (`random.seed(95)`), hand-adjudicated: 30 of 30 confirm BLIND, zero false-BLIND.** By the rule of\n  three that bounds the false-BLIND rate at **<= ~10%, at 95% confidence** — a binomial upper bound\n  assuming the 30 are a simple random sample of the 304 and each site's adjudication is independent;\n  it is **not a deterministic guarantee**, and zero errors in 30 excludes nothing outright (hertz).\n  This is the FIRST check run in the\n  direction that would REDUCE the blind count and it found nothing; every error found in either\n  bucket still runs the other way.\n  (3) **Population coverage, measured against every `sleep` in the corpus** — 472 call-sites, 349\n  inside a detected window, 75 one-shot settles in no loop. The remaining 48 dedup to 47 loop\n  headers and **every one is explained, 0 unexplained**: **32** matched a census shape but cannot\n  FAIL within 60 lines (excluded BY DESIGN — the census counts loops that wait AND can fail), and\n  **15 are the detector's true false negatives**, a fixed nameable set:\n  `while std::time::Instant::now() < deadline` (the PATH-QUALIFIED spelling — the regex demands a\n  bare `Instant::now()`; `broker.rs:389`, `shellchan.rs:114`), `while !stop.load(Ordering::Relaxed)`,\n  `while <predicate>(…)` (`shell_relink_force_e2e.rs:194/241`, `shell_stale_online_e2e.rs:146`,\n  `redispatch.rs:269`), and one `for (a, b) in [...]`. Those 15 stay UNCLASSIFIED.\n  **The 32 change how this census may be QUOTED:** \"323 poll loops that wait and can fail\" silently\n  excludes 32 loops that wait and CANNOT fail at the poll — a defensible scope, but a scope, and the\n  sentence must carry it.\n- **Restated census, and the form to quote.** **321** sites in the adjudicated population (323 minus\n  2 membership errors from the CLOCK bucket; a 3rd — `net_worker_starve.rs:99`, a fixed-window\n  SAMPLER that always runs its window and has no expiry failure — turned up in the BLIND sample, so\n  3 errors in 49 hand-adjudicated sites means the population carries ~6% slop and **321 is not\n  exact**). **317** classified BLIND. **4** report a measurement. **15** poll loops outside the\n  detector's reach, unclassified. **Still not established, and still not to be written: that 317 is\n  a FLOOR, or any repository-wide rate.** One direction is now exhaustive, the other bounded at\n  <=10% by a 30-site sample — a bounded estimate, never a floor, and silent about the 15.\n- **A distinction this validation surfaced, and the remedy above should carry: \"emits a clock\" is\n  TWO different things.** `transport_death_eof.rs:540` prints the OBSERVED quantity\n  (`{canary_after}ms`); `er_brief_once_per_session_e2e.rs:288` prints the MARGIN (`elapsed=`). Only\n  the second tells a reader how close the budget came. 3 of the 4 surviving CLOCK sites report a\n  margin, 1 reports an observation — and **a binary CLOCK/BLIND classifier cannot see that\n  difference**, which is a limit of the census, not of the sites.\n- **One edit to preserved evidence, DECLARED.** `census.py` printed `<-- IR-95 population (a FLOOR)`\n  on its blind line. That sentence was retracted the day it was written, but the retraction never\n  reached the SCRIPT, so re-running the preserved artifact reprinted the withdrawn claim at whoever\n  ran it — a retraction does not propagate to the next reader on its own. The LABEL, and only the\n  label, is corrected in place; the computation is untouched and **still reproduces 323 / 19 / 304**,\n  which is what makes this validation checkable against it. The old line is quoted verbatim in\n  `VALIDATION.md`.\n- **A FIRST detector was discarded, and its failure is itself evidence for cost 1 above.** Keying on\n  expiry VOCABULARY (\"never\", \"timed out\", \"did not appear\") found 53 sites and **missed\n  `contract_e2e.rs:393` entirely — the very site this entry was filed from** — because its panic\n  message is a CONTENT sentence. A wording-keyed census is structurally blind to exactly the sites\n  whose messages mislead. Recorded so no one re-runs the cheap version and reports 53 as the answer.\n- **Positive control passes, and it found siblings.** Both originating sites appear, both BLIND:\n  `sync.rs:102` and `contract_e2e.rs:395`. The census also surfaced **two fixed budgets nobody had\n  noticed** — `sync.rs:89` (`0..300`, beside the `0..400` at :102) and `contract_e2e.rs:51`\n  (`0..400`, beside the wall deadline at :393). Concentration: `inject_control_wedge.rs` 18,\n  `broker.rs` 10, `endpoint_lifecycle.rs` 9, `dispatch.rs` 7, `twohost.rs` 7.\n- **PRODUCER-PROGRESS INSTRUMENT — SPEC, 2026-09-10, and the three readings it does NOT support.**\n  The remedy above asks for the waited-on party's progress because a watcher's own timings cannot\n  separate a slow watcher from a slow producer. `last_streams_seen=0` throughout is equally\n  consistent with \"the producer never produced\" and \"the watcher never saw it\", and neither arm of\n  the releases#294 pair can tell those apart. **Design (doyle), narrowed by hertz and todlando, who\n  independently found the same three defects in the first form of it.**\n  **INSTRUMENT** — rides the IPC the poll ALREADY makes, so it adds no channel and no budget: the\n  responder's broker surfaces, alongside `net_streams`, a monotonic `streams_created_total` AND a\n  monotonic `streams_retired_total` for the session, the sequence and age of its last transition,\n  and the STREAM IDS of the most recent transitions so the watcher can correlate them against the\n  ids it sees and skips. The watcher prints the producer's counters beside its own observation.\n  **SEMANTICS THAT MUST BE DECLARED BEFORE A SINGLE READING IS TAKEN** — a bare count is not a\n  measurement until these are fixed: WHICH HOOK \"created\" fires at (broker stream-table\n  registration? wire acceptance?), WHICH KEY the counter is scoped to and what a session rotation\n  does to it, the COUNTER LIFETIME and reset behaviour (process lifetime, per session, what a broker\n  restart does), and WHICH CLOCK the age is measured against and whether it is comparable to the\n  watcher's.\n  **WHAT EACH READING LICENSES, and what it does NOT** (the first form of this table asserted three\n  causal conclusions it had not earned):\n  · `created=0` at expiry means **no creation was RECORDED AT THAT HOOK, in that counter's scope,\n    for that session key**. It does **NOT** establish that the requester never produced, and it does\n    **NOT** exonerate the watcher — the hook may sit downstream of the real production, or be scoped\n    to a different key.\n  · `created>0` with every snapshot empty is **CONSISTENT WITH a visibility/registration defect AND\n    with a stream being created and retired entirely between two 25 ms polls**. On its own it\n    establishes neither; the retire counter and the ids are what separate them.\n  · **Creation AFTER expiry cannot be observed by a poll that has already stopped.** A last-change\n    age cannot supply it. That needs either a separately bounded, separately declared post-expiry\n    observation, or a retained producer event trace with timestamps.\n  **Process constraints:** separately versioned and announced, never slipped between arms of a\n  comparison, and the existing diagnostic patch and every budget stay UNCHANGED. Widening a budget\n  to make a red go green remains refused.\n- **`last_streams_seen` IS A FILTERED-VIEW COUNT — the sharpest narrowing this field has had, and it\n  applies to all three expiries in the releases#294 pair.** The poll calls `net_streams`; the broker\n  answers at `broker.rs:9546` `dispatch_net_streams` -> `host.dispatch_stream_infos()`\n  (`nethost.rs:1952`) -> `stream_infos_filtered(FALSE)`, and that filter drops TWO classes\n  SERVER-SIDE, before serialization (ADR-0040 decision 2, `REQ-STREAM-INFOS-SERVER-FILTER`):\n  `!e.retired.load(SeqCst)` and `!e.initiated_locally`. So `last_streams_seen=0` does **NOT** mean\n  the broker held no streams. It means **zero NON-RETIRED, NON-LOCALLY-INITIATED rows at that\n  instant** — a row that exists and is retired is invisible to the poll BY DESIGN. That is narrower\n  than the corrected form the RCA had settled on (\"the final snapshot was empty\"), and it is a\n  hook-scope fact of exactly the kind the preconditions above demand be pinned before any reading.\n- **A \"reuse it, no product change\" stage-1 design WAS PROPOSED AND IS WITHDRAWN — recorded because\n  the reason generalises.** `NetHost::stream_counts()` (`nethost.rs:1980`) is already surfaced as\n  `NetStatusReply.streams_held` (`broker.rs:9002`, `msg.rs:874`) and documents itself as\n  \"retirement-blind ON PURPOSE ... the resource truth the eligibility view hides\". Reading it beside\n  `net_streams` looked like it would separate \"filtered out\" from \"absent\" for free. It does not,\n  for four reasons, and hertz and todlando raised them independently:\n  · **Two IPC replies are not an atomic snapshot.** `filtered=0` then `held>0` is equally consistent\n    with a row ARRIVING BETWEEN THE TWO CALLS. Such a pair must never be labelled proof of filtering,\n    and needs call order and timestamps recorded if it is read at all.\n  · **`streams_held` is HOST-SCOPED, not exchange-scoped.** It counts unrelated and locally-initiated\n    rows the filtered view drops, so it cannot speak to the exchange under investigation without\n    stream-ID correlation; any conclusion from it stays aggregate.\n  · **It adds UNMEASURED perturbation** — a second IPC per iteration changes the 400-iteration\n    window's wall duration by an amount nobody has measured. **CORRECTED 2026-09-10 (hertz,\n    todlando), because the first form of this bullet was itself an overclaim in two ways and both\n    are instructive:** (a) it called perturbation DISQUALIFYING, and it is not — instrumentation\n    that perturbs timing can still be useful; the objection is ADDED, UNMEASURED perturbation, not\n    perturbation as such. (b) It SIZED that perturbation from two figures that cannot carry it: the\n    measured `net_streams` cost (60,295 us / 400 = 0.151 ms per iteration) does **not** estimate the\n    `net-status` cost — different call, different work — and the **0.29% expiry difference between\n    the two arms is NOT an established causal effect size**, only an unexplained gap between two n=1\n    observations. Sizing an observer effect against it treats an open question as a known\n    quantity.\n  · A single POST-EXPIRY sample avoids perturbing the poll but then describes LATER state, not\n    expiry state, and is still host-scoped.\n- **THE INSTRUMENT THAT SURVIVES REVIEW: a retained, EXCHANGE-CORRELATED create/retire TRACE**\n  (hertz and todlando, converged independently). Recorded per stream lifecycle transition on the\n  producer side — stream id, conn id, remote id, transition, `initiated_locally`, a monotonic\n  sequence and a timestamp on a NAMED clock — retained and read AFTER the fact rather than sampled\n  by the watcher, so it adds **NO POLL CALLS**. Say that, and not \"adds nothing\" (hertz): it still\n  adds PRODUCER-SIDE work that may affect arrival timing and resource contention, and **that effect\n  is unmeasured too**. The trace is preferable for having no watcher IPC, not for being free. It captures between-poll transitions,\n  which neither a gauge nor an in-loop counter can: **a gauge reads 0 for a stream created and\n  retired between two 25 ms polls exactly as it does for one never created.** Correlation to the\n  exchange is by stream id against the ids the watcher saw and skipped.\n  **MEASURED: it does not exist today** — zero stream-lifetime log lines in `nethost.rs`. So this is\n  a PRODUCT change, not a reuse, and it stays unbuilt while the product is frozen. Its preconditions\n  are the ones above, unchanged. Production AFTER the trace's retention window remains outside it.\n- **THE FIRST MARGINS THIS ENTRY PRODUCED UNDER CI / GOLDEN CONDITIONS — instrumented run\n  34458491560, 2026-09-10\n  (hertz's patch; deployah's lane; read independently by doyle).** The remedy above was argued for\n  on the ground that a poll which prints nothing cannot say how close it came. It has now printed\n  on a runner. **NOT the first margins overall** — the earlier local 12-leg run already reported\n  them, including a 392/400 (hertz, todlando). **The genuinely novel quantity is narrower and\n  sharper than \"CI margins\" (deployah): it is a FAILING poll's margin, which no local leg could\n  produce because all 12 of them PASSED.** A budget's behaviour at expiry is the one thing a green\n  run structurally cannot report, and it is the case the remedy exists for.\n  **The figure is the MAXIMUM AMONG SUCCESSFUL polls in this run — explicitly NOT a ceiling, and not\n  a bound on observations**: the poll that EXPIRED in this same run consumed 400/400 = 100%. So:\n  among the polls that PASSED on hfenduleam, both instrumented sites peak at ~63% of budget. The\n  seven successful\n  `[IR95-SYNC]` waits in that run are 92, 19, 72, 254, 21, 21 and 20 iterations — **worst 254/400 =\n  63.5%** (6.449393 s) — and the `[IR95-CONTRACT]` success consumed **18.857089 s of its 30.000 s\n  wall = 62.9%**. Two independent sites, two different budget KINDS, the same maximum-among-passes.\n  Headroom at that worst SUCCESSFUL case ~37%; the failing case had none left. **n=7 and n=1, one\n  box, one run: a first CI measurement, not a stability claim, and NO budget change is proposed on\n  it.**\n- **The iteration budget's WALL EQUIVALENT, also measured for the first time.** The expiring poll's\n  400 iterations cost **10.199907 s against 400 × 25 ms = 10.000 s nominal — 2.0% over**, with\n  per-iteration overhead ~0.5 ms against a 25 ms sleep (IPC 60.295 ms total, 0.151 ms per iteration,\n  **0.59% of elapsed**; sleep is 99.4%). So on this box in this run a \"400 iteration\" budget and a\n  \"~10.2 s wall\" are nearly the same object — the iteration budget did NOT silently become a\n  different budget under load. That bounds one standing worry about blind iteration counts, and it\n  is precisely the class of thing that stops being guessable the moment a clock prints. Box-local\n  and run-local; it is not a general result.\n- **A scope limit the instrumentation itself imposes, and a smaller ask than it first looks.**\n  `last_streams_seen` is an ASSIGNMENT per iteration (`sync.rs:111`), not an accumulator, so\n  `last_streams_seen=0` at expiry describes the FINAL iteration only — not all 400 (todlando's\n  correction; deployah withdrew the aggregate reading, doyle confirmed it at source). But the loop's\n  CONTROL FLOW already proves the interesting half for free: the `find()` at `:113` returns the\n  instant a non-skipped stream appears, so **reaching the expiry print IS proof that no non-skipped\n  stream was seen in any of the 400 SNAPSHOTS** — no aggregate trace required. **It does NOT mean\n  no stream EXISTED between snapshots** (hertz): the poll samples at 25 ms, and nothing here\n  observes the gaps. What is genuinely\n  unmeasured is only whether a SKIPPED stream was ever present, and `skip` is empty on that call.\n  An aggregate/per-iteration trace therefore buys less here than the gap first suggests.\n- **NOT ESTABLISHED: that all 304 deserve a clock.** The census SIZES the problem; it does not\n  schedule it, and it does not pre-judge which sites are worth the edit. Remedy triage is owed\n  separately and is the larger half.\n- **Kin:** [[IR-84]] (the one `PUMP_PEER_FAIL` arm the rigs fire was the only one carrying no clock —\n  **the same class in product code**; this entry is its test-corpus face), [[IR-85]] (budgets sized\n  against a box whose speed moved), [[IR-77]] (nothing stamps the spawn-to-first-log interval, so a\n  readiness red cannot say where the time went), [[IR-90]].\n- **Ripe when:** with the releases#294 instrumented base-vs-head comparison, which **cannot be run\n  without it** — the experiment's whole output is the margins these sites do not print. ·\n  **Size:** small per site; the census is the larger half.\n\n### IR-96 — the `daemon_stop_convoy_e2e` API-storm cell fails 3-of-3 under the HEAVY suite at the diagnostic tree while passing at the candidate in golden CI, and nothing yet separates instrumentation from box from product\n\n- **Status:** OPEN, **cause-unclassified** (todlando's and hertz's stipulation, adopted verbatim — a\n  triage placement here is NOT a finding of non-defect).\n…\n\n\n[Showing lines 5481-5930 of 6937. Use :5931 to continue]"}],"details":{"truncation":{"content":"\r\n### IR-92 — the message that WAKES an idle spt-hosted endpoint rides a delivery leg that never publishes MSG_IN, so a woken agent's own funnel holds none of the messages that woke it\r\n\r\n- **Status:** OPEN — filed doyle 2026-09-09 from hertz's census, probe and proposed text (his by\r\n  role; the recorder read and the REQ reading are doyle's). Fix lane unassigned: product change in\r\n  `spt-daemon` (todlando), test-side legs (hertz). · **Origin:** a 22:35Z empty `<msg from=\"hertz\"/>`\r\n  turn trigger after the #292 daemon restart, chased for its body; the body was in a spill file, and\r\n  the chase exposed that neither agent's io-events log held the messages that woke it.\r\n- **Release reconciliation, 2026-09-11 (source read at `e5a2fed9`):** core PR **#215 is\r\n  DOCS-ONLY**. Its merge and v0.69.0 ship-fact record (comment 5628532753) discharge the\r\n  **register rider**, not this product remedy. Core #217 is the separate #293 brain-read\r\n  census, not an inject-edge fix. `try_spt_hosted_inject` still returns the result of\r\n  `brain.inject_endpoint` without publishing `MSG_IN`. **IR-92 stays OPEN.** Carry the\r\n  observation-only chokepoint remedy into the next product intake (todlando product ownership,\r\n  hertz test ownership); neither offline owner's execution is implied by that assignment.\r\n- **THE TWO PUBLISH SITES ORDER THEMSELVES OPPOSITELY — read at `de5a44bc`, 2026-09-10, from the\r\n  bare-baseline red on `io_events_undriven_kinds_e2e` (golden 34467873057, Linux Phase A).** The\r\n  count below is right and the ORDERING is what this entry was missing:\r\n  · **PATH A, hook poll** (`delivery.rs`): `poll_drain()` publishes EVERY delivered row (`:757`) and\r\n    RETURNS them; its only caller `cmd_poll` (`:660`) then loops `emit_event` over the returned rows.\r\n    **Publication happens-before presentation**, strictly. An immediate log read after observed\r\n    presentation is CONTRACT-CORRECT here, and a bounded retry on this path WOULD conceal a real\r\n    violation. **Leave Path A alone.**\r\n  · **PATH B, the relay** (`startup.rs:1057`, the `deliver` closure): `emit(id, from, body)` — the\r\n    presentation — runs, and `publish_msg_io(...MSG_IN...)` runs AFTER it, per message, in the same\r\n    closure; the closure's own comment records that \"Both backlog (after notif validity) and live TCP\r\n    reach this edge.\" **Presentation happens-before publication.**\r\n  A test that detects presentation by reading the listener child's STDOUT through a pipe and then\r\n  reads the io-events log immediately is therefore **racy BY CONTRACT on Path B** — publication for\r\n  that message runs after its emit, in the child, and the pipe read can win. A bounded wait on the\r\n  log is permitted on Path B: **it does not weaken any publication-before-presentation guarantee\r\n  there, because there is none** (hertz's and todlando's narrowing — NOT \"conceals nothing\": the\r\n  wait still DEFINES WHICH PUBLICATION DELAYS THE TEST ACCEPTS, and it does not establish why any\r\n  given execution missed a row). A timeout would establish \"not published within the bound\", never\r\n  \"never publishes\", and cannot alone identify this entry's defect.\r\n- **A SECOND, INDEPENDENT DEFECT IN THAT CELL'S ASSERTION, true regardless of the above.**\r\n  `io_events_undriven_kinds_e2e.rs:818` asserts exact-once as\r\n  `vec![(\"MSG_IN\", Some(AUTHOR)), (\"MSG_IN\", Some(AUTHOR))]` — a `(kind, author)` pair per row, and\r\n  **both rows are identical**, so the assertion cannot tell the backlog row from the live row and\r\n  **two BACKLOG rows would satisfy it**. The identities exist and are already stamped:\r\n  `publish_msg_io_local` carries `.with_msg_id(msg_id_of(body))` — the short ID the failing panel\r\n  itself printed. Exact-once belongs per MESSAGE ID, not per author.\r\n  **AND IT CUTS BACKWARDS, WEAKENING EVERY GREEN THIS CELL HAS EVER RETURNED (deployah, on\r\n  arm-comparability grounds — the point nobody else had drawn):** the three PASSING executions of\r\n  this cell in the instrumented pair (base linux 3.612 s, head linux 2.343 s, head windows 16.411 s)\r\n  did **NOT** establish that both relay arms published. They established that two rows matching\r\n  `(MSG_IN, alice)` were present at read time. A green here is a WEAKER fact than it reads as — the\r\n  verdict stands in for a measurement the assertion never made. So \"both Linux legs were green\r\n  across the instrumented pair\" does not become FALSE, it becomes NARROWER than it was being used\r\n  for: it is a statement about the ASSERTION's outcome, not about publication. It does **not** make\r\n  the bare red likelier to be a product defect, does not classify anything, and does not separate\r\n  the race from non-publication — it removes a comparison the RCA was implicitly leaning on.\r\n  (Raised independently by hertz and todlando as an assertion defect; its backwards consequence for\r\n  the greens is deployah's.)\r\n- **Status of that red: UNEXPLAINED between DELAYED and ABSENT publication.** Path B makes the race\r\n  MECHANICALLY AVAILABLE, which is more than \"not excluded\" — but availability is not occurrence,\r\n  and one observation does not separate them. Kinship to this entry stays a HYPOTHESIS. The cell is\r\n  in neither `docs/FLAKE-LEDGER.md` nor this register (0 hits each): an unregistered signature.\r\n- **The mechanism, read at `de5a44bc`:** `MSG_IN` has exactly two publish sites in the tree —\r\n  `crates/spt/src/api/delivery.rs:757` (`publish_msg_io_local`, reached only from `poll_drain`, the\r\n  hook-poll leg, `TakerLeg::HookPoll`) and `crates/spt/src/api/startup.rs:1064` (`publish_msg_io`\r\n  inside the `api listen` relay's `deliver` sink — the Monitor-stream surface a hook-hosted session\r\n  never uses). **The spt-hosted inject leg reaches neither.** `crates/spt-daemon/src/inject.rs:75`\r\n  `try_spt_hosted_inject` renders the envelope and hands it to `brain.inject_endpoint`; the file has\r\n  zero `publish_msg_io` / `iobus` / `IO_KIND_MSG_IN` references in 343 lines (control: `TakerAudit`\r\n  / `claim_idle_edge_at` hit, so the grep is live). Every caller delivers through it unobserved:\r\n  `cli.rs:11739` send-time direct inject when the broker reports the target IDLE (the sender is\r\n  answered `SENT`), `cli.rs:11684` `--force-native`, `inject.rs:168` `drain_spool_offering` (the\r\n  idle-EDGE drain `delivery.rs:801`, the send-time already-idle re-offer, the pulse-tick belt, and the\r\n  native ER-briefing arm), and `wan.rs:822` / `:1173` WAN ingress. Two more drain edges are silent by\r\n  the same shape and did not fire here: `cmd_poll_shell` (`delivery.rs:705`, shell surface) and\r\n  `cmd_worker_poll` (`worker.rs:138`, worker surface). A call-site grep would have marked `relay.rs`\r\n  silent too — it publishes through its sink one crate up — so \"does this edge observe\" is answered\r\n  by following the row to a bus, never by grepping the edge.\r\n- **The rule it produces (hertz's refinement, measured across both logs):** for a hook-hosted live\r\n  agent (`is_spt_hosted_no_relay`), **`SENT` to an idle peer → direct inject → NEVER recorded on\r\n  the peer** (deterministic). **`QUEUED` → recorded IFF the hook poll takes the row.** One stamped\r\n  census, **as of 23:04Z 2026-09-09** (the counts grow with every message, so an unstamped figure is\r\n  stale on arrival): SENT-to-idle unrecorded on the receiver **12/12** (hertz’s five to doyle, doyle’s\r\n  seven to hertz — the seventh being the message that announced this filing, delivered by the defect\r\n  it named); QUEUED recorded **8/8**, every one drained mid-tool. Each side’s absence census matched\r\n  the other side’s verdict log without either seeing the other’s data.\r\n  by the caller census a spooled row can also be taken by the send-time already-idle re-offer or the\r\n  pulse-tick belt (`inject.rs:168`, unrecorded), so a `QUEUED` row’s fate is decided by the TAKER,\r\n  not the verdict — that arm was not observed tonight and stays a prediction.\r\n- **Measured, hfenduleam 2026-09-09, both full streams read end to end, same 23:04Z stamp:** hertz’s\r\n  log (through seq 1812): the messages that arrived as turn triggers (`UserPromptSubmit`, idle) — **7/7\r\n  unlogged**; those that arrived mid-tool (`PreToolUse`, busy) — **4/4 logged**, msg-id present,\r\n  `<LAST_MSGS>` clock moved (doyle's 22:55Z probe was `QUEUED`, drained mid-Bash, logged as 1804).\r\n  His \"zero `MSG_IN` since 14:02:34Z\" was **not a state change**: 1633 at 14:02 was the last message\r\n  that happened to catch him inside a tool call; everything after found him idle. doyle's log (1,121\r\n  events): PACER-0 **7 received / 6 logged**, the missing one `G4NK5FFT` being the row that woke the\r\n  session; hertz’s five `SENT` wake messages **absent entirely** and his four `QUEUED` ones **present\r\n  4/4**, each drained mid-tool; riders in the same spill (1856/1857 beside the promoted 1855;\r\n  `3NGTHQHN` beside a task-notification trigger) logged. One variable moved.\r\n- **Scope, corrected once (hertz struck his own \"bilateral\" clause on doyle's control):**\r\n  receiver-side only. The sender's `MSG_OUT` rows are intact on both sides, so an exchange IS\r\n  reconstructible from the **peer's** log — but not from the woken agent's own, which is the surface\r\n  a post-reset agent reads. hertz re-grounded his 22:36 session off seq 1786 of a log that holds his\r\n  half of every exchange since 14:02 and none of doyle's; a replay of an idle-woken agent shows its\r\n  own outbound answering nothing, and the last-received clock skips exactly the moments the peer was\r\n  talking, which reads as \"peer gone quiet\".\r\n- **Against the requirement's own words:** `REQ-IO-MSG-EDGES` (activated, `doc`/`impl`/`unit`)\r\n  states that \"MSG_IN publishes where core **delivers or injects** an inbound one, so the funnel\r\n  observes the edges rather than growing a parallel notion of what a message is\". This is not a case\r\n  the requirement failed to anticipate: **its own second clause is unimplemented** while `impl` and\r\n  `unit` read green on the first. The inject edge was never given a publisher when F-023 (idle-edge\r\n  drain), W5 (parked re-offer) and the WAN ingress added takers; the unit cell at `delivery.rs:1251`\r\n  pins the poll leg only, so the coverage the registry reports is green on two edges and vacuous on\r\n  the one the requirement names by verb.\r\n- **Remedy, and where it must sit:** publish `MSG_IN` **inside `try_spt_hosted_inject` on\r\n  `Some((true, _))`** — the one chokepoint all four callers share — so no caller can deliver\r\n  unobserved; a fix placed in `drain_spool_offering` would leave the send-time direct inject and WAN\r\n  ingress silent. Keep it observation-only (REQ-IO-EVENT-BUS): the inject verdict must not depend on\r\n  the bus. The unit cell to add mirrors `delivery.rs:1251`: an injected row owes exactly one\r\n  `MSG_IN`, a refused inject owes none. Post-hoc census of what was lost: spooled rows carry\r\n  `TakerLeg::IdleInject` / `NativeInject` in the audit column (REQ-SPOOL-TAKE-AUDIT); direct injects\r\n  never spooled and are enumerable only from the sender's `MSG_OUT`.\r\n- **OPEN, unranked, not smoothed:** doyle's pre-clear 1855 got a **bodiless** `USER_INPUT msg\r\n  from=\"hertz\"` row (the `api state busy` payload path, `delivery.rs:115` `state_io_kind`) while his\r\n  post-clear five got **no row at all**. Both are wake-delivered; the difference is downstream of\r\n  this gap, in what the adapter passed as the state payload, and is not this entry's mechanism.\r\n  Also out of scope, perri's surface: the claude-spt overflow notice names spills of the CURRENT\r\n  session id only, so the last spill before a `/clear` is never named again (how the 22:35Z body\r\n  went unread in the first place).\r\n- **Kin:** `REQ-IO-MSG-EDGES`, `REQ-MSG-IDLE-EDGE-DRAIN`, `REQ-IDLE-PARKED-DELIVERY`,\r\n  `REQ-SPOOL-TAKE-AUDIT`, **IR-84** (the arm the rigs fire was the only one without a clock — same\r\n  shape: the leg that fires most is the one the instrument never covered), releases#287 (shells after\r\n  a restart), memory `an-empty-msg-from-tag-is-a-turn-trigger-whose-body-lives-in-the-spill`.\r\n- **Ripe when:** any lane touches `spt-daemon::inject` or the IO funnel; small enough to ride the\r\n  next product batch. · **Size:** one publish call at one chokepoint, one unit cell, one `int` leg\r\n  (a hook-hosted receiver woken by a `SENT`, then `io-events` replayed for the msg-id).\r\n\r\n### IR-93 — no PDB ships beside the installed `spt` binary, so the one non-invasive read of a wedged production daemon comes back without a single named frame\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-10. **The number was reserved by NAME on 2026-09-09** at\r\n  the #293 mechanism read (\"PDB ask -> IR-93 at next sweep\") and this entry closes that claim — a\r\n  name-only IR with no entry text is the exact gap [[IR-85]]'s status line had to spend a paragraph\r\n  explaining about IR-84, and it is not being left open a second time. · **Origin:** the #293 pump\r\n  wedge on hfenduleam.\r\n- **What was actually paid.** With the daemon wedged and unrecoverable, hertz's `cdb -pv -p 31856`\r\n  dump (2026-09-09 23:23:26-31Z, 4.79 s suspend, 35 threads, preserved at\r\n  `.spt/preserved/293-brain-stacks-20260909T232326Z/`) was the ONLY direct observation available of\r\n  the live wedged process — the pump had already stopped, so the suspend cost the fleet nothing it\r\n  still had. It came back **with NO SYMBOLS: there is no PDB beside the installed exe.** Both\r\n  pump-ipc-reader threads were visible in `SleepEx` and all 32 brain threads in Wait, but the frames\r\n  are addresses.\r\n- **The cost, stated at the strength it holds.** The mechanism was named anyway — from SOURCE reading\r\n  (`Brain::read_event()` unbounded at `brain.rs:1025-1027`, 17 in-brain loopers), not from the dump.\r\n  What the dump could not do is say **WHICH call site parked THAT instance**, and that remains NOT\r\n  ESTABLISHED. A symbolised dump is the one artifact that answers it directly, and the next wedge\r\n  will present the same choice with the same empty answer.\r\n- **Remedy:** retain and ship the PDB beside the installed binary (or publish a symbol store the\r\n  debugger can resolve against) so a production dump names frames. **Weigh it honestly at rider\r\n  time:** this is a packaging/size decision, and a release profile that emits no debug info is a\r\n  deliberate choice someone made — this entry is the bill for it, not a claim it was wrong.\r\n- **Kin:** [[IR-82]] (a daemon death leaves no record of who died — same family: the corpse is the\r\n  evidence and nothing preserves it), [[IR-84]] (the arm with no clock), [[IR-95]] (a budget that\r\n  cannot say how much it burned).\r\n- **Ripe when:** next installer / release-packaging touch. · **Size:** packaging (profile + install\r\n  layout), no product code.\r\n\r\n### IR-94 — xtask's brainread deadline gate cannot SEE `serve_sync`: its registry is three hand-listed files and its predicate is a name shape, so a stream server outside both got the reply form and the gate stayed green\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 / v0.69.0 golden RED triage. **This\r\n  is an INDEPENDENT gate finding, not the cause of that red** — it was found while reading the\r\n  milestone's diff and stands whatever Finding 1 turns out to be. · **Origin:**\r\n  `xtask/src/brainread.rs`, new this milestone (the #293 fix's zero-call-site guard).\r\n- **Mechanism, read at source.** The gate's REACH is two hand-authored narrowings stacked:\r\n  **registry = exactly three files** (`dispatch.rs`, `attach.rs`, `brain.rs`) and **predicate = a name\r\n  shape** (`starts_with(\"serve_\") && ends_with(\"_feed\")` or `== \"serve_attach\"`). `serve_sync` is a\r\n  stream server that lives in **no registry file** and whose name **escapes the pattern**, so it is\r\n  invisible on both axes at once. It therefore carries the **REPLY form — the exact form this gate\r\n  REJECTS for every stream server it can see — and the gate is GREEN.** An enforcement whose\r\n  population is enumerated by hand reports compliance over the set it can see, which is not the set\r\n  that matters.\r\n- **Why it is inert TODAY and why that is not reassuring.** The production carrier is unbounded:\r\n  `dispatch::connect()` (`dispatch.rs:898`) uses `Brain::cold_start` with `io_timeout: None`, so\r\n  `call_deadline()` is `None` and the read is unbounded regardless of which form the server carries.\r\n  **It becomes LATENT the day `serve_sync` rides a pump carrier** — which is precisely the direction\r\n  the #293 fix is moving the codebase. The guard will still be green on that day.\r\n- **Owned:** todlando has taken that his migration/census missed `serve_sync`'s lifetime semantics.\r\n  Recorded because the entry is about the GATE's reach, not about who missed it.\r\n- **Remedy shape:** derive the population from the **behaviour** (a fn that serves a stream) rather\r\n  than from the file it sits in or the name it happens to carry, and make the gate **FAIL on a server\r\n  it cannot classify instead of skipping it**. Add a census leg that PRINTS the population checked —\r\n  a count is what would have exposed a three-file registry at a glance.\r\n- **Kin:** [[IR-84]], `unbounded-brain-carrier-cannot-be-bounded` (memory — the carrier question that\r\n  makes this inert today), `REQ-BRAIN-READ-BOUNDED-PER-CALL`.\r\n- **Ripe when:** next `brainread`/xtask touch, **and mandatorily BEFORE `serve_sync` is migrated to a\r\n  bounded carrier.** · **Size:** small.\r\n\r\n### IR-95 — a burned polling budget names WHAT it wanted and never HOW LONG it waited, so no run, green or red, can say how close it came\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 golden RED, where it cost this\r\n  triage most of a morning and four agents. · **Origin:** the two Windows Phase A failures at\r\n  `a9e786b2`, both polling budgets burned rather than value mismatches.\r\n- **The two sites, read at source.** They are not even the same KIND of budget, which is the first\r\n  thing no reader can tell from the panel:\r\n  · `crates/spt/tests/contract_e2e.rs:393-407` — a **WALL** deadline,\r\n  `let deadline = Instant::now() + Duration::from_secs(30)`, panicking\r\n  `\"the brain pulse must ingest the commune into the live context tier\"`. **No elapsed.**\r\n  · `crates/spt-daemon/tests/sync.rs:98-110` — an **ITERATION** budget, `for _ in 0..400 {\r\n  net_streams(); sleep(25ms) }`, panicking `\"sync stream never appeared at the responder's broker\"`.\r\n  **No elapsed, no iteration count** — and its own comment calls it a \"10s budget\", which is a\r\n  NOMINAL sum of sleeps, not a wall bound: each `net_streams()` IPC call adds to it (hertz), so on a\r\n  loaded box the wall it grants is unknown and larger.\r\n- **Four costs MEASURED in this one triage, each traceable to the missing clock:**\r\n  1. **The panic reads as a CONTENT claim.** `contract_e2e.rs:403`'s message is what a 30 s DEADLINE\r\n     EXPIRY prints, and doyle relayed it to three peers as \"a clean content assert, not a stall\"\r\n     before opening the source.\r\n  2. **History cannot supply margins at all.** nextest suppresses passing output by default, so\r\n     **eight consecutive goldens** of this cell's Windows durations exist and **not one carries an\r\n     internal margin**. (`--success-output immediate` retains it — so this is recoverable going\r\n     forward, and was not, going back.)\r\n  3. **A whole-test total cannot locate the poll inside the test.** This conflation was committed\r\n     **five times in forty minutes by three different agents** — deployah twice (retracted both),\r\n     doyle once *in the message correcting deployah for it*, and it was caught each time by todlando\r\n     and hertz. A defect that costs three careful agents five errors in one morning is not a people\r\n     problem; the number they needed was not printed anywhere.\r\n  4. **A FAIL and a PASS are not the same quantity.** `wait_for_stream_except` is called at\r\n     `sync.rs:201`, with `serve_sync`, the puller join and every assertion AFTER it — so a failing\r\n     run **truncates** there. This cell FAILED at 58.77 s and PASSED at 61.304 s, and that 2.5 s gap\r\n     carries no information in either direction. It was read as an anomaly (\"it took LESS time and\r\n     still failed\") until the call site was opened.\r\n- **Remedy:** on expiry, print **elapsed, the budget, and iterations consumed**; where the poll waits\r\n  on another party, print that party's **PRODUCER PROGRESS** too — a watcher's own timings cannot\r\n  separate a slow watcher from a slow producer (hertz, todlando), which is the single fact this\r\n  triage most needed and could not get. Keep the content sentence; it is the panic's `{what}`, not\r\n  its whole body.\r\n- **Population CENSUSED 2026-09-10 (doyle), discharging the census this entry declared OWED — 323\r\n  poll sites detected, 304 of them classified blind. SUPERSEDED 2026-09-10 by the validation\r\n  below: 317 blind of a 321-site population, and the census's own coverage measured.** Read-only, run beside golden diagnostic 34458491560\r\n  without dispatching anything to either runner. Preserved with its method, its raw classification\r\n  and its discarded first attempt at `.spt/preserved/ir95-poll-census-20260910/`.\r\n- **Method, deliberately WORDING-INDEPENDENT.** Over the 212 tracked `*.rs` files under\r\n  `**/tests/**` plus `xtask/`, take every loop by SHAPE — `for _ in 0..N`, `while Instant::now() <\r\n  deadline`, `while <x>.elapsed() < budget`, bare `loop {` — keep it only if it SLEEPS (a poll, not\r\n  a spin) and can FAIL (`panic!`/`assert!`/`expect(`/`bail!` on its exit path), then ask whether its\r\n  failure path emits a MEASURED VALUE (`.elapsed()`, `.as_millis()`, an iteration counter). **String\r\n  literals are stripped before that question is asked**, so the word \"budget\" inside a panic message\r\n  cannot credit itself with a clock. **Result: 323 sites, 19 apparently clocked, 304 blind.**\r\n- **304 of 323 DETECTED CANDIDATES CLASSIFIED BLIND — a classifier count, NOT a proven floor.**\r\n  Stated at that strength on hertz's and todlando's correction of a stronger form this entry\r\n  briefly carried. What was actually spot-checked is the CLOCK bucket, and both errors found there\r\n  ran the same direction, undercounting blindness: `brain_read_deadline.rs:87` was credited from\r\n  elsewhere in the read window while its real failure path is `panic!(\"whole-carrier brain never\r\n  connected to {name}\")`, carrying no clock at all; `er_briefing_presented_e2e.rs:310` returns\r\n  `Some(started.elapsed())` on SUCCESS and a bare `None` on expiry.\r\n- **What that does NOT license.** Finding only false-CLOCK errors does not exclude false-BLIND ones,\r\n  and nothing here establishes POPULATION COVERAGE — whether the four loop shapes catch every poll\r\n  in the corpus is unvalidated, so a poll expressed as a helper, a retry combinator or an iterator\r\n  chain is uncounted and unmeasured. **No repository-wide `>= 94%` claim is made and none should be\r\n  repeated from this entry.** The honest sentence is: 304 classified BLIND among 323 detected\r\n  candidates, with the checked errors so far undercounting blindness. Validating both buckets and\r\n  the population is owed before any bound is asserted.\r\n- **VALIDATED 2026-09-10 (doyle) — all three owed checks discharged; the headline figure MOVES to\r\n  317 blind of 321.** Preserved as `VALIDATION.md` beside the census (machine-bound per [[IR-90]]).\r\n  (1) **The CLOCK bucket is now adjudicated EXHAUSTIVELY, not spot-checked**: of 19, only **4** emit\r\n  a measured value on their own expiry path, **13 were FALSE CLOCKs** and move to BLIND, and **2 are\r\n  not poll-failure sites at all**. Two mechanisms cover all 13, neither of them a wording problem:\r\n  **window bleed** (7 — four credited by a `const CONVERGE_BUDGET: Duration = …as_millis()…`\r\n  *declaration* 20-25 lines BELOW a bare `panic!(\"brain could not connect\")`, one by a different\r\n  loop 57 lines away, two by an unrelated `now_ms()` helper) and **condition-use, not emission** (6 —\r\n  `assert!(started.elapsed() < Duration::from_secs(30), \"…viewer_count={count:?}\")` reads the clock\r\n  in the PREDICATE and omits it from the MESSAGE). Stripping string literals stopped a message\r\n  crediting itself; it does not stop CODE crediting a site whose message stays silent.\r\n  (2) **False-BLINDs checked at last — a seeded 30-site random sample of the BLIND bucket\r\n  (`random.seed(95)`), hand-adjudicated: 30 of 30 confirm BLIND, zero false-BLIND.** By the rule of\r\n  three that bounds the false-BLIND rate at **<= ~10%, at 95% confidence** — a binomial upper bound\r\n  assuming the 30 are a simple random sample of the 304 and each site's adjudication is independent;\r\n  it is **not a deterministic guarantee**, and zero errors in 30 excludes nothing outright (hertz).\r\n  This is the FIRST check run in the\r\n  direction that would REDUCE the blind count and it found nothing; every error found in either\r\n  bucket still runs the other way.\r\n  (3) **Population coverage, measured against every `sleep` in the corpus** — 472 call-sites, 349\r\n  inside a detected window, 75 one-shot settles in no loop. The remaining 48 dedup to 47 loop\r\n  headers and **every one is explained, 0 unexplained**: **32** matched a census shape but cannot\r\n  FAIL within 60 lines (excluded BY DESIGN — the census counts loops that wait AND can fail), and\r\n  **15 are the detector's true false negatives**, a fixed nameable set:\r\n  `while std::time::Instant::now() < deadline` (the PATH-QUALIFIED spelling — the regex demands a\r\n  bare `Instant::now()`; `broker.rs:389`, `shellchan.rs:114`), `while !stop.load(Ordering::Relaxed)`,\r\n  `while <predicate>(…)` (`shell_relink_force_e2e.rs:194/241`, `shell_stale_online_e2e.rs:146`,\r\n  `redispatch.rs:269`), and one `for (a, b) in [...]`. Those 15 stay UNCLASSIFIED.\r\n  **The 32 change how this census may be QUOTED:** \"323 poll loops that wait and can fail\" silently\r\n  excludes 32 loops that wait and CANNOT fail at the poll — a defensible scope, but a scope, and the\r\n  sentence must carry it.\r\n- **Restated census, and the form to quote.** **321** sites in the adjudicated population (323 minus\r\n  2 membership errors from the CLOCK bucket; a 3rd — `net_worker_starve.rs:99`, a fixed-window\r\n  SAMPLER that always runs its window and has no expiry failure — turned up in the BLIND sample, so\r\n  3 errors in 49 hand-adjudicated sites means the population carries ~6% slop and **321 is not\r\n  exact**). **317** classified BLIND. **4** report a measurement. **15** poll loops outside the\r\n  detector's reach, unclassified. **Still not established, and still not to be written: that 317 is\r\n  a FLOOR, or any repository-wide rate.** One direction is now exhaustive, the other bounded at\r\n  <=10% by a 30-site sample — a bounded estimate, never a floor, and silent about the 15.\r\n- **A distinction this validation surfaced, and the remedy above should carry: \"emits a clock\" is\r\n  TWO different things.** `transport_death_eof.rs:540` prints the OBSERVED quantity\r\n  (`{canary_after}ms`); `er_brief_once_per_session_e2e.rs:288` prints the MARGIN (`elapsed=`). Only\r\n  the second tells a reader how close the budget came. 3 of the 4 surviving CLOCK sites report a\r\n  margin, 1 reports an observation — and **a binary CLOCK/BLIND classifier cannot see that\r\n  difference**, which is a limit of the census, not of the sites.\r\n- **One edit to preserved evidence, DECLARED.** `census.py` printed `<-- IR-95 population (a FLOOR)`\r\n  on its blind line. That sentence was retracted the day it was written, but the retraction never\r\n  reached the SCRIPT, so re-running the preserved artifact reprinted the withdrawn claim at whoever\r\n  ran it — a retraction does not propagate to the next reader on its own. The LABEL, and only the\r\n  label, is corrected in place; the computation is untouched and **still reproduces 323 / 19 / 304**,\r\n  which is what makes this validation checkable against it. The old line is quoted verbatim in\r\n  `VALIDATION.md`.\r\n- **A FIRST detector was discarded, and its failure is itself evidence for cost 1 above.** Keying on\r\n  expiry VOCABULARY (\"never\", \"timed out\", \"did not appear\") found 53 sites and **missed\r\n  `contract_e2e.rs:393` entirely — the very site this entry was filed from** — because its panic\r\n  message is a CONTENT sentence. A wording-keyed census is structurally blind to exactly the sites\r\n  whose messages mislead. Recorded so no one re-runs the cheap version and reports 53 as the answer.\r\n- **Positive control passes, and it found siblings.** Both originating sites appear, both BLIND:\r\n  `sync.rs:102` and `contract_e2e.rs:395`. The census also surfaced **two fixed budgets nobody had\r\n  noticed** — `sync.rs:89` (`0..300`, beside the `0..400` at :102) and `contract_e2e.rs:51`\r\n  (`0..400`, beside the wall deadline at :393). Concentration: `inject_control_wedge.rs` 18,\r\n  `broker.rs` 10, `endpoint_lifecycle.rs` 9, `dispatch.rs` 7, `twohost.rs` 7.\r\n- **PRODUCER-PROGRESS INSTRUMENT — SPEC, 2026-09-10, and the three readings it does NOT support.**\r\n  The remedy above asks for the waited-on party's progress because a watcher's own timings cannot\r\n  separate a slow watcher from a slow producer. `last_streams_seen=0` throughout is equally\r\n  consistent with \"the producer never produced\" and \"the watcher never saw it\", and neither arm of\r\n  the releases#294 pair can tell those apart. **Design (doyle), narrowed by hertz and todlando, who\r\n  independently found the same three defects in the first form of it.**\r\n  **INSTRUMENT** — rides the IPC the poll ALREADY makes, so it adds no channel and no budget: the\r\n  responder's broker surfaces, alongside `net_streams`, a monotonic `streams_created_total` AND a\r\n  monotonic `streams_retired_total` for the session, the sequence and age of its last transition,\r\n  and the STREAM IDS of the most recent transitions so the watcher can correlate them against the\r\n  ids it sees and skips. The watcher prints the producer's counters beside its own observation.\r\n  **SEMANTICS THAT MUST BE DECLARED BEFORE A SINGLE READING IS TAKEN** — a bare count is not a\r\n  measurement until these are fixed: WHICH HOOK \"created\" fires at (broker stream-table\r\n  registration? wire acceptance?), WHICH KEY the counter is scoped to and what a session rotation\r\n  does to it, the COUNTER LIFETIME and reset behaviour (process lifetime, per session, what a broker\r\n  restart does), and WHICH CLOCK the age is measured against and whether it is comparable to the\r\n  watcher's.\r\n  **WHAT EACH READING LICENSES, and what it does NOT** (the first form of this table asserted three\r\n  causal conclusions it had not earned):\r\n  · `created=0` at expiry means **no creation was RECORDED AT THAT HOOK, in that counter's scope,\r\n    for that session key**. It does **NOT** establish that the requester never produced, and it does\r\n    **NOT** exonerate the watcher — the hook may sit downstream of the real production, or be scoped\r\n    to a different key.\r\n  · `created>0` with every snapshot empty is **CONSISTENT WITH a visibility/registration defect AND\r\n    with a stream being created and retired entirely between two 25 ms polls**. On its own it\r\n    establishes neither; the retire counter and the ids are what separate them.\r\n  · **Creation AFTER expiry cannot be observed by a poll that has already stopped.** A last-change\r\n    age cannot supply it. That needs either a separately bounded, separately declared post-expiry\r\n    observation, or a retained producer event trace with timestamps.\r\n  **Process constraints:** separately versioned and announced, never slipped between arms of a\r\n  comparison, and the existing diagnostic patch and every budget stay UNCHANGED. Widening a budget\r\n  to make a red go green remains refused.\r\n- **`last_streams_seen` IS A FILTERED-VIEW COUNT — the sharpest narrowing this field has had, and it\r\n  applies to all three expiries in the releases#294 pair.** The poll calls `net_streams`; the broker\r\n  answers at `broker.rs:9546` `dispatch_net_streams` -> `host.dispatch_stream_infos()`\r\n  (`nethost.rs:1952`) -> `stream_infos_filtered(FALSE)`, and that filter drops TWO classes\r\n  SERVER-SIDE, before serialization (ADR-0040 decision 2, `REQ-STREAM-INFOS-SERVER-FILTER`):\r\n  `!e.retired.load(SeqCst)` and `!e.initiated_locally`. So `last_streams_seen=0` does **NOT** mean\r\n  the broker held no streams. It means **zero NON-RETIRED, NON-LOCALLY-INITIATED rows at that\r\n  instant** — a row that exists and is retired is invisible to the poll BY DESIGN. That is narrower\r\n  than the corrected form the RCA had settled on (\"the final snapshot was empty\"), and it is a\r\n  hook-scope fact of exactly the kind the preconditions above demand be pinned before any reading.\r\n- **A \"reuse it, no product change\" stage-1 design WAS PROPOSED AND IS WITHDRAWN — recorded because\r\n  the reason generalises.** `NetHost::stream_counts()` (`nethost.rs:1980`) is already surfaced as\r\n  `NetStatusReply.streams_held` (`broker.rs:9002`, `msg.rs:874`) and documents itself as\r\n  \"retirement-blind ON PURPOSE ... the resource truth the eligibility view hides\". Reading it beside\r\n  `net_streams` looked like it would separate \"filtered out\" from \"absent\" for free. It does not,\r\n  for four reasons, and hertz and todlando raised them independently:\r\n  · **Two IPC replies are not an atomic snapshot.** `filtered=0` then `held>0` is equally consistent\r\n    with a row ARRIVING BETWEEN THE TWO CALLS. Such a pair must never be labelled proof of filtering,\r\n    and needs call order and timestamps recorded if it is read at all.\r\n  · **`streams_held` is HOST-SCOPED, not exchange-scoped.** It counts unrelated and locally-initiated\r\n    rows the filtered view drops, so it cannot speak to the exchange under investigation without\r\n    stream-ID correlation; any conclusion from it stays aggregate.\r\n  · **It adds UNMEASURED perturbation** — a second IPC per iteration changes the 400-iteration\r\n    window's wall duration by an amount nobody has measured. **CORRECTED 2026-09-10 (hertz,\r\n    todlando), because the first form of this bullet was itself an overclaim in two ways and both\r\n    are instructive:** (a) it called perturbation DISQUALIFYING, and it is not — instrumentation\r\n    that perturbs timing can still be useful; the objection is ADDED, UNMEASURED perturbation, not\r\n    perturbation as such. (b) It SIZED that perturbation from two figures that cannot carry it: the\r\n    measured `net_streams` cost (60,295 us / 400 = 0.151 ms per iteration) does **not** estimate the\r\n    `net-status` cost — different call, different work — and the **0.29% expiry difference between\r\n    the two arms is NOT an established causal effect size**, only an unexplained gap between two n=1\r\n    observations. Sizing an observer effect against it treats an open question as a known\r\n    quantity.\r\n  · A single POST-EXPIRY sample avoids perturbing the poll but then describes LATER state, not\r\n    expiry state, and is still host-scoped.\r\n- **THE INSTRUMENT THAT SURVIVES REVIEW: a retained, EXCHANGE-CORRELATED create/retire TRACE**\r\n  (hertz and todlando, converged independently). Recorded per stream lifecycle transition on the\r\n  producer side — stream id, conn id, remote id, transition, `initiated_locally`, a monotonic\r\n  sequence and a timestamp on a NAMED clock — retained and read AFTER the fact rather than sampled\r\n  by the watcher, so it adds **NO POLL CALLS**. Say that, and not \"adds nothing\" (hertz): it still\r\n  adds PRODUCER-SIDE work that may affect arrival timing and resource contention, and **that effect\r\n  is unmeasured too**. The trace is preferable for having no watcher IPC, not for being free. It captures between-poll transitions,\r\n  which neither a gauge nor an in-loop counter can: **a gauge reads 0 for a stream created and\r\n  retired between two 25 ms polls exactly as it does for one never created.** Correlation to the\r\n  exchange is by stream id against the ids the watcher saw and skipped.\r\n  **MEASURED: it does not exist today** — zero stream-lifetime log lines in `nethost.rs`. So this is\r\n  a PRODUCT change, not a reuse, and it stays unbuilt while the product is frozen. Its preconditions\r\n  are the ones above, unchanged. Production AFTER the trace's retention window remains outside it.\r\n- **THE FIRST MARGINS THIS ENTRY PRODUCED UNDER CI / GOLDEN CONDITIONS — instrumented run\r\n  34458491560, 2026-09-10\r\n  (hertz's patch; deployah's lane; read independently by doyle).** The remedy above was argued for\r\n  on the ground that a poll which prints nothing cannot say how close it came. It has now printed\r\n  on a runner. **NOT the first margins overall** — the earlier local 12-leg run already reported\r\n  them, including a 392/400 (hertz, todlando). **The genuinely novel quantity is narrower and\r\n  sharper than \"CI margins\" (deployah): it is a FAILING poll's margin, which no local leg could\r\n  produce because all 12 of them PASSED.** A budget's behaviour at expiry is the one thing a green\r\n  run structurally cannot report, and it is the case the remedy exists for.\r\n  **The figure is the MAXIMUM AMONG SUCCESSFUL polls in this run — explicitly NOT a ceiling, and not\r\n  a bound on observations**: the poll that EXPIRED in this same run consumed 400/400 = 100%. So:\r\n  among the polls that PASSED on hfenduleam, both instrumented sites peak at ~63% of budget. The\r\n  seven successful\r\n  `[IR95-SYNC]` waits in that run are 92, 19, 72, 254, 21, 21 and 20 iterations — **worst 254/400 =\r\n  63.5%** (6.449393 s) — and the `[IR95-CONTRACT]` success consumed **18.857089 s of its 30.000 s\r\n  wall = 62.9%**. Two independent sites, two different budget KINDS, the same maximum-among-passes.\r\n  Headroom at that worst SUCCESSFUL case ~37%; the failing case had none left. **n=7 and n=1, one\r\n  box, one run: a first CI measurement, not a stability claim, and NO budget change is proposed on\r\n  it.**\r\n- **The iteration budget's WALL EQUIVALENT, also measured for the first time.** The expiring poll's\r\n  400 iterations cost **10.199907 s against 400 × 25 ms = 10.000 s nominal — 2.0% over**, with\r\n  per-iteration overhead ~0.5 ms against a 25 ms sleep (IPC 60.295 ms total, 0.151 ms per iteration,\r\n  **0.59% of elapsed**; sleep is 99.4%). So on this box in this run a \"400 iteration\" budget and a\r\n  \"~10.2 s wall\" are nearly the same object — the iteration budget did NOT silently become a\r\n  different budget under load. That bounds one standing worry about blind iteration counts, and it\r\n  is precisely the class of thing that stops being guessable the moment a clock prints. Box-local\r\n  and run-local; it is not a general result.\r\n- **A scope limit the instrumentation itself imposes, and a smaller ask than it first looks.**\r\n  `last_streams_seen` is an ASSIGNMENT per iteration (`sync.rs:111`), not an accumulator, so\r\n  `last_streams_seen=0` at expiry describes the FINAL iteration only — not all 400 (todlando's\r\n  correction; deployah withdrew the aggregate reading, doyle confirmed it at source). But the loop's\r\n  CONTROL FLOW already proves the interesting half for free: the `find()` at `:113` returns the\r\n  instant a non-skipped stream appears, so **reaching the expiry print IS proof that no non-skipped\r\n  stream was seen in any of the 400 SNAPSHOTS** — no aggregate trace required. **It does NOT mean\r\n  no stream EXISTED between snapshots** (hertz): the poll samples at 25 ms, and nothing here\r\n  observes the gaps. What is genuinely\r\n  unmeasured is only whether a SKIPPED stream was ever present, and `skip` is empty on that call.\r\n  An aggregate/per-iteration trace therefore buys less here than the gap first suggests.\r\n- **NOT ESTABLISHED: that all 304 deserve a clock.** The census SIZES the problem; it does not\r\n  schedule it, and it does not pre-judge which sites are worth the edit. Remedy triage is owed\r\n  separately and is the larger half.\r\n- **Kin:** [[IR-84]] (the one `PUMP_PEER_FAIL` arm the rigs fire was the only one carrying no clock —\r\n  **the same class in product code**; this entry is its test-corpus face), [[IR-85]] (budgets sized\r\n  against a box whose speed moved), [[IR-77]] (nothing stamps the spawn-to-first-log interval, so a\r\n  readiness red cannot say where the time went), [[IR-90]].\r\n- **Ripe when:** with the releases#294 instrumented base-vs-head comparison, which **cannot be run\r\n  without it** — the experiment's whole output is the margins these sites do not print. ·\r\n  **Size:** small per site; the census is the larger half.\r\n\r\n### IR-96 — the `daemon_stop_convoy_e2e` API-storm cell fails 3-of-3 under the HEAVY suite at the diagnostic tree while passing at the candidate in golden CI, and nothing yet separates instrumentation from box from product\r\n\r\n- **Status:** OPEN, **cause-unclassified** (todlando's and hertz's stipulation, adopted verbatim — a\r","truncated":true,"truncatedBy":"lines","totalLines":1457,"totalBytes":40920,"outputLines":450,"outputBytes":40920,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6937,"displayContent":{"text":"### IR-91 — 561 untracked files sat at the repo root, 18 of them cited by tracked files, and the census that classified them used a corpus that made the discriminator invisible\n…\n- **Status:** CLOSED by the lane that filed it (the root-scratch classify PR), hertz 2026-09-09 on\n…\n- **Ripe when:** landed with this entry. · **Size:** one `.gitignore` stanza, 18 adds, 543\n…\n\r\n### IR-92 — the message that WAKES an idle spt-hosted endpoint rides a delivery leg that never publishes MSG_IN, so a woken agent's own funnel holds none of the messages that woke it\r\n\r\n- **Status:** OPEN — filed doyle 2026-09-09 from hertz's census, probe and proposed text (his by\r\n  role; the recorder read and the REQ reading are doyle's). Fix lane unassigned: product change in\r\n  `spt-daemon` (todlando), test-side legs (hertz). · **Origin:** a 22:35Z empty `<msg from=\"hertz\"/>`\r\n  turn trigger after the #292 daemon restart, chased for its body; the body was in a spill file, and\r\n  the chase exposed that neither agent's io-events log held the messages that woke it.\r\n- **Release reconciliation, 2026-09-11 (source read at `e5a2fed9`):** core PR **#215 is\r\n  DOCS-ONLY**. Its merge and v0.69.0 ship-fact record (comment 5628532753) discharge the\r\n  **register rider**, not this product remedy. Core #217 is the separate #293 brain-read\r\n  census, not an inject-edge fix. `try_spt_hosted_inject` still returns the result of\r\n  `brain.inject_endpoint` without publishing `MSG_IN`. **IR-92 stays OPEN.** Carry the\r\n  observation-only chokepoint remedy into the next product intake (todlando product ownership,\r\n  hertz test ownership); neither offline owner's execution is implied by that assignment.\r\n- **THE TWO PUBLISH SITES ORDER THEMSELVES OPPOSITELY — read at `de5a44bc`, 2026-09-10, from the\r\n  bare-baseline red on `io_events_undriven_kinds_e2e` (golden 34467873057, Linux Phase A).** The\r\n  count below is right and the ORDERING is what this entry was missing:\r\n  · **PATH A, hook poll** (`delivery.rs`): `poll_drain()` publishes EVERY delivered row (`:757`) and\r\n    RETURNS them; its only caller `cmd_poll` (`:660`) then loops `emit_event` over the returned rows.\r\n    **Publication happens-before presentation**, strictly. An immediate log read after observed\r\n    presentation is CONTRACT-CORRECT here, and a bounded retry on this path WOULD conceal a real\r\n    violation. **Leave Path A alone.**\r\n  · **PATH B, the relay** (`startup.rs:1057`, the `deliver` closure): `emit(id, from, body)` — the\r\n    presentation — runs, and `publish_msg_io(...MSG_IN...)` runs AFTER it, per message, in the same\r\n    closure; the closure's own comment records that \"Both backlog (after notif validity) and live TCP\r\n    reach this edge.\" **Presentation happens-before publication.**\r\n  A test that detects presentation by reading the listener child's STDOUT through a pipe and then\r\n  reads the io-events log immediately is therefore **racy BY CONTRACT on Path B** — publication for\r\n  that message runs after its emit, in the child, and the pipe read can win. A bounded wait on the\r\n  log is permitted on Path B: **it does not weaken any publication-before-presentation guarantee\r\n  there, because there is none** (hertz's and todlando's narrowing — NOT \"conceals nothing\": the\r\n  wait still DEFINES WHICH PUBLICATION DELAYS THE TEST ACCEPTS, and it does not establish why any\r\n  given execution missed a row). A timeout would establish \"not published within the bound\", never\r\n  \"never publishes\", and cannot alone identify this entry's defect.\r\n- **A SECOND, INDEPENDENT DEFECT IN THAT CELL'S ASSERTION, true regardless of the above.**\r\n  `io_events_undriven_kinds_e2e.rs:818` asserts exact-once as\r\n  `vec![(\"MSG_IN\", Some(AUTHOR)), (\"MSG_IN\", Some(AUTHOR))]` — a `(kind, author)` pair per row, and\r\n  **both rows are identical**, so the assertion cannot tell the backlog row from the live row and\r\n  **two BACKLOG rows would satisfy it**. The identities exist and are already stamped:\r\n  `publish_msg_io_local` carries `.with_msg_id(msg_id_of(body))` — the short ID the failing panel\r\n  itself printed. Exact-once belongs per MESSAGE ID, not per author.\r\n  **AND IT CUTS BACKWARDS, WEAKENING EVERY GREEN THIS CELL HAS EVER RETURNED (deployah, on\r\n  arm-comparability grounds — the point nobody else had drawn):** the three PASSING executions of\r\n  this cell in the instrumented pair (base linux 3.612 s, head linux 2.343 s, head windows 16.411 s)\r\n  did **NOT** establish that both relay arms published. They established that two rows matching\r\n  `(MSG_IN, alice)` were present at read time. A green here is a WEAKER fact than it reads as — the\r\n  verdict stands in for a measurement the assertion never made. So \"both Linux legs were green\r\n  across the instrumented pair\" does not become FALSE, it becomes NARROWER than it was being used\r\n  for: it is a statement about the ASSERTION's outcome, not about publication. It does **not** make\r\n  the bare red likelier to be a product defect, does not classify anything, and does not separate\r\n  the race from non-publication — it removes a comparison the RCA was implicitly leaning on.\r\n  (Raised independently by hertz and todlando as an assertion defect; its backwards consequence for\r\n  the greens is deployah's.)\r\n- **Status of that red: UNEXPLAINED between DELAYED and ABSENT publication.** Path B makes the race\r\n  MECHANICALLY AVAILABLE, which is more than \"not excluded\" — but availability is not occurrence,\r\n  and one observation does not separate them. Kinship to this entry stays a HYPOTHESIS. The cell is\r\n  in neither `docs/FLAKE-LEDGER.md` nor this register (0 hits each): an unregistered signature.\r\n- **The mechanism, read at `de5a44bc`:** `MSG_IN` has exactly two publish sites in the tree —\r\n  `crates/spt/src/api/delivery.rs:757` (`publish_msg_io_local`, reached only from `poll_drain`, the\r\n  hook-poll leg, `TakerLeg::HookPoll`) and `crates/spt/src/api/startup.rs:1064` (`publish_msg_io`\r\n  inside the `api listen` relay's `deliver` sink — the Monitor-stream surface a hook-hosted session\r\n  never uses). **The spt-hosted inject leg reaches neither.** `crates/spt-daemon/src/inject.rs:75`\r\n  `try_spt_hosted_inject` renders the envelope and hands it to `brain.inject_endpoint`; the file has\r\n  zero `publish_msg_io` / `iobus` / `IO_KIND_MSG_IN` references in 343 lines (control: `TakerAudit`\r\n  / `claim_idle_edge_at` hit, so the grep is live). Every caller delivers through it unobserved:\r\n  `cli.rs:11739` send-time direct inject when the broker reports the target IDLE (the sender is\r\n  answered `SENT`), `cli.rs:11684` `--force-native`, `inject.rs:168` `drain_spool_offering` (the\r\n  idle-EDGE drain `delivery.rs:801`, the send-time already-idle re-offer, the pulse-tick belt, and the\r\n  native ER-briefing arm), and `wan.rs:822` / `:1173` WAN ingress. Two more drain edges are silent by\r\n  the same shape and did not fire here: `cmd_poll_shell` (`delivery.rs:705`, shell surface) and\r\n  `cmd_worker_poll` (`worker.rs:138`, worker surface). A call-site grep would have marked `relay.rs`\r\n  silent too — it publishes through its sink one crate up — so \"does this edge observe\" is answered\r\n  by following the row to a bus, never by grepping the edge.\r\n- **The rule it produces (hertz's refinement, measured across both logs):** for a hook-hosted live\r\n  agent (`is_spt_hosted_no_relay`), **`SENT` to an idle peer → direct inject → NEVER recorded on\r\n  the peer** (deterministic). **`QUEUED` → recorded IFF the hook poll takes the row.** One stamped\r\n  census, **as of 23:04Z 2026-09-09** (the counts grow with every message, so an unstamped figure is\r\n  stale on arrival): SENT-to-idle unrecorded on the receiver **12/12** (hertz’s five to doyle, doyle’s\r\n  seven to hertz — the seventh being the message that announced this filing, delivered by the defect\r\n  it named); QUEUED recorded **8/8**, every one drained mid-tool. Each side’s absence census matched\r\n  the other side’s verdict log without either seeing the other’s data.\r\n  by the caller census a spooled row can also be taken by the send-time already-idle re-offer or the\r\n  pulse-tick belt (`inject.rs:168`, unrecorded), so a `QUEUED` row’s fate is decided by the TAKER,\r\n  not the verdict — that arm was not observed tonight and stays a prediction.\r\n- **Measured, hfenduleam 2026-09-09, both full streams read end to end, same 23:04Z stamp:** hertz’s\r\n  log (through seq 1812): the messages that arrived as turn triggers (`UserPromptSubmit`, idle) — **7/7\r\n  unlogged**; those that arrived mid-tool (`PreToolUse`, busy) — **4/4 logged**, msg-id present,\r\n  `<LAST_MSGS>` clock moved (doyle's 22:55Z probe was `QUEUED`, drained mid-Bash, logged as 1804).\r\n  His \"zero `MSG_IN` since 14:02:34Z\" was **not a state change**: 1633 at 14:02 was the last message\r\n  that happened to catch him inside a tool call; everything after found him idle. doyle's log (1,121\r\n  events): PACER-0 **7 received / 6 logged**, the missing one `G4NK5FFT` being the row that woke the\r\n  session; hertz’s five `SENT` wake messages **absent entirely** and his four `QUEUED` ones **present\r\n  4/4**, each drained mid-tool; riders in the same spill (1856/1857 beside the promoted 1855;\r\n  `3NGTHQHN` beside a task-notification trigger) logged. One variable moved.\r\n- **Scope, corrected once (hertz struck his own \"bilateral\" clause on doyle's control):**\r\n  receiver-side only. The sender's `MSG_OUT` rows are intact on both sides, so an exchange IS\r\n  reconstructible from the **peer's** log — but not from the woken agent's own, which is the surface\r\n  a post-reset agent reads. hertz re-grounded his 22:36 session off seq 1786 of a log that holds his\r\n  half of every exchange since 14:02 and none of doyle's; a replay of an idle-woken agent shows its\r\n  own outbound answering nothing, and the last-received clock skips exactly the moments the peer was\r\n  talking, which reads as \"peer gone quiet\".\r\n- **Against the requirement's own words:** `REQ-IO-MSG-EDGES` (activated, `doc`/`impl`/`unit`)\r\n  states that \"MSG_IN publishes where core **delivers or injects** an inbound one, so the funnel\r\n  observes the edges rather than growing a parallel notion of what a message is\". This is not a case\r\n  the requirement failed to anticipate: **its own second clause is unimplemented** while `impl` and\r\n  `unit` read green on the first. The inject edge was never given a publisher when F-023 (idle-edge\r\n  drain), W5 (parked re-offer) and the WAN ingress added takers; the unit cell at `delivery.rs:1251`\r\n  pins the poll leg only, so the coverage the registry reports is green on two edges and vacuous on\r\n  the one the requirement names by verb.\r\n- **Remedy, and where it must sit:** publish `MSG_IN` **inside `try_spt_hosted_inject` on\r\n  `Some((true, _))`** — the one chokepoint all four callers share — so no caller can deliver\r\n  unobserved; a fix placed in `drain_spool_offering` would leave the send-time direct inject and WAN\r\n  ingress silent. Keep it observation-only (REQ-IO-EVENT-BUS): the inject verdict must not depend on\r\n  the bus. The unit cell to add mirrors `delivery.rs:1251`: an injected row owes exactly one\r\n  `MSG_IN`, a refused inject owes none. Post-hoc census of what was lost: spooled rows carry\r\n  `TakerLeg::IdleInject` / `NativeInject` in the audit column (REQ-SPOOL-TAKE-AUDIT); direct injects\r\n  never spooled and are enumerable only from the sender's `MSG_OUT`.\r\n- **OPEN, unranked, not smoothed:** doyle's pre-clear 1855 got a **bodiless** `USER_INPUT msg\r\n  from=\"hertz\"` row (the `api state busy` payload path, `delivery.rs:115` `state_io_kind`) while his\r\n  post-clear five got **no row at all**. Both are wake-delivered; the difference is downstream of\r\n  this gap, in what the adapter passed as the state payload, and is not this entry's mechanism.\r\n  Also out of scope, perri's surface: the claude-spt overflow notice names spills of the CURRENT\r\n  session id only, so the last spill before a `/clear` is never named again (how the 22:35Z body\r\n  went unread in the first place).\r\n- **Kin:** `REQ-IO-MSG-EDGES`, `REQ-MSG-IDLE-EDGE-DRAIN`, `REQ-IDLE-PARKED-DELIVERY`,\r\n  `REQ-SPOOL-TAKE-AUDIT`, **IR-84** (the arm the rigs fire was the only one without a clock — same\r\n  shape: the leg that fires most is the one the instrument never covered), releases#287 (shells after\r\n  a restart), memory `an-empty-msg-from-tag-is-a-turn-trigger-whose-body-lives-in-the-spill`.\r\n- **Ripe when:** any lane touches `spt-daemon::inject` or the IO funnel; small enough to ride the\r\n  next product batch. · **Size:** one publish call at one chokepoint, one unit cell, one `int` leg\r\n  (a hook-hosted receiver woken by a `SENT`, then `io-events` replayed for the msg-id).\r\n\r\n### IR-93 — no PDB ships beside the installed `spt` binary, so the one non-invasive read of a wedged production daemon comes back without a single named frame\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-10. **The number was reserved by NAME on 2026-09-09** at\r\n  the #293 mechanism read (\"PDB ask -> IR-93 at next sweep\") and this entry closes that claim — a\r\n  name-only IR with no entry text is the exact gap [[IR-85]]'s status line had to spend a paragraph\r\n  explaining about IR-84, and it is not being left open a second time. · **Origin:** the #293 pump\r\n  wedge on hfenduleam.\r\n- **What was actually paid.** With the daemon wedged and unrecoverable, hertz's `cdb -pv -p 31856`\r\n  dump (2026-09-09 23:23:26-31Z, 4.79 s suspend, 35 threads, preserved at\r\n  `.spt/preserved/293-brain-stacks-20260909T232326Z/`) was the ONLY direct observation available of\r\n  the live wedged process — the pump had already stopped, so the suspend cost the fleet nothing it\r\n  still had. It came back **with NO SYMBOLS: there is no PDB beside the installed exe.** Both\r\n  pump-ipc-reader threads were visible in `SleepEx` and all 32 brain threads in Wait, but the frames\r\n  are addresses.\r\n- **The cost, stated at the strength it holds.** The mechanism was named anyway — from SOURCE reading\r\n  (`Brain::read_event()` unbounded at `brain.rs:1025-1027`, 17 in-brain loopers), not from the dump.\r\n  What the dump could not do is say **WHICH call site parked THAT instance**, and that remains NOT\r\n  ESTABLISHED. A symbolised dump is the one artifact that answers it directly, and the next wedge\r\n  will present the same choice with the same empty answer.\r\n- **Remedy:** retain and ship the PDB beside the installed binary (or publish a symbol store the\r\n  debugger can resolve against) so a production dump names frames. **Weigh it honestly at rider\r\n  time:** this is a packaging/size decision, and a release profile that emits no debug info is a\r\n  deliberate choice someone made — this entry is the bill for it, not a claim it was wrong.\r\n- **Kin:** [[IR-82]] (a daemon death leaves no record of who died — same family: the corpse is the\r\n  evidence and nothing preserves it), [[IR-84]] (the arm with no clock), [[IR-95]] (a budget that\r\n  cannot say how much it burned).\r\n- **Ripe when:** next installer / release-packaging touch. · **Size:** packaging (profile + install\r\n  layout), no product code.\r\n\r\n### IR-94 — xtask's brainread deadline gate cannot SEE `serve_sync`: its registry is three hand-listed files and its predicate is a name shape, so a stream server outside both got the reply form and the gate stayed green\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 / v0.69.0 golden RED triage. **This\r\n  is an INDEPENDENT gate finding, not the cause of that red** — it was found while reading the\r\n  milestone's diff and stands whatever Finding 1 turns out to be. · **Origin:**\r\n  `xtask/src/brainread.rs`, new this milestone (the #293 fix's zero-call-site guard).\r\n- **Mechanism, read at source.** The gate's REACH is two hand-authored narrowings stacked:\r\n  **registry = exactly three files** (`dispatch.rs`, `attach.rs`, `brain.rs`) and **predicate = a name\r\n  shape** (`starts_with(\"serve_\") && ends_with(\"_feed\")` or `== \"serve_attach\"`). `serve_sync` is a\r\n  stream server that lives in **no registry file** and whose name **escapes the pattern**, so it is\r\n  invisible on both axes at once. It therefore carries the **REPLY form — the exact form this gate\r\n  REJECTS for every stream server it can see — and the gate is GREEN.** An enforcement whose\r\n  population is enumerated by hand reports compliance over the set it can see, which is not the set\r\n  that matters.\r\n- **Why it is inert TODAY and why that is not reassuring.** The production carrier is unbounded:\r\n  `dispatch::connect()` (`dispatch.rs:898`) uses `Brain::cold_start` with `io_timeout: None`, so\r\n  `call_deadline()` is `None` and the read is unbounded regardless of which form the server carries.\r\n  **It becomes LATENT the day `serve_sync` rides a pump carrier** — which is precisely the direction\r\n  the #293 fix is moving the codebase. The guard will still be green on that day.\r\n- **Owned:** todlando has taken that his migration/census missed `serve_sync`'s lifetime semantics.\r\n  Recorded because the entry is about the GATE's reach, not about who missed it.\r\n- **Remedy shape:** derive the population from the **behaviour** (a fn that serves a stream) rather\r\n  than from the file it sits in or the name it happens to carry, and make the gate **FAIL on a server\r\n  it cannot classify instead of skipping it**. Add a census leg that PRINTS the population checked —\r\n  a count is what would have exposed a three-file registry at a glance.\r\n- **Kin:** [[IR-84]], `unbounded-brain-carrier-cannot-be-bounded` (memory — the carrier question that\r\n  makes this inert today), `REQ-BRAIN-READ-BOUNDED-PER-CALL`.\r\n- **Ripe when:** next `brainread`/xtask touch, **and mandatorily BEFORE `serve_sync` is migrated to a\r\n  bounded carrier.** · **Size:** small.\r\n\r\n### IR-95 — a burned polling budget names WHAT it wanted and never HOW LONG it waited, so no run, green or red, can say how close it came\r\n\r\n- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 golden RED, where it cost this\r\n  triage most of a morning and four agents. · **Origin:** the two Windows Phase A failures at\r\n  `a9e786b2`, both polling budgets burned rather than value mismatches.\r\n- **The two sites, read at source.** They are not even the same KIND of budget, which is the first\r\n  thing no reader can tell from the panel:\r\n  · `crates/spt/tests/contract_e2e.rs:393-407` — a **WALL** deadline,\r\n  `let deadline = Instant::now() + Duration::from_secs(30)`, panicking\r\n  `\"the brain pulse must ingest the commune into the live context tier\"`. **No elapsed.**\r\n  · `crates/spt-daemon/tests/sync.rs:98-110` — an **ITERATION** budget, `for _ in 0..400 {\r\n  net_streams(); sleep(25ms) }`, panicking `\"sync stream never appeared at the responder's broker\"`.\r\n  **No elapsed, no iteration count** — and its own comment calls it a \"10s budget\", which is a\r\n  NOMINAL sum of sleeps, not a wall bound: each `net_streams()` IPC call adds to it (hertz), so on a\r\n  loaded box the wall it grants is unknown and larger.\r\n- **Four costs MEASURED in this one triage, each traceable to the missing clock:**\r\n  1. **The panic reads as a CONTENT claim.** `contract_e2e.rs:403`'s message is what a 30 s DEADLINE\r\n     EXPIRY prints, and doyle relayed it to three peers as \"a clean content assert, not a stall\"\r\n     before opening the source.\r\n  2. **History cannot supply margins at all.** nextest suppresses passing output by default, so\r\n     **eight consecutive goldens** of this cell's Windows durations exist and **not one carries an\r\n     internal margin**. (`--success-output immediate` retains it — so this is recoverable going\r\n     forward, and was not, going back.)\r\n  3. **A whole-test total cannot locate the poll inside the test.** This conflation was committed\r\n     **five times in forty minutes by three different agents** — deployah twice (retracted both),\r\n     doyle once *in the message correcting deployah for it*, and it was caught each time by todlando\r\n     and hertz. A defect that costs three careful agents five errors in one morning is not a people\r\n     problem; the number they needed was not printed anywhere.\r\n  4. **A FAIL and a PASS are not the same quantity.** `wait_for_stream_except` is called at\r\n     `sync.rs:201`, with `serve_sync`, the puller join and every assertion AFTER it — so a failing\r\n     run **truncates** there. This cell FAILED at 58.77 s and PASSED at 61.304 s, and that 2.5 s gap\r\n     carries no information in either direction. It was read as an anomaly (\"it took LESS time and\r\n     still failed\") until the call site was opened.\r\n- **Remedy:** on expiry, print **elapsed, the budget, and iterations consumed**; where the poll waits\r\n  on another party, print that party's **PRODUCER PROGRESS** too — a watcher's own timings cannot\r\n  separate a slow watcher from a slow producer (hertz, todlando), which is the single fact this\r\n  triage most needed and could not get. Keep the content sentence; it is the panic's `{what}`, not\r\n  its whole body.\r\n- **Population CENSUSED 2026-09-10 (doyle), discharging the census this entry declared OWED — 323\r\n  poll sites detected, 304 of them classified blind. SUPERSEDED 2026-09-10 by the validation\r\n  below: 317 blind of a 321-site population, and the census's own coverage measured.** Read-only, run beside golden diagnostic 34458491560\r\n  without dispatching anything to either runner. Preserved with its method, its raw classification\r\n  and its discarded first attempt at `.spt/preserved/ir95-poll-census-20260910/`.\r\n- **Method, deliberately WORDING-INDEPENDENT.** Over the 212 tracked `*.rs` files under\r\n  `**/tests/**` plus `xtask/`, take every loop by SHAPE — `for _ in 0..N`, `while Instant::now() <\r\n  deadline`, `while <x>.elapsed() < budget`, bare `loop {` — keep it only if it SLEEPS (a poll, not\r\n  a spin) and can FAIL (`panic!`/`assert!`/`expect(`/`bail!` on its exit path), then ask whether its\r\n  failure path emits a MEASURED VALUE (`.elapsed()`, `.as_millis()`, an iteration counter). **String\r\n  literals are stripped before that question is asked**, so the word \"budget\" inside a panic message\r\n  cannot credit itself with a clock. **Result: 323 sites, 19 apparently clocked, 304 blind.**\r\n- **304 of 323 DETECTED CANDIDATES CLASSIFIED BLIND — a classifier count, NOT a proven floor.**\r\n  Stated at that strength on hertz's and todlando's correction of a stronger form this entry\r\n  briefly carried. What was actually spot-checked is the CLOCK bucket, and both errors found there\r\n  ran the same direction, undercounting blindness: `brain_read_deadline.rs:87` was credited from\r\n  elsewhere in the read window while its real failure path is `panic!(\"whole-carrier brain never\r\n  connected to {name}\")`, carrying no clock at all; `er_briefing_presented_e2e.rs:310` returns\r\n  `Some(started.elapsed())` on SUCCESS and a bare `None` on expiry.\r\n- **What that does NOT license.** Finding only false-CLOCK errors does not exclude false-BLIND ones,\r\n  and nothing here establishes POPULATION COVERAGE — whether the four loop shapes catch every poll\r\n  in the corpus is unvalidated, so a poll expressed as a helper, a retry combinator or an iterator\r\n  chain is uncounted and unmeasured. **No repository-wide `>= 94%` claim is made and none should be\r\n  repeated from this entry.** The honest sentence is: 304 classified BLIND among 323 detected\r\n  candidates, with the checked errors so far undercounting blindness. Validating both buckets and\r\n  the population is owed before any bound is asserted.\r\n- **VALIDATED 2026-09-10 (doyle) — all three owed checks discharged; the headline figure MOVES to\r\n  317 blind of 321.** Preserved as `VALIDATION.md` beside the census (machine-bound per [[IR-90]]).\r\n  (1) **The CLOCK bucket is now adjudicated EXHAUSTIVELY, not spot-checked**: of 19, only **4** emit\r\n  a measured value on their own expiry path, **13 were FALSE CLOCKs** and move to BLIND, and **2 are\r\n  not poll-failure sites at all**. Two mechanisms cover all 13, neither of them a wording problem:\r\n  **window bleed** (7 — four credited by a `const CONVERGE_BUDGET: Duration = …as_millis()…`\r\n  *declaration* 20-25 lines BELOW a bare `panic!(\"brain could not connect\")`, one by a different\r\n  loop 57 lines away, two by an unrelated `now_ms()` helper) and **condition-use, not emission** (6 —\r\n  `assert!(started.elapsed() < Duration::from_secs(30), \"…viewer_count={count:?}\")` reads the clock\r\n  in the PREDICATE and omits it from the MESSAGE). Stripping string literals stopped a message\r\n  crediting itself; it does not stop CODE crediting a site whose message stays silent.\r\n  (2) **False-BLINDs checked at last — a seeded 30-site random sample of the BLIND bucket\r\n  (`random.seed(95)`), hand-adjudicated: 30 of 30 confirm BLIND, zero false-BLIND.** By the rule of\r\n  three that bounds the false-BLIND rate at **<= ~10%, at 95% confidence** — a binomial upper bound\r\n  assuming the 30 are a simple random sample of the 304 and each site's adjudication is independent;\r\n  it is **not a deterministic guarantee**, and zero errors in 30 excludes nothing outright (hertz).\r\n  This is the FIRST check run in the\r\n  direction that would REDUCE the blind count and it found nothing; every error found in either\r\n  bucket still runs the other way.\r\n  (3) **Population coverage, measured against every `sleep` in the corpus** — 472 call-sites, 349\r\n  inside a detected window, 75 one-shot settles in no loop. The remaining 48 dedup to 47 loop\r\n  headers and **every one is explained, 0 unexplained**: **32** matched a census shape but cannot\r\n  FAIL within 60 lines (excluded BY DESIGN — the census counts loops that wait AND can fail), and\r\n  **15 are the detector's true false negatives**, a fixed nameable set:\r\n  `while std::time::Instant::now() < deadline` (the PATH-QUALIFIED spelling — the regex demands a\r\n  bare `Instant::now()`; `broker.rs:389`, `shellchan.rs:114`), `while !stop.load(Ordering::Relaxed)`,\r\n  `while <predicate>(…)` (`shell_relink_force_e2e.rs:194/241`, `shell_stale_online_e2e.rs:146`,\r\n  `redispatch.rs:269`), and one `for (a, b) in [...]`. Those 15 stay UNCLASSIFIED.\r\n  **The 32 change how this census may be QUOTED:** \"323 poll loops that wait and can fail\" silently\r\n  excludes 32 loops that wait and CANNOT fail at the poll — a defensible scope, but a scope, and the\r\n  sentence must carry it.\r\n- **Restated census, and the form to quote.** **321** sites in the adjudicated population (323 minus\r\n  2 membership errors from the CLOCK bucket; a 3rd — `net_worker_starve.rs:99`, a fixed-window\r\n  SAMPLER that always runs its window and has no expiry failure — turned up in the BLIND sample, so\r\n  3 errors in 49 hand-adjudicated sites means the population carries ~6% slop and **321 is not\r\n  exact**). **317** classified BLIND. **4** report a measurement. **15** poll loops outside the\r\n  detector's reach, unclassified. **Still not established, and still not to be written: that 317 is\r\n  a FLOOR, or any repository-wide rate.** One direction is now exhaustive, the other bounded at\r\n  <=10% by a 30-site sample — a bounded estimate, never a floor, and silent about the 15.\r\n- **A distinction this validation surfaced, and the remedy above should carry: \"emits a clock\" is\r\n  TWO different things.** `transport_death_eof.rs:540` prints the OBSERVED quantity\r\n  (`{canary_after}ms`); `er_brief_once_per_session_e2e.rs:288` prints the MARGIN (`elapsed=`). Only\r\n  the second tells a reader how close the budget came. 3 of the 4 surviving CLOCK sites report a\r\n  margin, 1 reports an observation — and **a binary CLOCK/BLIND classifier cannot see that\r\n  difference**, which is a limit of the census, not of the sites.\r\n- **One edit to preserved evidence, DECLARED.** `census.py` printed `<-- IR-95 population (a FLOOR)`\r\n  on its blind line. That sentence was retracted the day it was written, but the retraction never\r\n  reached the SCRIPT, so re-running the preserved artifact reprinted the withdrawn claim at whoever\r\n  ran it — a retraction does not propagate to the next reader on its own. The LABEL, and only the\r\n  label, is corrected in place; the computation is untouched and **still reproduces 323 / 19 / 304**,\r\n  which is what makes this validation checkable against it. The old line is quoted verbatim in\r\n  `VALIDATION.md`.\r\n- **A FIRST detector was discarded, and its failure is itself evidence for cost 1 above.** Keying on\r\n  expiry VOCABULARY (\"never\", \"timed out\", \"did not appear\") found 53 sites and **missed\r\n  `contract_e2e.rs:393` entirely — the very site this entry was filed from** — because its panic\r\n  message is a CONTENT sentence. A wording-keyed census is structurally blind to exactly the sites\r\n  whose messages mislead. Recorded so no one re-runs the cheap version and reports 53 as the answer.\r\n- **Positive control passes, and it found siblings.** Both originating sites appear, both BLIND:\r\n  `sync.rs:102` and `contract_e2e.rs:395`. The census also surfaced **two fixed budgets nobody had\r\n  noticed** — `sync.rs:89` (`0..300`, beside the `0..400` at :102) and `contract_e2e.rs:51`\r\n  (`0..400`, beside the wall deadline at :393). Concentration: `inject_control_wedge.rs` 18,\r\n  `broker.rs` 10, `endpoint_lifecycle.rs` 9, `dispatch.rs` 7, `twohost.rs` 7.\r\n- **PRODUCER-PROGRESS INSTRUMENT — SPEC, 2026-09-10, and the three readings it does NOT support.**\r\n  The remedy above asks for the waited-on party's progress because a watcher's own timings cannot\r\n  separate a slow watcher from a slow producer. `last_streams_seen=0` throughout is equally\r\n  consistent with \"the producer never produced\" and \"the watcher never saw it\", and neither arm of\r\n  the releases#294 pair can tell those apart. **Design (doyle), narrowed by hertz and todlando, who\r\n  independently found the same three defects in the first form of it.**\r\n  **INSTRUMENT** — rides the IPC the poll ALREADY makes, so it adds no channel and no budget: the\r\n  responder's broker surfaces, alongside `net_streams`, a monotonic `streams_created_total` AND a\r\n  monotonic `streams_retired_total` for the session, the sequence and age of its last transition,\r\n  and the STREAM IDS of the most recent transitions so the watcher can correlate them against the\r\n  ids it sees and skips. The watcher prints the producer's counters beside its own observation.\r\n  **SEMANTICS THAT MUST BE DECLARED BEFORE A SINGLE READING IS TAKEN** — a bare count is not a\r\n  measurement until these are fixed: WHICH HOOK \"created\" fires at (broker stream-table\r\n  registration? wire acceptance?), WHICH KEY the counter is scoped to and what a session rotation\r\n  does to it, the COUNTER LIFETIME and reset behaviour (process lifetime, per session, what a broker\r\n  restart does), and WHICH CLOCK the age is measured against and whether it is comparable to the\r\n  watcher's.\r\n  **WHAT EACH READING LICENSES, and what it does NOT** (the first form of this table asserted three\r\n  causal conclusions it had not earned):\r\n  · `created=0` at expiry means **no creation was RECORDED AT THAT HOOK, in that counter's scope,\r\n    for that session key**. It does **NOT** establish that the requester never produced, and it does\r\n    **NOT** exonerate the watcher — the hook may sit downstream of the real production, or be scoped\r\n    to a different key.\r\n  · `created>0` with every snapshot empty is **CONSISTENT WITH a visibility/registration defect AND\r\n    with a stream being created and retired entirely between two 25 ms polls**. On its own it\r\n    establishes neither; the retire counter and the ids are what separate them.\r\n  · **Creation AFTER expiry cannot be observed by a poll that has already stopped.** A last-change\r\n    age cannot supply it. That needs either a separately bounded, separately declared post-expiry\r\n    observation, or a retained producer event trace with timestamps.\r\n  **Process constraints:** separately versioned and announced, never slipped between arms of a\r\n  comparison, and the existing diagnostic patch and every budget stay UNCHANGED. Widening a budget\r\n  to make a red go green remains refused.\r\n- **`last_streams_seen` IS A FILTERED-VIEW COUNT — the sharpest narrowing this field has had, and it\r\n  applies to all three expiries in the releases#294 pair.** The poll calls `net_streams`; the broker\r\n  answers at `broker.rs:9546` `dispatch_net_streams` -> `host.dispatch_stream_infos()`\r\n  (`nethost.rs:1952`) -> `stream_infos_filtered(FALSE)`, and that filter drops TWO classes\r\n  SERVER-SIDE, before serialization (ADR-0040 decision 2, `REQ-STREAM-INFOS-SERVER-FILTER`):\r\n  `!e.retired.load(SeqCst)` and `!e.initiated_locally`. So `last_streams_seen=0` does **NOT** mean\r\n  the broker held no streams. It means **zero NON-RETIRED, NON-LOCALLY-INITIATED rows at that\r\n  instant** — a row that exists and is retired is invisible to the poll BY DESIGN. That is narrower\r\n  than the corrected form the RCA had settled on (\"the final snapshot was empty\"), and it is a\r\n  hook-scope fact of exactly the kind the preconditions above demand be pinned before any reading.\r\n- **A \"reuse it, no product change\" stage-1 design WAS PROPOSED AND IS WITHDRAWN — recorded because\r\n  the reason generalises.** `NetHost::stream_counts()` (`nethost.rs:1980`) is already surfaced as\r\n  `NetStatusReply.streams_held` (`broker.rs:9002`, `msg.rs:874`) and documents itself as\r\n  \"retirement-blind ON PURPOSE ... the resource truth the eligibility view hides\". Reading it beside\r\n  `net_streams` looked like it would separate \"filtered out\" from \"absent\" for free. It does not,\r\n  for four reasons, and hertz and todlando raised them independently:\r\n  · **Two IPC replies are not an atomic snapshot.** `filtered=0` then `held>0` is equally consistent\r\n    with a row ARRIVING BETWEEN THE TWO CALLS. Such a pair must never be labelled proof of filtering,\r\n    and needs call order and timestamps recorded if it is read at all.\r\n  · **`streams_held` is HOST-SCOPED, not exchange-scoped.** It counts unrelated and locally-initiated\r\n    rows the filtered view drops, so it cannot speak to the exchange under investigation without\r\n    stream-ID correlation; any conclusion from it stays aggregate.\r\n  · **It adds UNMEASURED perturbation** — a second IPC per iteration changes the 400-iteration\r\n    window's wall duration by an amount nobody has measured. **CORRECTED 2026-09-10 (hertz,\r\n    todlando), because the first form of this bullet was itself an overclaim in two ways and both\r\n    are instructive:** (a) it called perturbation DISQUALIFYING, and it is not — instrumentation\r\n    that perturbs timing can still be useful; the objection is ADDED, UNMEASURED perturbation, not\r\n    perturbation as such. (b) It SIZED that perturbation from two figures that cannot carry it: the\r\n    measured `net_streams` cost (60,295 us / 400 = 0.151 ms per iteration) does **not** estimate the\r\n    `net-status` cost — different call, different work — and the **0.29% expiry difference between\r\n    the two arms is NOT an established causal effect size**, only an unexplained gap between two n=1\r\n    observations. Sizing an observer effect against it treats an open question as a known\r\n    quantity.\r\n  · A single POST-EXPIRY sample avoids perturbing the poll but then describes LATER state, not\r\n    expiry state, and is still host-scoped.\r\n- **THE INSTRUMENT THAT SURVIVES REVIEW: a retained, EXCHANGE-CORRELATED create/retire TRACE**\r\n  (hertz and todlando, converged independently). Recorded per stream lifecycle transition on the\r\n  producer side — stream id, conn id, remote id, transition, `initiated_locally`, a monotonic\r\n  sequence and a timestamp on a NAMED clock — retained and read AFTER the fact rather than sampled\r\n  by the watcher, so it adds **NO POLL CALLS**. Say that, and not \"adds nothing\" (hertz): it still\r\n  adds PRODUCER-SIDE work that may affect arrival timing and resource contention, and **that effect\r\n  is unmeasured too**. The trace is preferable for having no watcher IPC, not for being free. It captures between-poll transitions,\r\n  which neither a gauge nor an in-loop counter can: **a gauge reads 0 for a stream created and\r\n  retired between two 25 ms polls exactly as it does for one never created.** Correlation to the\r\n  exchange is by stream id against the ids the watcher saw and skipped.\r\n  **MEASURED: it does not exist today** — zero stream-lifetime log lines in `nethost.rs`. So this is\r\n  a PRODUCT change, not a reuse, and it stays unbuilt while the product is frozen. Its preconditions\r\n  are the ones above, unchanged. Production AFTER the trace's retention window remains outside it.\r\n- **THE FIRST MARGINS THIS ENTRY PRODUCED UNDER CI / GOLDEN CONDITIONS — instrumented run\r\n  34458491560, 2026-09-10\r\n  (hertz's patch; deployah's lane; read independently by doyle).** The remedy above was argued for\r\n  on the ground that a poll which prints nothing cannot say how close it came. It has now printed\r\n  on a runner. **NOT the first margins overall** — the earlier local 12-leg run already reported\r\n  them, including a 392/400 (hertz, todlando). **The genuinely novel quantity is narrower and\r\n  sharper than \"CI margins\" (deployah): it is a FAILING poll's margin, which no local leg could\r\n  produce because all 12 of them PASSED.** A budget's behaviour at expiry is the one thing a green\r\n  run structurally cannot report, and it is the case the remedy exists for.\r\n  **The figure is the MAXIMUM AMONG SUCCESSFUL polls in this run — explicitly NOT a ceiling, and not\r\n  a bound on observations**: the poll that EXPIRED in this same run consumed 400/400 = 100%. So:\r\n  among the polls that PASSED on hfenduleam, both instrumented sites peak at ~63% of budget. The\r\n  seven successful\r\n  `[IR95-SYNC]` waits in that run are 92, 19, 72, 254, 21, 21 and 20 iterations — **worst 254/400 =\r\n  63.5%** (6.449393 s) — and the `[IR95-CONTRACT]` success consumed **18.857089 s of its 30.000 s\r\n  wall = 62.9%**. Two independent sites, two different budget KINDS, the same maximum-among-passes.\r\n  Headroom at that worst SUCCESSFUL case ~37%; the failing case had none left. **n=7 and n=1, one\r\n  box, one run: a first CI measurement, not a stability claim, and NO budget change is proposed on\r\n  it.**\r\n- **The iteration budget's WALL EQUIVALENT, also measured for the first time.** The expiring poll's\r\n  400 iterations cost **10.199907 s against 400 × 25 ms = 10.000 s nominal — 2.0% over**, with\r\n  per-iteration overhead ~0.5 ms against a 25 ms sleep (IPC 60.295 ms total, 0.151 ms per iteration,\r\n  **0.59% of elapsed**; sleep is 99.4%). So on this box in this run a \"400 iteration\" budget and a\r\n  \"~10.2 s wall\" are nearly the same object — the iteration budget did NOT silently become a\r\n  different budget under load. That bounds one standing worry about blind iteration counts, and it\r\n  is precisely the class of thing that stops being guessable the moment a clock prints. Box-local\r\n  and run-local; it is not a general result.\r\n- **A scope limit the instrumentation itself imposes, and a smaller ask than it first looks.**\r\n  `last_streams_seen` is an ASSIGNMENT per iteration (`sync.rs:111`), not an accumulator, so\r\n  `last_streams_seen=0` at expiry describes the FINAL iteration only — not all 400 (todlando's\r\n  correction; deployah withdrew the aggregate reading, doyle confirmed it at source). But the loop's\r\n  CONTROL FLOW already proves the interesting half for free: the `find()` at `:113` returns the\r\n  instant a non-skipped stream appears, so **reaching the expiry print IS proof that no non-skipped\r\n  stream was seen in any of the 400 SNAPSHOTS** — no aggregate trace required. **It does NOT mean\r\n  no stream EXISTED between snapshots** (hertz): the poll samples at 25 ms, and nothing here\r\n  observes the gaps. What is genuinely\r\n  unmeasured is only whether a SKIPPED stream was ever present, and `skip` is empty on that call.\r\n  An aggregate/per-iteration trace therefore buys less here than the gap first suggests.\r\n- **NOT ESTABLISHED: that all 304 deserve a clock.** The census SIZES the problem; it does not\r\n  schedule it, and it does not pre-judge which sites are worth the edit. Remedy triage is owed\r\n  separately and is the larger half.\r\n- **Kin:** [[IR-84]] (the one `PUMP_PEER_FAIL` arm the rigs fire was the only one carrying no clock —\r\n  **the same class in product code**; this entry is its test-corpus face), [[IR-85]] (budgets sized\r\n  against a box whose speed moved), [[IR-77]] (nothing stamps the spawn-to-first-log interval, so a\r\n  readiness red cannot say where the time went), [[IR-90]].\r\n- **Ripe when:** with the releases#294 instrumented base-vs-head comparison, which **cannot be run\r\n  without it** — the experiment's whole output is the margins these sites do not print. ·\r\n  **Size:** small per site; the census is the larger half.\r\n\r\n### IR-96 — the `daemon_stop_convoy_e2e` API-storm cell fails 3-of-3 under the HEAVY suite at the diagnostic tree while passing at the candidate in golden CI, and nothing yet separates instrumentation from box from product\r\n\r\n- **Status:** OPEN, **cause-unclassified** (todlando's and hertz's stipulation, adopted verbatim — a\r\n  triage placement here is NOT a finding of non-defect).\n…\n","startLine":5428,"lineNumbers":[5428,null,5430,null,5479,null,5481,5482,5483,5484,5485,5486,5487,5488,5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504,5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552,5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600,5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616,5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632,5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664,5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792,5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,null,5963]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":6937,"totalBytes":40920,"outputLines":450,"outputBytes":40920,"shownRange":{"start":5481,"end":5930},"nextOffset":5931}}},"isError":false,"timestamp":1789483669305}}
{"type":"message","id":"b78dba37","parentId":"28b4373a","timestamp":"2026-09-15T14:47:49.316Z","message":{"role":"toolResult","toolCallId":"call_Str3WkuDknjM3SZXXaQTQMCX|fc_000c7cef03cac861016aa95a95282487d1950d6423ddc7c130","toolName":"read","content":[{"type":"text","text":"### IR-95 — a burned polling budget names WHAT it wanted and never HOW LONG it waited, so no run, green or red, can say how close it came\n…\n- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 golden RED, where it cost this\n…\n- **Ripe when:** with the releases#294 instrumented base-vs-head comparison, which **cannot be run\n…\n\n### IR-96 — the `daemon_stop_convoy_e2e` API-storm cell fails 3-of-3 under the HEAVY suite at the diagnostic tree while passing at the candidate in golden CI, and nothing yet separates instrumentation from box from product\n\n- **Status:** OPEN, **cause-unclassified** (todlando's and hertz's stipulation, adopted verbatim — a\n  triage placement here is NOT a finding of non-defect).\n- **Origin:** releases#294 / v0.69.0 Arm B, 2026-09-10, deployah executing at diagnostic tree\n  `ed8ecd94` (= candidate `a9e786b2` + the unlanded sync instrumentation, never merged).\n- **What:** `spt::daemon_stop_convoy_e2e stop_under_an_api_storm_stays_down_then_start_brings_up_exactly_one`\n  FAILED in **all three** Arm B runs, with durations **growing every run: 9.473s · 10.973s ·\n  14.553s**. Different signature from the #294 sync cell; nothing was filed against #294.\n- **THE DIFFERENTIAL that makes it worth an entry rather than a shrug:** the same cell shows **0\n  failures at the candidate** in golden 34481993681 Phase A on this same box — that run's single\n  failure was the sync cell (`3381 tests run: 3380 passed (6 slow, 5 leaky), 1 failed, 1 skipped`).\n  So: 0-of-1 at `a9e786b2` under CI load, 3-of-3 at `ed8ecd94` under local HEAVY load.\n- **WHAT THAT DOES NOT ESTABLISH.** It does **not** isolate the instrumentation or the box as the\n  only candidates — a condition-dependent or intermittent PRODUCT defect remains live, and a single\n  CI pass is not evidence of absence. doyle claimed that elimination on 2026-09-10 and **withdrew\n  it** the same hour under todlando's and hertz's correction; the withdrawal is recorded in\n  `.spt/preserved/gate-r2-34481993681-20260910/CLASSIFICATION-AMENDMENT-2-doyle.md`.\n- **Confounded by IR-97** (below): the three runs were not equivalent conditions.\n- **Ripe when:** any lane touches daemon stop/start convoy behaviour, OR a golden run reds this cell\n  at a candidate, OR someone runs the cell at `a9e786b2` under the same local HEAVY workload — that\n  last one is the cheap discriminator and nobody has run it. · **Size:** one targeted local run to\n  discriminate; unknown beyond that.\n- **Disposition 2026-09-11 (doyle ruled, hertz's own call to release):** the diagnostic pool\n  `.worktrees/hertz-294-sync-stages/target` is DELETED — ARCHIVAL, REBUILD REQUIRED. It held the\n  `ed8ecd94` diagnostic arm, not `a9e786b2`, so keeping it warm bought nothing for the discriminator\n  above; no exe/dll/pdb retained because nobody was spending a heavy-broker execution window on the\n  post-deletion proof run, and an unexecuted retained set is a prediction. Receipt\n  `.spt/preserved/doyle-294-sync-stages-reclaim-20260911/{before,after}.json`: 30,000,890,067\n  logical bytes / 30,723 files; free 179,320,270,848 -> 207,004,086,272 (observed gain\n  27,683,815,424; concurrent builds moved ~2.3 GB in the 12 s window, so the delta is not\n  single-operation attribution). The 209-PDB reclaim that preceded it (hertz, 44,005,806,080\n  observed) is `.spt/preserved/hertz-relay-20260911/reclaim-deletion-receipt.json`. Source tree,\n  branch `diag/294-sync-stages` and every preserved receipt stay. The investigation stays OPEN and\n  cause-unclassified; its next run is a rebuild at `a9e786b2`.\n\n### IR-97 — a suite that leaks a fixed cohort of child processes per invocation makes consecutive runs non-comparable, and the between-run accounting the protocol required was not enforced\n\n- **Status:** OPEN. **Protocol deviation** (hertz's framing, and it is stronger than \"confounder\":\n  the protocol ALREADY required between-run accounting — execution did not enforce it, so the fix is\n  enforcement, not a limitations paragraph).\n- **Origin:** releases#294 Arm B, 2026-09-10. Derived by doyle from deployah's preserved\n  `10-residual-births.json` against the run windows.\n- **What:** each Arm B suite leaked **exactly 6** `spt` children that outlived it; all **18** were\n  still alive at the post-B3 census. Because a process alive at census whose OS birth time falls in\n  an earlier window existed continuously through the runs between (pid + birth time is an identity),\n  the carried diag-tree residue was **0 during B1 · 6 during B2 · 12 during B3**. The three\n  \"repetitions\" were therefore not three equivalent conditions, and every cross-run comparison in\n  that arm inherits it.\n- **LIMITS, stated so the entry is not over-read:** process **COUNT** is measured; **LOAD is not** —\n  idle orphans may cost nothing, contention was UNMEASURED (overlap UNVERIFIED all arm), and this is\n  **not** a drift meter. It neither implicates nor excludes residue as a cause of the one expiry, and\n  it does not explain it: B3 carried twice the orphans and **passed**.\n- **Also unestablished, in both directions:** 18 censused against 15 killed shows only that three\n  were absent at the second read. \"Three self-exited\" needs exit evidence; \"I killed 18\" was\n  likewise refused by deployah at the time.\n- **Kin:** the LEAK rows every Arm A/B run reported; `REQ-HAZARD-RESUME-CUSTODY-ABA` (KH 7.51) and\n  KH 7.58 — the cleanup that resolved this was correctly scoped by **pid + image path**, leaving 15\n  unrelated `spt` processes untouched, where a name-based kill would have taken down the live agent\n  fleet including the gater's own session.\n- **Ripe when:** any repeated-run experiment is designed on this box — census BETWEEN runs, not only\n  at the end. · **Size:** a between-run census step plus a scoped reap in the harness.\n- **Applied 2026-09-11 (#304):** hertz requested and doyle granted an EXCLUSIVE EXECUTION window for\n  the admitted heavy-broker-PTY subset — builds from the second lane may overlap, real-daemon test\n  execution may not — because a second tree executing real daemons concurrently makes the census\n  non-attributable and reproduces exactly this defect. Window START/END go builder-to-builder\n  (hertz -> todlando) with doyle copied.\n- **Crossing 2026-09-11 09:12:45Z-09:13:35Z, recorded as a mechanism:** the coordinator resequenced\n  the two builders (todlando first) at ~09:12:2xZ; hertz's START went out at 09:12:45Z before that\n  arrived; todlando sampled admission at 09:12:57Z and launched. Both builders disclosed within a\n  minute; hertz's START turned out to be an ANNOUNCEMENT (nothing launched) and was retracted, so no\n  two real-daemon executions overlapped — but for 50 seconds three agents each held a different\n  picture of who owned the box, and each was right on the messages it had. Rules that fall out:\n  START is sent when the first producer is LAUNCHED, not when the window is decided; a builder who\n  learns of a crossing FINISHES the attempt in flight and marks the overlap rather than aborting\n  (an aborted attempt is a labelled hole, a marked overlap is still evidence); and a coordinator\n  resequencing two live builders names the token that transfers the box (the other's END), because\n  an ordering that depends on message arrival order is not an ordering.\n\n### IR-98 — a lane driver that PRINTS a producer's output can die on an unencodable byte AFTER that producer's evidence is on disk, so the run ends with complete evidence for producer N and NO files for N+1 — an absence that reads as \"never queued\", not as a failure\n\n- **Status:** OPEN as a mechanism; the measured instance is FIXED in hertz's lane driver (UTF-8 with\n  replacement reconfigured at import, positive control run before relaunch: U+2500 and U+2713\n  printed through the fixed driver, exit 0).\n- **Origin:** releases#304 hertz lane, 2026-09-11 08:58Z, exclusive execution window. Producer 1\n  (spt-daemon lib, 21 cases at `7b098cc2`) returned exit 100 with exit, observation.json, raw and\n  stdout all intact; the driver then printed the stderr tail to a cp1252 stdout, raised\n  `UnicodeEncodeError` on nextest's box-drawing characters, and killed the loop. Producers 2 and 3\n  (spt bins x5, docs_server_e2e x1) NEVER STARTED. Reported by hertz as a labelled hole before any\n  result was read as a pass.\n- **What (hertz's one line, kept):** a driver that prints a producer's output can destroy the REST\n  of a run while leaving the finished producer's evidence intact, so the surviving evidence looks\n  complete and the missing producers look like they were never queued. **The tell:** evidence files\n  exist for producer N and no files at all exist for N+1 — not a failure, not a skip, an absence.\n- **Rule:** a sequence driver's own crash is a run outcome and is written as one (which producers\n  ran, which never started, why), and console rendering of producer output never sits between a\n  producer's completion and the next producer's launch without a defined encoding.\n- **Kin:** [[IR-32]] (an instrument that agrees with itself), [[IR-46]] (one reading is an instant),\n  the memory rule \"cancelled = labelled hole\"; the shell-side kin is `render-not-read-pipefail`.\n- **Ripe when:** any new sequence driver or any driver that renders producer output to a console;\n  `.github/ci/local-lane.py` and its lane modules are the first population. · **Size:** one\n  encoding reconfigure plus a written \"never started\" arm in the run summary.\n\n### IR-99 — EOF and terminal retire on a ConnectionBound net stream arm on the OPENER CONN's exit; a same-morning diagnosis built on that mechanism was refuted by the compiler, so the mechanism stands and the two #304 reds beside it stay open\n\n- **Status:** OPEN. The mechanism is VERIFIED; both reds are CLASSIFIED NOT-product (instance 1: an\n  unpromised spectator EOF; instance 2: a journal replay of a reused op seq) — repairs built at\n  `849c2da8` (hertz) and blob `42efe323` (todlando), each awaiting its one exclusive-window run.\n- **Mechanism (hertz read, doyle verified at `a17dbfbd`):** `broker.rs:6368-6372`, conn teardown: for\n  every ConnectionBound row THIS conn opened, FIN + `retire_stream_terminal` +\n  `STREAM_CONNBOUND_RETIRE:{id}: opener conn exited`. ADR-0040 decision 6. A detach, a controller\n  swap, or a record on the wire does not arm it; the OPENER CONN's exit does.\n- **Instance 1 — hertz, `rc::tests::viewer_byte_detach_keeps_controller_and_child` (2026-09-11 09:00Z):**\n  a 10 s wait for `NetStreamEof` on the PEER row after a viewer detach expired. First diagnosis: the\n  opener conn (`operator`) outlived the loop, so no FIN — **WITHDRAWN at `27baeb61`**: the compiler\n  refused the fix with `E0382 use of moved value: operator` because `operator` is moved into the\n  viewport pump at `rc.rs:4263-4266` and is already dropped when `viewport.join()` returns before the\n  loop. Still true and still unexplained: the run retires stream 2 and never stream 1 while the\n  observer waits on the peer row. **Open question:** does a FIN on the locally-initiated row reach a\n  subscriber of the PEER row at all? UNCLASSIFIED; producer 2 of the #304 subset is held until it is.\n  **Second run at `96325c9b` (09:17-09:18Z, box quiet):** the case now prints\n  `PEER_ROW_SELECT: inbound_rows=1 on_dialed_conn=1 picked=1`, so the unordered `find` selection\n  (real, repaired by conn_id + exactly-one assert) had nothing to choose between and is NOT the\n  cause. Two runs at two shas now pin the topology: peer row = stream 1, operator's local row =\n  stream 2, `STREAM_CONNBOUND_RETIRE:2` fires, and a subscriber of stream 1 receives no\n  `NetStreamEof` within 10 s. **Measured fact:** a FIN plus terminal retire on the locally-initiated\n  loopback row does not deliver EOF to a subscriber of the paired peer row. Whether that is promised\n  by the design (ADR-0040, the stream-lease requirement) is the open question; a test-side edit that\n  drops the wait is refused until a citation answers it either way.\n  **Answered 09:22Z (hertz cited, doyle verified):** NOT promised. ADR-0040 decision 6 (:80-83, the\n  `REQ-STREAM-LEASE-CLASSES` doc tag) promises that on the opener's EOF *the target* sees FIN and\n  `serve_attach` runs `detach_session`; it names no spectator subscriber, and every promised\n  consequence was delivered in the red run itself (`Detached` join passed, controller and child\n  survived, stamps cleared). Verdict: NOT a product finding; the case asserted a property the design\n  never made. ADR-0040 :156-163 already names the trap — reasoning from the arm that reads like a\n  guarantee to a consequence it does not carry — and this is its third instance. Repair ruled: keep a\n  barrier on a PROMISED observable (the row's `finished`/gone state, or the `Detached` join itself)\n  and assert the absence against it; a bounded drain justified as a timing window is refused.\n  **These two instances are two lessons under one family heading, not one mechanism** (hertz's own\n  correction of his earlier framing): instance 1 is an unpromised event on a spectator subscription;\n  instance 2 is a conn exit between test arms retiring the rows the next arm needed.\n- **Instance 2 — todlando, `attach::admission_answers_the_clients_own_identity_with_applicable_policy`\n  (09:08Z):** \"no such stream 2\" one read after `STREAM_CONNBOUND_RETIRE:2`, with controller-attach,\n  writer-exit `channel-closed` and the retire in the same millisecond. By the mechanism the retire is\n  downstream of that conn exiting; WHY the writer saw `channel-closed` at admission is the open\n  question, with two named candidates (the helper's own lifecycle; the new ClientPolicy send being the\n  first wire-side send on that transport). UNCLASSIFIED; two approved discriminator probes pending.\n  **Probes (a),(b),(c) at 09:12-09:15Z:** (a) the unmodified loopback-pump cell is GREEN, so the\n  daemon change did not break the shared pump; (c) an identity-free arm run in position 2 fails the\n  same way, so declared identity is NOT necessary. **Shared-operator fix REFUTED (09:20Z):** one\n  borrowed conn across arms, error became `no such stream 2` again — the conn was never the thing\n  that died.\n  **CLASSIFIED 09:25Z (doyle, source at `d80239df`): NOT product — TEST DEFECT, one op seq reused\n  across arms.** Every arm called `request_attach_endpoint` with `MintedOp::new(Minter::Rc, 2)`.\n  The open is journaled: `dispatch_net_stream_open` (`broker.rs:9575-9598`) keys `apply_once` by\n  `EffectKey { class, minter, op }` (`effect.rs:299`) — no conn, no session, no stream in the key —\n  so arm 2's open returned `Replayed`, the closure never ran, the allocator was never consulted, and\n  `stream_op_id(Rc, 2)` handed back the RECORDED id 2 with `applied_now=false` (`broker.rs:6141`\n  comment says exactly this). Row 2 had been terminal-retired at arm 1's opener exit ⇒ \"no such\n  stream 2\". The allocator sentence above (monotonic `fetch_add`, nethost.rs:1109) and todlando's\n  measurement (a fresh open returning the just-retired id, twice) were BOTH true: the second open\n  never reached the allocator. Journal is file-backed per home (`bind_in(name, dir/effects.log)`),\n  so a reused home replays at position 1 too; todlando's homes were per-test fresh.\n  **Withdrawn by replacement (todlando, 09:26Z):** the 2x2 — its position-1 cell rested on marker\n  absence in stderr, and markers are never written to stderr on pass or fail (zero-match filter);\n  \"id reissued after terminal retire\" (a journal replay); \"FIN takes the conn with it\" (nothing was\n  opened the second time). No product suspicion reaches this register from instance 2.\n  **Repair (built, uncommitted, blob `42efe323`, base `58b95354`):** one broker, five arms, DISTINCT\n  seqs 2-6, identity-free control in positions 1 AND 2, `ARM_OPEN` prints the seq. Prediction filed\n  before the run: green on all five. Negative control on file: same seq, red twice. Run pending an\n  exclusive window after IR-97's producer 2.\n- **Rule (revised after the withdrawal):** a test that waits on EOF must first establish WHICH row\n  FINs and WHO observes it, from source, before it names a deadline \"a barrier\"; a test surprised by a\n  retire looks for the conn that exited before it looks at the stream. And a mechanism verified in\n  source does not verify the diagnosis built on it — ownership of the variable the diagnosis names is\n  a separate check the compiler happened to make for free here.\n- **Kin:** [[IR-97]] (same window), KH 7.66 (an expired bounded wait is CENSORED, not a latency), the\n  memory rule \"hedge is not grounding\".\n- **Ripe when:** any new test reads a ConnectionBound stream to EOF or asserts on a retire; the\n  ~20 house-standard 400x25 ms wait sites are the population to grep. · **Size:** one comment per site\n  naming what arms the edge, once the open question above has an answer.\n\n### IR-100 — an editor-driven rust-analyzer runs `cargo check --workspace --all-targets` into a LANE's pool on its own schedule, so a builder census counts it, a lock wait charges it to nobody, and the lane's disk growth carries it uncredited\n\n- **Status:** OPEN. Recorded 2026-09-11 09:30Z from todlando's trace; no mitigation applied.\n- **Instance (todlando, `.worktrees/304-product`, 09:29Z):** his distinct-seq build printed\n  `Blocking waiting for file lock on build directory`. Holder pid 28176, ancestry\n  `cargo check --quiet --workspace --all-targets --manifest-path .worktrees/304-product/Cargo.toml`\n  ← `rustup` ← `RUST-ANALYZER.EXE` ← `claude.exe` ← `claude-spt.exe` — his OWN session's language\n  server, checking his lane's manifest into his lane's `target/`. Not CI, not another lane. NOT a\n  pool violation (same tree, same lane; `SPT_POOL_FOREIGN` correctly silent).\n- **Second instance, the asymmetry (hertz, 09:31:40Z, ancestry walked):** TWO analyzers on this box,\n  one per live session, BOTH with cwd at the project root. todlando's (rust-analyzer 46072) resolved\n  `.worktrees/304-product/Cargo.toml` and builds into HIS pool; hertz's (26640) resolved the ROOT\n  manifest and builds into the root `target/` — a pool that is not his lane's. So hertz's growth\n  figures and lock waits were never charged by his own analyzer, and NOT because anyone chose that:\n  cwd is identical for both, so cwd is not the discriminant. The candidate is which files each\n  session opened (rust-analyzer discovers its workspace from them) — UNMEASURED. Read IR-100 as \"the\n  blast radius depends on which manifest the analyzer resolved, and nobody chose it\", never as \"that\n  lane was clean\".\n- **Instrument (hertz, same hour):** `lane_run.builder_census` now walks each builder's ancestry and\n  attributes it `ci` / `analyzer` / `agent` / `unknown`, printing the manifest from the cmdline when\n  legible; live box read 11 ci, 1 analyzer, 0 agent, 0 unknown. Quiet predicate revised from \"zero\n  builders\" (never clears under a peer's analyzer, leases nothing when it does) to \"zero CI builders\n  AND no builder whose manifest is MY worktree\"; a peer's analyzer is recorded contention, not a\n  refusal. Still a sample, not a lease.\n- **Why it matters (three census readings it breaks):** (1) `BUILDERS=n` in an admission census\n  includes it, so a nonzero count is not \"CI or another lane\" and a zero is not \"quiet for the next\n  minute\" — an editor can start a workspace check at any moment; the census is a sample, not a lease\n  (hertz's own words on his window, [[IR-97]]). (2) Its rmeta/dep-info growth lands in the lane's\n  allocation without a declared producer, so a producer's \"growth\" is an upper bound on that\n  producer. (3) It delays a producer without failing it: a one-attempt run that sat on the lock is\n  slow for a reason no window ledger named.\n- **Third limit, from outside (todlando 09:42Z, hertz confirmed 09:43Z):** a BUILDER census is blind\n  to a peer's EXECUTION phase. hertz's producers run test binaries, which carry none of the builder\n  names the census matches on, so 0 cargo sampled DURING his open window read as \"quiet\" — and doyle\n  read his own zero-cargo sample as an answer to a START he had already recorded. hertz's own\n  instrument would not have caught hertz's own window. todlando's admission census (09:42:58Z) already\n  sweeps the other half: test binaries under any `target\\debug\\deps` (0) with a positive control (10\n  shells visible), which is the form the census must take. Rule: a census is ADMISSION evidence only —\n  builders by ancestry AND executing test binaries under `deps`, each with a positive control; whether\n  the box is BUSY is answered only by a granted-and-acknowledged window ([[IR-97]]), never by a sample.\n- **Fourth limit, the census's own blind spot (hertz 10:13Z, measured 556 processes):** a path-keyed\n  filter must count what it COULD NOT ANSWER FOR separately from what it answered \"no\" to. todlando's\n  WMI/Get-Process path reader refused ~180 protected processes (declared); hertz's psutil reader saw\n  553/556 but his `exe or \"\"` swallow turned two EMPTY paths into \"not in the pool\" and declared 1\n  blind when the real hole was 3. Both under-declared, by different mechanisms. A blind spot that does\n  not raise is the same clean zero a broken filter returns. admission.py now counts empty as blind.\n- **Rules:** a builder census classifies by ANCESTRY, never by count — `Runner.Worker.exe` = CI, a\n  lane's own cargo = a producer, `RUST-ANALYZER.EXE` = editor check. A lock wait is recorded as a\n  delay with its holder's ancestry, as here; nobody kills an analyzer, and the analyzer's check is\n  charged to the LANE, so any growth figure quoted from a lane pool says so.\n- **Recommendation to the operator (rides here, not as a directive to agents):**\n  `rust-analyzer.cargo.targetDir` (true, or a path under the lane's `target/`) gives the analyzer\n  its own build directory — that removes the LOCK contention and the census ambiguity in one\n  setting; it does not remove the disk, which stays in the same pool subtree by design.\n- **Kin:** [[IR-97]] (exclusive execution windows; builds may overlap), [[IR-56]] (a pool is a\n  relationship, not a path), the memory rules \"measure the box before the instrument\" and \"quiet\n  window predicate\".\n- **Ripe when:** the next admission census on this box, or the next lock wait anyone traces.\n  · **Size:** one editor setting plus one line in the census procedure.\n\n### IR-101 — no per-lane producer compiles a lib crate's own `#[cfg(test)]` module on the branch that broke it, so a stale caller of a lane's own signature change rides green through six real-daemon runs and surfaces only at assembly, or from an editor\n\n- **Status:** OPEN. Rule adopted 2026-09-11 09:35Z; instrument = one command at inventory and one at\n  assembly.\n- **Instance (todlando, `feat/304-remote-friction-product`, 09:33Z):** `a4017a15` (#301) dropped the\n  port parameter from `webserve::handle_path`/`resolve_path` (six params). Six call sites in that\n  file's own `#[cfg(test)]` module — :856, :1132, :1201, :1206, :1213, :1333 at `58b95354`, verified —\n  still passed seven with a literal `5474`. `E0061`, committed since `a4017a15`, invisible to every\n  producer the lane ran: `cargo nextest … -p spt-daemon --test attach` builds the INTEGRATION target\n  and a lib's cfg(test) module is not in that graph. Found by the analyzer of [[IR-100]] (`cargo check\n  --workspace --all-targets` is the one invocation on the box that compiles lib test modules).\n  Fix `5853cb14`: the six arguments dropped, 6+/6−, nothing else.\n- **Consumer half (hertz):** his lane ran `-p spt-daemon --lib` all morning, which DOES compile that\n  module, and was 21/21 green at `a17dbfbd` — because he had ALREADY repaired those callers at\n  `5fd683e9` (test-only, all hunks past the cfg(test) line at :821; verified) while rewriting the\n  #301 node-root cases in the same module. So the gap is not \"nobody builds it\"; it is \"nobody builds\n  it on the branch that broke it\", and a per-lane green on the other lane is silent about this one.\n  todlando's first account (\"hertz's tree lacks a4017a15\") was wrong and withdrawn; `merge-base\n  --is-ancestor` is TRUE.\n- **The collision it exposed:** two lanes edited one cfg(test) module for one issue all morning,\n  independently. Measured with `git merge-tree --write-tree 849c2da8 5853cb14` (no checkout touched,\n  merge-base `d89a655f`): exactly ONE conflict, content, `webserve.rs`; `rc.rs` and\n  `bootstrap_firewall/windows.rs` auto-merge. Loud, not silent. Ruled: todlando keeps `5853cb14` (a\n  lane whose lib tests do not compile is blind to this class); assembly resolves that module to\n  hertz's blob and asserts the resolved blob equals his; hertz owns `webserve.rs` cfg(test) for #304.\n- **The clean win that drops coverage (hertz, 09:37Z):** reading todlando's six-line diff showed\n  hertz what his own module had deleted: the case at todlando's :1198 was the only place feeding\n  hostile text through `escape_html`, which is still live in production on the message facet\n  (`webserve.rs:494-510`). His #301 rewrite replaced that case and dropped the escaper coverage.\n  Resolving \"to hertz's blob\" would have lost it PERMANENTLY with no conflict — a correct-looking\n  resolution, not a merge collision, is the silent case. Restored at `9f09db4e` (test-only, +30 at\n  :1185: the compound string, each of five entities alone, a pass-through negative control; the\n  comment names its limit — escaper, not call sites). His absence census (\"grep returned NOTHING\")\n  came from a predicate built from the case he was looking at (`script a=|&lt;script|&#39;|&quot;`),\n  which cannot match `&amp;`; rule: census the SUBJECT (`grep escape_html`), never its rendered\n  effect.\n- **Second instance, integration axis (doyle, 09:39Z):** `a4017a15` deleted the registry index\n  outright (`fn index`, `Index`, `IndexEntry`, the `?json` twin; 19+/84−). `tests/webserve_e2e.rs`\n  (last touched `f3a5e169`, 2026-09-07; byte-identical on main and all three lane shas) asserts\n  that index at :53 and :67 (`GET /LoCaL/?json` = 200 with entries, `GET /local/` = 200 HTML with\n  `source &amp; quote.txt`). Integration tests run only in the golden lane, and no #304 producer\n  names this file (allocations grep: only deployah's #294 arms and CI job logs). Prediction filed\n  before any run: `production_listener_routes_nodes_docs_and_live_registry_references` RED at every\n  #304 sha; the other four cases UNKNOWN. Tags riding in it: REQ-WEB-URL-NODE-PREFIX,\n  REQ-WEB-SERVING-REGISTRY, REQ-DOCS-LOCAL-SERVER, REQ-WEB-ADAPTER-DOCS-FACET — if\n  REQ-WEB-SERVING-REGISTRY's int evidence WAS the index, it is relocated, not faked. Assigned to\n  hertz as producer 3 in a SECOND window after producers 1+2 at `9f09db4e`, so the frozen sha is not\n  churned. todlando's hermetic unit twin of it (`index_escapes_html_…`) reds at :1197 on his branch\n  for the same reason; that case is scheduled to stop existing at assembly and nobody fixes it.\n- **Rules:** (1) a lane inventory owes `cargo check --workspace --all-targets` at the sha it reports,\n  before any evidence is quoted — a prerequisite, not evidence about the merge. (2) The assembly\n  compile gate is the same command on the MERGED tree, before `traceable-reqs check`; it is the only\n  step that sees the cross-lane case. (3) A per-lane `--lib` green on a sibling lane is never cited\n  for the lane under test. (4) A lane that DELETES a surface greps the integration tree for that\n  surface's assertions in the same change; golden is not the place to learn an e2e was pinned to it.\n  (5) Before resolving a same-module conflict to one side, diff the LOSING side for assertions the\n  winner lacks — the conflict is the loud case; the clean win is the one that drops coverage.\n  (6) A hermetic in-proc cell is not a window producer, but it is ANNOUNCED before it runs so an\n  ancestry census can attribute it (todlando's 09:37 cell read as `agent=4` during hertz's sample).\n- **Kin:** [[IR-100]] (the instrument that found it), the memory rules \"cfg-gated code is invisible\n  to the other platform gate\" (same shape, other axis), \"gate population excludes consumers\",\n  \"resolve wrapper conflict toward the shared body\".\n- **Ripe when:** now — the next #304 inventory and the #304 assembly. · **Size:** one line in the\n  inventory script, one in the assembly runbook.\n\n### IR-102 — a dirty file the lane DECLARED is still invisible to an assignment made against its committed blob, so the gater measures and predicts on a blob the lane was never going to run\n\n- **Status:** OPEN. Recorded 2026-09-11 09:50Z from hertz's correction; ruling applied (commit all\n  five), no instrument yet.\n- **Instance (#304, hertz lane, 09:17Z–09:48Z):** hertz named his dirty files at his 09:17 START and\n  said none entered producer 2's compile scope — true. doyle then measured `tests/webserve_e2e.rs`\n  byte-identical on main, 849c2da8, 9f09db4e and 5853cb14 (true of the COMMITTED blob), predicted\n  reds at :53/:67 against it, and assigned the repin to hertz. hertz's working tree had carried an\n  uncommitted 16+/20- repin of that file all morning. The prediction was UNTESTABLE AS FILED: the blob\n  it named was not the blob the lane would run. Four more dirty files (ci.yml, golden.yml,\n  twohost_web.rs, attach_link_push_e2e.rs, webserve_cross_node_e2e.rs) carried an impl tag for a REQ\n  registered only in the lane (REQ-LOCAL-GATE-EXECUTION-EVIDENCE, stages impl+unit), a checker\n  version pin the lane's `[placement]` table depends on (0.4.0; main and the gater's box at 0.2.0),\n  and int tags on 169 lines no producer had run.\n- **Mechanism:** \"declared\" answers \"does it touch THIS run\"; it never answers \"is it the SUBJECT of\n  the next assignment\". A gater who measures `git show <sha>:<path>` across shas is measuring\n  committed history and cannot see a working tree by construction — the two instruments answer\n  different questions and the answers were confused because the file had the same name in both.\n- **Rules:** (1) an assembly takes COMMITTED blobs only; a tag on an uncommitted line is a tag on\n  nothing, and uncommitted work at assembly is not in the release. (2) Before assigning a file to a\n  lane, `git -C <lane> status --short -- <path>` — one command — and if it is dirty, the assignment\n  names the working blob, not the committed one. (3) A lane's START names each dirty file with what\n  it IS (subject, REQ, stage), not only what it is not (outside this producer's scope). (4) A\n  registry or workflow edit that lives only in a lane's working tree is a gate the assembled head\n  will fail; commit it first, one subject per commit, REQ named.\n- **Kin:** [[IR-101]] (a surface no per-lane producer compiles), [[IR-97]] (windows), the memory\n  rules \"verify the SUBJECT, not just the measurement\" and \"name the file AND sha a condition came\n  from\" — this instance is the case where the sha was named correctly and was still the wrong\n  instrument.\n- **Ripe when:** now — the #304 assembly (checker 0.4.0 on the gater's box before the\n  traceable-reqs gate) and every future lane assignment. · **Size:** one status line per assignment;\n  one CLI upgrade.\n\n### IR-103 — a rig that re-enters something already retired reads as a product red: four instances in ONE cell (#230), each masking the next\n\n- **Status:** OPEN. Recorded 2026-09-11 10:00Z (doyle). Amended 10:20Z: the third instance's repair\n  RAN (todlando window 10:12-10:18Z, one attempt) and its structural falsifiers all HELD — distinct\n  `serve_stream` per arm (1, 3), red inside the bound naming its arm, arm 2 seated and staying seated,\n  distinct `gen=` per arm (30 ms apart). It exposed a FOURTH instance, below. Its repair ran at\n  committed blob 0845e68d (10:22Z): GREEN, five arms; a trace producer (`--success-output\n  immediate`, 10:24Z) confirmed five matched ARM_OPEN/ARM_DONE pairs, serve_streams 1/3/5/7/9,\n  five distinct gens, every session-detach inside its own arm's bracket. REQ-ATTACH-CLIENT-STALE\n  int is MEASURED on every arm; nothing about the seat, lease or generation was ever in question.\n  The cell stays open only for the parked hazard below.\n- **The three, in the order they were paid for:** (1) a reused `MintedOp` seq on one broker replayed\n  the retired stream's id from the effect journal (IR-99 instance 2; EffectKey carries no\n  conn/stream). (2) hertz's spectator subscription on a stream the server holds: one seat, healthy\n  prior displaced (nethost.rs:546-562) — a channel that cannot exist. (3) `wait_for_stream`\n  (tests/attach.rs:113-122) returns the FIRST non-local stream with no exclusion, so every arm after\n  the first re-served arm 1's retired stream from `net_from_seq = 0`, replayed arm 1's Request record\n  (identical `gen=` in the trace read as a clock collision), hit arm 1's leftover FIN, and detached —\n  the `session-detach was_controller=true` that two readers took for a stale release. Arms 2-5 had\n  NEVER executed; REQ-ATTACH-CLIENT-STALE int is UNTESTED beyond arm 1, not red.\n- **Instance (4), 10:18Z:** the helper sent EVERY arm's keystroke with a literal input op of `1`\n  (tests/attach.rs, `send_attach_input`). The broker dedups a PtyWrite on\n  `EffectKey { class: session_id, minter, op }` (effect.rs:299-303, applied through\n  `journal.apply_once` at broker.rs:8803-8809) — no stream, no conn, no arm, and NO `EffectKind`:\n  a Request op and an Input op sharing an integer on one session collide with each other. Arm 1\n  typed; arm 2's identical key hit the applied-set, the closure never ran, the PTY was never\n  written, and the echo its loop waited for could not exist — a correct 10 s read red\n  (`brain IPC read deadline elapsed`, attach.rs:1940) on a healthy seat. Repair: input ops at\n  `100 + op_seq` (102..106), disjoint from the Request ops 2..6, mechanism recorded at the call\n  site. Arm 2 EXECUTED for the first time; arm 2's assertion and arms 3-5 still have not.\n  Ownership, todlando's words: the #230 verdict named the CLASS (one op seq reused across arms)\n  and he fixed the INSTANCE the failure pointed at — the Request op — leaving the Input op one\n  function away in the same helper.\n- **Mechanism (the class):** each instance is a rig selecting a retired object by a key too coarse\n  to exclude it — (seq) without stream, (stream) without seat, (first row) without served-set,\n  (input op) without arm. And\n  each red was terminated BY the previous defect: closing the seq reuse removed the error that had\n  been ending arm 2, exposing an unbounded read (`call_deadline()` None on a cold_start conn,\n  attach.rs:1305 rule) that turned the next defect into a 240 s timeout. Stacked, in one direction.\n- **Two derivations, both wrong the same way (kept on purpose):** doyle read the sixth\n  `serve_attach` argument as a seat generation (it is `net_from_seq`, attach.rs:479); todlando read\n  identical `gen=` values as a wall-ms collision (attach.rs:968 mints wall-ms; there was never a\n  second sample). Both built a PRODUCT mechanism on a trace whose anomaly was the rig's. The\n  refutation came from reading the trace's `serve_stream=1` twice against a strictly monotonic\n  allocator (nethost.rs:868/880/1109) — a monotonic id repeating is one object seen twice, never two.\n- **PARKED, unmeasured, no REQ:** the seat-generation guard (`detach_if_gen`, broker.rs:3506-3516)\n  is inert on EQUAL generations and the mint is wall-ms. Two Requests inside one clock tick on one\n  conn would make a stale release match the live seat. Structural, re-derivable, and NOT observed:\n  the discriminator is a cell that mints two Requests in one tick, seats the second, releases the\n  first, and asserts the seat survives. Nobody builds it until a field report or a cell shows the\n  collision; nobody cites it as a finding.\n- **Rules:** a rig that picks an object by \"first\"/\"any\"/\"same seq\" names the population it excludes,\n  or it is re-entering a retired object; a monotonic id appearing twice in a trace is the SAME object\n  and the trace is read again from there; an anomaly explained by a product mechanism gets its\n  falsifier built BEFORE the product ruling (todlando's \"I built the refutation after sending\");\n  when a verdict names a CLASS, the repair sweeps every key of that class in the cell before the\n  next window — the fourth instance was the same helper, one function over, and cost a window.\n- **Population sweep (todlando, 10:05Z, source only):** the bare first-peer-row form appears in\n  six more `crates/spt-daemon/tests` files; the defect needs a SECOND condition (several arms\n  sharing one target brain / NetHost table). Every repeated caller builds its own broker per call\n  (exit_every_reap :125, transport_death_eof :442-443, inject_control_wedge three separate fns) and\n  the rest are single-call. CLEAN — the #230 cell is the only two-condition site in the repo, which\n  is why the form survived: it was correct for every case until one cell reused a target. Limits\n  named: that crate's tests only (the `initiated_locally` grep population); a read, not a run.\n  Repair took the shape one file over (tests/controller_lease.rs:170 `wait_for_new_stream`).\n- **Kin:** [[IR-99]], [[IR-101]], [[IR-102]], memory \"journaled seq reuse replays the retired\n  stream\", \"stacked defects mask each other\", \"discriminator question\".\n- **Ripe when:** now — the #230 rig repair, and every cell whose arms share one broker/conn.\n  · **Size:** one served-set parameter in one helper; one register line.\n\n### IR-104 — checker 0.4.0 silently skips a FILE scan root under git enumeration: 81 doc stages read as missing, and a local 0.2.0 green hid it because the two versions disagree on what is evidence\n\n- **Status:** FIXED UPSTREAM 2026-09-11 (traceable-reqs v0.4.1, PR #21 -> d9af11d, red-first cells);\n  spt-core consumes via hertz's #304 lane pin fixup. Closes when that pin is on main.\n- **Instance:** `traceable-reqs.toml` has declared `CONTEXT.md` a scan root since the seed (a FILE\n  root: the glossary carries doc-stage tags). 0.2.0 honoured it. 0.4.0 (SPEC §Scan enumeration:\n  \"an allowlist of directories\") filtered git candidates with `rel_under_root`, which required a `/`\n  after the root prefix; a candidate equal to the root had an empty remainder and never qualified.\n  Measured: 0.4.0 on main = 81 `missing_stage … stage=doc`, every one with its doc tag in\n  CONTEXT.md and 71 nowhere else; positive control: 0 of 253 doc tags under `docs/` were affected.\n  The walk strategy (`git = \"off\"`) never had the bug.\n- **Why it hid:** the box's CLI was 0.2.0 while CI's pin moved to 0.4.0 in the lane, so every local\n  `check` today validated against a different evidence rule than the gate it stood in for. hertz\n  found the placement half of that silence first (0.2.0 emits nothing for a `[placement]` table it\n  cannot read); the doc half surfaced only when the gater built 0.4.0 and ran it. A green from a\n  checker that does not match CI's version is a measurement of the wrong tool.\n- **Rejected remedies, measured:** `roots = [\".\"]` recovers the 81 and admits 43 root-level plan\n  documents with code-stage tags in prose (148 misplaced), then 12 with malformed tag-shaped tokens\n  and AGENTS.md's own example tag; an exclude list of 55 historic files is the wrong shape.\n  `scan.exclude` cannot express \"every root file except one\" (no negation).\n- **Rules:** (1) before citing any `traceable-reqs check`, print `--version` and compare it to\n  the CI pin in the tree being judged; a mismatch is a labelled hole, not a green. (2) A checker\n  upgrade is a gate change: run old and new on the SAME tree and account for every finding that\n  appears or disappears before the pin moves. (3) The assembly gate runs the pinned version; the\n  binary is built from the tag (`traceable-reqs-<ver>.exe`), never \"whatever is on PATH\".\n- **Kin:** [[IR-37]] (placement enforcement, the same release), [[IR-102]] (a declared thing still\n  unread), memory rules \"a predicate needs its tool\", \"zero-match filter reads as absent\".\n- **Ripe when:** now — the #304 assembly. · **Size:** one pin fixup; one line in the gate runbook.\n\n### IR-105 — an assertion derived from a MODEL of the fixture instead of read off the fixture can only be refuted by a run, and the lane convention that defers the run gives the class a one-window latency: the repair for the first instance carried the second\n\n- **Status:** OPEN. Rule adopted 2026-09-11 (hertz, W1 close). Instrument = read the line, and read\n  what the line LANDS on, before asserting either.\n…\n\n\n[Showing lines 5927-6369 of 6937. Use :6370 to continue]"}],"details":{"truncation":{"content":"\r\n### IR-96 — the `daemon_stop_convoy_e2e` API-storm cell fails 3-of-3 under the HEAVY suite at the diagnostic tree while passing at the candidate in golden CI, and nothing yet separates instrumentation from box from product\r\n\r\n- **Status:** OPEN, **cause-unclassified** (todlando's and hertz's stipulation, adopted verbatim — a\r\n  triage placement here is NOT a finding of non-defect).\r\n- **Origin:** releases#294 / v0.69.0 Arm B, 2026-09-10, deployah executing at diagnostic tree\r\n  `ed8ecd94` (= candidate `a9e786b2` + the unlanded sync instrumentation, never merged).\r\n- **What:** `spt::daemon_stop_convoy_e2e stop_under_an_api_storm_stays_down_then_start_brings_up_exactly_one`\r\n  FAILED in **all three** Arm B runs, with durations **growing every run: 9.473s · 10.973s ·\r\n  14.553s**. Different signature from the #294 sync cell; nothing was filed against #294.\r\n- **THE DIFFERENTIAL that makes it worth an entry rather than a shrug:** the same cell shows **0\r\n  failures at the candidate** in golden 34481993681 Phase A on this same box — that run's single\r\n  failure was the sync cell (`3381 tests run: 3380 passed (6 slow, 5 leaky), 1 failed, 1 skipped`).\r\n  So: 0-of-1 at `a9e786b2` under CI load, 3-of-3 at `ed8ecd94` under local HEAVY load.\r\n- **WHAT THAT DOES NOT ESTABLISH.** It does **not** isolate the instrumentation or the box as the\r\n  only candidates — a condition-dependent or intermittent PRODUCT defect remains live, and a single\r\n  CI pass is not evidence of absence. doyle claimed that elimination on 2026-09-10 and **withdrew\r\n  it** the same hour under todlando's and hertz's correction; the withdrawal is recorded in\r\n  `.spt/preserved/gate-r2-34481993681-20260910/CLASSIFICATION-AMENDMENT-2-doyle.md`.\r\n- **Confounded by IR-97** (below): the three runs were not equivalent conditions.\r\n- **Ripe when:** any lane touches daemon stop/start convoy behaviour, OR a golden run reds this cell\r\n  at a candidate, OR someone runs the cell at `a9e786b2` under the same local HEAVY workload — that\r\n  last one is the cheap discriminator and nobody has run it. · **Size:** one targeted local run to\r\n  discriminate; unknown beyond that.\r\n- **Disposition 2026-09-11 (doyle ruled, hertz's own call to release):** the diagnostic pool\r\n  `.worktrees/hertz-294-sync-stages/target` is DELETED — ARCHIVAL, REBUILD REQUIRED. It held the\r\n  `ed8ecd94` diagnostic arm, not `a9e786b2`, so keeping it warm bought nothing for the discriminator\r\n  above; no exe/dll/pdb retained because nobody was spending a heavy-broker execution window on the\r\n  post-deletion proof run, and an unexecuted retained set is a prediction. Receipt\r\n  `.spt/preserved/doyle-294-sync-stages-reclaim-20260911/{before,after}.json`: 30,000,890,067\r\n  logical bytes / 30,723 files; free 179,320,270,848 -> 207,004,086,272 (observed gain\r\n  27,683,815,424; concurrent builds moved ~2.3 GB in the 12 s window, so the delta is not\r\n  single-operation attribution). The 209-PDB reclaim that preceded it (hertz, 44,005,806,080\r\n  observed) is `.spt/preserved/hertz-relay-20260911/reclaim-deletion-receipt.json`. Source tree,\r\n  branch `diag/294-sync-stages` and every preserved receipt stay. The investigation stays OPEN and\r\n  cause-unclassified; its next run is a rebuild at `a9e786b2`.\r\n\r\n### IR-97 — a suite that leaks a fixed cohort of child processes per invocation makes consecutive runs non-comparable, and the between-run accounting the protocol required was not enforced\r\n\r\n- **Status:** OPEN. **Protocol deviation** (hertz's framing, and it is stronger than \"confounder\":\r\n  the protocol ALREADY required between-run accounting — execution did not enforce it, so the fix is\r\n  enforcement, not a limitations paragraph).\r\n- **Origin:** releases#294 Arm B, 2026-09-10. Derived by doyle from deployah's preserved\r\n  `10-residual-births.json` against the run windows.\r\n- **What:** each Arm B suite leaked **exactly 6** `spt` children that outlived it; all **18** were\r\n  still alive at the post-B3 census. Because a process alive at census whose OS birth time falls in\r\n  an earlier window existed continuously through the runs between (pid + birth time is an identity),\r\n  the carried diag-tree residue was **0 during B1 · 6 during B2 · 12 during B3**. The three\r\n  \"repetitions\" were therefore not three equivalent conditions, and every cross-run comparison in\r\n  that arm inherits it.\r\n- **LIMITS, stated so the entry is not over-read:** process **COUNT** is measured; **LOAD is not** —\r\n  idle orphans may cost nothing, contention was UNMEASURED (overlap UNVERIFIED all arm), and this is\r\n  **not** a drift meter. It neither implicates nor excludes residue as a cause of the one expiry, and\r\n  it does not explain it: B3 carried twice the orphans and **passed**.\r\n- **Also unestablished, in both directions:** 18 censused against 15 killed shows only that three\r\n  were absent at the second read. \"Three self-exited\" needs exit evidence; \"I killed 18\" was\r\n  likewise refused by deployah at the time.\r\n- **Kin:** the LEAK rows every Arm A/B run reported; `REQ-HAZARD-RESUME-CUSTODY-ABA` (KH 7.51) and\r\n  KH 7.58 — the cleanup that resolved this was correctly scoped by **pid + image path**, leaving 15\r\n  unrelated `spt` processes untouched, where a name-based kill would have taken down the live agent\r\n  fleet including the gater's own session.\r\n- **Ripe when:** any repeated-run experiment is designed on this box — census BETWEEN runs, not only\r\n  at the end. · **Size:** a between-run census step plus a scoped reap in the harness.\r\n- **Applied 2026-09-11 (#304):** hertz requested and doyle granted an EXCLUSIVE EXECUTION window for\r\n  the admitted heavy-broker-PTY subset — builds from the second lane may overlap, real-daemon test\r\n  execution may not — because a second tree executing real daemons concurrently makes the census\r\n  non-attributable and reproduces exactly this defect. Window START/END go builder-to-builder\r\n  (hertz -> todlando) with doyle copied.\r\n- **Crossing 2026-09-11 09:12:45Z-09:13:35Z, recorded as a mechanism:** the coordinator resequenced\r\n  the two builders (todlando first) at ~09:12:2xZ; hertz's START went out at 09:12:45Z before that\r\n  arrived; todlando sampled admission at 09:12:57Z and launched. Both builders disclosed within a\r\n  minute; hertz's START turned out to be an ANNOUNCEMENT (nothing launched) and was retracted, so no\r\n  two real-daemon executions overlapped — but for 50 seconds three agents each held a different\r\n  picture of who owned the box, and each was right on the messages it had. Rules that fall out:\r\n  START is sent when the first producer is LAUNCHED, not when the window is decided; a builder who\r\n  learns of a crossing FINISHES the attempt in flight and marks the overlap rather than aborting\r\n  (an aborted attempt is a labelled hole, a marked overlap is still evidence); and a coordinator\r\n  resequencing two live builders names the token that transfers the box (the other's END), because\r\n  an ordering that depends on message arrival order is not an ordering.\r\n\r\n### IR-98 — a lane driver that PRINTS a producer's output can die on an unencodable byte AFTER that producer's evidence is on disk, so the run ends with complete evidence for producer N and NO files for N+1 — an absence that reads as \"never queued\", not as a failure\r\n\r\n- **Status:** OPEN as a mechanism; the measured instance is FIXED in hertz's lane driver (UTF-8 with\r\n  replacement reconfigured at import, positive control run before relaunch: U+2500 and U+2713\r\n  printed through the fixed driver, exit 0).\r\n- **Origin:** releases#304 hertz lane, 2026-09-11 08:58Z, exclusive execution window. Producer 1\r\n  (spt-daemon lib, 21 cases at `7b098cc2`) returned exit 100 with exit, observation.json, raw and\r\n  stdout all intact; the driver then printed the stderr tail to a cp1252 stdout, raised\r\n  `UnicodeEncodeError` on nextest's box-drawing characters, and killed the loop. Producers 2 and 3\r\n  (spt bins x5, docs_server_e2e x1) NEVER STARTED. Reported by hertz as a labelled hole before any\r\n  result was read as a pass.\r\n- **What (hertz's one line, kept):** a driver that prints a producer's output can destroy the REST\r\n  of a run while leaving the finished producer's evidence intact, so the surviving evidence looks\r\n  complete and the missing producers look like they were never queued. **The tell:** evidence files\r\n  exist for producer N and no files at all exist for N+1 — not a failure, not a skip, an absence.\r\n- **Rule:** a sequence driver's own crash is a run outcome and is written as one (which producers\r\n  ran, which never started, why), and console rendering of producer output never sits between a\r\n  producer's completion and the next producer's launch without a defined encoding.\r\n- **Kin:** [[IR-32]] (an instrument that agrees with itself), [[IR-46]] (one reading is an instant),\r\n  the memory rule \"cancelled = labelled hole\"; the shell-side kin is `render-not-read-pipefail`.\r\n- **Ripe when:** any new sequence driver or any driver that renders producer output to a console;\r\n  `.github/ci/local-lane.py` and its lane modules are the first population. · **Size:** one\r\n  encoding reconfigure plus a written \"never started\" arm in the run summary.\r\n\r\n### IR-99 — EOF and terminal retire on a ConnectionBound net stream arm on the OPENER CONN's exit; a same-morning diagnosis built on that mechanism was refuted by the compiler, so the mechanism stands and the two #304 reds beside it stay open\r\n\r\n- **Status:** OPEN. The mechanism is VERIFIED; both reds are CLASSIFIED NOT-product (instance 1: an\r\n  unpromised spectator EOF; instance 2: a journal replay of a reused op seq) — repairs built at\r\n  `849c2da8` (hertz) and blob `42efe323` (todlando), each awaiting its one exclusive-window run.\r\n- **Mechanism (hertz read, doyle verified at `a17dbfbd`):** `broker.rs:6368-6372`, conn teardown: for\r\n  every ConnectionBound row THIS conn opened, FIN + `retire_stream_terminal` +\r\n  `STREAM_CONNBOUND_RETIRE:{id}: opener conn exited`. ADR-0040 decision 6. A detach, a controller\r\n  swap, or a record on the wire does not arm it; the OPENER CONN's exit does.\r\n- **Instance 1 — hertz, `rc::tests::viewer_byte_detach_keeps_controller_and_child` (2026-09-11 09:00Z):**\r\n  a 10 s wait for `NetStreamEof` on the PEER row after a viewer detach expired. First diagnosis: the\r\n  opener conn (`operator`) outlived the loop, so no FIN — **WITHDRAWN at `27baeb61`**: the compiler\r\n  refused the fix with `E0382 use of moved value: operator` because `operator` is moved into the\r\n  viewport pump at `rc.rs:4263-4266` and is already dropped when `viewport.join()` returns before the\r\n  loop. Still true and still unexplained: the run retires stream 2 and never stream 1 while the\r\n  observer waits on the peer row. **Open question:** does a FIN on the locally-initiated row reach a\r\n  subscriber of the PEER row at all? UNCLASSIFIED; producer 2 of the #304 subset is held until it is.\r\n  **Second run at `96325c9b` (09:17-09:18Z, box quiet):** the case now prints\r\n  `PEER_ROW_SELECT: inbound_rows=1 on_dialed_conn=1 picked=1`, so the unordered `find` selection\r\n  (real, repaired by conn_id + exactly-one assert) had nothing to choose between and is NOT the\r\n  cause. Two runs at two shas now pin the topology: peer row = stream 1, operator's local row =\r\n  stream 2, `STREAM_CONNBOUND_RETIRE:2` fires, and a subscriber of stream 1 receives no\r\n  `NetStreamEof` within 10 s. **Measured fact:** a FIN plus terminal retire on the locally-initiated\r\n  loopback row does not deliver EOF to a subscriber of the paired peer row. Whether that is promised\r\n  by the design (ADR-0040, the stream-lease requirement) is the open question; a test-side edit that\r\n  drops the wait is refused until a citation answers it either way.\r\n  **Answered 09:22Z (hertz cited, doyle verified):** NOT promised. ADR-0040 decision 6 (:80-83, the\r\n  `REQ-STREAM-LEASE-CLASSES` doc tag) promises that on the opener's EOF *the target* sees FIN and\r\n  `serve_attach` runs `detach_session`; it names no spectator subscriber, and every promised\r\n  consequence was delivered in the red run itself (`Detached` join passed, controller and child\r\n  survived, stamps cleared). Verdict: NOT a product finding; the case asserted a property the design\r\n  never made. ADR-0040 :156-163 already names the trap — reasoning from the arm that reads like a\r\n  guarantee to a consequence it does not carry — and this is its third instance. Repair ruled: keep a\r\n  barrier on a PROMISED observable (the row's `finished`/gone state, or the `Detached` join itself)\r\n  and assert the absence against it; a bounded drain justified as a timing window is refused.\r\n  **These two instances are two lessons under one family heading, not one mechanism** (hertz's own\r\n  correction of his earlier framing): instance 1 is an unpromised event on a spectator subscription;\r\n  instance 2 is a conn exit between test arms retiring the rows the next arm needed.\r\n- **Instance 2 — todlando, `attach::admission_answers_the_clients_own_identity_with_applicable_policy`\r\n  (09:08Z):** \"no such stream 2\" one read after `STREAM_CONNBOUND_RETIRE:2`, with controller-attach,\r\n  writer-exit `channel-closed` and the retire in the same millisecond. By the mechanism the retire is\r\n  downstream of that conn exiting; WHY the writer saw `channel-closed` at admission is the open\r\n  question, with two named candidates (the helper's own lifecycle; the new ClientPolicy send being the\r\n  first wire-side send on that transport). UNCLASSIFIED; two approved discriminator probes pending.\r\n  **Probes (a),(b),(c) at 09:12-09:15Z:** (a) the unmodified loopback-pump cell is GREEN, so the\r\n  daemon change did not break the shared pump; (c) an identity-free arm run in position 2 fails the\r\n  same way, so declared identity is NOT necessary. **Shared-operator fix REFUTED (09:20Z):** one\r\n  borrowed conn across arms, error became `no such stream 2` again — the conn was never the thing\r\n  that died.\r\n  **CLASSIFIED 09:25Z (doyle, source at `d80239df`): NOT product — TEST DEFECT, one op seq reused\r\n  across arms.** Every arm called `request_attach_endpoint` with `MintedOp::new(Minter::Rc, 2)`.\r\n  The open is journaled: `dispatch_net_stream_open` (`broker.rs:9575-9598`) keys `apply_once` by\r\n  `EffectKey { class, minter, op }` (`effect.rs:299`) — no conn, no session, no stream in the key —\r\n  so arm 2's open returned `Replayed`, the closure never ran, the allocator was never consulted, and\r\n  `stream_op_id(Rc, 2)` handed back the RECORDED id 2 with `applied_now=false` (`broker.rs:6141`\r\n  comment says exactly this). Row 2 had been terminal-retired at arm 1's opener exit ⇒ \"no such\r\n  stream 2\". The allocator sentence above (monotonic `fetch_add`, nethost.rs:1109) and todlando's\r\n  measurement (a fresh open returning the just-retired id, twice) were BOTH true: the second open\r\n  never reached the allocator. Journal is file-backed per home (`bind_in(name, dir/effects.log)`),\r\n  so a reused home replays at position 1 too; todlando's homes were per-test fresh.\r\n  **Withdrawn by replacement (todlando, 09:26Z):** the 2x2 — its position-1 cell rested on marker\r\n  absence in stderr, and markers are never written to stderr on pass or fail (zero-match filter);\r\n  \"id reissued after terminal retire\" (a journal replay); \"FIN takes the conn with it\" (nothing was\r\n  opened the second time). No product suspicion reaches this register from instance 2.\r\n  **Repair (built, uncommitted, blob `42efe323`, base `58b95354`):** one broker, five arms, DISTINCT\r\n  seqs 2-6, identity-free control in positions 1 AND 2, `ARM_OPEN` prints the seq. Prediction filed\r\n  before the run: green on all five. Negative control on file: same seq, red twice. Run pending an\r\n  exclusive window after IR-97's producer 2.\r\n- **Rule (revised after the withdrawal):** a test that waits on EOF must first establish WHICH row\r\n  FINs and WHO observes it, from source, before it names a deadline \"a barrier\"; a test surprised by a\r\n  retire looks for the conn that exited before it looks at the stream. And a mechanism verified in\r\n  source does not verify the diagnosis built on it — ownership of the variable the diagnosis names is\r\n  a separate check the compiler happened to make for free here.\r\n- **Kin:** [[IR-97]] (same window), KH 7.66 (an expired bounded wait is CENSORED, not a latency), the\r\n  memory rule \"hedge is not grounding\".\r\n- **Ripe when:** any new test reads a ConnectionBound stream to EOF or asserts on a retire; the\r\n  ~20 house-standard 400x25 ms wait sites are the population to grep. · **Size:** one comment per site\r\n  naming what arms the edge, once the open question above has an answer.\r\n\r\n### IR-100 — an editor-driven rust-analyzer runs `cargo check --workspace --all-targets` into a LANE's pool on its own schedule, so a builder census counts it, a lock wait charges it to nobody, and the lane's disk growth carries it uncredited\r\n\r\n- **Status:** OPEN. Recorded 2026-09-11 09:30Z from todlando's trace; no mitigation applied.\r\n- **Instance (todlando, `.worktrees/304-product`, 09:29Z):** his distinct-seq build printed\r\n  `Blocking waiting for file lock on build directory`. Holder pid 28176, ancestry\r\n  `cargo check --quiet --workspace --all-targets --manifest-path .worktrees/304-product/Cargo.toml`\r\n  ← `rustup` ← `RUST-ANALYZER.EXE` ← `claude.exe` ← `claude-spt.exe` — his OWN session's language\r\n  server, checking his lane's manifest into his lane's `target/`. Not CI, not another lane. NOT a\r\n  pool violation (same tree, same lane; `SPT_POOL_FOREIGN` correctly silent).\r\n- **Second instance, the asymmetry (hertz, 09:31:40Z, ancestry walked):** TWO analyzers on this box,\r\n  one per live session, BOTH with cwd at the project root. todlando's (rust-analyzer 46072) resolved\r\n  `.worktrees/304-product/Cargo.toml` and builds into HIS pool; hertz's (26640) resolved the ROOT\r\n  manifest and builds into the root `target/` — a pool that is not his lane's. So hertz's growth\r\n  figures and lock waits were never charged by his own analyzer, and NOT because anyone chose that:\r\n  cwd is identical for both, so cwd is not the discriminant. The candidate is which files each\r\n  session opened (rust-analyzer discovers its workspace from them) — UNMEASURED. Read IR-100 as \"the\r\n  blast radius depends on which manifest the analyzer resolved, and nobody chose it\", never as \"that\r\n  lane was clean\".\r\n- **Instrument (hertz, same hour):** `lane_run.builder_census` now walks each builder's ancestry and\r\n  attributes it `ci` / `analyzer` / `agent` / `unknown`, printing the manifest from the cmdline when\r\n  legible; live box read 11 ci, 1 analyzer, 0 agent, 0 unknown. Quiet predicate revised from \"zero\r\n  builders\" (never clears under a peer's analyzer, leases nothing when it does) to \"zero CI builders\r\n  AND no builder whose manifest is MY worktree\"; a peer's analyzer is recorded contention, not a\r\n  refusal. Still a sample, not a lease.\r\n- **Why it matters (three census readings it breaks):** (1) `BUILDERS=n` in an admission census\r\n  includes it, so a nonzero count is not \"CI or another lane\" and a zero is not \"quiet for the next\r\n  minute\" — an editor can start a workspace check at any moment; the census is a sample, not a lease\r\n  (hertz's own words on his window, [[IR-97]]). (2) Its rmeta/dep-info growth lands in the lane's\r\n  allocation without a declared producer, so a producer's \"growth\" is an upper bound on that\r\n  producer. (3) It delays a producer without failing it: a one-attempt run that sat on the lock is\r\n  slow for a reason no window ledger named.\r\n- **Third limit, from outside (todlando 09:42Z, hertz confirmed 09:43Z):** a BUILDER census is blind\r\n  to a peer's EXECUTION phase. hertz's producers run test binaries, which carry none of the builder\r\n  names the census matches on, so 0 cargo sampled DURING his open window read as \"quiet\" — and doyle\r\n  read his own zero-cargo sample as an answer to a START he had already recorded. hertz's own\r\n  instrument would not have caught hertz's own window. todlando's admission census (09:42:58Z) already\r\n  sweeps the other half: test binaries under any `target\\debug\\deps` (0) with a positive control (10\r\n  shells visible), which is the form the census must take. Rule: a census is ADMISSION evidence only —\r\n  builders by ancestry AND executing test binaries under `deps`, each with a positive control; whether\r\n  the box is BUSY is answered only by a granted-and-acknowledged window ([[IR-97]]), never by a sample.\r\n- **Fourth limit, the census's own blind spot (hertz 10:13Z, measured 556 processes):** a path-keyed\r\n  filter must count what it COULD NOT ANSWER FOR separately from what it answered \"no\" to. todlando's\r\n  WMI/Get-Process path reader refused ~180 protected processes (declared); hertz's psutil reader saw\r\n  553/556 but his `exe or \"\"` swallow turned two EMPTY paths into \"not in the pool\" and declared 1\r\n  blind when the real hole was 3. Both under-declared, by different mechanisms. A blind spot that does\r\n  not raise is the same clean zero a broken filter returns. admission.py now counts empty as blind.\r\n- **Rules:** a builder census classifies by ANCESTRY, never by count — `Runner.Worker.exe` = CI, a\r\n  lane's own cargo = a producer, `RUST-ANALYZER.EXE` = editor check. A lock wait is recorded as a\r\n  delay with its holder's ancestry, as here; nobody kills an analyzer, and the analyzer's check is\r\n  charged to the LANE, so any growth figure quoted from a lane pool says so.\r\n- **Recommendation to the operator (rides here, not as a directive to agents):**\r\n  `rust-analyzer.cargo.targetDir` (true, or a path under the lane's `target/`) gives the analyzer\r\n  its own build directory — that removes the LOCK contention and the census ambiguity in one\r\n  setting; it does not remove the disk, which stays in the same pool subtree by design.\r\n- **Kin:** [[IR-97]] (exclusive execution windows; builds may overlap), [[IR-56]] (a pool is a\r\n  relationship, not a path), the memory rules \"measure the box before the instrument\" and \"quiet\r\n  window predicate\".\r\n- **Ripe when:** the next admission census on this box, or the next lock wait anyone traces.\r\n  · **Size:** one editor setting plus one line in the census procedure.\r\n\r\n### IR-101 — no per-lane producer compiles a lib crate's own `#[cfg(test)]` module on the branch that broke it, so a stale caller of a lane's own signature change rides green through six real-daemon runs and surfaces only at assembly, or from an editor\r\n\r\n- **Status:** OPEN. Rule adopted 2026-09-11 09:35Z; instrument = one command at inventory and one at\r\n  assembly.\r\n- **Instance (todlando, `feat/304-remote-friction-product`, 09:33Z):** `a4017a15` (#301) dropped the\r\n  port parameter from `webserve::handle_path`/`resolve_path` (six params). Six call sites in that\r\n  file's own `#[cfg(test)]` module — :856, :1132, :1201, :1206, :1213, :1333 at `58b95354`, verified —\r\n  still passed seven with a literal `5474`. `E0061`, committed since `a4017a15`, invisible to every\r\n  producer the lane ran: `cargo nextest … -p spt-daemon --test attach` builds the INTEGRATION target\r\n  and a lib's cfg(test) module is not in that graph. Found by the analyzer of [[IR-100]] (`cargo check\r\n  --workspace --all-targets` is the one invocation on the box that compiles lib test modules).\r\n  Fix `5853cb14`: the six arguments dropped, 6+/6−, nothing else.\r\n- **Consumer half (hertz):** his lane ran `-p spt-daemon --lib` all morning, which DOES compile that\r\n  module, and was 21/21 green at `a17dbfbd` — because he had ALREADY repaired those callers at\r\n  `5fd683e9` (test-only, all hunks past the cfg(test) line at :821; verified) while rewriting the\r\n  #301 node-root cases in the same module. So the gap is not \"nobody builds it\"; it is \"nobody builds\r\n  it on the branch that broke it\", and a per-lane green on the other lane is silent about this one.\r\n  todlando's first account (\"hertz's tree lacks a4017a15\") was wrong and withdrawn; `merge-base\r\n  --is-ancestor` is TRUE.\r\n- **The collision it exposed:** two lanes edited one cfg(test) module for one issue all morning,\r\n  independently. Measured with `git merge-tree --write-tree 849c2da8 5853cb14` (no checkout touched,\r\n  merge-base `d89a655f`): exactly ONE conflict, content, `webserve.rs`; `rc.rs` and\r\n  `bootstrap_firewall/windows.rs` auto-merge. Loud, not silent. Ruled: todlando keeps `5853cb14` (a\r\n  lane whose lib tests do not compile is blind to this class); assembly resolves that module to\r\n  hertz's blob and asserts the resolved blob equals his; hertz owns `webserve.rs` cfg(test) for #304.\r\n- **The clean win that drops coverage (hertz, 09:37Z):** reading todlando's six-line diff showed\r\n  hertz what his own module had deleted: the case at todlando's :1198 was the only place feeding\r\n  hostile text through `escape_html`, which is still live in production on the message facet\r\n  (`webserve.rs:494-510`). His #301 rewrite replaced that case and dropped the escaper coverage.\r\n  Resolving \"to hertz's blob\" would have lost it PERMANENTLY with no conflict — a correct-looking\r\n  resolution, not a merge collision, is the silent case. Restored at `9f09db4e` (test-only, +30 at\r\n  :1185: the compound string, each of five entities alone, a pass-through negative control; the\r\n  comment names its limit — escaper, not call sites). His absence census (\"grep returned NOTHING\")\r\n  came from a predicate built from the case he was looking at (`script a=|&lt;script|&#39;|&quot;`),\r\n  which cannot match `&amp;`; rule: census the SUBJECT (`grep escape_html`), never its rendered\r\n  effect.\r\n- **Second instance, integration axis (doyle, 09:39Z):** `a4017a15` deleted the registry index\r\n  outright (`fn index`, `Index`, `IndexEntry`, the `?json` twin; 19+/84−). `tests/webserve_e2e.rs`\r\n  (last touched `f3a5e169`, 2026-09-07; byte-identical on main and all three lane shas) asserts\r\n  that index at :53 and :67 (`GET /LoCaL/?json` = 200 with entries, `GET /local/` = 200 HTML with\r\n  `source &amp; quote.txt`). Integration tests run only in the golden lane, and no #304 producer\r\n  names this file (allocations grep: only deployah's #294 arms and CI job logs). Prediction filed\r\n  before any run: `production_listener_routes_nodes_docs_and_live_registry_references` RED at every\r\n  #304 sha; the other four cases UNKNOWN. Tags riding in it: REQ-WEB-URL-NODE-PREFIX,\r\n  REQ-WEB-SERVING-REGISTRY, REQ-DOCS-LOCAL-SERVER, REQ-WEB-ADAPTER-DOCS-FACET — if\r\n  REQ-WEB-SERVING-REGISTRY's int evidence WAS the index, it is relocated, not faked. Assigned to\r\n  hertz as producer 3 in a SECOND window after producers 1+2 at `9f09db4e`, so the frozen sha is not\r\n  churned. todlando's hermetic unit twin of it (`index_escapes_html_…`) reds at :1197 on his branch\r\n  for the same reason; that case is scheduled to stop existing at assembly and nobody fixes it.\r\n- **Rules:** (1) a lane inventory owes `cargo check --workspace --all-targets` at the sha it reports,\r\n  before any evidence is quoted — a prerequisite, not evidence about the merge. (2) The assembly\r\n  compile gate is the same command on the MERGED tree, before `traceable-reqs check`; it is the only\r\n  step that sees the cross-lane case. (3) A per-lane `--lib` green on a sibling lane is never cited\r\n  for the lane under test. (4) A lane that DELETES a surface greps the integration tree for that\r\n  surface's assertions in the same change; golden is not the place to learn an e2e was pinned to it.\r\n  (5) Before resolving a same-module conflict to one side, diff the LOSING side for assertions the\r\n  winner lacks — the conflict is the loud case; the clean win is the one that drops coverage.\r\n  (6) A hermetic in-proc cell is not a window producer, but it is ANNOUNCED before it runs so an\r\n  ancestry census can attribute it (todlando's 09:37 cell read as `agent=4` during hertz's sample).\r\n- **Kin:** [[IR-100]] (the instrument that found it), the memory rules \"cfg-gated code is invisible\r\n  to the other platform gate\" (same shape, other axis), \"gate population excludes consumers\",\r\n  \"resolve wrapper conflict toward the shared body\".\r\n- **Ripe when:** now — the next #304 inventory and the #304 assembly. · **Size:** one line in the\r\n  inventory script, one in the assembly runbook.\r\n\r\n### IR-102 — a dirty file the lane DECLARED is still invisible to an assignment made against its committed blob, so the gater measures and predicts on a blob the lane was never going to run\r\n\r\n- **Status:** OPEN. Recorded 2026-09-11 09:50Z from hertz's correction; ruling applied (commit all\r\n  five), no instrument yet.\r\n- **Instance (#304, hertz lane, 09:17Z–09:48Z):** hertz named his dirty files at his 09:17 START and\r\n  said none entered producer 2's compile scope — true. doyle then measured `tests/webserve_e2e.rs`\r\n  byte-identical on main, 849c2da8, 9f09db4e and 5853cb14 (true of the COMMITTED blob), predicted\r\n  reds at :53/:67 against it, and assigned the repin to hertz. hertz's working tree had carried an\r\n  uncommitted 16+/20- repin of that file all morning. The prediction was UNTESTABLE AS FILED: the blob\r\n  it named was not the blob the lane would run. Four more dirty files (ci.yml, golden.yml,\r\n  twohost_web.rs, attach_link_push_e2e.rs, webserve_cross_node_e2e.rs) carried an impl tag for a REQ\r\n  registered only in the lane (REQ-LOCAL-GATE-EXECUTION-EVIDENCE, stages impl+unit), a checker\r\n  version pin the lane's `[placement]` table depends on (0.4.0; main and the gater's box at 0.2.0),\r\n  and int tags on 169 lines no producer had run.\r\n- **Mechanism:** \"declared\" answers \"does it touch THIS run\"; it never answers \"is it the SUBJECT of\r\n  the next assignment\". A gater who measures `git show <sha>:<path>` across shas is measuring\r\n  committed history and cannot see a working tree by construction — the two instruments answer\r\n  different questions and the answers were confused because the file had the same name in both.\r\n- **Rules:** (1) an assembly takes COMMITTED blobs only; a tag on an uncommitted line is a tag on\r\n  nothing, and uncommitted work at assembly is not in the release. (2) Before assigning a file to a\r\n  lane, `git -C <lane> status --short -- <path>` — one command — and if it is dirty, the assignment\r\n  names the working blob, not the committed one. (3) A lane's START names each dirty file with what\r\n  it IS (subject, REQ, stage), not only what it is not (outside this producer's scope). (4) A\r\n  registry or workflow edit that lives only in a lane's working tree is a gate the assembled head\r\n  will fail; commit it first, one subject per commit, REQ named.\r\n- **Kin:** [[IR-101]] (a surface no per-lane producer compiles), [[IR-97]] (windows), the memory\r\n  rules \"verify the SUBJECT, not just the measurement\" and \"name the file AND sha a condition came\r\n  from\" — this instance is the case where the sha was named correctly and was still the wrong\r\n  instrument.\r\n- **Ripe when:** now — the #304 assembly (checker 0.4.0 on the gater's box before the\r\n  traceable-reqs gate) and every future lane assignment. · **Size:** one status line per assignment;\r\n  one CLI upgrade.\r\n\r\n### IR-103 — a rig that re-enters something already retired reads as a product red: four instances in ONE cell (#230), each masking the next\r\n\r\n- **Status:** OPEN. Recorded 2026-09-11 10:00Z (doyle). Amended 10:20Z: the third instance's repair\r\n  RAN (todlando window 10:12-10:18Z, one attempt) and its structural falsifiers all HELD — distinct\r\n  `serve_stream` per arm (1, 3), red inside the bound naming its arm, arm 2 seated and staying seated,\r\n  distinct `gen=` per arm (30 ms apart). It exposed a FOURTH instance, below. Its repair ran at\r\n  committed blob 0845e68d (10:22Z): GREEN, five arms; a trace producer (`--success-output\r\n  immediate`, 10:24Z) confirmed five matched ARM_OPEN/ARM_DONE pairs, serve_streams 1/3/5/7/9,\r\n  five distinct gens, every session-detach inside its own arm's bracket. REQ-ATTACH-CLIENT-STALE\r\n  int is MEASURED on every arm; nothing about the seat, lease or generation was ever in question.\r\n  The cell stays open only for the parked hazard below.\r\n- **The three, in the order they were paid for:** (1) a reused `MintedOp` seq on one broker replayed\r\n  the retired stream's id from the effect journal (IR-99 instance 2; EffectKey carries no\r\n  conn/stream). (2) hertz's spectator subscription on a stream the server holds: one seat, healthy\r\n  prior displaced (nethost.rs:546-562) — a channel that cannot exist. (3) `wait_for_stream`\r\n  (tests/attach.rs:113-122) returns the FIRST non-local stream with no exclusion, so every arm after\r\n  the first re-served arm 1's retired stream from `net_from_seq = 0`, replayed arm 1's Request record\r\n  (identical `gen=` in the trace read as a clock collision), hit arm 1's leftover FIN, and detached —\r\n  the `session-detach was_controller=true` that two readers took for a stale release. Arms 2-5 had\r\n  NEVER executed; REQ-ATTACH-CLIENT-STALE int is UNTESTED beyond arm 1, not red.\r\n- **Instance (4), 10:18Z:** the helper sent EVERY arm's keystroke with a literal input op of `1`\r\n  (tests/attach.rs, `send_attach_input`). The broker dedups a PtyWrite on\r\n  `EffectKey { class: session_id, minter, op }` (effect.rs:299-303, applied through\r\n  `journal.apply_once` at broker.rs:8803-8809) — no stream, no conn, no arm, and NO `EffectKind`:\r\n  a Request op and an Input op sharing an integer on one session collide with each other. Arm 1\r\n  typed; arm 2's identical key hit the applied-set, the closure never ran, the PTY was never\r\n  written, and the echo its loop waited for could not exist — a correct 10 s read red\r\n  (`brain IPC read deadline elapsed`, attach.rs:1940) on a healthy seat. Repair: input ops at\r\n  `100 + op_seq` (102..106), disjoint from the Request ops 2..6, mechanism recorded at the call\r\n  site. Arm 2 EXECUTED for the first time; arm 2's assertion and arms 3-5 still have not.\r\n  Ownership, todlando's words: the #230 verdict named the CLASS (one op seq reused across arms)\r\n  and he fixed the INSTANCE the failure pointed at — the Request op — leaving the Input op one\r\n  function away in the same helper.\r\n- **Mechanism (the class):** each instance is a rig selecting a retired object by a key too coarse\r\n  to exclude it — (seq) without stream, (stream) without seat, (first row) without served-set,\r\n  (input op) without arm. And\r\n  each red was terminated BY the previous defect: closing the seq reuse removed the error that had\r\n  been ending arm 2, exposing an unbounded read (`call_deadline()` None on a cold_start conn,\r\n  attach.rs:1305 rule) that turned the next defect into a 240 s timeout. Stacked, in one direction.\r\n- **Two derivations, both wrong the same way (kept on purpose):** doyle read the sixth\r\n  `serve_attach` argument as a seat generation (it is `net_from_seq`, attach.rs:479); todlando read\r\n  identical `gen=` values as a wall-ms collision (attach.rs:968 mints wall-ms; there was never a\r\n  second sample). Both built a PRODUCT mechanism on a trace whose anomaly was the rig's. The\r\n  refutation came from reading the trace's `serve_stream=1` twice against a strictly monotonic\r\n  allocator (nethost.rs:868/880/1109) — a monotonic id repeating is one object seen twice, never two.\r\n- **PARKED, unmeasured, no REQ:** the seat-generation guard (`detach_if_gen`, broker.rs:3506-3516)\r\n  is inert on EQUAL generations and the mint is wall-ms. Two Requests inside one clock tick on one\r\n  conn would make a stale release match the live seat. Structural, re-derivable, and NOT observed:\r\n  the discriminator is a cell that mints two Requests in one tick, seats the second, releases the\r\n  first, and asserts the seat survives. Nobody builds it until a field report or a cell shows the\r\n  collision; nobody cites it as a finding.\r\n- **Rules:** a rig that picks an object by \"first\"/\"any\"/\"same seq\" names the population it excludes,\r\n  or it is re-entering a retired object; a monotonic id appearing twice in a trace is the SAME object\r\n  and the trace is read again from there; an anomaly explained by a product mechanism gets its\r\n  falsifier built BEFORE the product ruling (todlando's \"I built the refutation after sending\");\r\n  when a verdict names a CLASS, the repair sweeps every key of that class in the cell before the\r\n  next window — the fourth instance was the same helper, one function over, and cost a window.\r\n- **Population sweep (todlando, 10:05Z, source only):** the bare first-peer-row form appears in\r\n  six more `crates/spt-daemon/tests` files; the defect needs a SECOND condition (several arms\r\n  sharing one target brain / NetHost table). Every repeated caller builds its own broker per call\r\n  (exit_every_reap :125, transport_death_eof :442-443, inject_control_wedge three separate fns) and\r\n  the rest are single-call. CLEAN — the #230 cell is the only two-condition site in the repo, which\r\n  is why the form survived: it was correct for every case until one cell reused a target. Limits\r\n  named: that crate's tests only (the `initiated_locally` grep population); a read, not a run.\r\n  Repair took the shape one file over (tests/controller_lease.rs:170 `wait_for_new_stream`).\r\n- **Kin:** [[IR-99]], [[IR-101]], [[IR-102]], memory \"journaled seq reuse replays the retired\r\n  stream\", \"stacked defects mask each other\", \"discriminator question\".\r\n- **Ripe when:** now — the #230 rig repair, and every cell whose arms share one broker/conn.\r\n  · **Size:** one served-set parameter in one helper; one register line.\r\n\r\n### IR-104 — checker 0.4.0 silently skips a FILE scan root under git enumeration: 81 doc stages read as missing, and a local 0.2.0 green hid it because the two versions disagree on what is evidence\r\n\r\n- **Status:** FIXED UPSTREAM 2026-09-11 (traceable-reqs v0.4.1, PR #21 -> d9af11d, red-first cells);\r\n  spt-core consumes via hertz's #304 lane pin fixup. Closes when that pin is on main.\r\n- **Instance:** `traceable-reqs.toml` has declared `CONTEXT.md` a scan root since the seed (a FILE\r\n  root: the glossary carries doc-stage tags). 0.2.0 honoured it. 0.4.0 (SPEC §Scan enumeration:\r\n  \"an allowlist of directories\") filtered git candidates with `rel_under_root`, which required a `/`\r\n  after the root prefix; a candidate equal to the root had an empty remainder and never qualified.\r\n  Measured: 0.4.0 on main = 81 `missing_stage … stage=doc`, every one with its doc tag in\r\n  CONTEXT.md and 71 nowhere else; positive control: 0 of 253 doc tags under `docs/` were affected.\r\n  The walk strategy (`git = \"off\"`) never had the bug.\r\n- **Why it hid:** the box's CLI was 0.2.0 while CI's pin moved to 0.4.0 in the lane, so every local\r\n  `check` today validated against a different evidence rule than the gate it stood in for. hertz\r\n  found the placement half of that silence first (0.2.0 emits nothing for a `[placement]` table it\r\n  cannot read); the doc half surfaced only when the gater built 0.4.0 and ran it. A green from a\r\n  checker that does not match CI's version is a measurement of the wrong tool.\r\n- **Rejected remedies, measured:** `roots = [\".\"]` recovers the 81 and admits 43 root-level plan\r\n  documents with code-stage tags in prose (148 misplaced), then 12 with malformed tag-shaped tokens\r\n  and AGENTS.md's own example tag; an exclude list of 55 historic files is the wrong shape.\r\n  `scan.exclude` cannot express \"every root file except one\" (no negation).\r\n- **Rules:** (1) before citing any `traceable-reqs check`, print `--version` and compare it to\r\n  the CI pin in the tree being judged; a mismatch is a labelled hole, not a green. (2) A checker\r\n  upgrade is a gate change: run old and new on the SAME tree and account for every finding that\r\n  appears or disappears before the pin moves. (3) The assembly gate runs the pinned version; the\r\n  binary is built from the tag (`traceable-reqs-<ver>.exe`), never \"whatever is on PATH\".\r\n- **Kin:** [[IR-37]] (placement enforcement, the same release), [[IR-102]] (a declared thing still\r\n  unread), memory rules \"a predicate needs its tool\", \"zero-match filter reads as absent\".\r\n- **Ripe when:** now — the #304 assembly. · **Size:** one pin fixup; one line in the gate runbook.\r\n\r\n### IR-105 — an assertion derived from a MODEL of the fixture instead of read off the fixture can only be refuted by a run, and the lane convention that defers the run gives the class a one-window latency: the repair for the first instance carried the second\r\n\r\n- **Status:** OPEN. Rule adopted 2026-09-11 (hertz, W1 close). Instrument = read the line, and read\r","truncated":true,"truncatedBy":"lines","totalLines":1011,"totalBytes":40637,"outputLines":443,"outputBytes":40637,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6937,"displayContent":{"text":"### IR-95 — a burned polling budget names WHAT it wanted and never HOW LONG it waited, so no run, green or red, can say how close it came\n…\n- **Status:** OPEN, filed by doyle 2026-09-10 at the releases#294 golden RED, where it cost this\n…\n- **Ripe when:** with the releases#294 instrumented base-vs-head comparison, which **cannot be run\n…\n\r\n### IR-96 — the `daemon_stop_convoy_e2e` API-storm cell fails 3-of-3 under the HEAVY suite at the diagnostic tree while passing at the candidate in golden CI, and nothing yet separates instrumentation from box from product\r\n\r\n- **Status:** OPEN, **cause-unclassified** (todlando's and hertz's stipulation, adopted verbatim — a\r\n  triage placement here is NOT a finding of non-defect).\r\n- **Origin:** releases#294 / v0.69.0 Arm B, 2026-09-10, deployah executing at diagnostic tree\r\n  `ed8ecd94` (= candidate `a9e786b2` + the unlanded sync instrumentation, never merged).\r\n- **What:** `spt::daemon_stop_convoy_e2e stop_under_an_api_storm_stays_down_then_start_brings_up_exactly_one`\r\n  FAILED in **all three** Arm B runs, with durations **growing every run: 9.473s · 10.973s ·\r\n  14.553s**. Different signature from the #294 sync cell; nothing was filed against #294.\r\n- **THE DIFFERENTIAL that makes it worth an entry rather than a shrug:** the same cell shows **0\r\n  failures at the candidate** in golden 34481993681 Phase A on this same box — that run's single\r\n  failure was the sync cell (`3381 tests run: 3380 passed (6 slow, 5 leaky), 1 failed, 1 skipped`).\r\n  So: 0-of-1 at `a9e786b2` under CI load, 3-of-3 at `ed8ecd94` under local HEAVY load.\r\n- **WHAT THAT DOES NOT ESTABLISH.** It does **not** isolate the instrumentation or the box as the\r\n  only candidates — a condition-dependent or intermittent PRODUCT defect remains live, and a single\r\n  CI pass is not evidence of absence. doyle claimed that elimination on 2026-09-10 and **withdrew\r\n  it** the same hour under todlando's and hertz's correction; the withdrawal is recorded in\r\n  `.spt/preserved/gate-r2-34481993681-20260910/CLASSIFICATION-AMENDMENT-2-doyle.md`.\r\n- **Confounded by IR-97** (below): the three runs were not equivalent conditions.\r\n- **Ripe when:** any lane touches daemon stop/start convoy behaviour, OR a golden run reds this cell\r\n  at a candidate, OR someone runs the cell at `a9e786b2` under the same local HEAVY workload — that\r\n  last one is the cheap discriminator and nobody has run it. · **Size:** one targeted local run to\r\n  discriminate; unknown beyond that.\r\n- **Disposition 2026-09-11 (doyle ruled, hertz's own call to release):** the diagnostic pool\r\n  `.worktrees/hertz-294-sync-stages/target` is DELETED — ARCHIVAL, REBUILD REQUIRED. It held the\r\n  `ed8ecd94` diagnostic arm, not `a9e786b2`, so keeping it warm bought nothing for the discriminator\r\n  above; no exe/dll/pdb retained because nobody was spending a heavy-broker execution window on the\r\n  post-deletion proof run, and an unexecuted retained set is a prediction. Receipt\r\n  `.spt/preserved/doyle-294-sync-stages-reclaim-20260911/{before,after}.json`: 30,000,890,067\r\n  logical bytes / 30,723 files; free 179,320,270,848 -> 207,004,086,272 (observed gain\r\n  27,683,815,424; concurrent builds moved ~2.3 GB in the 12 s window, so the delta is not\r\n  single-operation attribution). The 209-PDB reclaim that preceded it (hertz, 44,005,806,080\r\n  observed) is `.spt/preserved/hertz-relay-20260911/reclaim-deletion-receipt.json`. Source tree,\r\n  branch `diag/294-sync-stages` and every preserved receipt stay. The investigation stays OPEN and\r\n  cause-unclassified; its next run is a rebuild at `a9e786b2`.\r\n\r\n### IR-97 — a suite that leaks a fixed cohort of child processes per invocation makes consecutive runs non-comparable, and the between-run accounting the protocol required was not enforced\r\n\r\n- **Status:** OPEN. **Protocol deviation** (hertz's framing, and it is stronger than \"confounder\":\r\n  the protocol ALREADY required between-run accounting — execution did not enforce it, so the fix is\r\n  enforcement, not a limitations paragraph).\r\n- **Origin:** releases#294 Arm B, 2026-09-10. Derived by doyle from deployah's preserved\r\n  `10-residual-births.json` against the run windows.\r\n- **What:** each Arm B suite leaked **exactly 6** `spt` children that outlived it; all **18** were\r\n  still alive at the post-B3 census. Because a process alive at census whose OS birth time falls in\r\n  an earlier window existed continuously through the runs between (pid + birth time is an identity),\r\n  the carried diag-tree residue was **0 during B1 · 6 during B2 · 12 during B3**. The three\r\n  \"repetitions\" were therefore not three equivalent conditions, and every cross-run comparison in\r\n  that arm inherits it.\r\n- **LIMITS, stated so the entry is not over-read:** process **COUNT** is measured; **LOAD is not** —\r\n  idle orphans may cost nothing, contention was UNMEASURED (overlap UNVERIFIED all arm), and this is\r\n  **not** a drift meter. It neither implicates nor excludes residue as a cause of the one expiry, and\r\n  it does not explain it: B3 carried twice the orphans and **passed**.\r\n- **Also unestablished, in both directions:** 18 censused against 15 killed shows only that three\r\n  were absent at the second read. \"Three self-exited\" needs exit evidence; \"I killed 18\" was\r\n  likewise refused by deployah at the time.\r\n- **Kin:** the LEAK rows every Arm A/B run reported; `REQ-HAZARD-RESUME-CUSTODY-ABA` (KH 7.51) and\r\n  KH 7.58 — the cleanup that resolved this was correctly scoped by **pid + image path**, leaving 15\r\n  unrelated `spt` processes untouched, where a name-based kill would have taken down the live agent\r\n  fleet including the gater's own session.\r\n- **Ripe when:** any repeated-run experiment is designed on this box — census BETWEEN runs, not only\r\n  at the end. · **Size:** a between-run census step plus a scoped reap in the harness.\r\n- **Applied 2026-09-11 (#304):** hertz requested and doyle granted an EXCLUSIVE EXECUTION window for\r\n  the admitted heavy-broker-PTY subset — builds from the second lane may overlap, real-daemon test\r\n  execution may not — because a second tree executing real daemons concurrently makes the census\r\n  non-attributable and reproduces exactly this defect. Window START/END go builder-to-builder\r\n  (hertz -> todlando) with doyle copied.\r\n- **Crossing 2026-09-11 09:12:45Z-09:13:35Z, recorded as a mechanism:** the coordinator resequenced\r\n  the two builders (todlando first) at ~09:12:2xZ; hertz's START went out at 09:12:45Z before that\r\n  arrived; todlando sampled admission at 09:12:57Z and launched. Both builders disclosed within a\r\n  minute; hertz's START turned out to be an ANNOUNCEMENT (nothing launched) and was retracted, so no\r\n  two real-daemon executions overlapped — but for 50 seconds three agents each held a different\r\n  picture of who owned the box, and each was right on the messages it had. Rules that fall out:\r\n  START is sent when the first producer is LAUNCHED, not when the window is decided; a builder who\r\n  learns of a crossing FINISHES the attempt in flight and marks the overlap rather than aborting\r\n  (an aborted attempt is a labelled hole, a marked overlap is still evidence); and a coordinator\r\n  resequencing two live builders names the token that transfers the box (the other's END), because\r\n  an ordering that depends on message arrival order is not an ordering.\r\n\r\n### IR-98 — a lane driver that PRINTS a producer's output can die on an unencodable byte AFTER that producer's evidence is on disk, so the run ends with complete evidence for producer N and NO files for N+1 — an absence that reads as \"never queued\", not as a failure\r\n\r\n- **Status:** OPEN as a mechanism; the measured instance is FIXED in hertz's lane driver (UTF-8 with\r\n  replacement reconfigured at import, positive control run before relaunch: U+2500 and U+2713\r\n  printed through the fixed driver, exit 0).\r\n- **Origin:** releases#304 hertz lane, 2026-09-11 08:58Z, exclusive execution window. Producer 1\r\n  (spt-daemon lib, 21 cases at `7b098cc2`) returned exit 100 with exit, observation.json, raw and\r\n  stdout all intact; the driver then printed the stderr tail to a cp1252 stdout, raised\r\n  `UnicodeEncodeError` on nextest's box-drawing characters, and killed the loop. Producers 2 and 3\r\n  (spt bins x5, docs_server_e2e x1) NEVER STARTED. Reported by hertz as a labelled hole before any\r\n  result was read as a pass.\r\n- **What (hertz's one line, kept):** a driver that prints a producer's output can destroy the REST\r\n  of a run while leaving the finished producer's evidence intact, so the surviving evidence looks\r\n  complete and the missing producers look like they were never queued. **The tell:** evidence files\r\n  exist for producer N and no files at all exist for N+1 — not a failure, not a skip, an absence.\r\n- **Rule:** a sequence driver's own crash is a run outcome and is written as one (which producers\r\n  ran, which never started, why), and console rendering of producer output never sits between a\r\n  producer's completion and the next producer's launch without a defined encoding.\r\n- **Kin:** [[IR-32]] (an instrument that agrees with itself), [[IR-46]] (one reading is an instant),\r\n  the memory rule \"cancelled = labelled hole\"; the shell-side kin is `render-not-read-pipefail`.\r\n- **Ripe when:** any new sequence driver or any driver that renders producer output to a console;\r\n  `.github/ci/local-lane.py` and its lane modules are the first population. · **Size:** one\r\n  encoding reconfigure plus a written \"never started\" arm in the run summary.\r\n\r\n### IR-99 — EOF and terminal retire on a ConnectionBound net stream arm on the OPENER CONN's exit; a same-morning diagnosis built on that mechanism was refuted by the compiler, so the mechanism stands and the two #304 reds beside it stay open\r\n\r\n- **Status:** OPEN. The mechanism is VERIFIED; both reds are CLASSIFIED NOT-product (instance 1: an\r\n  unpromised spectator EOF; instance 2: a journal replay of a reused op seq) — repairs built at\r\n  `849c2da8` (hertz) and blob `42efe323` (todlando), each awaiting its one exclusive-window run.\r\n- **Mechanism (hertz read, doyle verified at `a17dbfbd`):** `broker.rs:6368-6372`, conn teardown: for\r\n  every ConnectionBound row THIS conn opened, FIN + `retire_stream_terminal` +\r\n  `STREAM_CONNBOUND_RETIRE:{id}: opener conn exited`. ADR-0040 decision 6. A detach, a controller\r\n  swap, or a record on the wire does not arm it; the OPENER CONN's exit does.\r\n- **Instance 1 — hertz, `rc::tests::viewer_byte_detach_keeps_controller_and_child` (2026-09-11 09:00Z):**\r\n  a 10 s wait for `NetStreamEof` on the PEER row after a viewer detach expired. First diagnosis: the\r\n  opener conn (`operator`) outlived the loop, so no FIN — **WITHDRAWN at `27baeb61`**: the compiler\r\n  refused the fix with `E0382 use of moved value: operator` because `operator` is moved into the\r\n  viewport pump at `rc.rs:4263-4266` and is already dropped when `viewport.join()` returns before the\r\n  loop. Still true and still unexplained: the run retires stream 2 and never stream 1 while the\r\n  observer waits on the peer row. **Open question:** does a FIN on the locally-initiated row reach a\r\n  subscriber of the PEER row at all? UNCLASSIFIED; producer 2 of the #304 subset is held until it is.\r\n  **Second run at `96325c9b` (09:17-09:18Z, box quiet):** the case now prints\r\n  `PEER_ROW_SELECT: inbound_rows=1 on_dialed_conn=1 picked=1`, so the unordered `find` selection\r\n  (real, repaired by conn_id + exactly-one assert) had nothing to choose between and is NOT the\r\n  cause. Two runs at two shas now pin the topology: peer row = stream 1, operator's local row =\r\n  stream 2, `STREAM_CONNBOUND_RETIRE:2` fires, and a subscriber of stream 1 receives no\r\n  `NetStreamEof` within 10 s. **Measured fact:** a FIN plus terminal retire on the locally-initiated\r\n  loopback row does not deliver EOF to a subscriber of the paired peer row. Whether that is promised\r\n  by the design (ADR-0040, the stream-lease requirement) is the open question; a test-side edit that\r\n  drops the wait is refused until a citation answers it either way.\r\n  **Answered 09:22Z (hertz cited, doyle verified):** NOT promised. ADR-0040 decision 6 (:80-83, the\r\n  `REQ-STREAM-LEASE-CLASSES` doc tag) promises that on the opener's EOF *the target* sees FIN and\r\n  `serve_attach` runs `detach_session`; it names no spectator subscriber, and every promised\r\n  consequence was delivered in the red run itself (`Detached` join passed, controller and child\r\n  survived, stamps cleared). Verdict: NOT a product finding; the case asserted a property the design\r\n  never made. ADR-0040 :156-163 already names the trap — reasoning from the arm that reads like a\r\n  guarantee to a consequence it does not carry — and this is its third instance. Repair ruled: keep a\r\n  barrier on a PROMISED observable (the row's `finished`/gone state, or the `Detached` join itself)\r\n  and assert the absence against it; a bounded drain justified as a timing window is refused.\r\n  **These two instances are two lessons under one family heading, not one mechanism** (hertz's own\r\n  correction of his earlier framing): instance 1 is an unpromised event on a spectator subscription;\r\n  instance 2 is a conn exit between test arms retiring the rows the next arm needed.\r\n- **Instance 2 — todlando, `attach::admission_answers_the_clients_own_identity_with_applicable_policy`\r\n  (09:08Z):** \"no such stream 2\" one read after `STREAM_CONNBOUND_RETIRE:2`, with controller-attach,\r\n  writer-exit `channel-closed` and the retire in the same millisecond. By the mechanism the retire is\r\n  downstream of that conn exiting; WHY the writer saw `channel-closed` at admission is the open\r\n  question, with two named candidates (the helper's own lifecycle; the new ClientPolicy send being the\r\n  first wire-side send on that transport). UNCLASSIFIED; two approved discriminator probes pending.\r\n  **Probes (a),(b),(c) at 09:12-09:15Z:** (a) the unmodified loopback-pump cell is GREEN, so the\r\n  daemon change did not break the shared pump; (c) an identity-free arm run in position 2 fails the\r\n  same way, so declared identity is NOT necessary. **Shared-operator fix REFUTED (09:20Z):** one\r\n  borrowed conn across arms, error became `no such stream 2` again — the conn was never the thing\r\n  that died.\r\n  **CLASSIFIED 09:25Z (doyle, source at `d80239df`): NOT product — TEST DEFECT, one op seq reused\r\n  across arms.** Every arm called `request_attach_endpoint` with `MintedOp::new(Minter::Rc, 2)`.\r\n  The open is journaled: `dispatch_net_stream_open` (`broker.rs:9575-9598`) keys `apply_once` by\r\n  `EffectKey { class, minter, op }` (`effect.rs:299`) — no conn, no session, no stream in the key —\r\n  so arm 2's open returned `Replayed`, the closure never ran, the allocator was never consulted, and\r\n  `stream_op_id(Rc, 2)` handed back the RECORDED id 2 with `applied_now=false` (`broker.rs:6141`\r\n  comment says exactly this). Row 2 had been terminal-retired at arm 1's opener exit ⇒ \"no such\r\n  stream 2\". The allocator sentence above (monotonic `fetch_add`, nethost.rs:1109) and todlando's\r\n  measurement (a fresh open returning the just-retired id, twice) were BOTH true: the second open\r\n  never reached the allocator. Journal is file-backed per home (`bind_in(name, dir/effects.log)`),\r\n  so a reused home replays at position 1 too; todlando's homes were per-test fresh.\r\n  **Withdrawn by replacement (todlando, 09:26Z):** the 2x2 — its position-1 cell rested on marker\r\n  absence in stderr, and markers are never written to stderr on pass or fail (zero-match filter);\r\n  \"id reissued after terminal retire\" (a journal replay); \"FIN takes the conn with it\" (nothing was\r\n  opened the second time). No product suspicion reaches this register from instance 2.\r\n  **Repair (built, uncommitted, blob `42efe323`, base `58b95354`):** one broker, five arms, DISTINCT\r\n  seqs 2-6, identity-free control in positions 1 AND 2, `ARM_OPEN` prints the seq. Prediction filed\r\n  before the run: green on all five. Negative control on file: same seq, red twice. Run pending an\r\n  exclusive window after IR-97's producer 2.\r\n- **Rule (revised after the withdrawal):** a test that waits on EOF must first establish WHICH row\r\n  FINs and WHO observes it, from source, before it names a deadline \"a barrier\"; a test surprised by a\r\n  retire looks for the conn that exited before it looks at the stream. And a mechanism verified in\r\n  source does not verify the diagnosis built on it — ownership of the variable the diagnosis names is\r\n  a separate check the compiler happened to make for free here.\r\n- **Kin:** [[IR-97]] (same window), KH 7.66 (an expired bounded wait is CENSORED, not a latency), the\r\n  memory rule \"hedge is not grounding\".\r\n- **Ripe when:** any new test reads a ConnectionBound stream to EOF or asserts on a retire; the\r\n  ~20 house-standard 400x25 ms wait sites are the population to grep. · **Size:** one comment per site\r\n  naming what arms the edge, once the open question above has an answer.\r\n\r\n### IR-100 — an editor-driven rust-analyzer runs `cargo check --workspace --all-targets` into a LANE's pool on its own schedule, so a builder census counts it, a lock wait charges it to nobody, and the lane's disk growth carries it uncredited\r\n\r\n- **Status:** OPEN. Recorded 2026-09-11 09:30Z from todlando's trace; no mitigation applied.\r\n- **Instance (todlando, `.worktrees/304-product`, 09:29Z):** his distinct-seq build printed\r\n  `Blocking waiting for file lock on build directory`. Holder pid 28176, ancestry\r\n  `cargo check --quiet --workspace --all-targets --manifest-path .worktrees/304-product/Cargo.toml`\r\n  ← `rustup` ← `RUST-ANALYZER.EXE` ← `claude.exe` ← `claude-spt.exe` — his OWN session's language\r\n  server, checking his lane's manifest into his lane's `target/`. Not CI, not another lane. NOT a\r\n  pool violation (same tree, same lane; `SPT_POOL_FOREIGN` correctly silent).\r\n- **Second instance, the asymmetry (hertz, 09:31:40Z, ancestry walked):** TWO analyzers on this box,\r\n  one per live session, BOTH with cwd at the project root. todlando's (rust-analyzer 46072) resolved\r\n  `.worktrees/304-product/Cargo.toml` and builds into HIS pool; hertz's (26640) resolved the ROOT\r\n  manifest and builds into the root `target/` — a pool that is not his lane's. So hertz's growth\r\n  figures and lock waits were never charged by his own analyzer, and NOT because anyone chose that:\r\n  cwd is identical for both, so cwd is not the discriminant. The candidate is which files each\r\n  session opened (rust-analyzer discovers its workspace from them) — UNMEASURED. Read IR-100 as \"the\r\n  blast radius depends on which manifest the analyzer resolved, and nobody chose it\", never as \"that\r\n  lane was clean\".\r\n- **Instrument (hertz, same hour):** `lane_run.builder_census` now walks each builder's ancestry and\r\n  attributes it `ci` / `analyzer` / `agent` / `unknown`, printing the manifest from the cmdline when\r\n  legible; live box read 11 ci, 1 analyzer, 0 agent, 0 unknown. Quiet predicate revised from \"zero\r\n  builders\" (never clears under a peer's analyzer, leases nothing when it does) to \"zero CI builders\r\n  AND no builder whose manifest is MY worktree\"; a peer's analyzer is recorded contention, not a\r\n  refusal. Still a sample, not a lease.\r\n- **Why it matters (three census readings it breaks):** (1) `BUILDERS=n` in an admission census\r\n  includes it, so a nonzero count is not \"CI or another lane\" and a zero is not \"quiet for the next\r\n  minute\" — an editor can start a workspace check at any moment; the census is a sample, not a lease\r\n  (hertz's own words on his window, [[IR-97]]). (2) Its rmeta/dep-info growth lands in the lane's\r\n  allocation without a declared producer, so a producer's \"growth\" is an upper bound on that\r\n  producer. (3) It delays a producer without failing it: a one-attempt run that sat on the lock is\r\n  slow for a reason no window ledger named.\r\n- **Third limit, from outside (todlando 09:42Z, hertz confirmed 09:43Z):** a BUILDER census is blind\r\n  to a peer's EXECUTION phase. hertz's producers run test binaries, which carry none of the builder\r\n  names the census matches on, so 0 cargo sampled DURING his open window read as \"quiet\" — and doyle\r\n  read his own zero-cargo sample as an answer to a START he had already recorded. hertz's own\r\n  instrument would not have caught hertz's own window. todlando's admission census (09:42:58Z) already\r\n  sweeps the other half: test binaries under any `target\\debug\\deps` (0) with a positive control (10\r\n  shells visible), which is the form the census must take. Rule: a census is ADMISSION evidence only —\r\n  builders by ancestry AND executing test binaries under `deps`, each with a positive control; whether\r\n  the box is BUSY is answered only by a granted-and-acknowledged window ([[IR-97]]), never by a sample.\r\n- **Fourth limit, the census's own blind spot (hertz 10:13Z, measured 556 processes):** a path-keyed\r\n  filter must count what it COULD NOT ANSWER FOR separately from what it answered \"no\" to. todlando's\r\n  WMI/Get-Process path reader refused ~180 protected processes (declared); hertz's psutil reader saw\r\n  553/556 but his `exe or \"\"` swallow turned two EMPTY paths into \"not in the pool\" and declared 1\r\n  blind when the real hole was 3. Both under-declared, by different mechanisms. A blind spot that does\r\n  not raise is the same clean zero a broken filter returns. admission.py now counts empty as blind.\r\n- **Rules:** a builder census classifies by ANCESTRY, never by count — `Runner.Worker.exe` = CI, a\r\n  lane's own cargo = a producer, `RUST-ANALYZER.EXE` = editor check. A lock wait is recorded as a\r\n  delay with its holder's ancestry, as here; nobody kills an analyzer, and the analyzer's check is\r\n  charged to the LANE, so any growth figure quoted from a lane pool says so.\r\n- **Recommendation to the operator (rides here, not as a directive to agents):**\r\n  `rust-analyzer.cargo.targetDir` (true, or a path under the lane's `target/`) gives the analyzer\r\n  its own build directory — that removes the LOCK contention and the census ambiguity in one\r\n  setting; it does not remove the disk, which stays in the same pool subtree by design.\r\n- **Kin:** [[IR-97]] (exclusive execution windows; builds may overlap), [[IR-56]] (a pool is a\r\n  relationship, not a path), the memory rules \"measure the box before the instrument\" and \"quiet\r\n  window predicate\".\r\n- **Ripe when:** the next admission census on this box, or the next lock wait anyone traces.\r\n  · **Size:** one editor setting plus one line in the census procedure.\r\n\r\n### IR-101 — no per-lane producer compiles a lib crate's own `#[cfg(test)]` module on the branch that broke it, so a stale caller of a lane's own signature change rides green through six real-daemon runs and surfaces only at assembly, or from an editor\r\n\r\n- **Status:** OPEN. Rule adopted 2026-09-11 09:35Z; instrument = one command at inventory and one at\r\n  assembly.\r\n- **Instance (todlando, `feat/304-remote-friction-product`, 09:33Z):** `a4017a15` (#301) dropped the\r\n  port parameter from `webserve::handle_path`/`resolve_path` (six params). Six call sites in that\r\n  file's own `#[cfg(test)]` module — :856, :1132, :1201, :1206, :1213, :1333 at `58b95354`, verified —\r\n  still passed seven with a literal `5474`. `E0061`, committed since `a4017a15`, invisible to every\r\n  producer the lane ran: `cargo nextest … -p spt-daemon --test attach` builds the INTEGRATION target\r\n  and a lib's cfg(test) module is not in that graph. Found by the analyzer of [[IR-100]] (`cargo check\r\n  --workspace --all-targets` is the one invocation on the box that compiles lib test modules).\r\n  Fix `5853cb14`: the six arguments dropped, 6+/6−, nothing else.\r\n- **Consumer half (hertz):** his lane ran `-p spt-daemon --lib` all morning, which DOES compile that\r\n  module, and was 21/21 green at `a17dbfbd` — because he had ALREADY repaired those callers at\r\n  `5fd683e9` (test-only, all hunks past the cfg(test) line at :821; verified) while rewriting the\r\n  #301 node-root cases in the same module. So the gap is not \"nobody builds it\"; it is \"nobody builds\r\n  it on the branch that broke it\", and a per-lane green on the other lane is silent about this one.\r\n  todlando's first account (\"hertz's tree lacks a4017a15\") was wrong and withdrawn; `merge-base\r\n  --is-ancestor` is TRUE.\r\n- **The collision it exposed:** two lanes edited one cfg(test) module for one issue all morning,\r\n  independently. Measured with `git merge-tree --write-tree 849c2da8 5853cb14` (no checkout touched,\r\n  merge-base `d89a655f`): exactly ONE conflict, content, `webserve.rs`; `rc.rs` and\r\n  `bootstrap_firewall/windows.rs` auto-merge. Loud, not silent. Ruled: todlando keeps `5853cb14` (a\r\n  lane whose lib tests do not compile is blind to this class); assembly resolves that module to\r\n  hertz's blob and asserts the resolved blob equals his; hertz owns `webserve.rs` cfg(test) for #304.\r\n- **The clean win that drops coverage (hertz, 09:37Z):** reading todlando's six-line diff showed\r\n  hertz what his own module had deleted: the case at todlando's :1198 was the only place feeding\r\n  hostile text through `escape_html`, which is still live in production on the message facet\r\n  (`webserve.rs:494-510`). His #301 rewrite replaced that case and dropped the escaper coverage.\r\n  Resolving \"to hertz's blob\" would have lost it PERMANENTLY with no conflict — a correct-looking\r\n  resolution, not a merge collision, is the silent case. Restored at `9f09db4e` (test-only, +30 at\r\n  :1185: the compound string, each of five entities alone, a pass-through negative control; the\r\n  comment names its limit — escaper, not call sites). His absence census (\"grep returned NOTHING\")\r\n  came from a predicate built from the case he was looking at (`script a=|&lt;script|&#39;|&quot;`),\r\n  which cannot match `&amp;`; rule: census the SUBJECT (`grep escape_html`), never its rendered\r\n  effect.\r\n- **Second instance, integration axis (doyle, 09:39Z):** `a4017a15` deleted the registry index\r\n  outright (`fn index`, `Index`, `IndexEntry`, the `?json` twin; 19+/84−). `tests/webserve_e2e.rs`\r\n  (last touched `f3a5e169`, 2026-09-07; byte-identical on main and all three lane shas) asserts\r\n  that index at :53 and :67 (`GET /LoCaL/?json` = 200 with entries, `GET /local/` = 200 HTML with\r\n  `source &amp; quote.txt`). Integration tests run only in the golden lane, and no #304 producer\r\n  names this file (allocations grep: only deployah's #294 arms and CI job logs). Prediction filed\r\n  before any run: `production_listener_routes_nodes_docs_and_live_registry_references` RED at every\r\n  #304 sha; the other four cases UNKNOWN. Tags riding in it: REQ-WEB-URL-NODE-PREFIX,\r\n  REQ-WEB-SERVING-REGISTRY, REQ-DOCS-LOCAL-SERVER, REQ-WEB-ADAPTER-DOCS-FACET — if\r\n  REQ-WEB-SERVING-REGISTRY's int evidence WAS the index, it is relocated, not faked. Assigned to\r\n  hertz as producer 3 in a SECOND window after producers 1+2 at `9f09db4e`, so the frozen sha is not\r\n  churned. todlando's hermetic unit twin of it (`index_escapes_html_…`) reds at :1197 on his branch\r\n  for the same reason; that case is scheduled to stop existing at assembly and nobody fixes it.\r\n- **Rules:** (1) a lane inventory owes `cargo check --workspace --all-targets` at the sha it reports,\r\n  before any evidence is quoted — a prerequisite, not evidence about the merge. (2) The assembly\r\n  compile gate is the same command on the MERGED tree, before `traceable-reqs check`; it is the only\r\n  step that sees the cross-lane case. (3) A per-lane `--lib` green on a sibling lane is never cited\r\n  for the lane under test. (4) A lane that DELETES a surface greps the integration tree for that\r\n  surface's assertions in the same change; golden is not the place to learn an e2e was pinned to it.\r\n  (5) Before resolving a same-module conflict to one side, diff the LOSING side for assertions the\r\n  winner lacks — the conflict is the loud case; the clean win is the one that drops coverage.\r\n  (6) A hermetic in-proc cell is not a window producer, but it is ANNOUNCED before it runs so an\r\n  ancestry census can attribute it (todlando's 09:37 cell read as `agent=4` during hertz's sample).\r\n- **Kin:** [[IR-100]] (the instrument that found it), the memory rules \"cfg-gated code is invisible\r\n  to the other platform gate\" (same shape, other axis), \"gate population excludes consumers\",\r\n  \"resolve wrapper conflict toward the shared body\".\r\n- **Ripe when:** now — the next #304 inventory and the #304 assembly. · **Size:** one line in the\r\n  inventory script, one in the assembly runbook.\r\n\r\n### IR-102 — a dirty file the lane DECLARED is still invisible to an assignment made against its committed blob, so the gater measures and predicts on a blob the lane was never going to run\r\n\r\n- **Status:** OPEN. Recorded 2026-09-11 09:50Z from hertz's correction; ruling applied (commit all\r\n  five), no instrument yet.\r\n- **Instance (#304, hertz lane, 09:17Z–09:48Z):** hertz named his dirty files at his 09:17 START and\r\n  said none entered producer 2's compile scope — true. doyle then measured `tests/webserve_e2e.rs`\r\n  byte-identical on main, 849c2da8, 9f09db4e and 5853cb14 (true of the COMMITTED blob), predicted\r\n  reds at :53/:67 against it, and assigned the repin to hertz. hertz's working tree had carried an\r\n  uncommitted 16+/20- repin of that file all morning. The prediction was UNTESTABLE AS FILED: the blob\r\n  it named was not the blob the lane would run. Four more dirty files (ci.yml, golden.yml,\r\n  twohost_web.rs, attach_link_push_e2e.rs, webserve_cross_node_e2e.rs) carried an impl tag for a REQ\r\n  registered only in the lane (REQ-LOCAL-GATE-EXECUTION-EVIDENCE, stages impl+unit), a checker\r\n  version pin the lane's `[placement]` table depends on (0.4.0; main and the gater's box at 0.2.0),\r\n  and int tags on 169 lines no producer had run.\r\n- **Mechanism:** \"declared\" answers \"does it touch THIS run\"; it never answers \"is it the SUBJECT of\r\n  the next assignment\". A gater who measures `git show <sha>:<path>` across shas is measuring\r\n  committed history and cannot see a working tree by construction — the two instruments answer\r\n  different questions and the answers were confused because the file had the same name in both.\r\n- **Rules:** (1) an assembly takes COMMITTED blobs only; a tag on an uncommitted line is a tag on\r\n  nothing, and uncommitted work at assembly is not in the release. (2) Before assigning a file to a\r\n  lane, `git -C <lane> status --short -- <path>` — one command — and if it is dirty, the assignment\r\n  names the working blob, not the committed one. (3) A lane's START names each dirty file with what\r\n  it IS (subject, REQ, stage), not only what it is not (outside this producer's scope). (4) A\r\n  registry or workflow edit that lives only in a lane's working tree is a gate the assembled head\r\n  will fail; commit it first, one subject per commit, REQ named.\r\n- **Kin:** [[IR-101]] (a surface no per-lane producer compiles), [[IR-97]] (windows), the memory\r\n  rules \"verify the SUBJECT, not just the measurement\" and \"name the file AND sha a condition came\r\n  from\" — this instance is the case where the sha was named correctly and was still the wrong\r\n  instrument.\r\n- **Ripe when:** now — the #304 assembly (checker 0.4.0 on the gater's box before the\r\n  traceable-reqs gate) and every future lane assignment. · **Size:** one status line per assignment;\r\n  one CLI upgrade.\r\n\r\n### IR-103 — a rig that re-enters something already retired reads as a product red: four instances in ONE cell (#230), each masking the next\r\n\r\n- **Status:** OPEN. Recorded 2026-09-11 10:00Z (doyle). Amended 10:20Z: the third instance's repair\r\n  RAN (todlando window 10:12-10:18Z, one attempt) and its structural falsifiers all HELD — distinct\r\n  `serve_stream` per arm (1, 3), red inside the bound naming its arm, arm 2 seated and staying seated,\r\n  distinct `gen=` per arm (30 ms apart). It exposed a FOURTH instance, below. Its repair ran at\r\n  committed blob 0845e68d (10:22Z): GREEN, five arms; a trace producer (`--success-output\r\n  immediate`, 10:24Z) confirmed five matched ARM_OPEN/ARM_DONE pairs, serve_streams 1/3/5/7/9,\r\n  five distinct gens, every session-detach inside its own arm's bracket. REQ-ATTACH-CLIENT-STALE\r\n  int is MEASURED on every arm; nothing about the seat, lease or generation was ever in question.\r\n  The cell stays open only for the parked hazard below.\r\n- **The three, in the order they were paid for:** (1) a reused `MintedOp` seq on one broker replayed\r\n  the retired stream's id from the effect journal (IR-99 instance 2; EffectKey carries no\r\n  conn/stream). (2) hertz's spectator subscription on a stream the server holds: one seat, healthy\r\n  prior displaced (nethost.rs:546-562) — a channel that cannot exist. (3) `wait_for_stream`\r\n  (tests/attach.rs:113-122) returns the FIRST non-local stream with no exclusion, so every arm after\r\n  the first re-served arm 1's retired stream from `net_from_seq = 0`, replayed arm 1's Request record\r\n  (identical `gen=` in the trace read as a clock collision), hit arm 1's leftover FIN, and detached —\r\n  the `session-detach was_controller=true` that two readers took for a stale release. Arms 2-5 had\r\n  NEVER executed; REQ-ATTACH-CLIENT-STALE int is UNTESTED beyond arm 1, not red.\r\n- **Instance (4), 10:18Z:** the helper sent EVERY arm's keystroke with a literal input op of `1`\r\n  (tests/attach.rs, `send_attach_input`). The broker dedups a PtyWrite on\r\n  `EffectKey { class: session_id, minter, op }` (effect.rs:299-303, applied through\r\n  `journal.apply_once` at broker.rs:8803-8809) — no stream, no conn, no arm, and NO `EffectKind`:\r\n  a Request op and an Input op sharing an integer on one session collide with each other. Arm 1\r\n  typed; arm 2's identical key hit the applied-set, the closure never ran, the PTY was never\r\n  written, and the echo its loop waited for could not exist — a correct 10 s read red\r\n  (`brain IPC read deadline elapsed`, attach.rs:1940) on a healthy seat. Repair: input ops at\r\n  `100 + op_seq` (102..106), disjoint from the Request ops 2..6, mechanism recorded at the call\r\n  site. Arm 2 EXECUTED for the first time; arm 2's assertion and arms 3-5 still have not.\r\n  Ownership, todlando's words: the #230 verdict named the CLASS (one op seq reused across arms)\r\n  and he fixed the INSTANCE the failure pointed at — the Request op — leaving the Input op one\r\n  function away in the same helper.\r\n- **Mechanism (the class):** each instance is a rig selecting a retired object by a key too coarse\r\n  to exclude it — (seq) without stream, (stream) without seat, (first row) without served-set,\r\n  (input op) without arm. And\r\n  each red was terminated BY the previous defect: closing the seq reuse removed the error that had\r\n  been ending arm 2, exposing an unbounded read (`call_deadline()` None on a cold_start conn,\r\n  attach.rs:1305 rule) that turned the next defect into a 240 s timeout. Stacked, in one direction.\r\n- **Two derivations, both wrong the same way (kept on purpose):** doyle read the sixth\r\n  `serve_attach` argument as a seat generation (it is `net_from_seq`, attach.rs:479); todlando read\r\n  identical `gen=` values as a wall-ms collision (attach.rs:968 mints wall-ms; there was never a\r\n  second sample). Both built a PRODUCT mechanism on a trace whose anomaly was the rig's. The\r\n  refutation came from reading the trace's `serve_stream=1` twice against a strictly monotonic\r\n  allocator (nethost.rs:868/880/1109) — a monotonic id repeating is one object seen twice, never two.\r\n- **PARKED, unmeasured, no REQ:** the seat-generation guard (`detach_if_gen`, broker.rs:3506-3516)\r\n  is inert on EQUAL generations and the mint is wall-ms. Two Requests inside one clock tick on one\r\n  conn would make a stale release match the live seat. Structural, re-derivable, and NOT observed:\r\n  the discriminator is a cell that mints two Requests in one tick, seats the second, releases the\r\n  first, and asserts the seat survives. Nobody builds it until a field report or a cell shows the\r\n  collision; nobody cites it as a finding.\r\n- **Rules:** a rig that picks an object by \"first\"/\"any\"/\"same seq\" names the population it excludes,\r\n  or it is re-entering a retired object; a monotonic id appearing twice in a trace is the SAME object\r\n  and the trace is read again from there; an anomaly explained by a product mechanism gets its\r\n  falsifier built BEFORE the product ruling (todlando's \"I built the refutation after sending\");\r\n  when a verdict names a CLASS, the repair sweeps every key of that class in the cell before the\r\n  next window — the fourth instance was the same helper, one function over, and cost a window.\r\n- **Population sweep (todlando, 10:05Z, source only):** the bare first-peer-row form appears in\r\n  six more `crates/spt-daemon/tests` files; the defect needs a SECOND condition (several arms\r\n  sharing one target brain / NetHost table). Every repeated caller builds its own broker per call\r\n  (exit_every_reap :125, transport_death_eof :442-443, inject_control_wedge three separate fns) and\r\n  the rest are single-call. CLEAN — the #230 cell is the only two-condition site in the repo, which\r\n  is why the form survived: it was correct for every case until one cell reused a target. Limits\r\n  named: that crate's tests only (the `initiated_locally` grep population); a read, not a run.\r\n  Repair took the shape one file over (tests/controller_lease.rs:170 `wait_for_new_stream`).\r\n- **Kin:** [[IR-99]], [[IR-101]], [[IR-102]], memory \"journaled seq reuse replays the retired\r\n  stream\", \"stacked defects mask each other\", \"discriminator question\".\r\n- **Ripe when:** now — the #230 rig repair, and every cell whose arms share one broker/conn.\r\n  · **Size:** one served-set parameter in one helper; one register line.\r\n\r\n### IR-104 — checker 0.4.0 silently skips a FILE scan root under git enumeration: 81 doc stages read as missing, and a local 0.2.0 green hid it because the two versions disagree on what is evidence\r\n\r\n- **Status:** FIXED UPSTREAM 2026-09-11 (traceable-reqs v0.4.1, PR #21 -> d9af11d, red-first cells);\r\n  spt-core consumes via hertz's #304 lane pin fixup. Closes when that pin is on main.\r\n- **Instance:** `traceable-reqs.toml` has declared `CONTEXT.md` a scan root since the seed (a FILE\r\n  root: the glossary carries doc-stage tags). 0.2.0 honoured it. 0.4.0 (SPEC §Scan enumeration:\r\n  \"an allowlist of directories\") filtered git candidates with `rel_under_root`, which required a `/`\r\n  after the root prefix; a candidate equal to the root had an empty remainder and never qualified.\r\n  Measured: 0.4.0 on main = 81 `missing_stage … stage=doc`, every one with its doc tag in\r\n  CONTEXT.md and 71 nowhere else; positive control: 0 of 253 doc tags under `docs/` were affected.\r\n  The walk strategy (`git = \"off\"`) never had the bug.\r\n- **Why it hid:** the box's CLI was 0.2.0 while CI's pin moved to 0.4.0 in the lane, so every local\r\n  `check` today validated against a different evidence rule than the gate it stood in for. hertz\r\n  found the placement half of that silence first (0.2.0 emits nothing for a `[placement]` table it\r\n  cannot read); the doc half surfaced only when the gater built 0.4.0 and ran it. A green from a\r\n  checker that does not match CI's version is a measurement of the wrong tool.\r\n- **Rejected remedies, measured:** `roots = [\".\"]` recovers the 81 and admits 43 root-level plan\r\n  documents with code-stage tags in prose (148 misplaced), then 12 with malformed tag-shaped tokens\r\n  and AGENTS.md's own example tag; an exclude list of 55 historic files is the wrong shape.\r\n  `scan.exclude` cannot express \"every root file except one\" (no negation).\r\n- **Rules:** (1) before citing any `traceable-reqs check`, print `--version` and compare it to\r\n  the CI pin in the tree being judged; a mismatch is a labelled hole, not a green. (2) A checker\r\n  upgrade is a gate change: run old and new on the SAME tree and account for every finding that\r\n  appears or disappears before the pin moves. (3) The assembly gate runs the pinned version; the\r\n  binary is built from the tag (`traceable-reqs-<ver>.exe`), never \"whatever is on PATH\".\r\n- **Kin:** [[IR-37]] (placement enforcement, the same release), [[IR-102]] (a declared thing still\r\n  unread), memory rules \"a predicate needs its tool\", \"zero-match filter reads as absent\".\r\n- **Ripe when:** now — the #304 assembly. · **Size:** one pin fixup; one line in the gate runbook.\r\n\r\n### IR-105 — an assertion derived from a MODEL of the fixture instead of read off the fixture can only be refuted by a run, and the lane convention that defers the run gives the class a one-window latency: the repair for the first instance carried the second\r\n\r\n- **Status:** OPEN. Rule adopted 2026-09-11 (hertz, W1 close). Instrument = read the line, and read\r\n  what the line LANDS on, before asserting either.\n…\n","startLine":5673,"lineNumbers":[5673,null,5675,null,5924,null,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952,5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968,5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116,6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,6132,6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,6144,6145,6146,6147,6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163,6164,6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179,6180,6181,6182,6183,6184,6185,6186,6187,6188,6189,6190,6191,6192,6193,6194,6195,6196,6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,6242,6243,6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259,6260,6261,6262,6263,6264,6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275,6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,6286,6287,6288,6289,6290,6291,6292,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305,6306,6307,6308,6309,6310,6311,6312,6313,6314,6315,6316,6317,6318,6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334,6335,6336,6337,6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365,6366,6367,6368,6369,6370,null,6418]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":6937,"totalBytes":40637,"outputLines":443,"outputBytes":40637,"shownRange":{"start":5927,"end":6369},"nextOffset":6370}}},"isError":false,"timestamp":1789483669315}}
{"type":"message","id":"f2a6601b","parentId":"b78dba37","timestamp":"2026-09-15T14:47:49.340Z","message":{"role":"toolResult","toolCallId":"call_l6I7d56NfalytdGlREVyYtWf|fc_000c7cef03cac861016aa95a95282c87d18bbe240cbfa3c273","toolName":"read","content":[{"type":"text","text":"### IR-104 — checker 0.4.0 silently skips a FILE scan root under git enumeration: 81 doc stages read as missing, and a local 0.2.0 green hid it because the two versions disagree on what is evidence\n…\n- **Status:** FIXED UPSTREAM 2026-09-11 (traceable-reqs v0.4.1, PR #21 -> d9af11d, red-first cells);\n…\n- **Ripe when:** now — the #304 assembly. · **Size:** one pin fixup; one line in the gate runbook.\n\n### IR-105 — an assertion derived from a MODEL of the fixture instead of read off the fixture can only be refuted by a run, and the lane convention that defers the run gives the class a one-window latency: the repair for the first instance carried the second\n\n- **Status:** OPEN. Rule adopted 2026-09-11 (hertz, W1 close). Instrument = read the line, and read\n  what the line LANDS on, before asserting either.\n- **Instance 1 (hertz, `test/304-remote-friction`, `4ec34d1c`, 03:07Z):** `webserve_e2e.rs`\n  `subnet_node_labels_shadow_only_the_docs_compat_alias_while_members` still asserted the pre-#301\n  contract at the `/llms.txt/` line — a node root with an EMPTY remainder as `200`. Under the\n  node-root arm (`webserve.rs:778-781`) that path is a `302`, so the case died `302 != 200` at the\n  first assertion it reached and MASKED the five http calls after it. The `4823ae5d` sweep missed\n  the line because the case's other redirects are BARE-NODE ones, which take `redirect_node` and\n  are untouched by #301: I classified the case by its siblings and never read the line itself.\n  Cost: one window.\n- **Instance 2, inside the repair for instance 1 (`28d4eb68`, 03:19Z):** `4ec34d1c` was right about\n  the redirect and wrong about what it lands on — it followed through to `GET /llms.txt/docs/` and\n  asserted `200`. Measured at `71caedd4`: that is `404`, and the `404` is CORRECT. This fixture's\n  docs dir holds `cli/reference.md` and the root-file labels and no `index.html`, and a docs root\n  without one is a 404 by design — `webserve.rs:1028-1033` writes `index.html` precisely in order\n  to get `200` at `/local/docs/`. So the new assertion pinned index-presence, which is not this\n  case's subject. I asserted a property of a redirect TARGET without reading what the target\n  contains. Cost: a second window.\n- **The mechanism, stated once:** both assertions were derived from a model — the case's siblings in\n  instance 1, the contract's shape in instance 2 — rather than read off the fixture in front of me.\n  A model-derived assertion is indistinguishable from a correct one at authoring time AND at review\n  time; only a run refutes it. This lane commits such work `UNCOMPILED AND UNRUN at commit time:\n  written outside the window, measured in the next one` (both commit bodies carry that line\n  verbatim), so the class has a one-window refutation latency BY CONSTRUCTION, and a repair authored\n  inside that same blind interval inherits the defect it repairs. That is the register-worthy part:\n  the fix for a from-a-model assertion was itself a from-a-model assertion, 12 minutes later.\n- **Resolution:** `28d4eb68` drops the directory-root status and keeps the `302` + `Location` pair.\n  The line AFTER it already fetches `/llms.txt/docs/llms.txt` and compares bytes — a real leaf\n  fetched THROUGH the redirect target, which is stronger evidence the target is live than a status\n  on the directory root ever was. Blast radius measured at `71caedd4`, producer 3: the case cleared\n  the old line and the new pair and failed only on this one; the four sibling cases stayed green.\n  Producer 3 GREEN @`28d4eb68`.\n- **Third instance, caught BEFORE it shipped (same session, this entry's own id):** this file in the\n  `#304` test lane ends at IR-97; main ends at IR-104. Numbering this entry from the register in\n  front of me would have produced `IR-98` — a collision with a real entry, written while looking at\n  a file that had every right to look complete. The id is `105` because it was read off main. Same\n  mechanism, third direction: a stale local artifact IS a model of the shared one.\n- **Rule:** assert against what the fixture CONTAINS, at a named line you have read, in the tree the\n  claim will live in. Three corollaries earned here: a sweep must read every line it claims to have\n  swept (classifying a case by its siblings is a model); following a redirect obliges you to read\n  the target's contents before asserting its status (the target's shape is a model); and a register\n  id, like any shared address, is read off the shared tree, never off your lane's copy.\n- **Ripe when:** any test edit is authored outside the window that will measure it — which is this\n  lane's normal mode. · **Size:** a read, not a tool; the deferred-run interval is the thing to\n  shorten if it recurs.\n- **Kin:** [[IR-101]] (its census read the rendered effect instead of the subject — same family,\n  same morning, same file), [[IR-102]] (predicting against a blob nobody would run), memory\n  \"rig inherits the defect it studies\", \"verify the SUBJECT not just the measurement\",\n  \"precise claim is falsifiable\".\n\n### IR-106 — a red set HANDED OVER in a message was reported as a POPULATION: both members verified, their lines and modes corrected, and the count still wrong by half\n\n- **Status:** OPEN as a discipline line; the instance is closed (the run that refuted it is on file).\n  Author and subject: todlando. Filed by doyle 2026-09-11 11:20Z from todlando's text; IR-105 lands\n  from hertz's lane at the same assembly, which is why this number follows it.\n- **Instance (2026-09-11, #304 W1 product lane).** todlando was handed a red set naming TWO cells in\n  the spt-daemon webserve module. He opened each one, CORRECTED its line number and its failure mode,\n  and reported the corrected pair as his prediction. The unfiltered run at 3e7eaf67 showed FOUR reds\n  of the same mechanism (the retired `/local/` index twin): the two named, plus\n  `corrupt_registry_is_loud_but_does_not_disable_unrelated_facets` (:1228, 302 vs 500) and\n  `node_routing_reserves_facets_without_registry_fallback` (:1011, 302 vs 200). A post-run sweep\n  mapping every single-segment node-root literal to its enclosing fn closed the population at four,\n  by enumeration; two further cells touch a root and pass for stated reasons.\n- **Why the verification is what hides it.** Checking a member answers \"is this one real\". It cannot\n  answer \"is this all of them\": no amount of per-member rigour turns a received list into an\n  enumeration, and correcting a handed-down set FEELS more rigorous than enumerating it.\n- **Mirror instance one window later, other direction (hertz, same lane).** His enumeration was\n  SOUND (every node-root literal in the module mapped to its enclosing fn) but its SCOPE was\n  inherited from the one file he happened to be resolving; the merge also brought\n  `bootstrap_firewall.rs` (+4) and `bootstrap_firewall/windows.rs` (+2), so his whole-suite count was\n  short by six (predicted 981, measured 987). Same family: a sound instrument pointed at the wrong\n  population.\n- **Rule.** Before any COUNT enters a prediction, a START or an END, run the enumerating predicate\n  YOURSELF, with a tool that can express the population you are claiming (an unfiltered run; a grep\n  whose root is the crate, not the file you have open). A set received in a message is a lead.\n- **Kin:** [[IR-100]] (a census counts what its filter could not answer for, separately from a no),\n  [[IR-101]] (a per-lane green is silent about the population it did not select), [[IR-105]] (a\n  from-a-model assertion is refuted only by a run), memory \"a predicate without its tool is not evidence\".\n- **Ripe when:** now, a line in the window protocol, not a build. Fold into the START/END template\n  beside the census. · **Size:** one entry, one clause; no code.\n\n### IR-107 — a rig that redirects TMP INSIDE the checkout puts every tempdir fixture under a git toplevel, and cells whose premise is \"outside any repo\" resolve THIS repo's remote\n\n- **Status:** RIG FIXED in hertz's lane (base now under `AppData/Local/Temp/hertz-304-rig/<label>`;\n  `HERTZ_RIG_TMP_IN_REPO=1` restores the old placement on purpose as the negative control). Recorded\n  2026-09-11 11:20Z (doyle, from hertz's and todlando's measurements); corrected 11:35Z on hertz's\n  read. The A/B COMPLETED in window 7 at cba18cd5: arm A (base outside any repo) 2 run / 2 passed;\n  arm B (base inside the checkout) 2 run / 2 FAILED at :1404 and :842 with the strings below, the two\n  bases recorded and differing. Window 6's arm B was the non-measurement described below.\n- **Instance.** hertz's first unfiltered `spt-daemon --lib` at 69438c01 redded two cells that neither\n  lane touches and that todlando's unfiltered run had passed 8 minutes earlier on the same bytes and\n  box: `registryhost::tests::recent_projects_for_dedups_newest_first_excludes_spt_internal` (:1404,\n  got `[\"github-com-bigscreenvr-spt-bs-core\"]`) and `projwriter::tests::batched_complexity_counters_hold`\n  (:842, got `Some(\"spt-bs-core\")`). Both fixtures require a directory outside any repo.\n- **Mechanism, measured with a control.** `lane_run.py` set TMP/TEMP/TMPDIR/RUNNER_TEMP to\n  `EVID/temp/<label>` inside the spt-core checkout; `git -C <that dir> rev-parse --show-toplevel`\n  answers the checkout (remote `BigscreenVR/spt-bs-core`), while the same probe from the default TMP\n  answers \"not a git repository\". `project_id_for_dir` is REMOTE-URL FIRST: `slug(remote)` and\n  `display_from_url(remote)` are the two observed strings exactly, and the folder-name fallback could\n  not have produced either (candidate folder names: 304-product, hertz-304, spt-core). So git got as\n  far as step ONE of the derivation. The first mechanism offered (\"any in-repo cwd\") was killed by one\n  datum: ci.yml:143 runs `kind(lib)` unfiltered on this runner with an in-repo cwd and passed at\n  6a7dd6b7. The variable was the FIXTURE's location, never the process cwd.\n- **Instrument defects in this lane today, all hertz's, all closed:** (window 5) `cargo ... | tail;\n  echo $?` reports tail's status (memory \"render-not-read-pipefail\") — the compile gate was in fact\n  green, so that reading was VOID evidence rather than a masked red; the same construct one command\n  later printed 0 over a checker [must] finding, a true exit 1 — the hazard is that an exit read\n  through a pipe certifies nothing, not that it hides reds. (window 4 START gate, 10:26Z) a negative\n  control that returned at the refusal branch vouched for nothing about the send arm, which then\n  crashed on a NameError on the first real launch (memory \"make a new rig red on purpose\",\n  refinement). (window 8, premise lane, 12:14Z) a FOURTH void-exit instance in one day — `$?` and `${PIPESTATUS[0]}` both read a later command, a backgrounded python traceback surfaced as exit 0; every verdict rests on the producer's own recorded exit file or cargo's Finished line. Also: the window driver crashed at its END on a stale dict key AFTER json.dump had written the report — report-before-print is load-bearing and was right by accident; ordered the other way six measured arms evaporate at the summary line. (Linux cells lane, 12:46Z) fifth and sixth: a python driver died on a SyntaxError while the shell reported exit 0 (exposed only by STALE red logs from the previous sha), and a census script stalled mid-run while its ssh reported exit 0. Both caugh…\n- **Third instrument defect, same window (hertz, 11:25Z):** a mutation driver's revert check was\n  `git hash-object` plus `git diff --quiet`, and BOTH normalize line endings; `git checkout --`\n  re-materialized docshost.rs as CRLF, the LF-written anchors then counted 0, and the driver REFUSED\n  at arm 5 = w6-rdrop (the guard working: nothing written; rdrop and lib-full were measured in window\n  7: rdrop RED at :683 with left Some(59827), lib-full 988/988) while the oid check reported an identical blob over\n  bytes that had just changed. An oid check cannot see an eol rewrite; a revert proof records bytes,\n  crlf and bare-lf counts beside the oids. Also: an arm whose switch reaches only the CHILD env while\n  the base is chosen from the PARENT's ran the control arm's conditions and passed for its reason (a\n  non-measurement, not a refutation) - the driver now refuses to call it a measurement if the two\n  bases match.\n- **Rule.** A rig's TMP resolves OUTSIDE every git toplevel, and the rig proves it once per box with\n  `rev-parse --show-toplevel` expecting \"not a git repository\". A test whose premise is \"no repo\n  here\" names that premise in its first assertion so the failure reads as environment, not product.\n- **Kin:** [[IR-100]], [[IR-101]] (per-lane green silent about the unselected population; these two\n  cells were invisible to the stock 21-name producer for the whole lane), [[IR-106]].\n- **Ripe when:** now for the rig (done). The assertion-premise clause for the two cells rides a\n  SEPARATE follow-up lane after W1 closes (ruled 11:35Z: neither #304 lane touches registryhost.rs or\n  projwriter.rs, and a comment in two untouched modules does not widen the integration diff);\n  hertz's rig also writes its admission record under a stale sha tag (`admission-61bfd85c.json`),\n  the same family as a reused artifact path — fix in that lane. Consequence already paid: the\n  window-5 and window-6 admission census records were silently OVERWRITTEN by the later windows\n  writing the same path, so those two ENDs stand on the transcript alone, not on a record. · **Size:** one env line in the rig\n  (done); two comment lines in tests; one filename in the rig.\n\n- **Instances 9-11, all 2026-09-12, #304 W-2 (one night, three different surfaces).** NINTH (doyle's gate leg, 03:20Z): `cargo ... | tail` over non-interactive ssh to kitsubito returned 0 while cargo was off PATH in the non-login shell — already named in releases#304 comment 5643115673 and filed here for the count. TENTH (hertz, 05:30Z, while writing register entries about instruments that lie): `traceable-reqs check 2>&1 | tail -20; echo \"CHECK_EXIT=$?\"` printed `CHECK_EXIT=0` — tail's exit over a checker that exits 1, i.e. a 312-finding red read as clean. He re-ran it only because the register had made him suspicious of his own zero, which is the entry doing its job and not a skill. ELEVENTH (todlando, 05:20Z, a NEW surface — the harness itself): `cargo ne…\n\n- **Linux consumer recurrence (todlando, 2026-09-13, #304 at `b8482445`).**\n  My first consumer driver put `RUNNER_TEMP` under the checkout's preserved-evidence\n  directory, then exported its child sandbox as TEMP/TMP/TMPDIR. Phase A ran 3417 cells:\n  3414 passed (2 leaky), 3 failed, 1 skipped, exit 100. The two daemon premise\n  assertions named this exact fault; `spt-store::project::tests::derivation_ladder`\n  also derived the enclosing repository rather than its fixture folder. **That\n  attempt is VOID, not a candidate regression.** The temp-root Git probe returned\n  the enclosing checkout (exit 0); the replacement `/tmp/spt-consumer-304-b8482445-valid-*`\n  root and every exported temp path returned \"not a git repository\" (exit 128).\n  The replacement driver enforces that boundary before launching any producer.\n  On unchanged candidate bytes, valid Phase A then ran 3417/3417 passed (1 leaky),\n  1 skipped, exit 0; no main delta or source edit was needed. Original raw,\n  `temp-premise-correction.json`, and the valid `attempt2/` receipts remain under\n  `.spt/preserved/304-handoff/consumer-linux/`. This repeats the existing rule;\n  preserving evidence inside the repository never licenses putting fixtures there.\n\n- **Live-agent identity environment recurrence — Windows consumer (2026-09-13, #304).**\n  Doyle reported in `5E3WTZ3N` that his live session's `OWL_SESSION_ID` reached the\n  test driver: Windows consumer attempt 1 is **VOID, not a candidate regression**.\n  Recorded by hertz from that report, not from an independent rerun. The current\n  phase was to drain before a full scrubbed rerun; no corrected Windows result or\n  BOX CLEAR is claimed here. A.2 remains held and the preparation clock unstarted.\n  **Same mechanism, different input:** TMP placement changes a fixture's repository\n  context; inherited session identity changes its caller context. In both cases\n  the harness environment is part of the subject, not neutral launch plumbing.\n  A clean checkout and pinned executable do not establish the intended test premise.\n  **Rule:** construct the producer's child environment from its declared test/CI\n  contract, removing inherited live-session identity inputs as a set before launch.\n  Verify the effective environment handed to the actual test producer after all\n  wrapper/sandbox setup; record names and presence/absence, never identity values.\n  Fixtures that test identity must supply their own explicit fixture identity.\n  Keep the live agent's own environment and lifecycle intact; this is test-driver\n  isolation, not permission to evade a guard on real operational commands.\n  Preserve the invalid attempt's logs and verdict separately from the corrected\n  run; an environment-premise failure does not authorize a product patch.\n  **Kin:** [[IR-22]] records the earlier identity-inheritance failure and its\n  one-variable-at-a-time diagnostic trap; [[IR-122]] distinguishes a real rig's\n  intentional live-session refusal from an isolated test's contaminated premise.\n\n### IR-108 — four brainproc unit cells leak a process on every run; two others leak by ordering\n\n- **Status:** OPEN, product-side backlog candidate (not #304's). Recorded 2026-09-11 11:35Z (doyle)\n  from three unfiltered `spt-daemon --lib` runs on identical bytes on HFENDULEAM (todlando 10:52Z at\n  3e7eaf67; hertz 11:00Z at 69438c01 and 11:27Z at cba18cd5), all green.\n- **Cell-shaped (leak 3 of 3):** `brainproc::tests::clear_before_spawn_defeats_exact_generation_stale_file`,\n  `ready_but_old_gen_never_drains_does_not_promote_rolls_back`, `stale_generation_minus_one_ready_never_promotes`,\n  `trial_kills_alive_never_ready_candidate_before_rollback`. **Run-shaped:**\n  `broker::tests::windows_session_is_zombie_sees_a_handle_held_corpse_as_dead` (2 of 3),\n  `livehost::tests::legacy_psyche_sweep_guard_is_id_specific_and_fail_safe` (1 of 3).\n- **Why it matters:** nextest's LEAK is a child that outlives the test; on a shared box that is a\n  process census entry with no owner and a pool handle that can pin a worktree (memory\n  worktree-pin-holder-triage). Every post-census this cycle read zero survivors, so the leaks reap\n  themselves within the run's teardown; the hazard is the window between.\n- **Count is PER RUN, not a set (corrected 12:28Z, doyle, on todlando's fold-lane read):** at 61d3459f (fold/304-w2-admission, 992/992) FOUR leaked — brainproc x3 (clear_before_spawn, ready_but_old_gen, stale_generation_minus_one) + broker windows_session_is_zombie — and `trial_kills_alive_never_ready_candidate_before_rollback` RAN (PASS 0.559s, 116/992) and did NOT leak. So \"brainproc x4 cell-shaped\" is 3-of-4 cell-shaped across four runs on three trees; the fourth is run-shaped. A leaky set carried from one END to the next without re-deriving is the inherited-claim habit (IR-106) at its mildest.\n- **Discriminator before any fix:** run each cell alone with `--success-output immediate` and read what\n  child it spawns and why it is not waited; a cell-shaped leak is a missing wait or kill in the\n  fixture, a run-shaped one is teardown ordering.\n- **Kin:** [[IR-100]], memory \"e2e leaked daemons shared box\", \"rig ownership reap only your own\".\n- **Ripe when:** next product wave that touches brainproc, or a findings-backlog sweep. · **Size:**\n  four fixture waits; unknown for the two run-shaped.\n\n### IR-109 — a manifest `[placement] module_banner = \"accept\"` block LOOSENS the local checker to zero; CI's pinned checker is structurally blind to placement, so the loosening is invisible until the pin moves\n\n[…138ln elided…]\n- **Second-order, and it bit me inside this very entry.** `git checkout -- <file>` restores from the INDEX, not HEAD. Having staged a first draft, I \"reverted\" it and appended a rewrite — producing a file carrying BOTH. Caught by the diffstat (49 insertions for a ten-line entry). Restore from `HEAD --` when HEAD is what you mean; the diffstat is the control.\n- **Corollary, accepted by doyle.** The killed arm reported `TEST_EXIT=137`. That is the SIGKILL, delivered during compilation with ZERO tests executed (last lines `Compiling acto / iroh-dns / wmi`) — a VOID arm, not a red. A 137 sitting in a log over a test arm is precisely the number quoted later as a product failure. Same family as IR-113 (a killed mutation arm does not unwind).\n- **Instance 2 — a DIFFERENT tool surface, 2026-09-12 03:39Z (hertz).** The mechanism is not a property of todlando's guard. hertz ran a recursive `grep -rl` over the project tree; it exceeded the foreground timeout and the harness backgrounded it. `TaskStop` returned `{\"message\":\"Successfully stopped task: bn74vtqn0\"}` — a structured success from the harness itself, not a hand-rolled echo. The process was still in the table two minutes later: pid 35104, StartTime 03:37:20Z, **CPU 13.25 s**, killed only by an explicit `Stop-Process -Id 35104 -Force` and confirmed gone by a post-state count of 0 against a live positive control (`pwsh` count 12). So a first-party tool's success object is no better warranted than an `echo`, and the rule generalises: **read the …\n- **Ripe when:** now — the rule costs three lines in any guard. · **Size:** procedure.\n\n### IR-117 — a predicate that cannot fail: pre-registered outcomes whose branches are not mutually exclusive, and a requirement titled with the TASK instead of the INVARIANT\n\n- **Status:** OPEN, mechanism recorded 2026-09-12 03:48Z (hertz, both instances his own; doyle ruled the second).\n- **Instance 1 — the outcome set.** For the #304 W-2 packet capture hertz pre-registered four outcomes, of which (a) was \"SYN retransmission despite the RST\" and (b) was \"above the wire in the Windows client path\". The capture showed five SYNs at a flat ~511 ms, each RST'd in 18-25 us and each ignored — which is (a)'s packet shape with (b)'s locus. The two branches were the same answer told at two altitudes, so EITHER could have been declared \"confirmed\" and neither could have been refuted by the actual result. Pre-registration defends against fitting the story to the data; it does nothing against branches that cannot both be false.\n- **Instance 2 — the requirement title.** hertz drafted `REQ-NET-WINDOWS-REFUSAL-BUDGET` titled \"enumerate the spt paths that treat connection-refused as a fast negative on Windows\". doyle refused it: that is the TASK, not the invariant. A requirement stated as a task is discharged by DOING the task — it would have gone green the instant the enumeration was written, whether or not one path was fixed, and would have had nothing to say about the NEXT connect bound anyone adds. The accepted title states a product invariant (\"classified by its error kind, never by elapsed time; every connect bound documented against the measured floor\"), which new code can violate.\n- **Mechanism.** Both are the same defect at different altitudes: an instrument whose every reachable outcome is a pass. Kin on the outcome side: memory discriminator-question, refuse-mechanism-until-something-discriminates, one-sample-is-not-a-negative. Kin on the requirement side: the activation model itself (a stage that cannot go red is not coverage), gate-against-documented-design.\n- **Rule.** Before registering an outcome set, name for EACH branch an observation that would refute it; if two branches share a refuter, they are one branch and the set is unfinished. Before adding a `REQ-*`, state it as something CODE can violate, never as work a person can complete — if the only way to make it red is to not write a document, it is a task and belongs in a lane, not the registry. Corollary from the same ruling: a measured constant may NOT enter product code as a threshold. The requirement forbids the interpretation (time as a proxy for error kind); it does not bless the number, which was measured on our machines and not on a user's.\n- **Ripe when:** now — both checks are one sentence each at authoring time. · **Size:** procedure.\n\n### IR-118 — an instrument read mid-flight, or through a filter that cannot match, returns a COMPLETE-LOOKING wrong answer with no error\n\n- **Status:** OPEN, two instances one hour apart, 2026-09-12 (hertz); doyle asked for the filter line beside IR-117.\n- **Instance 1 — the capture read in flight, and it would have inverted the verdict.** `tcpdump -w /tmp/hz-cap.pcap` was still running when the packets were wanted. The file was **8192 bytes** live and **11933 bytes** after `kill -TERM` flushed it; the 3741-byte tail WAS the four SYN retransmissions. Reading the live file would have yielded a well-formed pcap showing one SYN and one prompt RST — i.e. the pre-registered outcome (b), the WRONG answer, assembled entirely from the RIGHT answer's own evidence, with no truncation error and a plausible packet count. The tell was available and nearly missed: a block-aligned size (8192) is a flush boundary, not a record.\n- **Instance 2 — the filter that cannot match, class instance 2.** Censusing Windows TCP settings, hertz piped `netsh int tcp show supplemental template=internet` through `Select-String -Pattern 'Template|Initial RTO|Max SYN|Retransmissions'`. It returned ONE line — the header — because none of those words appear in the table's rows (which read `Minimum RTO (msec)`, `Initial Congestion Window (MSS)`, …). Had it been trusted it would have reported \"no retransmission settings exposed\", which is the identical clean zero a CORRECT filter over an empty template returns. Recovered only by re-running the command raw.\n- **Mechanism.** In both cases the instrument succeeded, exited 0, and returned a well-formed artefact that under-reports its population — a partial buffer and a non-matching pattern are indistinguishable from a complete capture and an empty table. Neither failure can be detected from the artefact alone; both need a second read of a different kind. Kin: memory zero-match-filter-reads-as-absent, count-predicate-needs-its-own-positive-control, verdict-from-probe-competence, absence-needs-sibling-probe.\n- **Rule.** Terminate a `-w` capture and confirm the writer is gone BEFORE reading it, and quote the writer's own census (`N packets captured / N received by filter / 0 dropped by kernel`) beside the packet list; a block-aligned file size is evidence you are mid-flush. For any filtered dump, either carry a positive control the filter MUST match, or dump raw once and read the filter against the real field names — a filtered census that returns only its header has measured nothing.\n- **Ripe when:** now — both rules cost one extra command. · **Size:** procedure.\n\n### IR-119 — a control that only had to prove a ROUTE served a real directory; and a rig is not torn down until its last process is gone, whatever the analysis says\n\n- **Status:** OPEN, mechanisms recorded 2026-09-12 05:46Z (doyle) from hertz's unprompted self-disclosure. The security remedy is an OPERATOR item, filed on releases#304 comment **5643876746** (rotate the kitsubito self-hosted runner's registration credential); this entry carries only the reusable mechanisms.\n- **Instance.** The accepted-connection control for the W-2 packet capture was `python3 -m http.server 29472 --bind 0.0.0.0` with **cwd `/home/reavus`** — the self-hosted runner account's home — for **1 h 59 m 54 s**. The off-box bind was REQUIRED (the peer dialled from another machine); the working directory was the whole defect. An empty temp dir returns the identical HTTP 200 and proves exactly as much. `http.server` builds its index from `os.listdir` and filters nothing, so 20 dotfiles including the runner credential files were listed and fetchable; mode 0600 did not protect one of them, because the server ran AS that user. kitsubito's posture was separately verified as RSTing with **no** host filter (ufw inactive, nft input policy accept on both tables)…\n- **Mechanism.** A route control and a file server are the SAME COMMAND, so the cheapest way to answer \"can the peer reach this port\" silently publishes whatever directory the shell was sitting in, and the excess is invisible in the result — the 200 looks identical either way. Same family as a pattern-kill that matches its own ssh line: a tool doing more than the measurement asked for.\n- **Second mechanism, and it is why two hours passed rather than two minutes.** The author tore down the CAPTURE, named the outcome, and stopped — treating \"the verdict is named\" as \"the leg is finished\". **Naming an outcome is a milestone in the ANALYSIS, never in the RIG.** A rig is torn down when its last process is gone, and the artefact you are proud of is not the only thing you left running. Found only because a stale wake line replayed his own teardown list back to him two hours later.\n- **Rule.** (1) A control that proves a route binds an EMPTY throwaway directory, never a home, a repo or a working dir, and it goes down in the SAME breath as the capture it controls. (2) Every rig's teardown is a list of PROCESSES asserted gone against a live positive control, never a list of conclusions. (3) A teardown note written BEFORE a ruling does not license deleting the ruling's cited evidence: `/tmp/hz-cap.pcap` and `/tmp/hz-cap.log` were KEPT by ruling, twice, because they are the primary record of a posted verdict.\n- **Evidence quality worth copying.** The window was MEASURED (1 h 59 m 54 s), not estimated; the served-request record was complete (2 requests, both ours, `GET /`, no descent, no file fetch) and its LIMIT was stated rather than implied — a server log is evidence about requests SERVED, never about the network. An independent wire instrument (the pcap, 0 dropped by kernel) covered **4.4%** of the window, and that figure is the capture PROCESS LIFETIME: reading the 2.08 s packet span as the coverage would have understated the evidence 150-fold, because a running capture with no packets is still observing.\n- **Kin:** [[IR-116]] (assert the post-state, never an echo), [[IR-118]] (an instrument complete about what it measures and silent about the rest), memory rig-ownership-reap-only-your-own, reap-root-needs-authenticated-ancestry.\n- **Ripe when:** now — both rules are one line each in any rig. · **Size:** procedure.\n\n### IR-120 — a claim named for the one axis nobody varied: six readings over two routes and two libraries, all on ONE box, reported as a property of the platform\n\n- **Status:** OPEN, mechanism recorded 2026-09-12 05:47Z (doyle); the instance is liam's, refuted by hertz's own arm and conceded by its author.\n- **Instance.** The ~2.05 s Windows refused-connect latency was filed as \"the WINDOWS refusal latency\" on six readings that varied ROUTE (loopback, LAN hop to Linux) and LIBRARY (curl, .NET TcpClient) and held HOST constant — every one on HFENDULEAM. Route- and library-independence were measured; \"Windows\" was the name of the box. A per-host WFP callout, endpoint agent or filter driver swallowing RSTs would have produced exactly those six readings on exactly those two routes and generalised nothing. Settled only by going to get the missing axis: a second Windows box (Win10 19045 against the first's Win11 26200) read 2077.3 ms, inside 30 ms of the band. The claim survived; it was not ENTITLED to until then.\n- **The control the claim also lacked.** Nothing in the record distinguished \"Windows pays 2 s\" from \"TCP to a closed port costs 2 s\" or \"curl reports refusals slowly\" — because every reading was Windows, the word could not be earned from them, only assumed for want of an alternative. The Linux arm supplied it: closed port and open port within **66 microseconds** of each other on the same libraries, so the refusal costs ~0 there and cannot be told from an open port by latency at all. With that control \"Windows\" is measured; without it, it was a label.\n- **Mechanism.** Breadth along the axes you happened to vary reads as generality. The check is cheap and nobody runs it: write the claim's subject noun, ask which axis that noun names, then ask whether that axis was varied. Second instance from the same author in one night (a PowerShell-edition confound priced as the product's cost), and a sibling shape in the same leg: \"the box was quiet\" inferred from the absence of ANNOUNCED work, when silence is exactly what an unannounced three-minute recursive grep produces — quiet was never measured for that window either.\n- **Rule.** A claim names its population and its varied axes in the same sentence, and the axis in the claim's NOUN must be one of the varied ones. One host is a host, not a platform; one edition is an edition, not a cost. A quantity claimed as a property of a class carries a NEGATIVE CONTROL from outside that class, or it is a label. Corollary already ruled: a constant measured only on our boxes does not enter product code as a threshold — see [[IR-117]].\n- **Kin:** memory verified-members-are-not-an-enumerated-population, one-sample-is-not-a-negative, tool-claim-must-name-its-environment, absence-needs-sibling-probe, windows-client-refused-connect-costs-2s.\n- **Ripe when:** now — it is a sentence-shape check at authoring time. · **Size:** procedure.\n\n### IR-121 — one declaration command expands every right-hand side before assigning any name, so a dependent id silently binds the CALLER'S GLOBAL and two arms collapse onto one artifact path; and `cat -A` behind msys `sed` is not a byte reader\n\n- **Status:** OPEN, mechanisms recorded 2026-09-12 09:05Z. Instance 1 found by hertz in todlando's driver and confirmed by doyle; repaired as a separately pinned revision (v6 `dcfb732a…` → v7 `927eafb9…`) per the standing rule that a demonstrated execution incompatibility gets a new hash and renewed verification rather than an in-place accommodation. Instance 2 is todlando's own, found while reading the repair site.\n- **Instance 1 — the id that looked right.** `trial()` opened with `local arm=\"$1\" n=\"$2\" id=\"$arm-$n\"`. A single declaration command expands EVERY right-hand side before assigning any of its names, so `$arm` was still unset when `id` was built — but `$n` was **not** empty, because the caller is `for n in 1 2 3; do trial a \"$n\"; done` and `n` is a GLOBAL at that point. The id therefore read `-1`, not the empty-ish `-` that would have been noticed: a plausible, consistently-formed, wrong identity. Both arms produced `-1,-2,-3`, so every per-trial artifact keyed on id — captures, stop captures, census tags, portfields snapshots, cpu brackets — collided, and **Arm B overwrote Arm A in place** with nothing downstream able to tell them apart. `arm` itself was cor…\n- **The audit the one fix does not discharge.** A predicate was written over the whole delivered set — any `local`/`declare`/`typeset`/`export`/`readonly` whose later right-hand side references a name assigned earlier in the SAME command — with a positive control broken on purpose (plain `local`, `declare`, and the `${name}` brace form: 3 arms) and a negative control of the same declarations split (0 hits). v6 = 2 hits, both that one line; v7 = 0; v5 = the same single site. Stated over-report: the predicate does not split on `;`, so two correct statements on one physical line read as a dependency — the real site was confirmed not to be that shape. The PowerShell and Python helpers got their own predicates (zero multi-target assignments across four `.ps1`, pr…\n- **Instance 2 — the byte reader that was not one.** The repair site was first read with `sed -n '869,880p' file | cat -A`, which printed `$` at every line end — i.e. LF. The file is CRLF throughout (measured: 1117 CR = 1117 LF = 1117 CRLF). msys `sed` reads in text mode and drops the CRs, so `cat -A` faithfully rendered bytes that `sed` had already removed. The project's own rule (\"after any scripted edit, verify the BYTES\") was followed and still defeated, because the verification ran downstream of a text-mode filter.\n- **Third consequence of instance 1, and the worse half of it (hertz, measured independently; re-measured here).** The bad id does not only collide the arms — it begins with a DASH, so every artifact is named `-1.out`, `-2.err`, `-1.stop.out`. Measured in a throwaway dir: `sha256sum *.out` over such a population exits 1 with `unknown option -- 1` and hashes NOTHING (control: the same command over `a-1.out` alone exits 0 and hashes it); `grep -c x -1.out` exits 2 having measured nothing; `sha256sum ./*.out` is the repair. That is the LOUD form. The dangerous form is the one hertz's own detector took: it returned a clean EMPTY snapshot — \"0 artifacts altered\" — in the arm that was supposed to be red, because its glob handed the dashes to a tool that consumed t…\n- **Mechanism.** Both are a wrong answer with no error: a declaration whose dependency is satisfied by an unrelated variable that happens to exist, and a byte census whose bytes were filtered before they were counted. Neither is detectable from its own output — the id is well-formed, the `cat -A` dump is honest about what reached it.\n- **Fourth instance, in the very commit that recorded this entry (todlando, self-reported).** The amendment above was applied with a Python text-mode read (`open(p).read()`, universal newlines) and written back with `newline='\n'`. This register carried **two lone CR bytes** - `\n\n- **Instances 9-11` and `\n\n- **Addendum 2026-09-12 03:20Z` - present since at least `7cdcf5da`. Universal newlines translated each bare CR into a newline, so the commit silently rewrote two lines belonging to OTHER entries (net: 2 stray CRs removed, 2 blank lines added; markdown-harmless, still undeclared). Caught by reading the commit's own diff rather than trusting the insertion count: a one-bullet append that reports **5 insertions, 2 deletions** is telling you it touched something else. A text-mode read is a WRITE hazard, not only a measurement hazard - edit a file whose byte shape you have not measured in binary, and review the diff, never the intent.\n- **Rule.** (1) A declaration that depends on a name is its OWN statement; never share a `local` with the name it reads. (2) Derive an identity used as an artifact key ONLY after its parts are assigned, and guard it against its expected shape — a key that can go wrong silently overwrites evidence rather than failing. (3) A negative control for an id scheme must carry the caller's real variable environment: with the caller's global `n` absent, this defect reads as the harmless `-` and is easy to dismiss. (4) Read bytes with a byte reader — `python3` on the raw file, or `od`/`xxd` — never through msys `sed`, `grep`, or any text-mode filter; if a CR/LF count is the claim, count CR and LF bytes and state both.\n- **Kin:** [[IR-118]] (a complete-looking wrong answer from an instrument that succeeded), memory count-predicate-needs-its-own-positive-control, make-a-new-rig-red-on-purpose, scripted-edit-zero-match-refusal, render-not-read-pipefail, windows-firewall-census-clean-zeros.\n- **Ripe when:** now — (1) and (4) are habits, (2) is three lines in any rig. · **Size:** procedure.\n\n### IR-122 — the field rig's isolated-daemon stop cannot run from an spt-hosted session, so every run leaves a live daemon holding the subject exe inside the pool it just released\n\n- **Status:** OPEN, recurring. Instance 1 attempt 2 (`rig/arm2-driver-stdout.txt`: `RIG_DAEMON_STOP_REFUSED_OR_ERRORED — reported, not forced`). Instance 2 run `20260912T231404Z` under frozen r10 (`rig_daemon_stop_EXIT=3`, `cleanup-failures.txt`, `rig-daemon-stop.err`). Recorded by hertz 2026-09-12 23:50Z at doyle's direction; **this is a RIG defect, and any product-surface change requires a separate contract review.**\n…\n\n\n[Showing lines 1-208 and 347-413 of 413; 138 middle lines (19.1KB) elided. Use :6772 to continue. Read artifact://733 for full output. Some lines truncated to 768 chars]"}],"details":{"truncation":{"content":"\r\n### IR-105 — an assertion derived from a MODEL of the fixture instead of read off the fixture can only be refuted by a run, and the lane convention that defers the run gives the class a one-window latency: the repair for the first instance carried the second\r\n\r\n- **Status:** OPEN. Rule adopted 2026-09-11 (hertz, W1 close). Instrument = read the line, and read\r\n  what the line LANDS on, before asserting either.\r\n- **Instance 1 (hertz, `test/304-remote-friction`, `4ec34d1c`, 03:07Z):** `webserve_e2e.rs`\r\n  `subnet_node_labels_shadow_only_the_docs_compat_alias_while_members` still asserted the pre-#301\r\n  contract at the `/llms.txt/` line — a node root with an EMPTY remainder as `200`. Under the\r\n  node-root arm (`webserve.rs:778-781`) that path is a `302`, so the case died `302 != 200` at the\r\n  first assertion it reached and MASKED the five http calls after it. The `4823ae5d` sweep missed\r\n  the line because the case's other redirects are BARE-NODE ones, which take `redirect_node` and\r\n  are untouched by #301: I classified the case by its siblings and never read the line itself.\r\n  Cost: one window.\r\n- **Instance 2, inside the repair for instance 1 (`28d4eb68`, 03:19Z):** `4ec34d1c` was right about\r\n  the redirect and wrong about what it lands on — it followed through to `GET /llms.txt/docs/` and\r\n  asserted `200`. Measured at `71caedd4`: that is `404`, and the `404` is CORRECT. This fixture's\r\n  docs dir holds `cli/reference.md` and the root-file labels and no `index.html`, and a docs root\r\n  without one is a 404 by design — `webserve.rs:1028-1033` writes `index.html` precisely in order\r\n  to get `200` at `/local/docs/`. So the new assertion pinned index-presence, which is not this\r\n  case's subject. I asserted a property of a redirect TARGET without reading what the target\r\n  contains. Cost: a second window.\r\n- **The mechanism, stated once:** both assertions were derived from a model — the case's siblings in\r\n  instance 1, the contract's shape in instance 2 — rather than read off the fixture in front of me.\r\n  A model-derived assertion is indistinguishable from a correct one at authoring time AND at review\r\n  time; only a run refutes it. This lane commits such work `UNCOMPILED AND UNRUN at commit time:\r\n  written outside the window, measured in the next one` (both commit bodies carry that line\r\n  verbatim), so the class has a one-window refutation latency BY CONSTRUCTION, and a repair authored\r\n  inside that same blind interval inherits the defect it repairs. That is the register-worthy part:\r\n  the fix for a from-a-model assertion was itself a from-a-model assertion, 12 minutes later.\r\n- **Resolution:** `28d4eb68` drops the directory-root status and keeps the `302` + `Location` pair.\r\n  The line AFTER it already fetches `/llms.txt/docs/llms.txt` and compares bytes — a real leaf\r\n  fetched THROUGH the redirect target, which is stronger evidence the target is live than a status\r\n  on the directory root ever was. Blast radius measured at `71caedd4`, producer 3: the case cleared\r\n  the old line and the new pair and failed only on this one; the four sibling cases stayed green.\r\n  Producer 3 GREEN @`28d4eb68`.\r\n- **Third instance, caught BEFORE it shipped (same session, this entry's own id):** this file in the\r\n  `#304` test lane ends at IR-97; main ends at IR-104. Numbering this entry from the register in\r\n  front of me would have produced `IR-98` — a collision with a real entry, written while looking at\r\n  a file that had every right to look complete. The id is `105` because it was read off main. Same\r\n  mechanism, third direction: a stale local artifact IS a model of the shared one.\r\n- **Rule:** assert against what the fixture CONTAINS, at a named line you have read, in the tree the\r\n  claim will live in. Three corollaries earned here: a sweep must read every line it claims to have\r\n  swept (classifying a case by its siblings is a model); following a redirect obliges you to read\r\n  the target's contents before asserting its status (the target's shape is a model); and a register\r\n  id, like any shared address, is read off the shared tree, never off your lane's copy.\r\n- **Ripe when:** any test edit is authored outside the window that will measure it — which is this\r\n  lane's normal mode. · **Size:** a read, not a tool; the deferred-run interval is the thing to\r\n  shorten if it recurs.\r\n- **Kin:** [[IR-101]] (its census read the rendered effect instead of the subject — same family,\r\n  same morning, same file), [[IR-102]] (predicting against a blob nobody would run), memory\r\n  \"rig inherits the defect it studies\", \"verify the SUBJECT not just the measurement\",\r\n  \"precise claim is falsifiable\".\r\n\r\n### IR-106 — a red set HANDED OVER in a message was reported as a POPULATION: both members verified, their lines and modes corrected, and the count still wrong by half\r\n\r\n- **Status:** OPEN as a discipline line; the instance is closed (the run that refuted it is on file).\r\n  Author and subject: todlando. Filed by doyle 2026-09-11 11:20Z from todlando's text; IR-105 lands\r\n  from hertz's lane at the same assembly, which is why this number follows it.\r\n- **Instance (2026-09-11, #304 W1 product lane).** todlando was handed a red set naming TWO cells in\r\n  the spt-daemon webserve module. He opened each one, CORRECTED its line number and its failure mode,\r\n  and reported the corrected pair as his prediction. The unfiltered run at 3e7eaf67 showed FOUR reds\r\n  of the same mechanism (the retired `/local/` index twin): the two named, plus\r\n  `corrupt_registry_is_loud_but_does_not_disable_unrelated_facets` (:1228, 302 vs 500) and\r\n  `node_routing_reserves_facets_without_registry_fallback` (:1011, 302 vs 200). A post-run sweep\r\n  mapping every single-segment node-root literal to its enclosing fn closed the population at four,\r\n  by enumeration; two further cells touch a root and pass for stated reasons.\r\n- **Why the verification is what hides it.** Checking a member answers \"is this one real\". It cannot\r\n  answer \"is this all of them\": no amount of per-member rigour turns a received list into an\r\n  enumeration, and correcting a handed-down set FEELS more rigorous than enumerating it.\r\n- **Mirror instance one window later, other direction (hertz, same lane).** His enumeration was\r\n  SOUND (every node-root literal in the module mapped to its enclosing fn) but its SCOPE was\r\n  inherited from the one file he happened to be resolving; the merge also brought\r\n  `bootstrap_firewall.rs` (+4) and `bootstrap_firewall/windows.rs` (+2), so his whole-suite count was\r\n  short by six (predicted 981, measured 987). Same family: a sound instrument pointed at the wrong\r\n  population.\r\n- **Rule.** Before any COUNT enters a prediction, a START or an END, run the enumerating predicate\r\n  YOURSELF, with a tool that can express the population you are claiming (an unfiltered run; a grep\r\n  whose root is the crate, not the file you have open). A set received in a message is a lead.\r\n- **Kin:** [[IR-100]] (a census counts what its filter could not answer for, separately from a no),\r\n  [[IR-101]] (a per-lane green is silent about the population it did not select), [[IR-105]] (a\r\n  from-a-model assertion is refuted only by a run), memory \"a predicate without its tool is not evidence\".\r\n- **Ripe when:** now, a line in the window protocol, not a build. Fold into the START/END template\r\n  beside the census. · **Size:** one entry, one clause; no code.\r\n\r\n### IR-107 — a rig that redirects TMP INSIDE the checkout puts every tempdir fixture under a git toplevel, and cells whose premise is \"outside any repo\" resolve THIS repo's remote\r\n\r\n- **Status:** RIG FIXED in hertz's lane (base now under `AppData/Local/Temp/hertz-304-rig/<label>`;\r\n  `HERTZ_RIG_TMP_IN_REPO=1` restores the old placement on purpose as the negative control). Recorded\r\n  2026-09-11 11:20Z (doyle, from hertz's and todlando's measurements); corrected 11:35Z on hertz's\r\n  read. The A/B COMPLETED in window 7 at cba18cd5: arm A (base outside any repo) 2 run / 2 passed;\r\n  arm B (base inside the checkout) 2 run / 2 FAILED at :1404 and :842 with the strings below, the two\r\n  bases recorded and differing. Window 6's arm B was the non-measurement described below.\r\n- **Instance.** hertz's first unfiltered `spt-daemon --lib` at 69438c01 redded two cells that neither\r\n  lane touches and that todlando's unfiltered run had passed 8 minutes earlier on the same bytes and\r\n  box: `registryhost::tests::recent_projects_for_dedups_newest_first_excludes_spt_internal` (:1404,\r\n  got `[\"github-com-bigscreenvr-spt-bs-core\"]`) and `projwriter::tests::batched_complexity_counters_hold`\r\n  (:842, got `Some(\"spt-bs-core\")`). Both fixtures require a directory outside any repo.\r\n- **Mechanism, measured with a control.** `lane_run.py` set TMP/TEMP/TMPDIR/RUNNER_TEMP to\r\n  `EVID/temp/<label>` inside the spt-core checkout; `git -C <that dir> rev-parse --show-toplevel`\r\n  answers the checkout (remote `BigscreenVR/spt-bs-core`), while the same probe from the default TMP\r\n  answers \"not a git repository\". `project_id_for_dir` is REMOTE-URL FIRST: `slug(remote)` and\r\n  `display_from_url(remote)` are the two observed strings exactly, and the folder-name fallback could\r\n  not have produced either (candidate folder names: 304-product, hertz-304, spt-core). So git got as\r\n  far as step ONE of the derivation. The first mechanism offered (\"any in-repo cwd\") was killed by one\r\n  datum: ci.yml:143 runs `kind(lib)` unfiltered on this runner with an in-repo cwd and passed at\r\n  6a7dd6b7. The variable was the FIXTURE's location, never the process cwd.\r\n- **Instrument defects in this lane today, all hertz's, all closed:** (window 5) `cargo ... | tail;\r\n  echo $?` reports tail's status (memory \"render-not-read-pipefail\") — the compile gate was in fact\r\n  green, so that reading was VOID evidence rather than a masked red; the same construct one command\r\n  later printed 0 over a checker [must] finding, a true exit 1 — the hazard is that an exit read\r\n  through a pipe certifies nothing, not that it hides reds. (window 4 START gate, 10:26Z) a negative\r\n  control that returned at the refusal branch vouched for nothing about the send arm, which then\r\n  crashed on a NameError on the first real launch (memory \"make a new rig red on purpose\",\r\n  refinement). (window 8, premise lane, 12:14Z) a FOURTH void-exit instance in one day — `$?` and `${PIPESTATUS[0]}` both read a later command, a backgrounded python traceback surfaced as exit 0; every verdict rests on the producer's own recorded exit file or cargo's Finished line. Also: the window driver crashed at its END on a stale dict key AFTER json.dump had written the report — report-before-print is load-bearing and was right by accident; ordered the other way six measured arms evaporate at the summary line. (Linux cells lane, 12:46Z) fifth and sixth: a python driver died on a SyntaxError while the shell reported exit 0 (exposed only by STALE red logs from the previous sha), and a census script stalled mid-run while its ssh reported exit 0. Both caugh…\n- **Third instrument defect, same window (hertz, 11:25Z):** a mutation driver's revert check was\r\n  `git hash-object` plus `git diff --quiet`, and BOTH normalize line endings; `git checkout --`\r\n  re-materialized docshost.rs as CRLF, the LF-written anchors then counted 0, and the driver REFUSED\r\n  at arm 5 = w6-rdrop (the guard working: nothing written; rdrop and lib-full were measured in window\r\n  7: rdrop RED at :683 with left Some(59827), lib-full 988/988) while the oid check reported an identical blob over\r\n  bytes that had just changed. An oid check cannot see an eol rewrite; a revert proof records bytes,\r\n  crlf and bare-lf counts beside the oids. Also: an arm whose switch reaches only the CHILD env while\r\n  the base is chosen from the PARENT's ran the control arm's conditions and passed for its reason (a\r\n  non-measurement, not a refutation) - the driver now refuses to call it a measurement if the two\r\n  bases match.\r\n- **Rule.** A rig's TMP resolves OUTSIDE every git toplevel, and the rig proves it once per box with\r\n  `rev-parse --show-toplevel` expecting \"not a git repository\". A test whose premise is \"no repo\r\n  here\" names that premise in its first assertion so the failure reads as environment, not product.\r\n- **Kin:** [[IR-100]], [[IR-101]] (per-lane green silent about the unselected population; these two\r\n  cells were invisible to the stock 21-name producer for the whole lane), [[IR-106]].\r\n- **Ripe when:** now for the rig (done). The assertion-premise clause for the two cells rides a\r\n  SEPARATE follow-up lane after W1 closes (ruled 11:35Z: neither #304 lane touches registryhost.rs or\r\n  projwriter.rs, and a comment in two untouched modules does not widen the integration diff);\r\n  hertz's rig also writes its admission record under a stale sha tag (`admission-61bfd85c.json`),\r\n  the same family as a reused artifact path — fix in that lane. Consequence already paid: the\r\n  window-5 and window-6 admission census records were silently OVERWRITTEN by the later windows\r\n  writing the same path, so those two ENDs stand on the transcript alone, not on a record. · **Size:** one env line in the rig\r\n  (done); two comment lines in tests; one filename in the rig.\r\n\r\n- **Instances 9-11, all 2026-09-12, #304 W-2 (one night, three different surfaces).** NINTH (doyle's gate leg, 03:20Z): `cargo ... | tail` over non-interactive ssh to kitsubito returned 0 while cargo was off PATH in the non-login shell — already named in releases#304 comment 5643115673 and filed here for the count. TENTH (hertz, 05:30Z, while writing register entries about instruments that lie): `traceable-reqs check 2>&1 | tail -20; echo \"CHECK_EXIT=$?\"` printed `CHECK_EXIT=0` — tail's exit over a checker that exits 1, i.e. a 312-finding red read as clean. He re-ran it only because the register had made him suspicious of his own zero, which is the entry doing its job and not a skill. ELEVENTH (todlando, 05:20Z, a NEW surface — the harness itself): `cargo ne…\n\r\n- **Linux consumer recurrence (todlando, 2026-09-13, #304 at `b8482445`).**\r\n  My first consumer driver put `RUNNER_TEMP` under the checkout's preserved-evidence\r\n  directory, then exported its child sandbox as TEMP/TMP/TMPDIR. Phase A ran 3417 cells:\r\n  3414 passed (2 leaky), 3 failed, 1 skipped, exit 100. The two daemon premise\r\n  assertions named this exact fault; `spt-store::project::tests::derivation_ladder`\r\n  also derived the enclosing repository rather than its fixture folder. **That\r\n  attempt is VOID, not a candidate regression.** The temp-root Git probe returned\r\n  the enclosing checkout (exit 0); the replacement `/tmp/spt-consumer-304-b8482445-valid-*`\r\n  root and every exported temp path returned \"not a git repository\" (exit 128).\r\n  The replacement driver enforces that boundary before launching any producer.\r\n  On unchanged candidate bytes, valid Phase A then ran 3417/3417 passed (1 leaky),\r\n  1 skipped, exit 0; no main delta or source edit was needed. Original raw,\r\n  `temp-premise-correction.json`, and the valid `attempt2/` receipts remain under\r\n  `.spt/preserved/304-handoff/consumer-linux/`. This repeats the existing rule;\r\n  preserving evidence inside the repository never licenses putting fixtures there.\r\n\r\n- **Live-agent identity environment recurrence — Windows consumer (2026-09-13, #304).**\r\n  Doyle reported in `5E3WTZ3N` that his live session's `OWL_SESSION_ID` reached the\r\n  test driver: Windows consumer attempt 1 is **VOID, not a candidate regression**.\r\n  Recorded by hertz from that report, not from an independent rerun. The current\r\n  phase was to drain before a full scrubbed rerun; no corrected Windows result or\r\n  BOX CLEAR is claimed here. A.2 remains held and the preparation clock unstarted.\r\n  **Same mechanism, different input:** TMP placement changes a fixture's repository\r\n  context; inherited session identity changes its caller context. In both cases\r\n  the harness environment is part of the subject, not neutral launch plumbing.\r\n  A clean checkout and pinned executable do not establish the intended test premise.\r\n  **Rule:** construct the producer's child environment from its declared test/CI\r\n  contract, removing inherited live-session identity inputs as a set before launch.\r\n  Verify the effective environment handed to the actual test producer after all\r\n  wrapper/sandbox setup; record names and presence/absence, never identity values.\r\n  Fixtures that test identity must supply their own explicit fixture identity.\r\n  Keep the live agent's own environment and lifecycle intact; this is test-driver\r\n  isolation, not permission to evade a guard on real operational commands.\r\n  Preserve the invalid attempt's logs and verdict separately from the corrected\r\n  run; an environment-premise failure does not authorize a product patch.\r\n  **Kin:** [[IR-22]] records the earlier identity-inheritance failure and its\r\n  one-variable-at-a-time diagnostic trap; [[IR-122]] distinguishes a real rig's\r\n  intentional live-session refusal from an isolated test's contaminated premise.\r\n\r\n### IR-108 — four brainproc unit cells leak a process on every run; two others leak by ordering\r\n\r\n- **Status:** OPEN, product-side backlog candidate (not #304's). Recorded 2026-09-11 11:35Z (doyle)\r\n  from three unfiltered `spt-daemon --lib` runs on identical bytes on HFENDULEAM (todlando 10:52Z at\r\n  3e7eaf67; hertz 11:00Z at 69438c01 and 11:27Z at cba18cd5), all green.\r\n- **Cell-shaped (leak 3 of 3):** `brainproc::tests::clear_before_spawn_defeats_exact_generation_stale_file`,\r\n  `ready_but_old_gen_never_drains_does_not_promote_rolls_back`, `stale_generation_minus_one_ready_never_promotes`,\r\n  `trial_kills_alive_never_ready_candidate_before_rollback`. **Run-shaped:**\r\n  `broker::tests::windows_session_is_zombie_sees_a_handle_held_corpse_as_dead` (2 of 3),\r\n  `livehost::tests::legacy_psyche_sweep_guard_is_id_specific_and_fail_safe` (1 of 3).\r\n- **Why it matters:** nextest's LEAK is a child that outlives the test; on a shared box that is a\r\n  process census entry with no owner and a pool handle that can pin a worktree (memory\r\n  worktree-pin-holder-triage). Every post-census this cycle read zero survivors, so the leaks reap\r\n  themselves within the run's teardown; the hazard is the window between.\r\n- **Count is PER RUN, not a set (corrected 12:28Z, doyle, on todlando's fold-lane read):** at 61d3459f (fold/304-w2-admission, 992/992) FOUR leaked — brainproc x3 (clear_before_spawn, ready_but_old_gen, stale_generation_minus_one) + broker windows_session_is_zombie — and `trial_kills_alive_never_ready_candidate_before_rollback` RAN (PASS 0.559s, 116/992) and did NOT leak. So \"brainproc x4 cell-shaped\" is 3-of-4 cell-shaped across four runs on three trees; the fourth is run-shaped. A leaky set carried from one END to the next without re-deriving is the inherited-claim habit (IR-106) at its mildest.\r\n- **Discriminator before any fix:** run each cell alone with `--success-output immediate` and read what\r\n  child it spawns and why it is not waited; a cell-shaped leak is a missing wait or kill in the\r\n  fixture, a run-shaped one is teardown ordering.\r\n- **Kin:** [[IR-100]], memory \"e2e leaked daemons shared box\", \"rig ownership reap only your own\".\r\n- **Ripe when:** next product wave that touches brainproc, or a findings-backlog sweep. · **Size:**\r\n  four fixture waits; unknown for the two run-shaped.\r\n\r\n### IR-109 — a manifest `[placement] module_banner = \"accept\"` block LOOSENS the local checker to zero; CI's pinned checker is structurally blind to placement, so the loosening is invisible until the pin moves\r\n\r\n- **Status:** OPEN, RATIFIED 12:33Z (doyle, releases#304) as a TRANSITIONAL policy for the #304 head: the 0.4.1 pin stays (a tightening for every new tag), the accept key exempts only the 312 legacy banner tags, and this entry is the retirement ticket. Recorded 2026-09-11 12:10Z (doyle) from hertz's A/B/C and 0.2.0 arms; the commit's \"agreed\" is corrected by the ruling, not by rewriting a measured sha.\r\n- **Instance.** 33936943 \"chore(traceability): enable agreed placement policy\" (07:38Z, trailer todlando, on\r\n  feat/304-remote-friction-product and test/304-remote-friction, NOT on main) adds `[placement] enforce = \"on\"`,\r\n  `module_banner = \"accept\"`. The word \"agreed\" is UNRATIFIED: todlando cannot evidence it (his session that\r\n  wrote it is gone) and doyle did not rule it.\r\n- **Measured, same binary 0.4.1, same tree 4b54a95d, manifest the only variable:** as-is exit 1 / 312\r\n  misplaced_tag; block added exit 0 / 0; `enforce = \"on\"` alone exit 1 / 312. `module_banner` is the sole\r\n  load-bearing key; enforce is the default already. CI-pinned 0.2.0 (golden.yml WANT=0.2.0) at the same sha:\r\n  exit 0 / 0 — the `misplaced_tag` kind does not exist in that version; placement lives only in its `review`\r\n  subcommand, which `check` never reaches. asm-304 (0c05e722, 0.4.1 + the block): exit 0, bought by the key.\r\n- **Why it matters.** AGENTS.md rule 1: tags sit on the evidence, never at file tops to satisfy coverage. The\r\n  312 are banner tags that violate it; the accept key retires them by policy rather than by moving one tag, and\r\n  the gate that CI actually runs cannot see either state.\r\n- **Rule.** A checker config change that lowers a finding count is a loosening and is ruled on the record\r\n  before it rides; \"agreed\" in a commit message is not a ruling. The honest statement of a zero under such a\r\n  config names the config (\"zero under a manifest that accepts module banners\").\r\n- **Kin:** memory checker-version-must-match-ci-pin (live instance), [[IR-104]].\r\n- **CORRECTED 12:24Z (doyle):** the pin HAS moved on the W1 lane ancestry — 71caedd4 \"ci: pin traceable-reqs to v0.4.1\" (10:11Z) sits under 697eb398 (not on main), so ci.yml:253 and golden.yml:1424 both read WANT=0.4.1 at the integration head while origin/main reads WANT=0.2.0 at ci.yml:253 and golden.yml:1414. The accept key is therefore LIVE at the assembled golden gate today, not dormant: asm-304 reads 0 [must] under 0.4.1 because of the key. A lane off 697eb398 reads nine further [must] (code-stage tags in docs prose: F-035-CONFLICT, PUMP-W2-DESIGN, DEBUG-CONVERGE-PLAN, INFRA-REGISTER) that the assembly does not: measured at F-035-CONFLICT:47, 697eb398 carries the bracketed tags and origin/main carries them with brackets elided (\"so the checker\" clause),…\n- **Ripe when:** now — the key rides #304 only as a labelled hole named in the golden hand-off; retire by relocating the 312 tags and deleting the key in a lane of its own. · **Size:** 312 tag moves; the key.\r\n\r\n### IR-110 — the gater ruled a wave from origin/main's manifest while the milestone's own product lane already carried the surface; a second implementation was built to its W-1 END before the first was noticed\r\n\r\n- **Status:** OPEN, STOP LINE on #304 W2 (comment 5634187958). Recorded 2026-09-11 12:10Z (doyle, own instance).\r\n- **Instance.** feat/304-remote-friction-product @3e7eaf67 implements #297 TCP admission under\r\n  REQ-WEB-LAN-BOOTSTRAP-FIREWALL (bootstrap_firewall.rs + windows.rs + linux.rs, lanhost/servehost/serveverb/cli\r\n  call sites, docs-site section, ADR-0059 \"Amendment 2\" at d71df7aa): program-scoped Windows effector, all\r\n  profiles, no remote restriction, zero tests in the module (six guard-level cells arrive with hertz 7b098cc2,\r\n  none on scope). doyle deactivated its int stage the same morning and then ruled W2 fork (i) and let four\r\n  REQ-LAN-BOOTSTRAP-* ids mint from ORIGIN/MAIN's manifest, where the id is absent (0 occurrences). todlando\r\n  built build/304-w2-bootstrap-tcp @fe427497: a second, tested (E4 red at the bound-port assertion, 5/5, 981==981)\r\n  netsh implementation, port+remote scoped, never program, a second \"## Amendment 2\" in the same ADR file.\r\n  He found the collision at his W-1 END by reading the product lane, and touched nothing.\r\n- **Mechanism.** IR-106 from the gater's chair: the population enumerated (main's manifest) was not the\r\n  population the claim was about (the milestone head's). The tell was available all morning — the gater's own\r\n  deactivation note names the id — and a grep of the assembly worktree (asm-304) instead of the main checkout\r\n  would have returned 1.\r\n- **Consequence.** The two texts disagree on a FACT (which rule shape admits TCP over the tailnet on this box;\r\n  W-0 measured program scope admitting nothing for UDP only), both amendments share a heading, and an\r\n  assembled head would run both start paths and write two rule sets.\r\n- **Rule.** Before minting or activating any id for a milestone wave, enumerate the ASSEMBLY head's manifest\r\n  (asm-<milestone>), not main's; a wave that \"closes\" a surface names the id it closes and greps the milestone\r\n  head for it first. A fork ruling states the tree it enumerated.\r\n- **Kin:** [[IR-106]], [[IR-107]] (same day, same class in three chairs).\r\n- **Ripe when:** now — W-2a discriminating measurement in flight (arms A-D on the installed 5470 listener from\r\n  kitsubito), then the fold ruling (one id, one ADR section, the tested decision seam + cells attached to the\r\n  surviving effector). · **Size:** one measurement; one fold commit on the W2 lane; the ADR merge is a content\r\n  decision, not a merge decision.\r\n- **Labelled hole (12:14Z):** bootstrap_firewall/linux.rs (676 lines) has ZERO #[test]; all six cells sit in bootstrap_firewall.rs and windows.rs. Under cfg the Linux arm is invisible to this box's unit lane, so the surviving id's unit stage reads green over an untested Linux backend set. Closed by a hertz cells lane run on kitsubito against ufw_scope / owned / backend (queued 12:14Z; ten cells red-first at be99017f, 12:41Z). RULE learned there: `ci.yml` lint runs clippy `--all-targets -D warnings` on kitsubito ONLY, and `--all-targets` lints cells as hard as product — a Linux-only red that no Windows gate sees caught todlando's `needless_borrow` (linux.rs:293, fixed be99017f) and hertz's own `cloned_ref_to_slice_refs` (linux.rs:891, test module) one hour ap…\n\r\n### IR-111 — the installed product's own inbound UDP rule reads Duplicate / Inactive in ActiveStore, shadowed by the fallback rule; a by-name probe reads it green\r\n\r\n- **Status:** OPEN, product-side backlog candidate (REQ-INBOUND-WINDOWS-RULE-BINDER-PATH-MATCH family). Recorded\r\n  2026-09-11 12:14Z (doyle) from an unelevated `Get-NetFirewallRule` read of both stores on HFENDULEAM.\r\n- **Instance.** ActiveStore: `spt-core inbound UDP` (Program = installed spt.exe, Profile Any, UDP, Remote Any)\r\n  Enabled=True, **Enforcement=Duplicate, PrimaryStatus=Inactive**; `spt-fallback inbound UDP` (same program,\r\n  Profile Any) Enforcement=ProfileInactive Enforced, Status OK. PersistentStore shows both as\r\n  Enforcement=NotApplicable, Status OK — the persistent view cannot see the shadowing at all.\r\n- **Why it matters.** The product's reconcile and the `inbound_block_hint` probe key on the product rule's NAME.\r\n  The rule that is doing the work is the other one; delete or repoint the fallback and the product rule may\r\n  become the enforced one with no change in what the name probe reports, or the reverse. Kin to the W1\r\n  effector's own comment (\"never certify a rule which ActiveStore reports as ignored or ineffective\") — the\r\n  UDP side never reads ActiveStore.\r\n- **Also seen, same read:** ~26 enforced program-scoped Private rules naming target/debug and actions-runner\r\n  test binaries (spt_net-*, spt_daemon-*, spt.exe), Proto TCP+UDP, LPort Any, Remote Any — the rig-rule\r\n  population the hfenduleam program-scope memory describes; none admits the tailnet.\r\n- **Rule.** A rule probe that certifies anything reads ActiveStore EnforcementStatus, not PersistentStore\r\n  presence and not the name.\r\n- **Kin:** [[IR-110]], memory hfenduleam-program-scoped-firewall-rules-do-not-admit-tailnet.\r\n- **Ripe when:** the next inbound-rule wave, or when the W1 CIM two-store query is generalised to the UDP side.\r\n  · **Size:** one ActiveStore read in the probe; one dedupe decision.\r\n\r\n### IR-112 — bare `cargo test -p spt-daemon --lib` reds two process-global cells on Linux at a sha where nextest is green; libtest is not a sound gate for this crate\r\n\r\n- **Status:** OPEN, rig rule (CI unaffected: `ci.yml` runs `kind(lib)` under nextest). Recorded 2026-09-11 12:46Z\r\n  (doyle) from hertz's Linux cells lane END on kitsubito.\r\n- **Instance.** At 697eb398 on kitsubito: `cargo nextest list -p spt-daemon --lib` = 989 ids; `cargo test -p\r\n  spt-daemon --lib` = 989 run, 987 passed, **2 FAILED, exit 101**:\r\n  `answerop::tests::an_approval_notifies_a_plain_knocker_with_no_pre_authorization` (answerop.rs:324, \"expected\r\n  exactly one courtesy: [] left: 0 right: 1\") and\r\n  `brainproc::tests::the_ready_breadcrumb_tells_a_computed_hash_from_a_cached_one` (brainproc.rs:2347, \"the FIRST\r\n  ready write in a process pays for the digest\"). Both PASS under nextest with the identical filter, exit 0.\r\n- **Mechanism.** Process-per-test vs one shared libtest process: both cells read process-global state (the\r\n  brainproc one says so in its own panic text); under libtest a sibling's write is visible. IR-108's leaky-cell\r\n  class, measured on Linux. Kin memory bystander-test-reads-process-global, daemon-lib-tests-deadlock-on-live-host.\r\n- **Rule.** A gate or rig over spt-daemon's lib runs NEXTEST; a `cargo test --lib` red on this crate is a rig\r\n  fault until discriminated under nextest with the same filter. Count agreement (list == run) says nothing about\r\n  exit agreement — check both.\r\n- **Kin:** [[IR-108]], [[IR-100]].\r\n- **Ripe when:** a sweep makes those two cells hermetic (the fix belongs to the cells, not the gate). · **Size:**\r\n  two fixtures.\r\n\r\n### IR-113 — a killed mutation arm does not unwind: the subject stays mutated and the NEXT arm measures a tree nobody declared; and a mutation that reds on a compile error is a void arm that \"it compiled\" cannot detect\r\n\r\n- **Status:** OPEN, rig rule for every mutation driver. Recorded 2026-09-11 13:05Z (doyle) from todlando's FOLD-1b\r\n  window (fold/304-w2-admission, windows.rs).\r\n- **Instance.** A first M1 injected an early return through a struct literal naming a helper that does not exist —\r\n  a mutation that would red on E0425, not at the cell's assertion, i.e. a void red-first arm. The job was stopped\r\n  mid-run; the driver's restore is its LAST line, so the kill left the MUTATED file on disk: working oid d8ddfdf3\r\n  against pristine 1f475a80, two residue markers present. Caught only because the next act was an oid compare, not\r\n  the next arm. Restored and re-measured identical (residue 0, 786 == 786 lines). Second half: clippy on the\r\n  mutated tree exited 0, so \"it compiled\" would not have exposed the void arm either.\r\n- **Mechanism.** Mutate → run → restore is not transactional; any exit before the last line (kill, timeout, crash,\r\n  nextest hang) strands the mutation. A void arm is one whose red is not AT the assertion the prediction named.\r\n- **Rule.** (1) A mutation driver restores in a finally/trap path, and every arm BEGINS by asserting the subject's\r\n  oid equals the declared pristine oid — the previous arm's revert is proven at the next arm's start, not trusted.\r\n  (2) A red-first arm is accepted only when the artifact names the predicted assertion line; a compile-error red,\r\n  a panic elsewhere, or a red at a different line is VOID, not a pass and not a fail. (3) Mutations are one-token\r\n  edits with an anchor count asserted at 1; an arm that did not change the file voids itself loudly.\r\n- **Kin:** [[IR-107]] (revert proven by oid AND byte shape), memory scripted-edit-zero-match-refusal,\r\n  make-a-new-rig-red-on-purpose.\r\n- **Ripe when:** now — the rule is cheap and the drivers exist; every lane's driver adopts it at its next edit. ·\r\n  **Size:** a trap/finally and one oid compare per arm.\r\n\r\n### IR-114 — three hands wrote one firewall rule set inside ninety seconds under two directors; every census was true at its instant and false a minute later\r\n\r\n- **Status:** OPEN, procedure ruled 2026-09-12 00:50Z (doyle) on todlando's reconciliation; recorded 00:52Z.\r\n- **Instance.** #304 W-2a arms on HFENDULEAM: ~00:44Z todlando asked the operator to delete spt-w2a-C so B would stand alone; ~00:45Z the operator said \"C down\" and todlando's census read B present / C absent (true then); 00:45:05Z liam ADDED C at doyle's direction (doyle had been idle 11 h and did not know the operator's window); 00:46:14Z liam DELETED B at doyle's direction; 00:49:09Z todlando re-measured C present / B absent. Nobody was wrong; the population was not stable. Every fetch todlando reported had an adjacent census and stands; a long background census that straddled the writes returned no spt-w2a rows at all and is UNMEASURED. Separately, doyle's drop-log arm crossed liam's revert in flight: three fetches ran with logging already off — a void a…\n- **Mechanism.** Two directors (operator, gater) each driving a different elevated hand against the same shared host state, neither seeing the other's window; a census taken as a separate earlier step and carried forward.\r\n- **Rule.** For any arm on shared host state: ONE WRITER; the census is taken BY THE FETCHER in the SAME command as the fetch, before and after; the prediction names the exact expected population (an unexpected row is a red); every write is announced with its UTC time to every party; a director resuming after a gap re-measures the population before issuing a write. Kin: memory verify-the-subject-not-just-the-measurement, name-the-file-and-sha.\r\n- **Also measured tonight (todlando):** 'spt-core daemon' (proto Any, Private, remote Any, program = the listener's exe) covers the Private-classified Tailscale interface while TCP 5470 times out from kitsubito and the LAN address answers 200 with ICMP alive — so W-0 measured the tailnet ACL, not program scoping, and DESIRED_PROGRAM=false's cited justification is VOID (the constant may still be right; its citation is not). The shape question moves to a throwaway port and listener over the LAN (arm E).\r\n- **Ripe when:** now — the rule costs nothing. · **Size:** procedure.\r\n\r\n### IR-115 — a firewall census whose port test is DENIED reads every rule as port=Any and counts port-scoped rules as blanket; a `netsh show rule` without `verbose` omits Program and reads every rule as program=Any; a control count that merges two agents' reads is nobody's control\r\n\r\n- **Status:** OPEN, mechanisms recorded 2026-09-12 01:14Z (doyle) from todlando's and liam's own corrections during #304 arm E.\r\n- **Instances.** (1) todlando's first census A (\"26 blanket rules\") and B (\"occupied LocalPort set: EMPTY\"): `Get-NetFirewallPortFilter -All` returns \"Access is denied\" unelevated, the probe swallowed the denial, every rule read as port=Any, and B's positive control (the hand rule carries LocalPort 5470) is what caught it. (2) His replacement pass: `netsh advfirewall firewall show rule name=all` without `verbose` prints no Program line, so it reported 417 blankets and ZERO rules naming spt.exe — provably false, caught by the same control. The third pass (`dir=in verbose`) passed both controls (port-5470 rows = 1, spt.exe rows = 7) and was the census used. (3) doyle's fetcher: first census predicate listed port-covering and program-covering rules as two separ…\n- **Mechanism.** A denied or under-scoped read does not error; it returns the permissive default for the field it could not see, so the census reads MORE admits than exist and a shape question gets decided on a phantom population. Kin: memory a-predicate-without-its-tool-is-not-evidence, verdict-from-probe-competence, zero-match-filter-reads-as-absent.\r\n- **Rule.** A firewall census names its tool and privilege and carries two positive controls in the SAME dump: one rule known to carry a specific LocalPort, one known to name a specific Program. A census that cannot see both has not seen the population. The reaching predicate is port-covers AND program-covers AND LocalIP-covers AND profile-covers, one set. Every loopback and remote read records its curl exit code. Counts are per agent; a merged count is restated per agent or discarded.\r\n- **Ripe when:** now — the rule costs one grep. · **Size:** procedure.\r\n\r\n- **Addendum 2026-09-12 03:20Z (doyle, #304 W-2 A5/A4): the Windows Firewall event log is DIRECTION-BLIND, so a rig that keys \"written\" or \"removed\" on it cannot fail in the direction it claims.** Population controlled over one read (2011x48 / 2052x6 / 2097x6, a 400-event re-read of the same window returning the identical six): id 2052 fires on creates AND deletes in the observed population, id 2097 is create-specific, and NOTHING observed is delete-specific. The CENSUS carries the sign; the log carries only the instant. The same read established a MEASURED gap (zero events between A5's end and A4's start) and that nothing commits after the client dies — both usable, neither a direction. Kin: the firewall status fields do not discriminate either, since an ad…\n\r\n### IR-116 — a watchdog that calls a killer and then echoes success reports a kill it never made; `pkill` is absent in msys, so the guard logged \"stopped\" while the arm it guarded ran on\r\n\r\n- **Status:** OPEN, mechanism recorded 2026-09-12 01:24Z (todlando) from his own guard during #304 FOLD-2's Windows arm at 7357ea32; doyle asked for the line.\r\n- **Instance.** todlando armed a watchdog to stop a test arm before it reached `cargo test --workspace --lib`, because spt-daemon lib tests deadlock on a live host. Shape: `if grep -q \"CLIPPY_EXIT=\" log; then pkill -f \"bash /tmp/arms.sh\" 2>/dev/null; echo \"GUARD: arms.sh stopped after clippy at $(date -u)\"`. It printed `GUARD: arms.sh stopped after clippy at 01:24:06Z`. Nothing was stopped: `pkill` does not exist in this msys/Git-Bash environment (`command not found`, exit 127), `2>/dev/null` ate the message, and the `echo` was never gated on the killer's exit. The arm ran on into its compile phase and was found by tailing the build log, not by the guard — whose only output was a green.\r\n- **Mechanism.** Two defects stack, and either alone would have been caught by the other: a missing binary, and a success line that cannot fail. Same family as IR-107 seen from the other side — there a trailing command's exit was mistaken for the producer's; here no exit was consulted at all. The aggravating factor is WHERE it lives: a guard is written while thinking about the hazard it guards, not about the guard, and a guard that never fires looks identical to a guard that works. Kin: memory watchdog-reports-a-kill-it-never-made, verdict-from-exit-not-from-silence, a-predicate-without-its-tool-is-not-evidence.\r\n- **Rule.** A watchdog asserts the POST-STATE and never echoes after the call: `kill …; sleep 1; if still_running; then echo \"GUARD FAILED\"; exit 1; fi`. On msys use `kill -9 <pid>` with a pid you resolved yourself, or `taskkill //PID <p> //T //F`; do not assume `pkill`/`pgrep` exist — check the tool before building a guard on it. Reap your own tree only: resolve the pid and its children, never a machine-wide sweep on a shared box.\r\n- **Second-order, and it bit me inside this very entry.** `git checkout -- <file>` restores from the INDEX, not HEAD. Having staged a first draft, I \"reverted\" it and appended a rewrite — producing a file carrying BOTH. Caught by the diffstat (49 insertions for a ten-line entry). Restore from `HEAD --` when HEAD is what you mean; the diffstat is the control.\r\n- **Corollary, accepted by doyle.** The killed arm reported `TEST_EXIT=137`. That is the SIGKILL, delivered during compilation with ZERO tests executed (last lines `Compiling acto / iroh-dns / wmi`) — a VOID arm, not a red. A 137 sitting in a log over a test arm is precisely the number quoted later as a product failure. Same family as IR-113 (a killed mutation arm does not unwind).\r\n- **Instance 2 — a DIFFERENT tool surface, 2026-09-12 03:39Z (hertz).** The mechanism is not a property of todlando's guard. hertz ran a recursive `grep -rl` over the project tree; it exceeded the foreground timeout and the harness backgrounded it. `TaskStop` returned `{\"message\":\"Successfully stopped task: bn74vtqn0\"}` — a structured success from the harness itself, not a hand-rolled echo. The process was still in the table two minutes later: pid 35104, StartTime 03:37:20Z, **CPU 13.25 s**, killed only by an explicit `Stop-Process -Id 35104 -Force` and confirmed gone by a post-state count of 0 against a live positive control (`pwsh` count 12). So a first-party tool's success object is no better warranted than an `echo`, and the rule generalises: **read the …\n- **Ripe when:** now — the rule costs three lines in any guard. · **Size:** procedure.\r\n\r\n### IR-117 — a predicate that cannot fail: pre-registered outcomes whose branches are not mutually exclusive, and a requirement titled with the TASK instead of the INVARIANT\r\n\r\n- **Status:** OPEN, mechanism recorded 2026-09-12 03:48Z (hertz, both instances his own; doyle ruled the second).\r\n- **Instance 1 — the outcome set.** For the #304 W-2 packet capture hertz pre-registered four outcomes, of which (a) was \"SYN retransmission despite the RST\" and (b) was \"above the wire in the Windows client path\". The capture showed five SYNs at a flat ~511 ms, each RST'd in 18-25 us and each ignored — which is (a)'s packet shape with (b)'s locus. The two branches were the same answer told at two altitudes, so EITHER could have been declared \"confirmed\" and neither could have been refuted by the actual result. Pre-registration defends against fitting the story to the data; it does nothing against branches that cannot both be false.\r\n- **Instance 2 — the requirement title.** hertz drafted `REQ-NET-WINDOWS-REFUSAL-BUDGET` titled \"enumerate the spt paths that treat connection-refused as a fast negative on Windows\". doyle refused it: that is the TASK, not the invariant. A requirement stated as a task is discharged by DOING the task — it would have gone green the instant the enumeration was written, whether or not one path was fixed, and would have had nothing to say about the NEXT connect bound anyone adds. The accepted title states a product invariant (\"classified by its error kind, never by elapsed time; every connect bound documented against the measured floor\"), which new code can violate.\r\n- **Mechanism.** Both are the same defect at different altitudes: an instrument whose every reachable outcome is a pass. Kin on the outcome side: memory discriminator-question, refuse-mechanism-until-something-discriminates, one-sample-is-not-a-negative. Kin on the requirement side: the activation model itself (a stage that cannot go red is not coverage), gate-against-documented-design.\r\n- **Rule.** Before registering an outcome set, name for EACH branch an observation that would refute it; if two branches share a refuter, they are one branch and the set is unfinished. Before adding a `REQ-*`, state it as something CODE can violate, never as work a person can complete — if the only way to make it red is to not write a document, it is a task and belongs in a lane, not the registry. Corollary from the same ruling: a measured constant may NOT enter product code as a threshold. The requirement forbids the interpretation (time as a proxy for error kind); it does not bless the number, which was measured on our machines and not on a user's.\r\n- **Ripe when:** now — both checks are one sentence each at authoring time. · **Size:** procedure.\r\n\r\n### IR-118 — an instrument read mid-flight, or through a filter that cannot match, returns a COMPLETE-LOOKING wrong answer with no error\r\n\r\n- **Status:** OPEN, two instances one hour apart, 2026-09-12 (hertz); doyle asked for the filter line beside IR-117.\r\n- **Instance 1 — the capture read in flight, and it would have inverted the verdict.** `tcpdump -w /tmp/hz-cap.pcap` was still running when the packets were wanted. The file was **8192 bytes** live and **11933 bytes** after `kill -TERM` flushed it; the 3741-byte tail WAS the four SYN retransmissions. Reading the live file would have yielded a well-formed pcap showing one SYN and one prompt RST — i.e. the pre-registered outcome (b), the WRONG answer, assembled entirely from the RIGHT answer's own evidence, with no truncation error and a plausible packet count. The tell was available and nearly missed: a block-aligned size (8192) is a flush boundary, not a record.\r\n- **Instance 2 — the filter that cannot match, class instance 2.** Censusing Windows TCP settings, hertz piped `netsh int tcp show supplemental template=internet` through `Select-String -Pattern 'Template|Initial RTO|Max SYN|Retransmissions'`. It returned ONE line — the header — because none of those words appear in the table's rows (which read `Minimum RTO (msec)`, `Initial Congestion Window (MSS)`, …). Had it been trusted it would have reported \"no retransmission settings exposed\", which is the identical clean zero a CORRECT filter over an empty template returns. Recovered only by re-running the command raw.\r\n- **Mechanism.** In both cases the instrument succeeded, exited 0, and returned a well-formed artefact that under-reports its population — a partial buffer and a non-matching pattern are indistinguishable from a complete capture and an empty table. Neither failure can be detected from the artefact alone; both need a second read of a different kind. Kin: memory zero-match-filter-reads-as-absent, count-predicate-needs-its-own-positive-control, verdict-from-probe-competence, absence-needs-sibling-probe.\r\n- **Rule.** Terminate a `-w` capture and confirm the writer is gone BEFORE reading it, and quote the writer's own census (`N packets captured / N received by filter / 0 dropped by kernel`) beside the packet list; a block-aligned file size is evidence you are mid-flush. For any filtered dump, either carry a positive control the filter MUST match, or dump raw once and read the filter against the real field names — a filtered census that returns only its header has measured nothing.\r\n- **Ripe when:** now — both rules cost one extra command. · **Size:** procedure.\r\n\r\n### IR-119 — a control that only had to prove a ROUTE served a real directory; and a rig is not torn down until its last process is gone, whatever the analysis says\r\n\r\n- **Status:** OPEN, mechanisms recorded 2026-09-12 05:46Z (doyle) from hertz's unprompted self-disclosure. The security remedy is an OPERATOR item, filed on releases#304 comment **5643876746** (rotate the kitsubito self-hosted runner's registration credential); this entry carries only the reusable mechanisms.\r\n- **Instance.** The accepted-connection control for the W-2 packet capture was `python3 -m http.server 29472 --bind 0.0.0.0` with **cwd `/home/reavus`** — the self-hosted runner account's home — for **1 h 59 m 54 s**. The off-box bind was REQUIRED (the peer dialled from another machine); the working directory was the whole defect. An empty temp dir returns the identical HTTP 200 and proves exactly as much. `http.server` builds its index from `os.listdir` and filters nothing, so 20 dotfiles including the runner credential files were listed and fetchable; mode 0600 did not protect one of them, because the server ran AS that user. kitsubito's posture was separately verified as RSTing with **no** host filter (ufw inactive, nft input policy accept on both tables)…\n- **Mechanism.** A route control and a file server are the SAME COMMAND, so the cheapest way to answer \"can the peer reach this port\" silently publishes whatever directory the shell was sitting in, and the excess is invisible in the result — the 200 looks identical either way. Same family as a pattern-kill that matches its own ssh line: a tool doing more than the measurement asked for.\r\n- **Second mechanism, and it is why two hours passed rather than two minutes.** The author tore down the CAPTURE, named the outcome, and stopped — treating \"the verdict is named\" as \"the leg is finished\". **Naming an outcome is a milestone in the ANALYSIS, never in the RIG.** A rig is torn down when its last process is gone, and the artefact you are proud of is not the only thing you left running. Found only because a stale wake line replayed his own teardown list back to him two hours later.\r\n- **Rule.** (1) A control that proves a route binds an EMPTY throwaway directory, never a home, a repo or a working dir, and it goes down in the SAME breath as the capture it controls. (2) Every rig's teardown is a list of PROCESSES asserted gone against a live positive control, never a list of conclusions. (3) A teardown note written BEFORE a ruling does not license deleting the ruling's cited evidence: `/tmp/hz-cap.pcap` and `/tmp/hz-cap.log` were KEPT by ruling, twice, because they are the primary record of a posted verdict.\r\n- **Evidence quality worth copying.** The window was MEASURED (1 h 59 m 54 s), not estimated; the served-request record was complete (2 requests, both ours, `GET /`, no descent, no file fetch) and its LIMIT was stated rather than implied — a server log is evidence about requests SERVED, never about the network. An independent wire instrument (the pcap, 0 dropped by kernel) covered **4.4%** of the window, and that figure is the capture PROCESS LIFETIME: reading the 2.08 s packet span as the coverage would have understated the evidence 150-fold, because a running capture with no packets is still observing.\r\n- **Kin:** [[IR-116]] (assert the post-state, never an echo), [[IR-118]] (an instrument complete about what it measures and silent about the rest), memory rig-ownership-reap-only-your-own, reap-root-needs-authenticated-ancestry.\r\n- **Ripe when:** now — both rules are one line each in any rig. · **Size:** procedure.\r\n\r\n### IR-120 — a claim named for the one axis nobody varied: six readings over two routes and two libraries, all on ONE box, reported as a property of the platform\r\n\r\n- **Status:** OPEN, mechanism recorded 2026-09-12 05:47Z (doyle); the instance is liam's, refuted by hertz's own arm and conceded by its author.\r\n- **Instance.** The ~2.05 s Windows refused-connect latency was filed as \"the WINDOWS refusal latency\" on six readings that varied ROUTE (loopback, LAN hop to Linux) and LIBRARY (curl, .NET TcpClient) and held HOST constant — every one on HFENDULEAM. Route- and library-independence were measured; \"Windows\" was the name of the box. A per-host WFP callout, endpoint agent or filter driver swallowing RSTs would have produced exactly those six readings on exactly those two routes and generalised nothing. Settled only by going to get the missing axis: a second Windows box (Win10 19045 against the first's Win11 26200) read 2077.3 ms, inside 30 ms of the band. The claim survived; it was not ENTITLED to until then.\r\n- **The control the claim also lacked.** Nothing in the record distinguished \"Windows pays 2 s\" from \"TCP to a closed port costs 2 s\" or \"curl reports refusals slowly\" — because every reading was Windows, the word could not be earned from them, only assumed for want of an alternative. The Linux arm supplied it: closed port and open port within **66 microseconds** of each other on the same libraries, so the refusal costs ~0 there and cannot be told from an open port by latency at all. With that control \"Windows\" is measured; without it, it was a label.\r\n- **Mechanism.** Breadth along the axes you happened to vary reads as generality. The check is cheap and nobody runs it: write the claim's subject noun, ask which axis that noun names, then ask whether that axis was varied. Second instance from the same author in one night (a PowerShell-edition confound priced as the product's cost), and a sibling shape in the same leg: \"the box was quiet\" inferred from the absence of ANNOUNCED work, when silence is exactly what an unannounced three-minute recursive grep produces — quiet was never measured for that window either.\r\n- **Rule.** A claim names its population and its varied axes in the same sentence, and the axis in the claim's NOUN must be one of the varied ones. One host is a host, not a platform; one edition is an edition, not a cost. A quantity claimed as a property of a class carries a NEGATIVE CONTROL from outside that class, or it is a label. Corollary already ruled: a constant measured only on our boxes does not enter product code as a threshold — see [[IR-117]].\r\n- **Kin:** memory verified-members-are-not-an-enumerated-population, one-sample-is-not-a-negative, tool-claim-must-name-its-environment, absence-needs-sibling-probe, windows-client-refused-connect-costs-2s.\r\n- **Ripe when:** now — it is a sentence-shape check at authoring time. · **Size:** procedure.\r\n\r\n### IR-121 — one declaration command expands every right-hand side before assigning any name, so a dependent id silently binds the CALLER'S GLOBAL and two arms collapse onto one artifact path; and `cat -A` behind msys `sed` is not a byte reader\r\n\r\n- **Status:** OPEN, mechanisms recorded 2026-09-12 09:05Z. Instance 1 found by hertz in todlando's driver and confirmed by doyle; repaired as a separately pinned revision (v6 `dcfb732a…` → v7 `927eafb9…`) per the standing rule that a demonstrated execution incompatibility gets a new hash and renewed verification rather than an in-place accommodation. Instance 2 is todlando's own, found while reading the repair site.\r\n- **Instance 1 — the id that looked right.** `trial()` opened with `local arm=\"$1\" n=\"$2\" id=\"$arm-$n\"`. A single declaration command expands EVERY right-hand side before assigning any of its names, so `$arm` was still unset when `id` was built — but `$n` was **not** empty, because the caller is `for n in 1 2 3; do trial a \"$n\"; done` and `n` is a GLOBAL at that point. The id therefore read `-1`, not the empty-ish `-` that would have been noticed: a plausible, consistently-formed, wrong identity. Both arms produced `-1,-2,-3`, so every per-trial artifact keyed on id — captures, stop captures, census tags, portfields snapshots, cpu brackets — collided, and **Arm B overwrote Arm A in place** with nothing downstream able to tell them apart. `arm` itself was cor…\n- **The audit the one fix does not discharge.** A predicate was written over the whole delivered set — any `local`/`declare`/`typeset`/`export`/`readonly` whose later right-hand side references a name assigned earlier in the SAME command — with a positive control broken on purpose (plain `local`, `declare`, and the `${name}` brace form: 3 arms) and a negative control of the same declarations split (0 hits). v6 = 2 hits, both that one line; v7 = 0; v5 = the same single site. Stated over-report: the predicate does not split on `;`, so two correct statements on one physical line read as a dependency — the real site was confirmed not to be that shape. The PowerShell and Python helpers got their own predicates (zero multi-target assignments across four `.ps1`, pr…\n- **Instance 2 — the byte reader that was not one.** The repair site was first read with `sed -n '869,880p' file | cat -A`, which printed `$` at every line end — i.e. LF. The file is CRLF throughout (measured: 1117 CR = 1117 LF = 1117 CRLF). msys `sed` reads in text mode and drops the CRs, so `cat -A` faithfully rendered bytes that `sed` had already removed. The project's own rule (\"after any scripted edit, verify the BYTES\") was followed and still defeated, because the verification ran downstream of a text-mode filter.\r\n- **Third consequence of instance 1, and the worse half of it (hertz, measured independently; re-measured here).** The bad id does not only collide the arms — it begins with a DASH, so every artifact is named `-1.out`, `-2.err`, `-1.stop.out`. Measured in a throwaway dir: `sha256sum *.out` over such a population exits 1 with `unknown option -- 1` and hashes NOTHING (control: the same command over `a-1.out` alone exits 0 and hashes it); `grep -c x -1.out` exits 2 having measured nothing; `sha256sum ./*.out` is the repair. That is the LOUD form. The dangerous form is the one hertz's own detector took: it returned a clean EMPTY snapshot — \"0 artifacts altered\" — in the arm that was supposed to be red, because its glob handed the dashes to a tool that consumed t…\n- **Mechanism.** Both are a wrong answer with no error: a declaration whose dependency is satisfied by an unrelated variable that happens to exist, and a byte census whose bytes were filtered before they were counted. Neither is detectable from its own output — the id is well-formed, the `cat -A` dump is honest about what reached it.\r\n- **Fourth instance, in the very commit that recorded this entry (todlando, self-reported).** The amendment above was applied with a Python text-mode read (`open(p).read()`, universal newlines) and written back with `newline='\r\n'`. This register carried **two lone CR bytes** - `\r\n\r\n- **Instances 9-11` and `\r\n\r\n- **Addendum 2026-09-12 03:20Z` - present since at least `7cdcf5da`. Universal newlines translated each bare CR into a newline, so the commit silently rewrote two lines belonging to OTHER entries (net: 2 stray CRs removed, 2 blank lines added; markdown-harmless, still undeclared). Caught by reading the commit's own diff rather than trusting the insertion count: a one-bullet append that reports **5 insertions, 2 deletions** is telling you it touched something else. A text-mode read is a WRITE hazard, not only a measurement hazard - edit a file whose byte shape you have not measured in binary, and review the diff, never the intent.\r\n- **Rule.** (1) A declaration that depends on a name is its OWN statement; never share a `local` with the name it reads. (2) Derive an identity used as an artifact key ONLY after its parts are assigned, and guard it against its expected shape — a key that can go wrong silently overwrites evidence rather than failing. (3) A negative control for an id scheme must carry the caller's real variable environment: with the caller's global `n` absent, this defect reads as the harmless `-` and is easy to dismiss. (4) Read bytes with a byte reader — `python3` on the raw file, or `od`/`xxd` — never through msys `sed`, `grep`, or any text-mode filter; if a CR/LF count is the claim, count CR and LF bytes and state both.\r\n- **Kin:** [[IR-118]] (a complete-looking wrong answer from an instrument that succeeded), memory count-predicate-needs-its-own-positive-control, make-a-new-rig-red-on-purpose, scripted-edit-zero-match-refusal, render-not-read-pipefail, windows-firewall-census-clean-zeros.\r\n- **Ripe when:** now — (1) and (4) are habits, (2) is three lines in any rig. · **Size:** procedure.\r\n\r\n### IR-122 — the field rig's isolated-daemon stop cannot run from an spt-hosted session, so every run leaves a live daemon holding the subject exe inside the pool it just released\r\n\r\n- **Status:** OPEN, recurring. Instance 1 attempt 2 (`rig/arm2-driver-stdout.txt`: `RIG_DAEMON_STOP_REFUSED_OR_ERRORED — reported, not forced`). Instance 2 run `20260912T231404Z` under frozen r10 (`rig_daemon_stop_EXIT=3`, `cleanup-failures.txt`, `rig-daemon-stop.err`). Recorded by hertz 2026-09-12 23:50Z at doyle's direction; **this is a RIG defect, and any product-surface change requires a separate contract review.**\r","truncated":true,"truncatedBy":"lines","totalLines":572,"totalBytes":63530,"outputLines":406,"outputBytes":63530,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6937,"displayContent":{"text":"### IR-104 — checker 0.4.0 silently skips a FILE scan root under git enumeration: 81 doc stages read as missing, and a local 0.2.0 green hid it because the two versions disagree on what is evidence\n…\n- **Status:** FIXED UPSTREAM 2026-09-11 (traceable-reqs v0.4.1, PR #21 -> d9af11d, red-first cells);\n…\n- **Ripe when:** now — the #304 assembly. · **Size:** one pin fixup; one line in the gate runbook.\n\r\n### IR-105 — an assertion derived from a MODEL of the fixture instead of read off the fixture can only be refuted by a run, and the lane convention that defers the run gives the class a one-window latency: the repair for the first instance carried the second\r\n\r\n- **Status:** OPEN. Rule adopted 2026-09-11 (hertz, W1 close). Instrument = read the line, and read\r\n  what the line LANDS on, before asserting either.\r\n- **Instance 1 (hertz, `test/304-remote-friction`, `4ec34d1c`, 03:07Z):** `webserve_e2e.rs`\r\n  `subnet_node_labels_shadow_only_the_docs_compat_alias_while_members` still asserted the pre-#301\r\n  contract at the `/llms.txt/` line — a node root with an EMPTY remainder as `200`. Under the\r\n  node-root arm (`webserve.rs:778-781`) that path is a `302`, so the case died `302 != 200` at the\r\n  first assertion it reached and MASKED the five http calls after it. The `4823ae5d` sweep missed\r\n  the line because the case's other redirects are BARE-NODE ones, which take `redirect_node` and\r\n  are untouched by #301: I classified the case by its siblings and never read the line itself.\r\n  Cost: one window.\r\n- **Instance 2, inside the repair for instance 1 (`28d4eb68`, 03:19Z):** `4ec34d1c` was right about\r\n  the redirect and wrong about what it lands on — it followed through to `GET /llms.txt/docs/` and\r\n  asserted `200`. Measured at `71caedd4`: that is `404`, and the `404` is CORRECT. This fixture's\r\n  docs dir holds `cli/reference.md` and the root-file labels and no `index.html`, and a docs root\r\n  without one is a 404 by design — `webserve.rs:1028-1033` writes `index.html` precisely in order\r\n  to get `200` at `/local/docs/`. So the new assertion pinned index-presence, which is not this\r\n  case's subject. I asserted a property of a redirect TARGET without reading what the target\r\n  contains. Cost: a second window.\r\n- **The mechanism, stated once:** both assertions were derived from a model — the case's siblings in\r\n  instance 1, the contract's shape in instance 2 — rather than read off the fixture in front of me.\r\n  A model-derived assertion is indistinguishable from a correct one at authoring time AND at review\r\n  time; only a run refutes it. This lane commits such work `UNCOMPILED AND UNRUN at commit time:\r\n  written outside the window, measured in the next one` (both commit bodies carry that line\r\n  verbatim), so the class has a one-window refutation latency BY CONSTRUCTION, and a repair authored\r\n  inside that same blind interval inherits the defect it repairs. That is the register-worthy part:\r\n  the fix for a from-a-model assertion was itself a from-a-model assertion, 12 minutes later.\r\n- **Resolution:** `28d4eb68` drops the directory-root status and keeps the `302` + `Location` pair.\r\n  The line AFTER it already fetches `/llms.txt/docs/llms.txt` and compares bytes — a real leaf\r\n  fetched THROUGH the redirect target, which is stronger evidence the target is live than a status\r\n  on the directory root ever was. Blast radius measured at `71caedd4`, producer 3: the case cleared\r\n  the old line and the new pair and failed only on this one; the four sibling cases stayed green.\r\n  Producer 3 GREEN @`28d4eb68`.\r\n- **Third instance, caught BEFORE it shipped (same session, this entry's own id):** this file in the\r\n  `#304` test lane ends at IR-97; main ends at IR-104. Numbering this entry from the register in\r\n  front of me would have produced `IR-98` — a collision with a real entry, written while looking at\r\n  a file that had every right to look complete. The id is `105` because it was read off main. Same\r\n  mechanism, third direction: a stale local artifact IS a model of the shared one.\r\n- **Rule:** assert against what the fixture CONTAINS, at a named line you have read, in the tree the\r\n  claim will live in. Three corollaries earned here: a sweep must read every line it claims to have\r\n  swept (classifying a case by its siblings is a model); following a redirect obliges you to read\r\n  the target's contents before asserting its status (the target's shape is a model); and a register\r\n  id, like any shared address, is read off the shared tree, never off your lane's copy.\r\n- **Ripe when:** any test edit is authored outside the window that will measure it — which is this\r\n  lane's normal mode. · **Size:** a read, not a tool; the deferred-run interval is the thing to\r\n  shorten if it recurs.\r\n- **Kin:** [[IR-101]] (its census read the rendered effect instead of the subject — same family,\r\n  same morning, same file), [[IR-102]] (predicting against a blob nobody would run), memory\r\n  \"rig inherits the defect it studies\", \"verify the SUBJECT not just the measurement\",\r\n  \"precise claim is falsifiable\".\r\n\r\n### IR-106 — a red set HANDED OVER in a message was reported as a POPULATION: both members verified, their lines and modes corrected, and the count still wrong by half\r\n\r\n- **Status:** OPEN as a discipline line; the instance is closed (the run that refuted it is on file).\r\n  Author and subject: todlando. Filed by doyle 2026-09-11 11:20Z from todlando's text; IR-105 lands\r\n  from hertz's lane at the same assembly, which is why this number follows it.\r\n- **Instance (2026-09-11, #304 W1 product lane).** todlando was handed a red set naming TWO cells in\r\n  the spt-daemon webserve module. He opened each one, CORRECTED its line number and its failure mode,\r\n  and reported the corrected pair as his prediction. The unfiltered run at 3e7eaf67 showed FOUR reds\r\n  of the same mechanism (the retired `/local/` index twin): the two named, plus\r\n  `corrupt_registry_is_loud_but_does_not_disable_unrelated_facets` (:1228, 302 vs 500) and\r\n  `node_routing_reserves_facets_without_registry_fallback` (:1011, 302 vs 200). A post-run sweep\r\n  mapping every single-segment node-root literal to its enclosing fn closed the population at four,\r\n  by enumeration; two further cells touch a root and pass for stated reasons.\r\n- **Why the verification is what hides it.** Checking a member answers \"is this one real\". It cannot\r\n  answer \"is this all of them\": no amount of per-member rigour turns a received list into an\r\n  enumeration, and correcting a handed-down set FEELS more rigorous than enumerating it.\r\n- **Mirror instance one window later, other direction (hertz, same lane).** His enumeration was\r\n  SOUND (every node-root literal in the module mapped to its enclosing fn) but its SCOPE was\r\n  inherited from the one file he happened to be resolving; the merge also brought\r\n  `bootstrap_firewall.rs` (+4) and `bootstrap_firewall/windows.rs` (+2), so his whole-suite count was\r\n  short by six (predicted 981, measured 987). Same family: a sound instrument pointed at the wrong\r\n  population.\r\n- **Rule.** Before any COUNT enters a prediction, a START or an END, run the enumerating predicate\r\n  YOURSELF, with a tool that can express the population you are claiming (an unfiltered run; a grep\r\n  whose root is the crate, not the file you have open). A set received in a message is a lead.\r\n- **Kin:** [[IR-100]] (a census counts what its filter could not answer for, separately from a no),\r\n  [[IR-101]] (a per-lane green is silent about the population it did not select), [[IR-105]] (a\r\n  from-a-model assertion is refuted only by a run), memory \"a predicate without its tool is not evidence\".\r\n- **Ripe when:** now, a line in the window protocol, not a build. Fold into the START/END template\r\n  beside the census. · **Size:** one entry, one clause; no code.\r\n\r\n### IR-107 — a rig that redirects TMP INSIDE the checkout puts every tempdir fixture under a git toplevel, and cells whose premise is \"outside any repo\" resolve THIS repo's remote\r\n\r\n- **Status:** RIG FIXED in hertz's lane (base now under `AppData/Local/Temp/hertz-304-rig/<label>`;\r\n  `HERTZ_RIG_TMP_IN_REPO=1` restores the old placement on purpose as the negative control). Recorded\r\n  2026-09-11 11:20Z (doyle, from hertz's and todlando's measurements); corrected 11:35Z on hertz's\r\n  read. The A/B COMPLETED in window 7 at cba18cd5: arm A (base outside any repo) 2 run / 2 passed;\r\n  arm B (base inside the checkout) 2 run / 2 FAILED at :1404 and :842 with the strings below, the two\r\n  bases recorded and differing. Window 6's arm B was the non-measurement described below.\r\n- **Instance.** hertz's first unfiltered `spt-daemon --lib` at 69438c01 redded two cells that neither\r\n  lane touches and that todlando's unfiltered run had passed 8 minutes earlier on the same bytes and\r\n  box: `registryhost::tests::recent_projects_for_dedups_newest_first_excludes_spt_internal` (:1404,\r\n  got `[\"github-com-bigscreenvr-spt-bs-core\"]`) and `projwriter::tests::batched_complexity_counters_hold`\r\n  (:842, got `Some(\"spt-bs-core\")`). Both fixtures require a directory outside any repo.\r\n- **Mechanism, measured with a control.** `lane_run.py` set TMP/TEMP/TMPDIR/RUNNER_TEMP to\r\n  `EVID/temp/<label>` inside the spt-core checkout; `git -C <that dir> rev-parse --show-toplevel`\r\n  answers the checkout (remote `BigscreenVR/spt-bs-core`), while the same probe from the default TMP\r\n  answers \"not a git repository\". `project_id_for_dir` is REMOTE-URL FIRST: `slug(remote)` and\r\n  `display_from_url(remote)` are the two observed strings exactly, and the folder-name fallback could\r\n  not have produced either (candidate folder names: 304-product, hertz-304, spt-core). So git got as\r\n  far as step ONE of the derivation. The first mechanism offered (\"any in-repo cwd\") was killed by one\r\n  datum: ci.yml:143 runs `kind(lib)` unfiltered on this runner with an in-repo cwd and passed at\r\n  6a7dd6b7. The variable was the FIXTURE's location, never the process cwd.\r\n- **Instrument defects in this lane today, all hertz's, all closed:** (window 5) `cargo ... | tail;\r\n  echo $?` reports tail's status (memory \"render-not-read-pipefail\") — the compile gate was in fact\r\n  green, so that reading was VOID evidence rather than a masked red; the same construct one command\r\n  later printed 0 over a checker [must] finding, a true exit 1 — the hazard is that an exit read\r\n  through a pipe certifies nothing, not that it hides reds. (window 4 START gate, 10:26Z) a negative\r\n  control that returned at the refusal branch vouched for nothing about the send arm, which then\r\n  crashed on a NameError on the first real launch (memory \"make a new rig red on purpose\",\r\n  refinement). (window 8, premise lane, 12:14Z) a FOURTH void-exit instance in one day — `$?` and `${PIPESTATUS[0]}` both read a later command, a backgrounded python traceback surfaced as exit 0; every verdict rests on the producer's own recorded exit file or cargo's Finished line. Also: the window driver crashed at its END on a stale dict key AFTER json.dump had written the report — report-before-print is load-bearing and was right by accident; ordered the other way six measured arms evaporate at the summary line. (Linux cells lane, 12:46Z) fifth and sixth: a python driver died on a SyntaxError while the shell reported exit 0 (exposed only by STALE red logs from the previous sha), and a census script stalled mid-run while its ssh reported exit 0. Both caugh…\n- **Third instrument defect, same window (hertz, 11:25Z):** a mutation driver's revert check was\r\n  `git hash-object` plus `git diff --quiet`, and BOTH normalize line endings; `git checkout --`\r\n  re-materialized docshost.rs as CRLF, the LF-written anchors then counted 0, and the driver REFUSED\r\n  at arm 5 = w6-rdrop (the guard working: nothing written; rdrop and lib-full were measured in window\r\n  7: rdrop RED at :683 with left Some(59827), lib-full 988/988) while the oid check reported an identical blob over\r\n  bytes that had just changed. An oid check cannot see an eol rewrite; a revert proof records bytes,\r\n  crlf and bare-lf counts beside the oids. Also: an arm whose switch reaches only the CHILD env while\r\n  the base is chosen from the PARENT's ran the control arm's conditions and passed for its reason (a\r\n  non-measurement, not a refutation) - the driver now refuses to call it a measurement if the two\r\n  bases match.\r\n- **Rule.** A rig's TMP resolves OUTSIDE every git toplevel, and the rig proves it once per box with\r\n  `rev-parse --show-toplevel` expecting \"not a git repository\". A test whose premise is \"no repo\r\n  here\" names that premise in its first assertion so the failure reads as environment, not product.\r\n- **Kin:** [[IR-100]], [[IR-101]] (per-lane green silent about the unselected population; these two\r\n  cells were invisible to the stock 21-name producer for the whole lane), [[IR-106]].\r\n- **Ripe when:** now for the rig (done). The assertion-premise clause for the two cells rides a\r\n  SEPARATE follow-up lane after W1 closes (ruled 11:35Z: neither #304 lane touches registryhost.rs or\r\n  projwriter.rs, and a comment in two untouched modules does not widen the integration diff);\r\n  hertz's rig also writes its admission record under a stale sha tag (`admission-61bfd85c.json`),\r\n  the same family as a reused artifact path — fix in that lane. Consequence already paid: the\r\n  window-5 and window-6 admission census records were silently OVERWRITTEN by the later windows\r\n  writing the same path, so those two ENDs stand on the transcript alone, not on a record. · **Size:** one env line in the rig\r\n  (done); two comment lines in tests; one filename in the rig.\r\n\r\n- **Instances 9-11, all 2026-09-12, #304 W-2 (one night, three different surfaces).** NINTH (doyle's gate leg, 03:20Z): `cargo ... | tail` over non-interactive ssh to kitsubito returned 0 while cargo was off PATH in the non-login shell — already named in releases#304 comment 5643115673 and filed here for the count. TENTH (hertz, 05:30Z, while writing register entries about instruments that lie): `traceable-reqs check 2>&1 | tail -20; echo \"CHECK_EXIT=$?\"` printed `CHECK_EXIT=0` — tail's exit over a checker that exits 1, i.e. a 312-finding red read as clean. He re-ran it only because the register had made him suspicious of his own zero, which is the entry doing its job and not a skill. ELEVENTH (todlando, 05:20Z, a NEW surface — the harness itself): `cargo ne…\n\r\n- **Linux consumer recurrence (todlando, 2026-09-13, #304 at `b8482445`).**\r\n  My first consumer driver put `RUNNER_TEMP` under the checkout's preserved-evidence\r\n  directory, then exported its child sandbox as TEMP/TMP/TMPDIR. Phase A ran 3417 cells:\r\n  3414 passed (2 leaky), 3 failed, 1 skipped, exit 100. The two daemon premise\r\n  assertions named this exact fault; `spt-store::project::tests::derivation_ladder`\r\n  also derived the enclosing repository rather than its fixture folder. **That\r\n  attempt is VOID, not a candidate regression.** The temp-root Git probe returned\r\n  the enclosing checkout (exit 0); the replacement `/tmp/spt-consumer-304-b8482445-valid-*`\r\n  root and every exported temp path returned \"not a git repository\" (exit 128).\r\n  The replacement driver enforces that boundary before launching any producer.\r\n  On unchanged candidate bytes, valid Phase A then ran 3417/3417 passed (1 leaky),\r\n  1 skipped, exit 0; no main delta or source edit was needed. Original raw,\r\n  `temp-premise-correction.json`, and the valid `attempt2/` receipts remain under\r\n  `.spt/preserved/304-handoff/consumer-linux/`. This repeats the existing rule;\r\n  preserving evidence inside the repository never licenses putting fixtures there.\r\n\r\n- **Live-agent identity environment recurrence — Windows consumer (2026-09-13, #304).**\r\n  Doyle reported in `5E3WTZ3N` that his live session's `OWL_SESSION_ID` reached the\r\n  test driver: Windows consumer attempt 1 is **VOID, not a candidate regression**.\r\n  Recorded by hertz from that report, not from an independent rerun. The current\r\n  phase was to drain before a full scrubbed rerun; no corrected Windows result or\r\n  BOX CLEAR is claimed here. A.2 remains held and the preparation clock unstarted.\r\n  **Same mechanism, different input:** TMP placement changes a fixture's repository\r\n  context; inherited session identity changes its caller context. In both cases\r\n  the harness environment is part of the subject, not neutral launch plumbing.\r\n  A clean checkout and pinned executable do not establish the intended test premise.\r\n  **Rule:** construct the producer's child environment from its declared test/CI\r\n  contract, removing inherited live-session identity inputs as a set before launch.\r\n  Verify the effective environment handed to the actual test producer after all\r\n  wrapper/sandbox setup; record names and presence/absence, never identity values.\r\n  Fixtures that test identity must supply their own explicit fixture identity.\r\n  Keep the live agent's own environment and lifecycle intact; this is test-driver\r\n  isolation, not permission to evade a guard on real operational commands.\r\n  Preserve the invalid attempt's logs and verdict separately from the corrected\r\n  run; an environment-premise failure does not authorize a product patch.\r\n  **Kin:** [[IR-22]] records the earlier identity-inheritance failure and its\r\n  one-variable-at-a-time diagnostic trap; [[IR-122]] distinguishes a real rig's\r\n  intentional live-session refusal from an isolated test's contaminated premise.\r\n\r\n### IR-108 — four brainproc unit cells leak a process on every run; two others leak by ordering\r\n\r\n- **Status:** OPEN, product-side backlog candidate (not #304's). Recorded 2026-09-11 11:35Z (doyle)\r\n  from three unfiltered `spt-daemon --lib` runs on identical bytes on HFENDULEAM (todlando 10:52Z at\r\n  3e7eaf67; hertz 11:00Z at 69438c01 and 11:27Z at cba18cd5), all green.\r\n- **Cell-shaped (leak 3 of 3):** `brainproc::tests::clear_before_spawn_defeats_exact_generation_stale_file`,\r\n  `ready_but_old_gen_never_drains_does_not_promote_rolls_back`, `stale_generation_minus_one_ready_never_promotes`,\r\n  `trial_kills_alive_never_ready_candidate_before_rollback`. **Run-shaped:**\r\n  `broker::tests::windows_session_is_zombie_sees_a_handle_held_corpse_as_dead` (2 of 3),\r\n  `livehost::tests::legacy_psyche_sweep_guard_is_id_specific_and_fail_safe` (1 of 3).\r\n- **Why it matters:** nextest's LEAK is a child that outlives the test; on a shared box that is a\r\n  process census entry with no owner and a pool handle that can pin a worktree (memory\r\n  worktree-pin-holder-triage). Every post-census this cycle read zero survivors, so the leaks reap\r\n  themselves within the run's teardown; the hazard is the window between.\r\n- **Count is PER RUN, not a set (corrected 12:28Z, doyle, on todlando's fold-lane read):** at 61d3459f (fold/304-w2-admission, 992/992) FOUR leaked — brainproc x3 (clear_before_spawn, ready_but_old_gen, stale_generation_minus_one) + broker windows_session_is_zombie — and `trial_kills_alive_never_ready_candidate_before_rollback` RAN (PASS 0.559s, 116/992) and did NOT leak. So \"brainproc x4 cell-shaped\" is 3-of-4 cell-shaped across four runs on three trees; the fourth is run-shaped. A leaky set carried from one END to the next without re-deriving is the inherited-claim habit (IR-106) at its mildest.\r\n- **Discriminator before any fix:** run each cell alone with `--success-output immediate` and read what\r\n  child it spawns and why it is not waited; a cell-shaped leak is a missing wait or kill in the\r\n  fixture, a run-shaped one is teardown ordering.\r\n- **Kin:** [[IR-100]], memory \"e2e leaked daemons shared box\", \"rig ownership reap only your own\".\r\n- **Ripe when:** next product wave that touches brainproc, or a findings-backlog sweep. · **Size:**\r\n  four fixture waits; unknown for the two run-shaped.\r\n\r\n### IR-109 — a manifest `[placement] module_banner = \"accept\"` block LOOSENS the local checker to zero; CI's pinned checker is structurally blind to placement, so the loosening is invisible until the pin moves\r\n\r\n- **Status:** OPEN, RATIFIED 12:33Z (doyle, releases#304) as a TRANSITIONAL policy for the #304 head: the 0.4.1 pin stays (a tightening for every new tag), the accept key exempts only the 312 legacy banner tags, and this entry is the retirement ticket. Recorded 2026-09-11 12:10Z (doyle) from hertz's A/B/C and 0.2.0 arms; the commit's \"agreed\" is corrected by the ruling, not by rewriting a measured sha.\r\n- **Instance.** 33936943 \"chore(traceability): enable agreed placement policy\" (07:38Z, trailer todlando, on\r\n  feat/304-remote-friction-product and test/304-remote-friction, NOT on main) adds `[placement] enforce = \"on\"`,\r\n  `module_banner = \"accept\"`. The word \"agreed\" is UNRATIFIED: todlando cannot evidence it (his session that\r\n  wrote it is gone) and doyle did not rule it.\r\n- **Measured, same binary 0.4.1, same tree 4b54a95d, manifest the only variable:** as-is exit 1 / 312\r\n  misplaced_tag; block added exit 0 / 0; `enforce = \"on\"` alone exit 1 / 312. `module_banner` is the sole\r\n  load-bearing key; enforce is the default already. CI-pinned 0.2.0 (golden.yml WANT=0.2.0) at the same sha:\r\n  exit 0 / 0 — the `misplaced_tag` kind does not exist in that version; placement lives only in its `review`\r\n  subcommand, which `check` never reaches. asm-304 (0c05e722, 0.4.1 + the block): exit 0, bought by the key.\r\n- **Why it matters.** AGENTS.md rule 1: tags sit on the evidence, never at file tops to satisfy coverage. The\r\n  312 are banner tags that violate it; the accept key retires them by policy rather than by moving one tag, and\r\n  the gate that CI actually runs cannot see either state.\r\n- **Rule.** A checker config change that lowers a finding count is a loosening and is ruled on the record\r\n  before it rides; \"agreed\" in a commit message is not a ruling. The honest statement of a zero under such a\r\n  config names the config (\"zero under a manifest that accepts module banners\").\r\n- **Kin:** memory checker-version-must-match-ci-pin (live instance), [[IR-104]].\r\n- **CORRECTED 12:24Z (doyle):** the pin HAS moved on the W1 lane ancestry — 71caedd4 \"ci: pin traceable-reqs to v0.4.1\" (10:11Z) sits under 697eb398 (not on main), so ci.yml:253 and golden.yml:1424 both read WANT=0.4.1 at the integration head while origin/main reads WANT=0.2.0 at ci.yml:253 and golden.yml:1414. The accept key is therefore LIVE at the assembled golden gate today, not dormant: asm-304 reads 0 [must] under 0.4.1 because of the key. A lane off 697eb398 reads nine further [must] (code-stage tags in docs prose: F-035-CONFLICT, PUMP-W2-DESIGN, DEBUG-CONVERGE-PLAN, INFRA-REGISTER) that the assembly does not: measured at F-035-CONFLICT:47, 697eb398 carries the bracketed tags and origin/main carries them with brackets elided (\"so the checker\" clause),…\n- **Ripe when:** now — the key rides #304 only as a labelled hole named in the golden hand-off; retire by relocating the 312 tags and deleting the key in a lane of its own. · **Size:** 312 tag moves; the key.\r\n\r\n### IR-110 — the gater ruled a wave from origin/main's manifest while the milestone's own product lane already carried the surface; a second implementation was built to its W-1 END before the first was noticed\r\n\r\n- **Status:** OPEN, STOP LINE on #304 W2 (comment 5634187958). Recorded 2026-09-11 12:10Z (doyle, own instance).\r\n- **Instance.** feat/304-remote-friction-product @3e7eaf67 implements #297 TCP admission under\r\n  REQ-WEB-LAN-BOOTSTRAP-FIREWALL (bootstrap_firewall.rs + windows.rs + linux.rs, lanhost/servehost/serveverb/cli\r\n  call sites, docs-site section, ADR-0059 \"Amendment 2\" at d71df7aa): program-scoped Windows effector, all\r\n  profiles, no remote restriction, zero tests in the module (six guard-level cells arrive with hertz 7b098cc2,\r\n  none on scope). doyle deactivated its int stage the same morning and then ruled W2 fork (i) and let four\r\n  REQ-LAN-BOOTSTRAP-* ids mint from ORIGIN/MAIN's manifest, where the id is absent (0 occurrences). todlando\r\n  built build/304-w2-bootstrap-tcp @fe427497: a second, tested (E4 red at the bound-port assertion, 5/5, 981==981)\r\n  netsh implementation, port+remote scoped, never program, a second \"## Amendment 2\" in the same ADR file.\r\n  He found the collision at his W-1 END by reading the product lane, and touched nothing.\r\n- **Mechanism.** IR-106 from the gater's chair: the population enumerated (main's manifest) was not the\r\n  population the claim was about (the milestone head's). The tell was available all morning — the gater's own\r\n  deactivation note names the id — and a grep of the assembly worktree (asm-304) instead of the main checkout\r\n  would have returned 1.\r\n- **Consequence.** The two texts disagree on a FACT (which rule shape admits TCP over the tailnet on this box;\r\n  W-0 measured program scope admitting nothing for UDP only), both amendments share a heading, and an\r\n  assembled head would run both start paths and write two rule sets.\r\n- **Rule.** Before minting or activating any id for a milestone wave, enumerate the ASSEMBLY head's manifest\r\n  (asm-<milestone>), not main's; a wave that \"closes\" a surface names the id it closes and greps the milestone\r\n  head for it first. A fork ruling states the tree it enumerated.\r\n- **Kin:** [[IR-106]], [[IR-107]] (same day, same class in three chairs).\r\n- **Ripe when:** now — W-2a discriminating measurement in flight (arms A-D on the installed 5470 listener from\r\n  kitsubito), then the fold ruling (one id, one ADR section, the tested decision seam + cells attached to the\r\n  surviving effector). · **Size:** one measurement; one fold commit on the W2 lane; the ADR merge is a content\r\n  decision, not a merge decision.\r\n- **Labelled hole (12:14Z):** bootstrap_firewall/linux.rs (676 lines) has ZERO #[test]; all six cells sit in bootstrap_firewall.rs and windows.rs. Under cfg the Linux arm is invisible to this box's unit lane, so the surviving id's unit stage reads green over an untested Linux backend set. Closed by a hertz cells lane run on kitsubito against ufw_scope / owned / backend (queued 12:14Z; ten cells red-first at be99017f, 12:41Z). RULE learned there: `ci.yml` lint runs clippy `--all-targets -D warnings` on kitsubito ONLY, and `--all-targets` lints cells as hard as product — a Linux-only red that no Windows gate sees caught todlando's `needless_borrow` (linux.rs:293, fixed be99017f) and hertz's own `cloned_ref_to_slice_refs` (linux.rs:891, test module) one hour ap…\n\r\n### IR-111 — the installed product's own inbound UDP rule reads Duplicate / Inactive in ActiveStore, shadowed by the fallback rule; a by-name probe reads it green\r\n\r\n- **Status:** OPEN, product-side backlog candidate (REQ-INBOUND-WINDOWS-RULE-BINDER-PATH-MATCH family). Recorded\r\n  2026-09-11 12:14Z (doyle) from an unelevated `Get-NetFirewallRule` read of both stores on HFENDULEAM.\r\n- **Instance.** ActiveStore: `spt-core inbound UDP` (Program = installed spt.exe, Profile Any, UDP, Remote Any)\r\n  Enabled=True, **Enforcement=Duplicate, PrimaryStatus=Inactive**; `spt-fallback inbound UDP` (same program,\r\n  Profile Any) Enforcement=ProfileInactive Enforced, Status OK. PersistentStore shows both as\r\n  Enforcement=NotApplicable, Status OK — the persistent view cannot see the shadowing at all.\r\n- **Why it matters.** The product's reconcile and the `inbound_block_hint` probe key on the product rule's NAME.\r\n  The rule that is doing the work is the other one; delete or repoint the fallback and the product rule may\r\n  become the enforced one with no change in what the name probe reports, or the reverse. Kin to the W1\r\n  effector's own comment (\"never certify a rule which ActiveStore reports as ignored or ineffective\") — the\r\n  UDP side never reads ActiveStore.\r\n- **Also seen, same read:** ~26 enforced program-scoped Private rules naming target/debug and actions-runner\r\n  test binaries (spt_net-*, spt_daemon-*, spt.exe), Proto TCP+UDP, LPort Any, Remote Any — the rig-rule\r\n  population the hfenduleam program-scope memory describes; none admits the tailnet.\r\n- **Rule.** A rule probe that certifies anything reads ActiveStore EnforcementStatus, not PersistentStore\r\n  presence and not the name.\r\n- **Kin:** [[IR-110]], memory hfenduleam-program-scoped-firewall-rules-do-not-admit-tailnet.\r\n- **Ripe when:** the next inbound-rule wave, or when the W1 CIM two-store query is generalised to the UDP side.\r\n  · **Size:** one ActiveStore read in the probe; one dedupe decision.\r\n\r\n### IR-112 — bare `cargo test -p spt-daemon --lib` reds two process-global cells on Linux at a sha where nextest is green; libtest is not a sound gate for this crate\r\n\r\n- **Status:** OPEN, rig rule (CI unaffected: `ci.yml` runs `kind(lib)` under nextest). Recorded 2026-09-11 12:46Z\r\n  (doyle) from hertz's Linux cells lane END on kitsubito.\r\n- **Instance.** At 697eb398 on kitsubito: `cargo nextest list -p spt-daemon --lib` = 989 ids; `cargo test -p\r\n  spt-daemon --lib` = 989 run, 987 passed, **2 FAILED, exit 101**:\r\n  `answerop::tests::an_approval_notifies_a_plain_knocker_with_no_pre_authorization` (answerop.rs:324, \"expected\r\n  exactly one courtesy: [] left: 0 right: 1\") and\r\n  `brainproc::tests::the_ready_breadcrumb_tells_a_computed_hash_from_a_cached_one` (brainproc.rs:2347, \"the FIRST\r\n  ready write in a process pays for the digest\"). Both PASS under nextest with the identical filter, exit 0.\r\n- **Mechanism.** Process-per-test vs one shared libtest process: both cells read process-global state (the\r\n  brainproc one says so in its own panic text); under libtest a sibling's write is visible. IR-108's leaky-cell\r\n  class, measured on Linux. Kin memory bystander-test-reads-process-global, daemon-lib-tests-deadlock-on-live-host.\r\n- **Rule.** A gate or rig over spt-daemon's lib runs NEXTEST; a `cargo test --lib` red on this crate is a rig\r\n  fault until discriminated under nextest with the same filter. Count agreement (list == run) says nothing about\r\n  exit agreement — check both.\r\n- **Kin:** [[IR-108]], [[IR-100]].\r\n- **Ripe when:** a sweep makes those two cells hermetic (the fix belongs to the cells, not the gate). · **Size:**\r\n  two fixtures.\r\n\r\n### IR-113 — a killed mutation arm does not unwind: the subject stays mutated and the NEXT arm measures a tree nobody declared; and a mutation that reds on a compile error is a void arm that \"it compiled\" cannot detect\r\n\r\n- **Status:** OPEN, rig rule for every mutation driver. Recorded 2026-09-11 13:05Z (doyle) from todlando's FOLD-1b\r\n  window (fold/304-w2-admission, windows.rs).\r\n- **Instance.** A first M1 injected an early return through a struct literal naming a helper that does not exist —\r\n  a mutation that would red on E0425, not at the cell's assertion, i.e. a void red-first arm. The job was stopped\r\n  mid-run; the driver's restore is its LAST line, so the kill left the MUTATED file on disk: working oid d8ddfdf3\r\n  against pristine 1f475a80, two residue markers present. Caught only because the next act was an oid compare, not\r\n  the next arm. Restored and re-measured identical (residue 0, 786 == 786 lines). Second half: clippy on the\r\n  mutated tree exited 0, so \"it compiled\" would not have exposed the void arm either.\r\n- **Mechanism.** Mutate → run → restore is not transactional; any exit before the last line (kill, timeout, crash,\r\n  nextest hang) strands the mutation. A void arm is one whose red is not AT the assertion the prediction named.\r\n- **Rule.** (1) A mutation driver restores in a finally/trap path, and every arm BEGINS by asserting the subject's\r\n  oid equals the declared pristine oid — the previous arm's revert is proven at the next arm's start, not trusted.\r\n  (2) A red-first arm is accepted only when the artifact names the predicted assertion line; a compile-error red,\r\n  a panic elsewhere, or a red at a different line is VOID, not a pass and not a fail. (3) Mutations are one-token\r\n  edits with an anchor count asserted at 1; an arm that did not change the file voids itself loudly.\r\n- **Kin:** [[IR-107]] (revert proven by oid AND byte shape), memory scripted-edit-zero-match-refusal,\r\n  make-a-new-rig-red-on-purpose.\r\n- **Ripe when:** now — the rule is cheap and the drivers exist; every lane's driver adopts it at its next edit. ·\r\n  **Size:** a trap/finally and one oid compare per arm.\r\n\r\n### IR-114 — three hands wrote one firewall rule set inside ninety seconds under two directors; every census was true at its instant and false a minute later\r\n\r\n- **Status:** OPEN, procedure ruled 2026-09-12 00:50Z (doyle) on todlando's reconciliation; recorded 00:52Z.\r\n- **Instance.** #304 W-2a arms on HFENDULEAM: ~00:44Z todlando asked the operator to delete spt-w2a-C so B would stand alone; ~00:45Z the operator said \"C down\" and todlando's census read B present / C absent (true then); 00:45:05Z liam ADDED C at doyle's direction (doyle had been idle 11 h and did not know the operator's window); 00:46:14Z liam DELETED B at doyle's direction; 00:49:09Z todlando re-measured C present / B absent. Nobody was wrong; the population was not stable. Every fetch todlando reported had an adjacent census and stands; a long background census that straddled the writes returned no spt-w2a rows at all and is UNMEASURED. Separately, doyle's drop-log arm crossed liam's revert in flight: three fetches ran with logging already off — a void a…\n- **Mechanism.** Two directors (operator, gater) each driving a different elevated hand against the same shared host state, neither seeing the other's window; a census taken as a separate earlier step and carried forward.\r\n- **Rule.** For any arm on shared host state: ONE WRITER; the census is taken BY THE FETCHER in the SAME command as the fetch, before and after; the prediction names the exact expected population (an unexpected row is a red); every write is announced with its UTC time to every party; a director resuming after a gap re-measures the population before issuing a write. Kin: memory verify-the-subject-not-just-the-measurement, name-the-file-and-sha.\r\n- **Also measured tonight (todlando):** 'spt-core daemon' (proto Any, Private, remote Any, program = the listener's exe) covers the Private-classified Tailscale interface while TCP 5470 times out from kitsubito and the LAN address answers 200 with ICMP alive — so W-0 measured the tailnet ACL, not program scoping, and DESIRED_PROGRAM=false's cited justification is VOID (the constant may still be right; its citation is not). The shape question moves to a throwaway port and listener over the LAN (arm E).\r\n- **Ripe when:** now — the rule costs nothing. · **Size:** procedure.\r\n\r\n### IR-115 — a firewall census whose port test is DENIED reads every rule as port=Any and counts port-scoped rules as blanket; a `netsh show rule` without `verbose` omits Program and reads every rule as program=Any; a control count that merges two agents' reads is nobody's control\r\n\r\n- **Status:** OPEN, mechanisms recorded 2026-09-12 01:14Z (doyle) from todlando's and liam's own corrections during #304 arm E.\r\n- **Instances.** (1) todlando's first census A (\"26 blanket rules\") and B (\"occupied LocalPort set: EMPTY\"): `Get-NetFirewallPortFilter -All` returns \"Access is denied\" unelevated, the probe swallowed the denial, every rule read as port=Any, and B's positive control (the hand rule carries LocalPort 5470) is what caught it. (2) His replacement pass: `netsh advfirewall firewall show rule name=all` without `verbose` prints no Program line, so it reported 417 blankets and ZERO rules naming spt.exe — provably false, caught by the same control. The third pass (`dir=in verbose`) passed both controls (port-5470 rows = 1, spt.exe rows = 7) and was the census used. (3) doyle's fetcher: first census predicate listed port-covering and program-covering rules as two separ…\n- **Mechanism.** A denied or under-scoped read does not error; it returns the permissive default for the field it could not see, so the census reads MORE admits than exist and a shape question gets decided on a phantom population. Kin: memory a-predicate-without-its-tool-is-not-evidence, verdict-from-probe-competence, zero-match-filter-reads-as-absent.\r\n- **Rule.** A firewall census names its tool and privilege and carries two positive controls in the SAME dump: one rule known to carry a specific LocalPort, one known to name a specific Program. A census that cannot see both has not seen the population. The reaching predicate is port-covers AND program-covers AND LocalIP-covers AND profile-covers, one set. Every loopback and remote read records its curl exit code. Counts are per agent; a merged count is restated per agent or discarded.\r\n- **Ripe when:** now — the rule costs one grep. · **Size:** procedure.\r\n\r\n- **Addendum 2026-09-12 03:20Z (doyle, #304 W-2 A5/A4): the Windows Firewall event log is DIRECTION-BLIND, so a rig that keys \"written\" or \"removed\" on it cannot fail in the direction it claims.** Population controlled over one read (2011x48 / 2052x6 / 2097x6, a 400-event re-read of the same window returning the identical six): id 2052 fires on creates AND deletes in the observed population, id 2097 is create-specific, and NOTHING observed is delete-specific. The CENSUS carries the sign; the log carries only the instant. The same read established a MEASURED gap (zero events between A5's end and A4's start) and that nothing commits after the client dies — both usable, neither a direction. Kin: the firewall status fields do not discriminate either, since an ad…\n\r\n### IR-116 — a watchdog that calls a killer and then echoes success reports a kill it never made; `pkill` is absent in msys, so the guard logged \"stopped\" while the arm it guarded ran on\r\n\r\n- **Status:** OPEN, mechanism recorded 2026-09-12 01:24Z (todlando) from his own guard during #304 FOLD-2's Windows arm at 7357ea32; doyle asked for the line.\r\n- **Instance.** todlando armed a watchdog to stop a test arm before it reached `cargo test --workspace --lib`, because spt-daemon lib tests deadlock on a live host. Shape: `if grep -q \"CLIPPY_EXIT=\" log; then pkill -f \"bash /tmp/arms.sh\" 2>/dev/null; echo \"GUARD: arms.sh stopped after clippy at $(date -u)\"`. It printed `GUARD: arms.sh stopped after clippy at 01:24:06Z`. Nothing was stopped: `pkill` does not exist in this msys/Git-Bash environment (`command not found`, exit 127), `2>/dev/null` ate the message, and the `echo` was never gated on the killer's exit. The arm ran on into its compile phase and was found by tailing the build log, not by the guard — whose only output was a green.\r\n- **Mechanism.** Two defects stack, and either alone would have been caught by the other: a missing binary, and a success line that cannot fail. Same family as IR-107 seen from the other side — there a trailing command's exit was mistaken for the producer's; here no exit was consulted at all. The aggravating factor is WHERE it lives: a guard is written while thinking about the hazard it guards, not about the guard, and a guard that never fires looks identical to a guard that works. Kin: memory watchdog-reports-a-kill-it-never-made, verdict-from-exit-not-from-silence, a-predicate-without-its-tool-is-not-evidence.\r\n- **Rule.** A watchdog asserts the POST-STATE and never echoes after the call: `kill …; sleep 1; if still_running; then echo \"GUARD FAILED\"; exit 1; fi`. On msys use `kill -9 <pid>` with a pid you resolved yourself, or `taskkill //PID <p> //T //F`; do not assume `pkill`/`pgrep` exist — check the tool before building a guard on it. Reap your own tree only: resolve the pid and its children, never a machine-wide sweep on a shared box.\r\n- **Second-order, and it bit me inside this very entry.** `git checkout -- <file>` restores from the INDEX, not HEAD. Having staged a first draft, I \"reverted\" it and appended a rewrite — producing a file carrying BOTH. Caught by the diffstat (49 insertions for a ten-line entry). Restore from `HEAD --` when HEAD is what you mean; the diffstat is the control.\r\n- **Corollary, accepted by doyle.** The killed arm reported `TEST_EXIT=137`. That is the SIGKILL, delivered during compilation with ZERO tests executed (last lines `Compiling acto / iroh-dns / wmi`) — a VOID arm, not a red. A 137 sitting in a log over a test arm is precisely the number quoted later as a product failure. Same family as IR-113 (a killed mutation arm does not unwind).\r\n- **Instance 2 — a DIFFERENT tool surface, 2026-09-12 03:39Z (hertz).** The mechanism is not a property of todlando's guard. hertz ran a recursive `grep -rl` over the project tree; it exceeded the foreground timeout and the harness backgrounded it. `TaskStop` returned `{\"message\":\"Successfully stopped task: bn74vtqn0\"}` — a structured success from the harness itself, not a hand-rolled echo. The process was still in the table two minutes later: pid 35104, StartTime 03:37:20Z, **CPU 13.25 s**, killed only by an explicit `Stop-Process -Id 35104 -Force` and confirmed gone by a post-state count of 0 against a live positive control (`pwsh` count 12). So a first-party tool's success object is no better warranted than an `echo`, and the rule generalises: **read the …\n- **Ripe when:** now — the rule costs three lines in any guard. · **Size:** procedure.\r\n\r\n### IR-117 — a predicate that cannot fail: pre-registered outcomes whose branches are not mutually exclusive, and a requirement titled with the TASK instead of the INVARIANT\r\n\r\n- **Status:** OPEN, mechanism recorded 2026-09-12 03:48Z (hertz, both instances his own; doyle ruled the second).\r\n- **Instance 1 — the outcome set.** For the #304 W-2 packet capture hertz pre-registered four outcomes, of which (a) was \"SYN retransmission despite the RST\" and (b) was \"above the wire in the Windows client path\". The capture showed five SYNs at a flat ~511 ms, each RST'd in 18-25 us and each ignored — which is (a)'s packet shape with (b)'s locus. The two branches were the same answer told at two altitudes, so EITHER could have been declared \"confirmed\" and neither could have been refuted by the actual result. Pre-registration defends against fitting the story to the data; it does nothing against branches that cannot both be false.\r\n- **Instance 2 — the requirement title.** hertz drafted `REQ-NET-WINDOWS-REFUSAL-BUDGET` titled \"enumerate the spt paths that treat connection-refused as a fast negative on Windows\". doyle refused it: that is the TASK, not the invariant. A requirement stated as a task is discharged by DOING the task — it would have gone green the instant the enumeration was written, whether or not one path was fixed, and would have had nothing to say about the NEXT connect bound anyone adds. The accepted title states a product invariant (\"classified by its error kind, never by elapsed time; every connect bound documented against the measured floor\"), which new code can violate.\r\n- **Mechanism.** Both are the same defect at different altitudes: an instrument whose every reachable outcome is a pass. Kin on the outcome side: memory discriminator-question, refuse-mechanism-until-something-discriminates, one-sample-is-not-a-negative. Kin on the requirement side: the activation model itself (a stage that cannot go red is not coverage), gate-against-documented-design.\r\n- **Rule.** Before registering an outcome set, name for EACH branch an observation that would refute it; if two branches share a refuter, they are one branch and the set is unfinished. Before adding a `REQ-*`, state it as something CODE can violate, never as work a person can complete — if the only way to make it red is to not write a document, it is a task and belongs in a lane, not the registry. Corollary from the same ruling: a measured constant may NOT enter product code as a threshold. The requirement forbids the interpretation (time as a proxy for error kind); it does not bless the number, which was measured on our machines and not on a user's.\r\n- **Ripe when:** now — both checks are one sentence each at authoring time. · **Size:** procedure.\r\n\r\n### IR-118 — an instrument read mid-flight, or through a filter that cannot match, returns a COMPLETE-LOOKING wrong answer with no error\r\n\r\n- **Status:** OPEN, two instances one hour apart, 2026-09-12 (hertz); doyle asked for the filter line beside IR-117.\r\n- **Instance 1 — the capture read in flight, and it would have inverted the verdict.** `tcpdump -w /tmp/hz-cap.pcap` was still running when the packets were wanted. The file was **8192 bytes** live and **11933 bytes** after `kill -TERM` flushed it; the 3741-byte tail WAS the four SYN retransmissions. Reading the live file would have yielded a well-formed pcap showing one SYN and one prompt RST — i.e. the pre-registered outcome (b), the WRONG answer, assembled entirely from the RIGHT answer's own evidence, with no truncation error and a plausible packet count. The tell was available and nearly missed: a block-aligned size (8192) is a flush boundary, not a record.\r\n- **Instance 2 — the filter that cannot match, class instance 2.** Censusing Windows TCP settings, hertz piped `netsh int tcp show supplemental template=internet` through `Select-String -Pattern 'Template|Initial RTO|Max SYN|Retransmissions'`. It returned ONE line — the header — because none of those words appear in the table's rows (which read `Minimum RTO (msec)`, `Initial Congestion Window (MSS)`, …). Had it been trusted it would have reported \"no retransmission settings exposed\", which is the identical clean zero a CORRECT filter over an empty template returns. Recovered only by re-running the command raw.\r\n- **Mechanism.** In both cases the instrument succeeded, exited 0, and returned a well-formed artefact that under-reports its population — a partial buffer and a non-matching pattern are indistinguishable from a complete capture and an empty table. Neither failure can be detected from the artefact alone; both need a second read of a different kind. Kin: memory zero-match-filter-reads-as-absent, count-predicate-needs-its-own-positive-control, verdict-from-probe-competence, absence-needs-sibling-probe.\r\n- **Rule.** Terminate a `-w` capture and confirm the writer is gone BEFORE reading it, and quote the writer's own census (`N packets captured / N received by filter / 0 dropped by kernel`) beside the packet list; a block-aligned file size is evidence you are mid-flush. For any filtered dump, either carry a positive control the filter MUST match, or dump raw once and read the filter against the real field names — a filtered census that returns only its header has measured nothing.\r\n- **Ripe when:** now — both rules cost one extra command. · **Size:** procedure.\r\n\r\n### IR-119 — a control that only had to prove a ROUTE served a real directory; and a rig is not torn down until its last process is gone, whatever the analysis says\r\n\r\n- **Status:** OPEN, mechanisms recorded 2026-09-12 05:46Z (doyle) from hertz's unprompted self-disclosure. The security remedy is an OPERATOR item, filed on releases#304 comment **5643876746** (rotate the kitsubito self-hosted runner's registration credential); this entry carries only the reusable mechanisms.\r\n- **Instance.** The accepted-connection control for the W-2 packet capture was `python3 -m http.server 29472 --bind 0.0.0.0` with **cwd `/home/reavus`** — the self-hosted runner account's home — for **1 h 59 m 54 s**. The off-box bind was REQUIRED (the peer dialled from another machine); the working directory was the whole defect. An empty temp dir returns the identical HTTP 200 and proves exactly as much. `http.server` builds its index from `os.listdir` and filters nothing, so 20 dotfiles including the runner credential files were listed and fetchable; mode 0600 did not protect one of them, because the server ran AS that user. kitsubito's posture was separately verified as RSTing with **no** host filter (ufw inactive, nft input policy accept on both tables)…\n- **Mechanism.** A route control and a file server are the SAME COMMAND, so the cheapest way to answer \"can the peer reach this port\" silently publishes whatever directory the shell was sitting in, and the excess is invisible in the result — the 200 looks identical either way. Same family as a pattern-kill that matches its own ssh line: a tool doing more than the measurement asked for.\r\n- **Second mechanism, and it is why two hours passed rather than two minutes.** The author tore down the CAPTURE, named the outcome, and stopped — treating \"the verdict is named\" as \"the leg is finished\". **Naming an outcome is a milestone in the ANALYSIS, never in the RIG.** A rig is torn down when its last process is gone, and the artefact you are proud of is not the only thing you left running. Found only because a stale wake line replayed his own teardown list back to him two hours later.\r\n- **Rule.** (1) A control that proves a route binds an EMPTY throwaway directory, never a home, a repo or a working dir, and it goes down in the SAME breath as the capture it controls. (2) Every rig's teardown is a list of PROCESSES asserted gone against a live positive control, never a list of conclusions. (3) A teardown note written BEFORE a ruling does not license deleting the ruling's cited evidence: `/tmp/hz-cap.pcap` and `/tmp/hz-cap.log` were KEPT by ruling, twice, because they are the primary record of a posted verdict.\r\n- **Evidence quality worth copying.** The window was MEASURED (1 h 59 m 54 s), not estimated; the served-request record was complete (2 requests, both ours, `GET /`, no descent, no file fetch) and its LIMIT was stated rather than implied — a server log is evidence about requests SERVED, never about the network. An independent wire instrument (the pcap, 0 dropped by kernel) covered **4.4%** of the window, and that figure is the capture PROCESS LIFETIME: reading the 2.08 s packet span as the coverage would have understated the evidence 150-fold, because a running capture with no packets is still observing.\r\n- **Kin:** [[IR-116]] (assert the post-state, never an echo), [[IR-118]] (an instrument complete about what it measures and silent about the rest), memory rig-ownership-reap-only-your-own, reap-root-needs-authenticated-ancestry.\r\n- **Ripe when:** now — both rules are one line each in any rig. · **Size:** procedure.\r\n\r\n### IR-120 — a claim named for the one axis nobody varied: six readings over two routes and two libraries, all on ONE box, reported as a property of the platform\r\n\r\n- **Status:** OPEN, mechanism recorded 2026-09-12 05:47Z (doyle); the instance is liam's, refuted by hertz's own arm and conceded by its author.\r\n- **Instance.** The ~2.05 s Windows refused-connect latency was filed as \"the WINDOWS refusal latency\" on six readings that varied ROUTE (loopback, LAN hop to Linux) and LIBRARY (curl, .NET TcpClient) and held HOST constant — every one on HFENDULEAM. Route- and library-independence were measured; \"Windows\" was the name of the box. A per-host WFP callout, endpoint agent or filter driver swallowing RSTs would have produced exactly those six readings on exactly those two routes and generalised nothing. Settled only by going to get the missing axis: a second Windows box (Win10 19045 against the first's Win11 26200) read 2077.3 ms, inside 30 ms of the band. The claim survived; it was not ENTITLED to until then.\r\n- **The control the claim also lacked.** Nothing in the record distinguished \"Windows pays 2 s\" from \"TCP to a closed port costs 2 s\" or \"curl reports refusals slowly\" — because every reading was Windows, the word could not be earned from them, only assumed for want of an alternative. The Linux arm supplied it: closed port and open port within **66 microseconds** of each other on the same libraries, so the refusal costs ~0 there and cannot be told from an open port by latency at all. With that control \"Windows\" is measured; without it, it was a label.\r\n- **Mechanism.** Breadth along the axes you happened to vary reads as generality. The check is cheap and nobody runs it: write the claim's subject noun, ask which axis that noun names, then ask whether that axis was varied. Second instance from the same author in one night (a PowerShell-edition confound priced as the product's cost), and a sibling shape in the same leg: \"the box was quiet\" inferred from the absence of ANNOUNCED work, when silence is exactly what an unannounced three-minute recursive grep produces — quiet was never measured for that window either.\r\n- **Rule.** A claim names its population and its varied axes in the same sentence, and the axis in the claim's NOUN must be one of the varied ones. One host is a host, not a platform; one edition is an edition, not a cost. A quantity claimed as a property of a class carries a NEGATIVE CONTROL from outside that class, or it is a label. Corollary already ruled: a constant measured only on our boxes does not enter product code as a threshold — see [[IR-117]].\r\n- **Kin:** memory verified-members-are-not-an-enumerated-population, one-sample-is-not-a-negative, tool-claim-must-name-its-environment, absence-needs-sibling-probe, windows-client-refused-connect-costs-2s.\r\n- **Ripe when:** now — it is a sentence-shape check at authoring time. · **Size:** procedure.\r\n\r\n### IR-121 — one declaration command expands every right-hand side before assigning any name, so a dependent id silently binds the CALLER'S GLOBAL and two arms collapse onto one artifact path; and `cat -A` behind msys `sed` is not a byte reader\r\n\r\n- **Status:** OPEN, mechanisms recorded 2026-09-12 09:05Z. Instance 1 found by hertz in todlando's driver and confirmed by doyle; repaired as a separately pinned revision (v6 `dcfb732a…` → v7 `927eafb9…`) per the standing rule that a demonstrated execution incompatibility gets a new hash and renewed verification rather than an in-place accommodation. Instance 2 is todlando's own, found while reading the repair site.\r\n- **Instance 1 — the id that looked right.** `trial()` opened with `local arm=\"$1\" n=\"$2\" id=\"$arm-$n\"`. A single declaration command expands EVERY right-hand side before assigning any of its names, so `$arm` was still unset when `id` was built — but `$n` was **not** empty, because the caller is `for n in 1 2 3; do trial a \"$n\"; done` and `n` is a GLOBAL at that point. The id therefore read `-1`, not the empty-ish `-` that would have been noticed: a plausible, consistently-formed, wrong identity. Both arms produced `-1,-2,-3`, so every per-trial artifact keyed on id — captures, stop captures, census tags, portfields snapshots, cpu brackets — collided, and **Arm B overwrote Arm A in place** with nothing downstream able to tell them apart. `arm` itself was cor…\n- **The audit the one fix does not discharge.** A predicate was written over the whole delivered set — any `local`/`declare`/`typeset`/`export`/`readonly` whose later right-hand side references a name assigned earlier in the SAME command — with a positive control broken on purpose (plain `local`, `declare`, and the `${name}` brace form: 3 arms) and a negative control of the same declarations split (0 hits). v6 = 2 hits, both that one line; v7 = 0; v5 = the same single site. Stated over-report: the predicate does not split on `;`, so two correct statements on one physical line read as a dependency — the real site was confirmed not to be that shape. The PowerShell and Python helpers got their own predicates (zero multi-target assignments across four `.ps1`, pr…\n- **Instance 2 — the byte reader that was not one.** The repair site was first read with `sed -n '869,880p' file | cat -A`, which printed `$` at every line end — i.e. LF. The file is CRLF throughout (measured: 1117 CR = 1117 LF = 1117 CRLF). msys `sed` reads in text mode and drops the CRs, so `cat -A` faithfully rendered bytes that `sed` had already removed. The project's own rule (\"after any scripted edit, verify the BYTES\") was followed and still defeated, because the verification ran downstream of a text-mode filter.\r\n- **Third consequence of instance 1, and the worse half of it (hertz, measured independently; re-measured here).** The bad id does not only collide the arms — it begins with a DASH, so every artifact is named `-1.out`, `-2.err`, `-1.stop.out`. Measured in a throwaway dir: `sha256sum *.out` over such a population exits 1 with `unknown option -- 1` and hashes NOTHING (control: the same command over `a-1.out` alone exits 0 and hashes it); `grep -c x -1.out` exits 2 having measured nothing; `sha256sum ./*.out` is the repair. That is the LOUD form. The dangerous form is the one hertz's own detector took: it returned a clean EMPTY snapshot — \"0 artifacts altered\" — in the arm that was supposed to be red, because its glob handed the dashes to a tool that consumed t…\n- **Mechanism.** Both are a wrong answer with no error: a declaration whose dependency is satisfied by an unrelated variable that happens to exist, and a byte census whose bytes were filtered before they were counted. Neither is detectable from its own output — the id is well-formed, the `cat -A` dump is honest about what reached it.\r\n- **Fourth instance, in the very commit that recorded this entry (todlando, self-reported).** The amendment above was applied with a Python text-mode read (`open(p).read()`, universal newlines) and written back with `newline='\r\n'`. This register carried **two lone CR bytes** - `\r\n\r\n- **Instances 9-11` and `\r\n\r\n- **Addendum 2026-09-12 03:20Z` - present since at least `7cdcf5da`. Universal newlines translated each bare CR into a newline, so the commit silently rewrote two lines belonging to OTHER entries (net: 2 stray CRs removed, 2 blank lines added; markdown-harmless, still undeclared). Caught by reading the commit's own diff rather than trusting the insertion count: a one-bullet append that reports **5 insertions, 2 deletions** is telling you it touched something else. A text-mode read is a WRITE hazard, not only a measurement hazard - edit a file whose byte shape you have not measured in binary, and review the diff, never the intent.\r\n- **Rule.** (1) A declaration that depends on a name is its OWN statement; never share a `local` with the name it reads. (2) Derive an identity used as an artifact key ONLY after its parts are assigned, and guard it against its expected shape — a key that can go wrong silently overwrites evidence rather than failing. (3) A negative control for an id scheme must carry the caller's real variable environment: with the caller's global `n` absent, this defect reads as the harmless `-` and is easy to dismiss. (4) Read bytes with a byte reader — `python3` on the raw file, or `od`/`xxd` — never through msys `sed`, `grep`, or any text-mode filter; if a CR/LF count is the claim, count CR and LF bytes and state both.\r\n- **Kin:** [[IR-118]] (a complete-looking wrong answer from an instrument that succeeded), memory count-predicate-needs-its-own-positive-control, make-a-new-rig-red-on-purpose, scripted-edit-zero-match-refusal, render-not-read-pipefail, windows-firewall-census-clean-zeros.\r\n- **Ripe when:** now — (1) and (4) are habits, (2) is three lines in any rig. · **Size:** procedure.\r\n\r\n### IR-122 — the field rig's isolated-daemon stop cannot run from an spt-hosted session, so every run leaves a live daemon holding the subject exe inside the pool it just released\r\n\r\n- **Status:** OPEN, recurring. Instance 1 attempt 2 (`rig/arm2-driver-stdout.txt`: `RIG_DAEMON_STOP_REFUSED_OR_ERRORED — reported, not forced`). Instance 2 run `20260912T231404Z` under frozen r10 (`rig_daemon_stop_EXIT=3`, `cleanup-failures.txt`, `rig-daemon-stop.err`). Recorded by hertz 2026-09-12 23:50Z at doyle's direction; **this is a RIG defect, and any product-surface change requires a separate contract review.**\r\n…\n","startLine":6338,"lineNumbers":[6338,null,6340,null,6365,6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381,6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397,6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443,6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473,6474,6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488,6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516,6517,6518,6519,6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,6549,6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,6565,6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,6609,6610,6611,6612,6613,6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,6624,6625,6626,6627,6628,6629,6630,6631,6632,6633,6634,6635,6636,6637,6638,6639,6640,6641,6642,6643,6644,6645,6646,6647,6648,6649,6650,6651,6652,6653,6654,6655,6656,6657,6658,6659,6660,6661,6662,6663,6664,6665,6666,6667,6668,6669,6670,6671,6672,6673,6674,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,6714,6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731,6732,6733,6734,6735,6736,6737,6738,6739,6740,6741,6742,6743,6744,6745,6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761,6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,null,6781]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"middle","truncatedBy":"middle","totalLines":413,"totalBytes":59855,"outputLines":276,"outputBytes":40295,"maxBytes":40960,"headRange":{"start":1,"end":208},"tailRange":{"start":347,"end":413},"elidedLines":138,"elidedBytes":19582,"artifactId":"733","nextOffset":6772},"limits":{"columnTruncated":{"maxColumn":768}}}},"isError":false,"timestamp":1789483669340}}
{"type":"message","id":"e10fbab6","parentId":"f2a6601b","timestamp":"2026-09-15T14:47:49.347Z","message":{"role":"toolResult","toolCallId":"call_fKsgbmNm0t8sArrjynyjUTCz|fc_000c7cef03cac861016aa95a95283487d18c59a8cf5696216b","toolName":"read","content":[{"type":"text","text":"### IR-122 — the field rig's isolated-daemon stop cannot run from an spt-hosted session, so every run leaves a live daemon holding the subject exe inside the pool it just released\n\n- **Status:** OPEN, recurring. Instance 1 attempt 2 (`rig/arm2-driver-stdout.txt`: `RIG_DAEMON_STOP_REFUSED_OR_ERRORED — reported, not forced`). Instance 2 run `20260912T231404Z` under frozen r10 (`rig_daemon_stop_EXIT=3`, `cleanup-failures.txt`, `rig-daemon-stop.err`). Recorded by hertz 2026-09-12 23:50Z at doyle's direction; **this is a RIG defect, and any product-surface change requires a separate contract review.**\n- **The refusal.** `DAEMON_STOP_REFUSED: a broker-stopping command is never run by an spt endpoint ($OWL_SESSION_ID is set). ... No flag overrides this, --force included.` The guard keys on the CALLER'S SESSION ENV, so it fires identically no matter which rig step reaches it and no matter what `SPT_HOME` the command targets.\n- **Not a new fault, and not an accident.** `readiness-r4-as-read.md:107-109` already states it: v9 DELIBERATELY leaves `OWL_SESSION_ID` set, the refusal is expected to recur, and it is \"reported, never worked around silently.\" The rig chooses a loud known refusal over an unproven workaround — that choice is right, and it is the reason this entry is about the leftover, not about the refusal.\n- **What it actually costs.** Cleanup completes with `steps_failed=1` and the isolated daemon SURVIVES. Measured in instance 2: supervisor `daemon run --detached` and its child `daemon brain --generation 0 --start-reason cold`, born 331 ms apart, both executing `<worktree>/target/release/spt.exe`. They hold the SUBJECT exe open inside a pool `pool_release` has already returned, so the next build into that pool can fail on a locked `spt.exe` — a red belonging to neither lane. See memory [[live-agents-lock-target-debug-spt-exe]], [[shared-target-two-live-trees]].\n- **The counterfactual the refusal does NOT license (doyle, correcting hertz in this instance).** That the guard refused does not prove the isolated-target command *would have* stopped the resident broker. The guard reads the env, not the routing; establishing what the command would have reached needs routing evidence nobody has gathered. State the refusal, never the averted disaster.\n- **Disposal, and it is the same four-field procedure both times** (`readiness-r4-as-read.md:110-118`): identify on pid, `CreationDate`, exact `ExecutablePath` and `CommandLine` — a bare pid match is unsound because pid reuse on this box is measured, see [[pid-reuse-across-reboot]]. The supervisor must still equal `<isolated-home>/daemon.pid`, and the brain's parent must be that supervisor. Then a fresh authorization NAMING THE NEW PIDS (the prior one is pid-specific and spent), supervisor first so the brain cannot respawn, `Stop-Process -Id` alone — never a tree kill, an image-name kill, or any action against the resident node daemon, which is a DIFFERENT binary under `AppData\\Local\\spt-core\\bin\\`. Post-state ASSERTED, not announced, or it is [[watchdog-reports-a-kill-it-never-made]].\n- **Mechanism.** A cleanup step that is structurally unrunnable in the environment the rig always runs in. It cannot be fixed by retrying, it never fails loudly enough to block the run, and its residue lands in a shared build pool rather than in the run's own directory — so the cost is paid by whoever builds next, not by the run that caused it.\n- **Rule (scoped by doyle 2026-09-12 — a bare pid-file kill is NOT approved as sufficient).** A rig that starts a daemon owns stopping it by a route that works from the rig's own environment, and `<isolated-home>/daemon.pid` is the pid SOURCE, never the authorization. Any rig cleanup that terminates a process must, at the moment of acting: re-read creation time, exact `ExecutablePath`, `CommandLine` and isolated-home association FRESH; confirm the supervisor still equals the pid file and the brain's parent is that supervisor; stop SUPERVISOR-FIRST so no child respawns; and report failure EXPLICITLY rather than escalating scope. Any mismatch or unreadable identity STOPS the action. No PID-only automation and no product-guard bypass is approved. A cleanup step whose failure leaves state in a SHARED resource reports that residue as an identity the next consumer can act on — pid, path, command line — not merely as a failed step.\n- **Kin:** [[IR-42]] (pool enforcement speaks at the next build, not at claim time), memory rig-ownership-reap-only-your-own, reap-root-needs-authenticated-ancestry, e2e-leaked-daemons-shared-box, no-machinewide-killon-shared-runner.\n- **Ripe when:** before the next field run. NOT a one-line change: the stop route is small, but the identity re-verification, supervisor-first ordering and explicit failure reporting above are part of the fix and are what make it safe. · **Size:** small.\n\n### IR-123 — a helper that LOGS cannot also RETURN through stdout: `record` tees, so `face=$(face_report ...)` captures the log block and the acceptance gate can never pass\n\n- **Status:** OPEN, mechanism recorded 2026-09-13 (hertz, found by exercising the D2 successor; confirmed by doyle from a direct source read of frozen r10). **Frozen r10 is PRESERVED as-is**; the return channel is corrected in its successor only.\n- **Instance.** `record()` is `echo \"$1\" | tee -a \"$R/findings.txt\"` — it writes to the log AND to stdout, deliberately, so a live operator sees the run. `face_report()` calls `record` twice (a FACE_COUNTS line and a FACE= line) and then `echo`es the face as its return value. The single caller reads it as `setup_face=$(face_report \"$SETUP_OUT\" \"$SETUP_ERR\" \"SETUP\" bootstrap)`, so the captured value is **the whole tee'd log block with the face appended**, and `[ \"$setup_face\" != reconciled ]` is true no matter what the product printed. The Arm-B acceptance gate — rc 0 AND face reconciled AND pair written, all three required — is therefore **unpassable on the ACCEPTED path**.\n- **Why no rig run caught it.** The stub cases that reached this line were REFUSALS, whose expected outcome is exactly the branch the defect forces (exit 3, Arm B held). A gate that always refuses looks identical to a gate that correctly refused a refusal. The accepted path had no arm at all until the D2 successor's control ran one with `LAN_FIREWALL_RECONCILED`, exit 0 and a pair measured present — see memory `setup-suppresses-failing-arm`.\n- **The same shape, twice more, in the successor's own new code** (both caught by the same control, both mine): `D2_T1_VALID=$(d2_validate_at t1)` captured the validator's tee'd log ahead of its verdict; and `local point=\"$1\" doc=\"$R/d2-$point.json\"` rebuilt [[IR-121]]'s declaration-ordering defect, so three documents present on disk all read `NO_DOCUMENT`. The precedent for the fix was already in the same file: r10's own `handoff_request` comment records that `spec=$(handoff_request ...)` was broken by exactly this tee and was repaired by setting parent globals and returning nothing on stdout.\n- **Scope of what this does and does not invalidate (doyle).** It does NOT invalidate r10's observed product refusal: the named rule reported `[5, 20]` and positive reconciliation was independently absent. It DOES invalidate any claim that the frozen rig could have admitted a successful setup — that path was never reachable.\n- **Mechanism.** A dual-purpose channel: the same stream carries human-readable logging and a machine-read value, so any helper that logs before returning hands its caller both. It fails silently and in the direction that looks conservative (a gate that refuses), which is why it survives review and why refusal-only exercises confirm it.\n- **Rule.** A function that calls `record` (or any logger that writes to stdout) **returns nothing on stdout**: it sets a named global, or writes its value to a file the caller reads. Every acceptance gate is exercised on BOTH paths — an accepting arm with real positive evidence and a refusing arm — because an acceptance test alone cannot distinguish a working gate from one that accepts everything, and a refusal test alone cannot distinguish a working gate from one that refuses everything.\n- **Kin:** [[IR-121]] (a wrong value with no error, same file), [[IR-118]], memory setup-suppresses-failing-arm, make-a-new-rig-red-on-purpose, every-return-arm-is-a-copy, zero-match-filter-reads-as-absent.\n- **Ripe when:** now — the successor already carries the fix at its call sites and in its own helper; the register entry is the part that outlives this lane. · **Size:** procedure.\n\n### IR-124 — a cleanup that runs `serve lan --stop` UNCONDITIONALLY creates the daemon it exists to remove, when the setup it is cleaning up after never ran\n\n- **Status:** OPEN, measured once in the field. D2 field run `20260913T041410Z`, driver `2e3aec1b`, recorded by hertz 2026-09-13 at doyle's direction. Archive `.spt/preserved/hertz-fp-driver-review/d2/field-run-20260913T041410Z/` (72 files, manifest `defa5d29…`). **This is a RIG defect. It is mine — I wrote the driver — and doyle's admission review missed the unconditional stop path as well; both are recorded because a review that misses a path is part of the mechanism, not an aside.**\n- **Instance.** The elevated setup was **DECLINED and NOT STARTED** by liam at 04:18:55Z — measured, unambiguous, and the right call: his leg was ready at 04:18:35Z against a hard 04:19:10Z expiry and he refused rather than race the teardown. Nothing ran, nothing mutated. The driver then entered cleanup and executed its own unconditional `env SPT_INSTALL_NO_FIREWALL=1 SPT_HOME=<isolated-home> <exe> serve lan --stop`, which dispatched through the daemon (`ensure_running`, `serveverb.rs:191`) and **CREATED** a supervisor (`daemon run --detached`, Windows PID 45944, `04:19:18.0312050Z`) and a brain (`daemon brain --generation 0 --start-reason cold`, PID 22524, `04:19:19.7696380Z`, parent 45944). `fp-home-d2`, measured ABSENT at the 04:13:58Z at-launch recheck, existed with `daemon.pid`, `brain.ready` and a full tree by 04:19:18Z.\n- **Why the hold could not stop it.** doyle held the elevated teardown for exactly this reason and liam held all commands. But this stop is **internal to the running driver**, not a handoff, so no authorization gate reached it: the only levers were killing the driver or editing a running script, and both are forbidden. **A guard that only governs dispatched work does not govern a step the subject performs itself.**\n- **The pre-dispatch markers named the mechanism and did not prevent it.** `daemon_may_run — serve dispatches through the daemon (ensure_running, serveverb.rs:191); the elevated leg may leave one running` was set BEFORE the setup was requested. The driver correctly refused to infer absence from its own expectation — and then triggered the very mechanism the marker warned about, from the cleanup path, on the branch where the warning did not apply.\n- **Three things kept apart, because collapsing any two misstates the run.** (1) Liam's testimony: NOT_STARTED, no mutation — still true, he created none of it. (2) The driver's conservative verdict: `CLEANUP=PENDING`, `residual_state=UNREADABLE`, `residue=UNMEASURED` — an honest refusal to claim clean, not a contradiction of liam. (3) An **actually observed** residual, created by the driver itself. That third thing is a measurement; the first two are testimony and abstention.\n- **Mechanism.** A teardown verb that is also a *start* verb. `serve lan --stop` must reach the daemon to ask it to stop, so invoking it when no daemon exists starts one. Cleanup paths are written for the case where setup succeeded, and are reached on every path including the ones where setup never happened; the branch nobody exercises is the branch where cleanup has nothing to clean.\n- **Rule.** A cleanup step whose command can CREATE the resource it removes must be **conditional on evidence that the resource exists** — not on the state markers, which say \"may exist\" by design, and not on the fact that cleanup was entered. Where the existence check is itself unavailable, the step is SKIPPED and reported as skipped, because an unnecessary teardown that spawns is strictly worse than a labelled gap. Exercise every cleanup path from the **setup-never-ran** state, not only from the setup-succeeded state.\n- **Kin:** [[IR-122]] (the other half: the stop that *cannot* run leaves a daemon; this is the stop that *should not* run and makes one), memory setup-suppresses-failing-arm, gate-against-documented-design, remedy-must-run-from-refusal-state.\n- **Ripe when:** before any repeat field run — a repeat under this driver reproduces the residue. · **Size:** small.\n\n### IR-125 — the driver's own executable sweep reported ZERO processes on the pinned exe while `Win32_Process` showed TWO, at the same instant\n\n- **Status:** OPEN, measured in D2 field run `20260913T041410Z` (hertz, 2026-09-13). **A FALSE-NEGATIVE SWEEP, not a false CLEAR** (doyle's classification, and the distinction is load-bearing): the ledger's actual verdict was `residual_state=UNREADABLE` / `CLEANUP=PENDING`, which was correct, and the sweep line is explicitly labelled evidence-only in the driver's own output.\n- **Instance.** `SUBJECT_EXE_PROBE=OK running_the_pinned_executable=0 enum_total=618` — the probe enumerated 618 processes and concluded none was running the pinned executable. A `Win32_Process` read moments later returned **two**, both with `ExecutablePath` exactly `…\\.worktrees\\304-w2-repr\\target\\release\\spt.exe`: PIDs 45944 and 22524. An independent sweep by path, not by pid, agreed: `count=2`.\n- **Why it matters despite being labelled evidence-only.** The line reads as a clean box to anyone skimming, and it is the only line in the run that speaks to \"is anything of ours still running\" in plain terms. It was contradicted only because a native read was performed for a different reason. Had the ledger's verdict logic depended on it, this is a false CLEAR.\n- **Candidate cause, NOT diagnosed** (deferred by doyle until cleanup was complete, and still open): the probe's raw path comparison. The Win32 `ExecutablePath` is backslashed Windows form; the driver's pinned `$EXE` is forward-slashed msys-friendly form. A literal comparison between those two spellings of the same file fails for every process. **Unconfirmed** — it is a candidate because it fits, not because it has been measured.\n- **Mechanism.** A predicate that can only ever return \"no\" reports a clean zero over a large, healthy-looking enumeration. `enum_total=618` is what makes it convincing: the instrument demonstrably ran and demonstrably saw the machine, and still could not see the thing it was looking for. Same family as the two other instrument-versus-reality mismatches in this lane, and all three were invisible to stubs.\n- **Rule.** A sweep that reports zero carries its own **positive control** — in the same run, the same predicate must find something known present, or the zero is UNMEASURED rather than absent. Where a predicate compares paths across the msys/Windows boundary, normalise both sides and prove the normalisation on a known-matching pair; never compare two spellings of a path and call a non-match an absence.\n- **Kin:** memory count-predicate-needs-its-own-positive-control, zero-match-filter-reads-as-absent, windows-firewall-census-clean-zeros, verdict-from-probe-competence, [[IR-118]].\n- **Ripe when:** with IR-124, before a repeat field run. · **Size:** small.\n\n### IR-126 — the experimental budget CONTAINED its own read-only preflight, leaving 128 s of a 300 s window for the elevated leg, and the leg was correctly declined\n\n- **Status:** OPEN, measured in D2 field run `20260913T041410Z` (hertz, 2026-09-13). Boundary NOT moved for that run — doyle refused the change mid-flight and was right to; this entry is the scheduling review he asked to be preserved.\n- **Measured, from the run's own timestamps.** Run start `04:14:10Z` · pre-setup absence census `04:16:23Z` · handoff request written `04:17:02Z`. So **172 s of the 300 s experimental budget went to in-budget read-only preflight** — CI axis queried by name across five statuses, ancestry census, six-instrument hashing, subject identity, 5470 guard baseline, pre-setup absence census — and the driver printed the remainder itself: `HANDOFF_WAIT bounded to 128s`.\n- **The consequence, and it is not hypothetical.** Liam's leg script was ready at `04:18:35Z`. Setup alone had measured ~9 s, plus four PowerShell stamps, plus a t1 capture of unmeasured duration, against 35 s of remaining clock. He DECLINED without mutation, which was the correct call and the one the instruction asked for. **The window was consumed before the work it existed for could start.**\n- **Two overruns recorded beside it, as observations and not as permissions.** Experimental activity ended at **306 s of the 300 s budget** (the deadline exits through the EXIT trap, so cleanup is never skipped, but the boundary was crossed). The driver was still running after its 180 s cleanup reporting bound had elapsed; it exited by `04:23:54Z`. Neither overrun was authorised, taken as an extension, or used to do more work.\n- **Mechanism.** A budget defined from process start, over a phase order that puts every read-only admission check inside it, gives the elevated leg whatever is left rather than what it needs. The preflight cost is not waste — those checks are why the run was admissible — but charging them to the same clock makes the window's usable size an accident of how slow the host's firewall enumeration is that minute.\n- **Rule.** Bound the ELEVATED LEG on its own clock, sized from its measured duration, and start it when the leg is dispatched. Admission checks get a separate bound. A driver that cannot guarantee a usable handoff window should REFUSE TO DISPATCH rather than dispatch a leg that cannot finish — an operator declining at the deadline is the correct outcome of a wrong window, not a failure of the operator.\n- **Kin:** [[IR-122]], memory your-cadence-can-be-the-blocker, reap-step-duration-is-not-the-window, twohost-run-window-discipline.\n- **Ripe when:** with IR-124 — a repeat field run under the current budget shape reproduces the squeeze. · **Size:** small.\n\n### IR-127 — a nested value-type assignment can leave the native job limit unset while the instrument logs the requested flag and a successful setter\n\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\n- **Instance.** The containment probe assigned `$info.BasicLimitInformation.LimitFlags = 0x2000`, logged the requested KILL_ON_JOB_CLOSE flag and `SetInformationJobObject=True`, read both owned processes as job members, closed the handle, and found both still alive. The nested field is a struct: PowerShell changed a copy, not the value subsequently marshalled. The offline discriminator measured `nested_assignment_flags=0`; modifying the nested value and assigning the whole value back measured `whole_value_assignment_flags=8192`.\n- **Correction and evidence.** The corrected probe assigns the whole nested value, calls `QueryInformationJobObject`, and refuses unless the kernel's flags equal the requested flags. Readback `0x2000` then preceded both members being measured GONE after close. Initial invalid arm and corrected measurement are preserved separately under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/` (`M3/` and `instrument-repair-20260913T104354Z/M3/`); the latter's `results.txt` carries the offline discriminator.\n- **Rule.** Mutating a nested interop value requires assigning that value back to its owner. Successful native setters establish only that the submitted value was accepted: read the effective configuration back and compare it before granting the operation authority. Requested flags are not observed flags.\n- **Kin:** [[IR-116]] (a successful call is not a post-state), [[IR-118]] (a complete-looking wrong answer).\n- **Ripe when:** any PowerShell/native configuration probe is authored or changed. **Size:** whole-value assignment plus checked native readback; retain the positive and negative discriminator.\n\n[…47ln elided…]\n- **Evidence.** Fourteen discriminator cases cover pre-rig exemption, native image resolution, known rig refusal, disappearance versus denied/failed queries, dead-provider control, unknown/equal/precision-overlap births and PID reuse. The final successor passed all fourteen. A read-only live run admitted **17** census hits, including 52860 as `PREDATES_RIG`; actual native self controls measured a **5-tick** CIM/native birth delta, admitted the other-image case and refused the same-image case. Proof: `W8TQ3MZC-census-controls-final.json` and `W8TQ3MZC-census-live-result.json` beside the receipt. Neither proof invoked the product or mutated the rig.\n- **Rule.** Admission asks whether an observed identity can belong to the owned rig, not whether the caller can read every process on the host. Preserve query failure, confirmed absence and replacement identity as different outcomes, with pid and birth in the receipt. Re-pin changed instruments; preserve failed windows and obtain a fresh grant rather than extending their clocks.\n- **Kin:** [[IR-107]] (live operational context enters the rig), [[IR-129]] (creation-time type/precision), [[IR-125]] (known-present control for absence), [[IR-15]] (identity-aware liveness).\n- **Ripe when:** a rig shares a host with elevated perches or short-lived CLI traffic. **Size:** birth-aware census and retained native identity probe, with fail-closed boundary controls.\n\n### IR-133 — a live capture cannot be read with read-only sharing, and daemon stderr belongs to the owned home\n\n- **Status:** Corrected in the r9 rig instrument; genuine fifth-window promotion completed with exit **0**, owned shutdown and final provenance. The subsequent field attempt failed its separate setup-handoff deadline, not this promotion read. Fourth #297 preparation measured by hertz on 2026-09-14; sharing failure localized by doyle in `R2VK8FQN`, run-identity binding ruled in `ANR522S5`, successor accepted in `GV3R6QUV`.\n- **Instance.** Fourteen admission leaves and genuine staging passed. The candidate applied daemonlessly, transitioned `applied-pending` → `applied`, brought up broker **14704** and brain **45220**, published the pinned generation-zero readiness record and emitted `BRAIN_PROMOTED` before the instrument stopped its owned job. The instrument returned only `OWNED_PROMOTION_READINESS_FAILED`. Six provisioning/promotion native jobs ended `CONFIRMED_GONE`, active counts zero; all nineteen signing-private files were absent. No field, GO or D3 occurred. Original receipt: `.spt/preserved/hertz-fp-driver-review/d2/W8TQ3MZC-FINAL-REFUSAL.json`.\n- **Mechanism.** The loop used `File.ReadAllText` on a capture held open for **Write**, with **Read** sharing, by the run-scoped launcher. Windows checks sharing in both directions: the new reader's default **Read** sharing excludes the existing writer, causing `IOException`, `0x80070020`. A completed step hid this defect because its writer had already closed. Changing only the writer's sharing does not repair the reader.\n- **Wrong source behind the exception.** The launcher's stderr capture was zero bytes; the daemon redirects stderr to `SPT_HOME/logs/daemon.stderr.log`. Reading the empty capture with compatible sharing would merely reach the later marker timeout. Read the actual owned-home log with `FileStream(Open, Read, FileShare.ReadWrite | FileShare.Delete)`, matching the existing native launcher's `ReadText` pattern; release each read handle before the next poll.\n- **Run binding.** A promotion marker counts only after the exact brain header naming the measured membership PID and readiness generation, and before another process header. Markers before that header, without it, or under another PID/generation refuse. A rolled `.1` can contribute only when absent before this owned launch and appearing during it, with the same header binding; preexisting backups cannot prove this run.\n- **Failure evidence.** Attach the instrument's constant assertion name and call-site line to its exception. Before cleanup can replace the active error, retain that name, source line, exception type and HResult. Non-assert exceptions have a null assertion name. Never serialize exception messages or environment values.\n- **Qualification.** Thirteen controls passed against `provision-promote-R2VK8FQN.ps1`: a live-held writer reproduces `0x80070020` with `ReadAllText`, the shared reader returns its exact bytes while the writer remains open, header/PID/generation/ordering and rolled-history boundaries refuse stale evidence, the actual rollback guard still refuses, and diagnostics omit a message canary. Proof: `R2VK8FQN-live-held-controls/result.json` beneath the receipt directory. No product invocations, rig mutations or fleet terminations.\n- **Live verification.** `provision-R2VK8FQN/promotion-complete.json` records `PROMOTION_COMPLETE`; the supervised promotion exited **0** after **12.9 s**. The real candidate passed the shared-log, PID/generation marker, final membership, durable-state and owned-shutdown checks. Its later field ledger remains a separate failed observation contract; successful provisioning does not turn that ledger green.\n- **Kin:** [[IR-132]] (instrument census refusal), [[IR-130]] and [[IR-131]] (phase labels lose the failing predicate). **Ripe when:** polling any live writer or accepting logs as run-specific evidence.\n\n### IR-134 — request latency consumes the elevated capture's execution budget, then a late terminal receipt leaves completed work unmeasured\n\n- **Status:** Instrument correction qualified without a sixth field window. Doyle accepted the execution-clock repair in principle under `HHDKCRH5`, then identified its still-insufficient receipt budget; the derived-window successor follows ruling `P9RLK4VU` and accepted arithmetic `KZG4IN37`. Candidate/packet/nonce/driver/runner repinning remains one future amendment, separate from field authorization. Fifth #297 field run `20260914T063552Z` remains failed and immutable. Its candidate's independent **PRODUCT RED** finding (`M5XKQ2DN`) is unchanged.\n- **Measured sequence.** Setup request `06:41:26Z`, elevated setup `06:43:18Z`–`06:43:24Z`, refused capture launcher `06:43:25Z`–`06:43:26Z`, receipt about `06:43:27Z`. The driver had written the capture deadline from request time: 112 seconds of handoff delay left the launcher's `deadline - now - 5` allocation at **−4 seconds**. No native t1 capture ran. The handoff expired before the receipt; cleanup reread its nonce and exit but retained the earlier `timestamp_order=UNMEASURED`, withholding mutation despite subsequently available terminal stamps.\n- **Clock correction.** The executor initializes `setup-start.utc`, `elevated-leg-start.epoch` and `d2-t1.deadline` immediately before `run_exactly`, from one UTC observation, with **CreateNew** writes. The independent allocation is **120 seconds**: the existing 90-second capture ceiling, 9 measured seconds around a refused capture, 5-second termination reserve and 16-second margin. Nine seconds is not a measurement of a successful capture. PREPARE initializes nothing; notification latency consumes only the separately bounded handoff. No preparation or activity window is reset or extended.\n- **Terminal evidence correction.** On handoff expiry, cleanup makes one final nonce/exit observation and, if terminal, rereads the six stamps before deciding whether completion is proven. A late observation preserves `handoff_wait=EXPIRED` and the original timeout exit separately from `setup_terminal_exit`; it never resumes activity or treats lateness as timely acceptance. Missing, duplicate or wrong nonce evidence and missing or reversed stamps remain unproven. An exceeded leg clock refuses the capture contract independently of terminal completion.\n- **No-field proof.** `.spt/preserved/hertz-fp-driver-review/d2/AQ23KKNI-controls/` preserves the actual extracted predecessor/successor predicates, emitted PowerShell initializer, nine receipt/product controls, five clock/ledger controls and clock results. The predecessor retained UNMEASURED after receipt publication; the successor recovered ordered completion without overwriting timeout. The actual initializer refused a second initialization without changing any clock bytes. With the measured 112-second notification delay and capture at leg-start +7, the old allocation is −4 seconds and the new allocation is 90 seconds. No product, firewall, signing or field operation was invoked.\n- **The outer-clock blocker, not fixed by the inner clock.** A receipt follows execution: **112 + 120 = 232 seconds** cannot fit the retained 120-second setup handoff. Keeping a 300-second activity window and refusing every GO would be a correct refusal of the wrong shape, not an executable field design. `P9RLK4VU` therefore re-derives future activity as **630 seconds**: pre-dispatch **74** (54 observed +20 margin), setup handoff **240** (112 latency +120 leg +8 margin), post-receipt probes **200**, t2 **100**, final transition **16**. Only setup supersedes the prior 120-second handoff cap; other handoffs retain it.\n- **Measured basis and explicit allowance.** The fifth timeline records portfields calls at up to **45 seconds**, census **46 seconds**, and t3 **25 seconds**; the earlier `20260913T041410Z` capture also took 25 seconds. Two analogous portfields calls plus census give **136 seconds**; another **64 seconds** is a labelled allowance for identity capture, D1 and bookkeeping, not a claimed complete post-receipt measurement. T2 receives a **90-second native ceiling**, **5-second launcher reporting reserve** and **5-second shell/reporting margin**. The post-receipt probe deadline cannot spend t2's allocation; t2 cannot spend the final transition reserve.\n- **Derived-window controls.** `P9RLK4VU-controls/result.json` records **16 passing controls**, executing extracted real Bash predicates and the wait loop against a virtual wall clock. The complete 630-second window and the measured 54-second pre-dispatch cost pass; 555 seconds remaining fails against the 556-second dispatch requirement, while 556 fits. The actual gate refuses before GO/mutation markers. A receipt after 112-second latency plus 120-second execution fits the new setup allowance; PREPARE and cleanup retain their 120-second caps. Published request and phase deadlines still truncate waits. Preparation remains **600 seconds** and cleanup remains **180 seconds including its 30-second ledger reserve**; an observation deadline cannot override cleanup. No product or field operation was executed.\n- **Separate product finding.** Candidate `b8482445` logged one `verify-query` completed at **2650 ms**, followed by a second pre-write snapshot killed at **3027 ms** under its **3000 ms** budget; no reconcile-write ran. The budget **starts before spawn and includes output collection** (`run_ps_inner`, source timing supplied by doyle in `IRXYIJHS`); spawn is not outside this clock. The successor ledger records this query kill separately from handoff/capture failure. Fifth-window cleanup was subsequently closed on existing measurements as **NOTHING_TO_REMOVE**; its original PENDING ledger was not rewritten.\n- **Kin:** [[IR-126]] (execution receives leftover scheduling time), [[IR-124]] (cleanup must not race unproven setup). **Rule:** measure execution from execution, preserve timeout and late completion as separate facts, and do not let an instrumentation repair erase a product failure.\n\n### IR-135 — checker pin and runner installation can disagree, and the repair path disguises that version mismatch as an authentication failure\n\n- **Status:** CI precheck remedy implemented in the IR-135 lane; workflow execution awaits integration. Measured by doyle in S4 golden `34946493637`, 2026-09-15; filed by hertz from `3HHHPWCR`. The immediate box mismatch was repaired by hand-install.\n- **Instance and mechanism.** The #304 candidate carried `71caedd4`, setting `WANT=0.4.1` in `golden.yml`/`ci.yml`, while kitsubito's `~/.local/bin/traceable-reqs` was **0.2.0**. The install step's mismatch path attempted a private clone without a provisioned `TRACEABLE_REQS_TOKEN` and exited **128 before any check**. The visible failure named authentication, not the wanted and installed versions. A checked-in pin is not evidence that the runner can supply it; the fallback requires a second, independently missing prerequisite.\n- **Implemented remedy (QD54OM7S).** Both workflows run an explicit pin/runner precheck and use `.github/ci/traceable-reqs.sh` as the single pin/install owner. It reports the actual version and native version exit; matching requires literal equality and exit zero. A mismatch without `TRACEABLE_REQS_TOKEN` refuses before clone/build, naming the version disagreement and missing credential separately. With a token present, source repair remains available and native clone failure is preserved; token presence never claims access. The installed version is checked before coverage. On kitsubito, eight isolated shell controls passed: matching precheck/install without a token, stale/missing/failing/lookalike versions refused, authenticated repair admission, and clone exit128 retained. The predecessor failed the stale/no-token discriminator with128; the successor refused with1 and both diagnostics. A separate smoke used kitsubito's real0.4.1 binary through both entry points without a token, exit0. No live credential was provisioned or private-source build exercised. Contract and reproduction command: `docs/TRACEABILITY.md` §CI checker admission and installation. PAT provisioning remains the operator's decision, banked since2026-07-30.\n- **Kin:** [[IR-104]] (the checker version changes what counts as evidence), [[IR-109]] (the #304 pin is already live). **Ripe when:** the next checker pin or golden-intake/install-step change. **Size:** a version diagnostic and intake assertion; credential provisioning is separate operator work.\n\n### IR-136 — a broker bound under the seed socket's name is not seed control, so a URL-minting rig can omit the very listener contract the product queries\n\n- **Status:** Instance fixed in S5 **`ddd7fc7f070667524578c282894dd44a2e36062f`**, test-only atop S4; S5 golden34957614641 passed, including both twohost roles. Shared fixture-composition remedy implemented and Linux-verified in the IR-136 lane. Origin: doyle's S4 golden `34946493637` twohost helper red, 2026-09-15.\n- **Mechanism.** Role B hosted broker IPC under an invented name, with neither `seedmap::serve_seed_control` nor a docs listener. `REQ-WEB-URL-BOUND-PORT` requires `serve_for` to ask the canonical seed-control plane for `DocsStatus` before publishing a URL; the missing plane returned `DOCS_PORT_DISCOVERY_FAILED: Connection refused (os error 111)`. Merely renaming a Broker to `seed_socket_name()` does not provide that protocol: `serve_request` is dispatched by seed control, not Broker. The docs-server fixture had already encountered the same trap. The last green twohost run predated this bound-port contract.\n- **Discriminator and scope.** Todlando's unchanged-S4 Linux fixture failed at the exact discovery seam without seed control/listener (**native 101**) and returned `Registered` at the actual bound port **33319** when those fixtures were added (**native 0**); both arms retained the invented B broker name. Evidence: `.spt/preserved/304-web-helper-rca/linux/`. S5 gives B distinct canonical broker/seed sockets, real seed control, a broker-backed ephemeral docs listener, and a discovered-port equality precondition. Helper expectations stay unchanged. A's helper cell relays B's returned URL and does not query its own DocsStatus; its existing broker-on-seed-name path is not this failure. The seven unopted-in Windows passes do not exercise the role-gated twohost bodies.\n<!-- [doc->REQ-SERVING-FIXTURE-CONTROL-PLANE] -->\n- **Shared remedy (P2Y2GWUP).** `crates/spt-daemon/tests/support/serving.rs` provides `ServingFixture`, included by both `docs_server_e2e` and `twohost_web` rather than exported as product surface. `start` composes the distinct canonical broker and real seed control, waits for seed readiness, binds broker-backed docs on port0, and asserts that seed-control `DocsStatus` returns that actual port. The caller supplies its private home, journal and optional NetHost; socket spelling is no longer a caller choice. `stop` stops and joins both IPC accept loops. The docs listener remains process-lifetime under the existing production interface, so tests require process-per-test isolation and one broker-backed listener per process.\n- **Negative-state coverage retained.** The docs fixture uses the separate `control` stage only to distinguish absent control (offline fallback permitted) from running control without a listener (fallback refused); its normal serving case uses the same complete constructor as role B. Role A's seed-named proxy Broker and the standalone docs-less listener remain intentionally separate: neither is the owner's URL-minting control plane. No default/configured port substitutes for discovery, and no production protocol changes.\n- **Shared-fixture proof (2026-09-15).** Kitsubito, private tree/target, jobs2: targeted clippy with `-D warnings` **0**; nextest, both migrated binaries, one test thread and zero retries **0**. All **3 docs cases** exercised their real bodies: absent-vs-unbound discovery, HTTP published-surface/security checks through the complete fixture, and the standalone docs-less pointer. The other **7 twohost cases** returned through their unopted role gate; these are compile coverage, not a new cross-host execution claim. Traceable0.4.1: **920complete/0findings**. Raw exits/output/hashes: `.spt/preserved/hertz-ir136-fixture/linux-v2/`; the initial wrapper PATH failure started no cargo and is preserved separately.\n- **Ripe when:** another URL-producing fixture is added. Use the shared complete constructor rather than rebuilding its three planes independently; use the partial stage only when missing-listener behavior is the test subject.\n\n### IR-137 — a redirected Start-Process child can share the tool call's console lifetime and die when that call returns\n\n- **Status:** RETIRED, 2026-09-15, doyle ruling `YPLFG3CG`: **no tracked callsite; discipline recorded + receipt**. This closes a Windows ad-hoc rig-craft item, not a CI or candidate defect; no helper or product change.\n- **Mechanism and rule.** `Start-Process` with redirected output from a PowerShell tool call was observed to end with **`STATUS_CONTROL_C_EXIT`** when the tool call ended: a returned child PID did not establish detachment. The reported detached form uses a **hidden window without redirects**. Where a child must outlive the call, qualify its survival after the caller returns and give it a durable output path of its own; do not treat process creation or a hidden window alone as lifetime evidence.\n- **Origin clarified (YPLFG3CG).** Claude Code PowerShell tool host, 2026-09-15T07:17Z, #304 S3 Windows attempt-2 launch A: redirected `Start-Process pwsh` PID47560; `rustc` exited `0xc000013a` seconds after the tool returned, driver receipt contained only its start line and no refusal file. The same driver relaunched with `-WindowStyle Hidden -PassThru` and no redirects (PID37536) ran25minutes to exit0. There is no tracked failing launcher to repair; the existing tracked g6 launcher already uses the reported good shape.\n- **Discipline and receipt.** [Windows ad-hoc rig launch discipline](GOLDEN-CI.md#windows-ad-hoc-rigs-that-outlive-the-tool-call) states the shape, child-owned durable output and post-return PID/birth/output qualification. Preserved harmless-child receipt: `.spt/preserved/hertz-ir137-caller-return/receipt.json`, SHA256 **`e1c9b207544e6313eac5421ebb692786ec18b3a165756b451bff3a704899b178`**. Both valid arms survived under **OMP**, wrote post-return events and exited0; an initial observer-handshake timeout is excluded. All3probe children ended and native handles closed. This does not reproduce the **Claude Code** failure; the host boundary stays explicit. Reopen only for a newly owned callsite or contrary evidence, not to build an unused helper.\n\n[Showing lines 1-68 and 116-169 of 169; 47 middle lines (13.5KB) elided. Use :6938 to continue. Read artifact://732 for full output]"}],"details":{"truncation":{"content":"### IR-122 — the field rig's isolated-daemon stop cannot run from an spt-hosted session, so every run leaves a live daemon holding the subject exe inside the pool it just released\r\n\r\n- **Status:** OPEN, recurring. Instance 1 attempt 2 (`rig/arm2-driver-stdout.txt`: `RIG_DAEMON_STOP_REFUSED_OR_ERRORED — reported, not forced`). Instance 2 run `20260912T231404Z` under frozen r10 (`rig_daemon_stop_EXIT=3`, `cleanup-failures.txt`, `rig-daemon-stop.err`). Recorded by hertz 2026-09-12 23:50Z at doyle's direction; **this is a RIG defect, and any product-surface change requires a separate contract review.**\r\n- **The refusal.** `DAEMON_STOP_REFUSED: a broker-stopping command is never run by an spt endpoint ($OWL_SESSION_ID is set). ... No flag overrides this, --force included.` The guard keys on the CALLER'S SESSION ENV, so it fires identically no matter which rig step reaches it and no matter what `SPT_HOME` the command targets.\r\n- **Not a new fault, and not an accident.** `readiness-r4-as-read.md:107-109` already states it: v9 DELIBERATELY leaves `OWL_SESSION_ID` set, the refusal is expected to recur, and it is \"reported, never worked around silently.\" The rig chooses a loud known refusal over an unproven workaround — that choice is right, and it is the reason this entry is about the leftover, not about the refusal.\r\n- **What it actually costs.** Cleanup completes with `steps_failed=1` and the isolated daemon SURVIVES. Measured in instance 2: supervisor `daemon run --detached` and its child `daemon brain --generation 0 --start-reason cold`, born 331 ms apart, both executing `<worktree>/target/release/spt.exe`. They hold the SUBJECT exe open inside a pool `pool_release` has already returned, so the next build into that pool can fail on a locked `spt.exe` — a red belonging to neither lane. See memory [[live-agents-lock-target-debug-spt-exe]], [[shared-target-two-live-trees]].\r\n- **The counterfactual the refusal does NOT license (doyle, correcting hertz in this instance).** That the guard refused does not prove the isolated-target command *would have* stopped the resident broker. The guard reads the env, not the routing; establishing what the command would have reached needs routing evidence nobody has gathered. State the refusal, never the averted disaster.\r\n- **Disposal, and it is the same four-field procedure both times** (`readiness-r4-as-read.md:110-118`): identify on pid, `CreationDate`, exact `ExecutablePath` and `CommandLine` — a bare pid match is unsound because pid reuse on this box is measured, see [[pid-reuse-across-reboot]]. The supervisor must still equal `<isolated-home>/daemon.pid`, and the brain's parent must be that supervisor. Then a fresh authorization NAMING THE NEW PIDS (the prior one is pid-specific and spent), supervisor first so the brain cannot respawn, `Stop-Process -Id` alone — never a tree kill, an image-name kill, or any action against the resident node daemon, which is a DIFFERENT binary under `AppData\\Local\\spt-core\\bin\\`. Post-state ASSERTED, not announced, or it is [[watchdog-reports-a-kill-it-never-made]].\r\n- **Mechanism.** A cleanup step that is structurally unrunnable in the environment the rig always runs in. It cannot be fixed by retrying, it never fails loudly enough to block the run, and its residue lands in a shared build pool rather than in the run's own directory — so the cost is paid by whoever builds next, not by the run that caused it.\r\n- **Rule (scoped by doyle 2026-09-12 — a bare pid-file kill is NOT approved as sufficient).** A rig that starts a daemon owns stopping it by a route that works from the rig's own environment, and `<isolated-home>/daemon.pid` is the pid SOURCE, never the authorization. Any rig cleanup that terminates a process must, at the moment of acting: re-read creation time, exact `ExecutablePath`, `CommandLine` and isolated-home association FRESH; confirm the supervisor still equals the pid file and the brain's parent is that supervisor; stop SUPERVISOR-FIRST so no child respawns; and report failure EXPLICITLY rather than escalating scope. Any mismatch or unreadable identity STOPS the action. No PID-only automation and no product-guard bypass is approved. A cleanup step whose failure leaves state in a SHARED resource reports that residue as an identity the next consumer can act on — pid, path, command line — not merely as a failed step.\r\n- **Kin:** [[IR-42]] (pool enforcement speaks at the next build, not at claim time), memory rig-ownership-reap-only-your-own, reap-root-needs-authenticated-ancestry, e2e-leaked-daemons-shared-box, no-machinewide-killon-shared-runner.\r\n- **Ripe when:** before the next field run. NOT a one-line change: the stop route is small, but the identity re-verification, supervisor-first ordering and explicit failure reporting above are part of the fix and are what make it safe. · **Size:** small.\r\n\r\n### IR-123 — a helper that LOGS cannot also RETURN through stdout: `record` tees, so `face=$(face_report ...)` captures the log block and the acceptance gate can never pass\r\n\r\n- **Status:** OPEN, mechanism recorded 2026-09-13 (hertz, found by exercising the D2 successor; confirmed by doyle from a direct source read of frozen r10). **Frozen r10 is PRESERVED as-is**; the return channel is corrected in its successor only.\r\n- **Instance.** `record()` is `echo \"$1\" | tee -a \"$R/findings.txt\"` — it writes to the log AND to stdout, deliberately, so a live operator sees the run. `face_report()` calls `record` twice (a FACE_COUNTS line and a FACE= line) and then `echo`es the face as its return value. The single caller reads it as `setup_face=$(face_report \"$SETUP_OUT\" \"$SETUP_ERR\" \"SETUP\" bootstrap)`, so the captured value is **the whole tee'd log block with the face appended**, and `[ \"$setup_face\" != reconciled ]` is true no matter what the product printed. The Arm-B acceptance gate — rc 0 AND face reconciled AND pair written, all three required — is therefore **unpassable on the ACCEPTED path**.\r\n- **Why no rig run caught it.** The stub cases that reached this line were REFUSALS, whose expected outcome is exactly the branch the defect forces (exit 3, Arm B held). A gate that always refuses looks identical to a gate that correctly refused a refusal. The accepted path had no arm at all until the D2 successor's control ran one with `LAN_FIREWALL_RECONCILED`, exit 0 and a pair measured present — see memory `setup-suppresses-failing-arm`.\r\n- **The same shape, twice more, in the successor's own new code** (both caught by the same control, both mine): `D2_T1_VALID=$(d2_validate_at t1)` captured the validator's tee'd log ahead of its verdict; and `local point=\"$1\" doc=\"$R/d2-$point.json\"` rebuilt [[IR-121]]'s declaration-ordering defect, so three documents present on disk all read `NO_DOCUMENT`. The precedent for the fix was already in the same file: r10's own `handoff_request` comment records that `spec=$(handoff_request ...)` was broken by exactly this tee and was repaired by setting parent globals and returning nothing on stdout.\r\n- **Scope of what this does and does not invalidate (doyle).** It does NOT invalidate r10's observed product refusal: the named rule reported `[5, 20]` and positive reconciliation was independently absent. It DOES invalidate any claim that the frozen rig could have admitted a successful setup — that path was never reachable.\r\n- **Mechanism.** A dual-purpose channel: the same stream carries human-readable logging and a machine-read value, so any helper that logs before returning hands its caller both. It fails silently and in the direction that looks conservative (a gate that refuses), which is why it survives review and why refusal-only exercises confirm it.\r\n- **Rule.** A function that calls `record` (or any logger that writes to stdout) **returns nothing on stdout**: it sets a named global, or writes its value to a file the caller reads. Every acceptance gate is exercised on BOTH paths — an accepting arm with real positive evidence and a refusing arm — because an acceptance test alone cannot distinguish a working gate from one that accepts everything, and a refusal test alone cannot distinguish a working gate from one that refuses everything.\r\n- **Kin:** [[IR-121]] (a wrong value with no error, same file), [[IR-118]], memory setup-suppresses-failing-arm, make-a-new-rig-red-on-purpose, every-return-arm-is-a-copy, zero-match-filter-reads-as-absent.\r\n- **Ripe when:** now — the successor already carries the fix at its call sites and in its own helper; the register entry is the part that outlives this lane. · **Size:** procedure.\r\n\r\n### IR-124 — a cleanup that runs `serve lan --stop` UNCONDITIONALLY creates the daemon it exists to remove, when the setup it is cleaning up after never ran\r\n\r\n- **Status:** OPEN, measured once in the field. D2 field run `20260913T041410Z`, driver `2e3aec1b`, recorded by hertz 2026-09-13 at doyle's direction. Archive `.spt/preserved/hertz-fp-driver-review/d2/field-run-20260913T041410Z/` (72 files, manifest `defa5d29…`). **This is a RIG defect. It is mine — I wrote the driver — and doyle's admission review missed the unconditional stop path as well; both are recorded because a review that misses a path is part of the mechanism, not an aside.**\r\n- **Instance.** The elevated setup was **DECLINED and NOT STARTED** by liam at 04:18:55Z — measured, unambiguous, and the right call: his leg was ready at 04:18:35Z against a hard 04:19:10Z expiry and he refused rather than race the teardown. Nothing ran, nothing mutated. The driver then entered cleanup and executed its own unconditional `env SPT_INSTALL_NO_FIREWALL=1 SPT_HOME=<isolated-home> <exe> serve lan --stop`, which dispatched through the daemon (`ensure_running`, `serveverb.rs:191`) and **CREATED** a supervisor (`daemon run --detached`, Windows PID 45944, `04:19:18.0312050Z`) and a brain (`daemon brain --generation 0 --start-reason cold`, PID 22524, `04:19:19.7696380Z`, parent 45944). `fp-home-d2`, measured ABSENT at the 04:13:58Z at-launch recheck, existed with `daemon.pid`, `brain.ready` and a full tree by 04:19:18Z.\r\n- **Why the hold could not stop it.** doyle held the elevated teardown for exactly this reason and liam held all commands. But this stop is **internal to the running driver**, not a handoff, so no authorization gate reached it: the only levers were killing the driver or editing a running script, and both are forbidden. **A guard that only governs dispatched work does not govern a step the subject performs itself.**\r\n- **The pre-dispatch markers named the mechanism and did not prevent it.** `daemon_may_run — serve dispatches through the daemon (ensure_running, serveverb.rs:191); the elevated leg may leave one running` was set BEFORE the setup was requested. The driver correctly refused to infer absence from its own expectation — and then triggered the very mechanism the marker warned about, from the cleanup path, on the branch where the warning did not apply.\r\n- **Three things kept apart, because collapsing any two misstates the run.** (1) Liam's testimony: NOT_STARTED, no mutation — still true, he created none of it. (2) The driver's conservative verdict: `CLEANUP=PENDING`, `residual_state=UNREADABLE`, `residue=UNMEASURED` — an honest refusal to claim clean, not a contradiction of liam. (3) An **actually observed** residual, created by the driver itself. That third thing is a measurement; the first two are testimony and abstention.\r\n- **Mechanism.** A teardown verb that is also a *start* verb. `serve lan --stop` must reach the daemon to ask it to stop, so invoking it when no daemon exists starts one. Cleanup paths are written for the case where setup succeeded, and are reached on every path including the ones where setup never happened; the branch nobody exercises is the branch where cleanup has nothing to clean.\r\n- **Rule.** A cleanup step whose command can CREATE the resource it removes must be **conditional on evidence that the resource exists** — not on the state markers, which say \"may exist\" by design, and not on the fact that cleanup was entered. Where the existence check is itself unavailable, the step is SKIPPED and reported as skipped, because an unnecessary teardown that spawns is strictly worse than a labelled gap. Exercise every cleanup path from the **setup-never-ran** state, not only from the setup-succeeded state.\r\n- **Kin:** [[IR-122]] (the other half: the stop that *cannot* run leaves a daemon; this is the stop that *should not* run and makes one), memory setup-suppresses-failing-arm, gate-against-documented-design, remedy-must-run-from-refusal-state.\r\n- **Ripe when:** before any repeat field run — a repeat under this driver reproduces the residue. · **Size:** small.\r\n\r\n### IR-125 — the driver's own executable sweep reported ZERO processes on the pinned exe while `Win32_Process` showed TWO, at the same instant\r\n\r\n- **Status:** OPEN, measured in D2 field run `20260913T041410Z` (hertz, 2026-09-13). **A FALSE-NEGATIVE SWEEP, not a false CLEAR** (doyle's classification, and the distinction is load-bearing): the ledger's actual verdict was `residual_state=UNREADABLE` / `CLEANUP=PENDING`, which was correct, and the sweep line is explicitly labelled evidence-only in the driver's own output.\r\n- **Instance.** `SUBJECT_EXE_PROBE=OK running_the_pinned_executable=0 enum_total=618` — the probe enumerated 618 processes and concluded none was running the pinned executable. A `Win32_Process` read moments later returned **two**, both with `ExecutablePath` exactly `…\\.worktrees\\304-w2-repr\\target\\release\\spt.exe`: PIDs 45944 and 22524. An independent sweep by path, not by pid, agreed: `count=2`.\r\n- **Why it matters despite being labelled evidence-only.** The line reads as a clean box to anyone skimming, and it is the only line in the run that speaks to \"is anything of ours still running\" in plain terms. It was contradicted only because a native read was performed for a different reason. Had the ledger's verdict logic depended on it, this is a false CLEAR.\r\n- **Candidate cause, NOT diagnosed** (deferred by doyle until cleanup was complete, and still open): the probe's raw path comparison. The Win32 `ExecutablePath` is backslashed Windows form; the driver's pinned `$EXE` is forward-slashed msys-friendly form. A literal comparison between those two spellings of the same file fails for every process. **Unconfirmed** — it is a candidate because it fits, not because it has been measured.\r\n- **Mechanism.** A predicate that can only ever return \"no\" reports a clean zero over a large, healthy-looking enumeration. `enum_total=618` is what makes it convincing: the instrument demonstrably ran and demonstrably saw the machine, and still could not see the thing it was looking for. Same family as the two other instrument-versus-reality mismatches in this lane, and all three were invisible to stubs.\r\n- **Rule.** A sweep that reports zero carries its own **positive control** — in the same run, the same predicate must find something known present, or the zero is UNMEASURED rather than absent. Where a predicate compares paths across the msys/Windows boundary, normalise both sides and prove the normalisation on a known-matching pair; never compare two spellings of a path and call a non-match an absence.\r\n- **Kin:** memory count-predicate-needs-its-own-positive-control, zero-match-filter-reads-as-absent, windows-firewall-census-clean-zeros, verdict-from-probe-competence, [[IR-118]].\r\n- **Ripe when:** with IR-124, before a repeat field run. · **Size:** small.\r\n\r\n### IR-126 — the experimental budget CONTAINED its own read-only preflight, leaving 128 s of a 300 s window for the elevated leg, and the leg was correctly declined\r\n\r\n- **Status:** OPEN, measured in D2 field run `20260913T041410Z` (hertz, 2026-09-13). Boundary NOT moved for that run — doyle refused the change mid-flight and was right to; this entry is the scheduling review he asked to be preserved.\r\n- **Measured, from the run's own timestamps.** Run start `04:14:10Z` · pre-setup absence census `04:16:23Z` · handoff request written `04:17:02Z`. So **172 s of the 300 s experimental budget went to in-budget read-only preflight** — CI axis queried by name across five statuses, ancestry census, six-instrument hashing, subject identity, 5470 guard baseline, pre-setup absence census — and the driver printed the remainder itself: `HANDOFF_WAIT bounded to 128s`.\r\n- **The consequence, and it is not hypothetical.** Liam's leg script was ready at `04:18:35Z`. Setup alone had measured ~9 s, plus four PowerShell stamps, plus a t1 capture of unmeasured duration, against 35 s of remaining clock. He DECLINED without mutation, which was the correct call and the one the instruction asked for. **The window was consumed before the work it existed for could start.**\r\n- **Two overruns recorded beside it, as observations and not as permissions.** Experimental activity ended at **306 s of the 300 s budget** (the deadline exits through the EXIT trap, so cleanup is never skipped, but the boundary was crossed). The driver was still running after its 180 s cleanup reporting bound had elapsed; it exited by `04:23:54Z`. Neither overrun was authorised, taken as an extension, or used to do more work.\r\n- **Mechanism.** A budget defined from process start, over a phase order that puts every read-only admission check inside it, gives the elevated leg whatever is left rather than what it needs. The preflight cost is not waste — those checks are why the run was admissible — but charging them to the same clock makes the window's usable size an accident of how slow the host's firewall enumeration is that minute.\r\n- **Rule.** Bound the ELEVATED LEG on its own clock, sized from its measured duration, and start it when the leg is dispatched. Admission checks get a separate bound. A driver that cannot guarantee a usable handoff window should REFUSE TO DISPATCH rather than dispatch a leg that cannot finish — an operator declining at the deadline is the correct outcome of a wrong window, not a failure of the operator.\r\n- **Kin:** [[IR-122]], memory your-cadence-can-be-the-blocker, reap-step-duration-is-not-the-window, twohost-run-window-discipline.\r\n- **Ripe when:** with IR-124 — a repeat field run under the current budget shape reproduces the squeeze. · **Size:** small.\r\n\r\n### IR-127 — a nested value-type assignment can leave the native job limit unset while the instrument logs the requested flag and a successful setter\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\r\n- **Instance.** The containment probe assigned `$info.BasicLimitInformation.LimitFlags = 0x2000`, logged the requested KILL_ON_JOB_CLOSE flag and `SetInformationJobObject=True`, read both owned processes as job members, closed the handle, and found both still alive. The nested field is a struct: PowerShell changed a copy, not the value subsequently marshalled. The offline discriminator measured `nested_assignment_flags=0`; modifying the nested value and assigning the whole value back measured `whole_value_assignment_flags=8192`.\r\n- **Correction and evidence.** The corrected probe assigns the whole nested value, calls `QueryInformationJobObject`, and refuses unless the kernel's flags equal the requested flags. Readback `0x2000` then preceded both members being measured GONE after close. Initial invalid arm and corrected measurement are preserved separately under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/` (`M3/` and `instrument-repair-20260913T104354Z/M3/`); the latter's `results.txt` carries the offline discriminator.\r\n- **Rule.** Mutating a nested interop value requires assigning that value back to its owner. Successful native setters establish only that the submitted value was accepted: read the effective configuration back and compare it before granting the operation authority. Requested flags are not observed flags.\r\n- **Kin:** [[IR-116]] (a successful call is not a post-state), [[IR-118]] (a complete-looking wrong answer).\r\n- **Ripe when:** any PowerShell/native configuration probe is authored or changed. **Size:** whole-value assignment plus checked native readback; retain the positive and negative discriminator.\r\n\r\n### IR-128 — PowerShell `$null` can become an empty native string, so a failed launch is misread as a policy refusal before the policy is reached\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\r\n- **Instance.** Both breakaway probe arms called a P/Invoke string parameter with PowerShell `$null`; both returned `CreateProcess` error **123** and created no child. This is an invalid-name result, not the **5** required to establish breakaway-policy denial. An offline C# string-parameter discriminator returned `IsNull($null)=False`: the PowerShell binder had supplied an empty string rather than native NULL.\r\n- **Correction and evidence.** A C# helper passes the executable explicitly, uses a mutable `StringBuilder` for `CreateProcessW`'s command line, and supplies C# null for the optional current directory. The repaired no-breakaway arm returned **5**, while the BREAKAWAY_OK contrast created a child measured outside the job and still alive after job closure. Original error-123 arms remain invalid and preserved under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/M5/`; corrected records live in its `instrument-repair-20260913T104354Z/M5-denied/` and `M5-allowed/`.\r\n- **Managed-string recurrence (group N).** The same binder coercion reached `[IO.File]::Replace($tmp, $record, $null)`: the optional backup path became empty, and publication failed with `The path is empty` before any subject was created. The initial N0 gate correctly refused; its partial record and exception are preserved under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T1109444702137Z-N/N0/`. The PowerShell publisher now uses the overwrite-rename overload `[IO.File]::Move($tmp, $record, $true)` instead of passing a nullable string. The corrected N0 reached the intended false coverage assertion; native C# publication retains a real C# null.\r\n- **Rule.** At native string seams, distinguish NULL from the empty string and verify what the language binder supplies. Use a typed native-call helper where this distinction is load-bearing. Classify the actual error code at the failing stage: a launch error before policy evaluation cannot establish a policy refusal. Command buffers documented writable must be mutable.\r\n- **Kin:** [[IR-113]] (a failure at the wrong stage is a void discriminator), [[IR-117]] (name the observation that refutes each branch).\r\n- **Ripe when:** any optional native string argument or process-creation probe crosses PowerShell's binder. **Size:** typed call seam and a null/empty discriminator.\r\n\r\n### IR-129 — JSON date materialization followed by implicit string parsing loses UTC kind and precision, turning a live creation anchor into a false pid-reuse verdict\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`. The first M8 exit 0 is explicitly INVALID.\r\n- **Instance.** `ConvertFrom-Json` materialized an ISO birth string as `DateTime`; `[DateTime]::Parse($id.created)` implicitly formatted that object back to text before parsing it. Kind and fractional precision were lost and local time was reinterpreted. The result printed birth timestamps agreeing within a microsecond but computed roughly seven-hour deltas, mislabelling four live registered identities `GONE_PID_REUSED`. The original output remains at `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/M8/`.\r\n- **Correction and evidence.** The reader handles `DateTime` values directly with `ToUniversalTime`; strings are parsed as `DateTimeOffset` and converted to UTC. Its live-self JSON-roundtrip control measured **9 ticks** difference; a deliberately 500-ms-skewed anchor measured **5,000,009 ticks** and could not match. The corrected final pass covered all **13** registered identities, found every one GONE, and retained the escaped child's earlier SURVIVING readings. Evidence: the same group's `instrument-repair-20260913T104354Z/all-identities-disposition.jsonl` and `final-disposition.stdout`.\r\n- **2026-09-14 recurrence caught before the field window.** The bound promotion instrument repeated the same reader/parse pair at its brain-birth guard. A language-only discriminator using that pair measured **251,998,765,433 ticks** error. Reading JSON with `-DateKind String` instead preserved the timestamp: same-anchor delta **0 ticks**, deliberately wrong 500-ms anchor **5,000,000 ticks** and refused by the unchanged **10-tick** guard. The successor changes only `Read-Json`; the original instrument remains intact. Evidence: `.spt/preserved/hertz-fp-driver-review/d2/promotion-date-discriminator-result.json` and `provision-promote-VGCTKD7A.ps1`. No field process was needed to expose this known hazard.\r\n- **Rule.** Treat deserialization's runtime type as part of the interface. Never reparse a typed date through implicit culture-sensitive formatting. Exercise both a same-process roundtrip and a wrong-anchor negative control; preserve raw timestamps and the computed delta so their agreement can be audited. Match at the actual reader resolution, not by discarding the fractional second.\r\n- **Kin:** [[IR-118]] (successful instrument, wrong answer), [[IR-125]] (an absence predicate needs a known-present control), [[IR-15]] (identity-aware liveness).\r\n- **Ripe when:** any JSON record is used to authenticate process identity or order events. **Size:** type-aware UTC conversion and two local controls.\r\n\r\n### IR-130 — a lowercase `$home` local collides with PowerShell's protected `$HOME`, refusing custody qualification before the signer is reached\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz on 2026-09-13 in the D2 custody lane; narrow correction and one fresh-root attempt authorized by doyle `5FWLC3F2`. Original refusal remains preserved.\r\n- **Instance.** The prepared custody controller passed syntax parsing and compiled its native observer successfully, then exited **1 after 3.33 s** before any custody arm. Its next statement assigned `$home = Join-Path $armRoot 'home'`. PowerShell variable names are case-insensitive: this is an assignment to automatic `$HOME`, whose measured options were **ReadOnly, AllScope**. A separate language-only reproduction returned **VariableNotWritable**. The original catch deliberately omitted exception details, so that error ID belongs to the minimized reproduction; the original record carries the generic refusal and `arms=[]`.\r\n- **Boundary and evidence.** Compiler native exit **0**, `COMPLETE`, `CONFIRMED_GONE`, active processes **0**; a public fixture and empty `custody-normal` directory existed, but no home, subject arguments, dummy EnvironmentFile, observer execution, signer, git child, real key, or field rig existed. Evidence: `.spt/preserved/hertz-fp-driver-review/d2/AZLCQNZL-CUSTODY-REFUSAL.txt`, `AZLCQNZL-home-variable-repro.json`, `AZLCQNZL-custody-failure-inventory.json`, and `controls-out/custody-6U2UZVXK/`.\r\n- **Correction.** Rename the local to `$qualificationHome` at its assignment/directory call and environment-overlay reference (two source lines), re-pin the controller, and use a fresh qualification root. Do not relax automatic-variable protection, reuse the failed root, or classify this as a rejection of the assembled xtask's seed isolation. The authorized retry's result is separate evidence, not a rewrite of the first attempt.\r\n- **Rule.** PowerShell locals share a case-insensitive namespace with automatic variables: use role-specific names rather than `$home`, `$host`, or `$pid`. Syntax acceptance and a successful subordinate compiler do not prove that controller initialization reached its behavioral discriminator. State the last stage actually executed; an empty retirement list is not evidence that secret-bearing processes ran and were cleaned.\r\n- **Kin:** [[IR-113]] (wrong-stage refusal is a void discriminator), [[IR-128]] (language-boundary failure before the intended policy), [[IR-118]] (plausible result without the claimed observation).\r\n- **Ripe when:** any PowerShell orchestration or custody controller is authored or changed. **Size:** two-line naming correction plus retained refusal and fresh-root qualification evidence.\r\n\r\n### IR-131 — a live-agent signing environment leaks into the provisioning process and correctly refuses before the private signer exists\r\n\r\n- **Status:** OPEN, rig invocation-environment defect, not a candidate or disk defect. Measured by hertz on 2026-09-14; classified by doyle in `VGCTKD7A`.\r\n- **Instance.** Second fresh #297 preparation admitted fourteen native leaves at `04:51:39.245Z`. The separate provisioning call launched at `04:51:52.802Z` and returned `STAGING_FAILED_PREFLIGHT`, native exit **1**, after **0.45 s**. No rig, private directory, key or field nonce existed. This was a preflight refusal before the `04:59:31Z` deadline, not a stalled launch.\r\n- **Exact check.** A read-only preflight discriminator surfaced `AMBIENT_SIGNING_SECRET_REFUSED` from `Assert-SeedAbsent`. A names-only environment probe found `SPT_RELEASE_SEED` **present**; `SPT_DEBUG_RELEASE_SEED` and `SPT_RELEASE_SEED_CMD` were absent. No values were emitted or changed. The refusal reproduced with **102,099,394,560 bytes free**, and the failing check reads process environment before filesystem preflight: reclaiming disk cannot cure this guard.\r\n- **Evidence gap.** The original catch persisted a failure JSON only after `$publicReady`, set after preflight. Earlier throws produced only a generic stderr phase and an empty evidence directory. Preserve safe, fixed preflight reasons and caller exit evidence before mutation; silence in the directory is not evidence that the command never ran. Original artifacts remain unchanged under `.spt/preserved/hertz-fp-driver-review/d2/`; see `IH4QFFXS-execution-boundary.json`, `X2LPSQ7A-preflight-only-result.json`, and `X2LPSQ7A-signing-env-presence-result.json`.\r\n- **Rule.** Scrub the environment handed to the **provisioning PowerShell process itself**, not merely its later signer child: remove every ambient `OWL_*`/`SPT_*` key except the leg's declared allowlist, recording names before/after, never values. Preserve the live agent's parent environment and lifecycle. The guard remains strict. The new debug signing seed enters only the controlled signer's private `EnvironmentFile`; it never becomes ambient in the provisioning process or helpers.\r\n- **Scrub qualification.** The fresh-child receipt recorded `before_names=[\"SPT_ENDPOINT_ID\",\"SPT_RELEASE_SEED\"]`, `after_names=[]`, and parent names unchanged. This exposed the next startup error: `Stop-Transcript -ErrorAction SilentlyContinue` throws a terminating exception when the required fresh `-NoProfile` host is not transcribing. The successor removes that invalid stop, not the forced-logging policy checks or seed guard. The complete no-mutation preflight then exited **0** with `PREFLIGHT_ONLY_PASS_NO_MUTATION`; no third preparation clock had begun. Evidence: `VGCTKD7A-preflight-result.json`, `VGCTKD7A-preflight-clean-result.json`, and `VGCTKD7A-preflight-clean-environment.json` plus its exit receipt.\r\n- **Kin:** [[IR-107]] (live-agent identity leaking into consumer/test legs), [[IR-130]] (preflight failure hidden by phase-only reporting), [[IR-122]] (live operational context is not an isolated rig).\r\n- **Ripe when:** any leg is launched from a live-agent session. **Size:** explicit child environment boundary and durable preflight evidence; no candidate change.\r\n\r\n### IR-132 — requiring every live-fleet `spt.exe` image path to be readable permanently refuses an isolated rig's admission\r\n\r\n- **Status:** OPEN, rig-instrument admission defect, not a candidate, environment-scrub or disk defect. Measured by hertz and independently localized by doyle on 2026-09-14; correction ruled in `W8TQ3MZC`, `6IQ4HYIL`, `QKQC2NET` and `MRQX7XEK`.\r\n- **Instance.** Third preparation passed fourteen native admission leaves and genuinely staged the signed set. Promotion then returned `PROMOTION_ADMISSION_FAILED`, native **1**, with `native_records=[]` and shutdown `NOT_STARTED`. Its census required a nonblank CIM `ExecutablePath` for **every** `spt.exe`, not merely one that could belong to the new rig. The read-only predicate replay passed twenty-five preceding statements and failed `SPT_PROCESS_PATH_UNREADABLE` at line 273. No apply, daemon, field nonce or firewall mutation occurred. Receipt: `.spt/preserved/hertz-fp-driver-review/d2/GEL6JAWN-FINAL-REFUSAL.json`.\r\n- **Shared-box mechanism.** The subsequent census exposed persistent PID **52860**, birth `2026-09-12T20:17:00.5331330Z`, with readable birth but unreadable image path; the rig did not exist until `2026-09-14T05:45:32.8201734Z`. Doyle additionally measured blank paths in **12/12** samples, with transient CLI children alongside the persistent process. An image-readability requirement cannot admit this live shared box. Missing per-rig state files remain an independent gate, not a substitute for process-identity reasoning.\r\n- **Correction.** Capture `(pid, CIM CreationDate)` together. A birth provably earlier than rig creation excludes that identity without needing its image; the **10-tick** precision allowance only narrows this exemption. Later or overlapping blank-path identities use the existing limited-query native image/birth/retained-handle seam. A native failure is unresolved, not gone. A successful immediate CIM re-read with a live positive control can establish absence; access-denied or failed queries cannot. PID reuse records the original identity gone and classifies the replacement independently. Unknown birth or a persistent unresolved identity refuses. No fleet-process termination is permitted.\r\n- **Evidence.** Fourteen discriminator cases cover pre-rig exemption, native image resolution, known rig refusal, disappearance versus denied/failed queries, dead-provider control, unknown/equal/precision-overlap births and PID reuse. The final successor passed all fourteen. A read-only live run admitted **17** census hits, including 52860 as `PREDATES_RIG`; actual native self controls measured a **5-tick** CIM/native birth delta, admitted the other-image case and refused the same-image case. Proof: `W8TQ3MZC-census-controls-final.json` and `W8TQ3MZC-census-live-result.json` beside the receipt. Neither proof invoked the product or mutated the rig.\r\n- **Rule.** Admission asks whether an observed identity can belong to the owned rig, not whether the caller can read every process on the host. Preserve query failure, confirmed absence and replacement identity as different outcomes, with pid and birth in the receipt. Re-pin changed instruments; preserve failed windows and obtain a fresh grant rather than extending their clocks.\r\n- **Kin:** [[IR-107]] (live operational context enters the rig), [[IR-129]] (creation-time type/precision), [[IR-125]] (known-present control for absence), [[IR-15]] (identity-aware liveness).\r\n- **Ripe when:** a rig shares a host with elevated perches or short-lived CLI traffic. **Size:** birth-aware census and retained native identity probe, with fail-closed boundary controls.\r\n\r\n### IR-133 — a live capture cannot be read with read-only sharing, and daemon stderr belongs to the owned home\r\n\r\n- **Status:** Corrected in the r9 rig instrument; genuine fifth-window promotion completed with exit **0**, owned shutdown and final provenance. The subsequent field attempt failed its separate setup-handoff deadline, not this promotion read. Fourth #297 preparation measured by hertz on 2026-09-14; sharing failure localized by doyle in `R2VK8FQN`, run-identity binding ruled in `ANR522S5`, successor accepted in `GV3R6QUV`.\r\n- **Instance.** Fourteen admission leaves and genuine staging passed. The candidate applied daemonlessly, transitioned `applied-pending` → `applied`, brought up broker **14704** and brain **45220**, published the pinned generation-zero readiness record and emitted `BRAIN_PROMOTED` before the instrument stopped its owned job. The instrument returned only `OWNED_PROMOTION_READINESS_FAILED`. Six provisioning/promotion native jobs ended `CONFIRMED_GONE`, active counts zero; all nineteen signing-private files were absent. No field, GO or D3 occurred. Original receipt: `.spt/preserved/hertz-fp-driver-review/d2/W8TQ3MZC-FINAL-REFUSAL.json`.\r\n- **Mechanism.** The loop used `File.ReadAllText` on a capture held open for **Write**, with **Read** sharing, by the run-scoped launcher. Windows checks sharing in both directions: the new reader's default **Read** sharing excludes the existing writer, causing `IOException`, `0x80070020`. A completed step hid this defect because its writer had already closed. Changing only the writer's sharing does not repair the reader.\r\n- **Wrong source behind the exception.** The launcher's stderr capture was zero bytes; the daemon redirects stderr to `SPT_HOME/logs/daemon.stderr.log`. Reading the empty capture with compatible sharing would merely reach the later marker timeout. Read the actual owned-home log with `FileStream(Open, Read, FileShare.ReadWrite | FileShare.Delete)`, matching the existing native launcher's `ReadText` pattern; release each read handle before the next poll.\r\n- **Run binding.** A promotion marker counts only after the exact brain header naming the measured membership PID and readiness generation, and before another process header. Markers before that header, without it, or under another PID/generation refuse. A rolled `.1` can contribute only when absent before this owned launch and appearing during it, with the same header binding; preexisting backups cannot prove this run.\r\n- **Failure evidence.** Attach the instrument's constant assertion name and call-site line to its exception. Before cleanup can replace the active error, retain that name, source line, exception type and HResult. Non-assert exceptions have a null assertion name. Never serialize exception messages or environment values.\r\n- **Qualification.** Thirteen controls passed against `provision-promote-R2VK8FQN.ps1`: a live-held writer reproduces `0x80070020` with `ReadAllText`, the shared reader returns its exact bytes while the writer remains open, header/PID/generation/ordering and rolled-history boundaries refuse stale evidence, the actual rollback guard still refuses, and diagnostics omit a message canary. Proof: `R2VK8FQN-live-held-controls/result.json` beneath the receipt directory. No product invocations, rig mutations or fleet terminations.\r\n- **Live verification.** `provision-R2VK8FQN/promotion-complete.json` records `PROMOTION_COMPLETE`; the supervised promotion exited **0** after **12.9 s**. The real candidate passed the shared-log, PID/generation marker, final membership, durable-state and owned-shutdown checks. Its later field ledger remains a separate failed observation contract; successful provisioning does not turn that ledger green.\r\n- **Kin:** [[IR-132]] (instrument census refusal), [[IR-130]] and [[IR-131]] (phase labels lose the failing predicate). **Ripe when:** polling any live writer or accepting logs as run-specific evidence.\r\n\r\n### IR-134 — request latency consumes the elevated capture's execution budget, then a late terminal receipt leaves completed work unmeasured\r\n\r\n- **Status:** Instrument correction qualified without a sixth field window. Doyle accepted the execution-clock repair in principle under `HHDKCRH5`, then identified its still-insufficient receipt budget; the derived-window successor follows ruling `P9RLK4VU` and accepted arithmetic `KZG4IN37`. Candidate/packet/nonce/driver/runner repinning remains one future amendment, separate from field authorization. Fifth #297 field run `20260914T063552Z` remains failed and immutable. Its candidate's independent **PRODUCT RED** finding (`M5XKQ2DN`) is unchanged.\r\n- **Measured sequence.** Setup request `06:41:26Z`, elevated setup `06:43:18Z`–`06:43:24Z`, refused capture launcher `06:43:25Z`–`06:43:26Z`, receipt about `06:43:27Z`. The driver had written the capture deadline from request time: 112 seconds of handoff delay left the launcher's `deadline - now - 5` allocation at **−4 seconds**. No native t1 capture ran. The handoff expired before the receipt; cleanup reread its nonce and exit but retained the earlier `timestamp_order=UNMEASURED`, withholding mutation despite subsequently available terminal stamps.\r\n- **Clock correction.** The executor initializes `setup-start.utc`, `elevated-leg-start.epoch` and `d2-t1.deadline` immediately before `run_exactly`, from one UTC observation, with **CreateNew** writes. The independent allocation is **120 seconds**: the existing 90-second capture ceiling, 9 measured seconds around a refused capture, 5-second termination reserve and 16-second margin. Nine seconds is not a measurement of a successful capture. PREPARE initializes nothing; notification latency consumes only the separately bounded handoff. No preparation or activity window is reset or extended.\r\n- **Terminal evidence correction.** On handoff expiry, cleanup makes one final nonce/exit observation and, if terminal, rereads the six stamps before deciding whether completion is proven. A late observation preserves `handoff_wait=EXPIRED` and the original timeout exit separately from `setup_terminal_exit`; it never resumes activity or treats lateness as timely acceptance. Missing, duplicate or wrong nonce evidence and missing or reversed stamps remain unproven. An exceeded leg clock refuses the capture contract independently of terminal completion.\r\n- **No-field proof.** `.spt/preserved/hertz-fp-driver-review/d2/AQ23KKNI-controls/` preserves the actual extracted predecessor/successor predicates, emitted PowerShell initializer, nine receipt/product controls, five clock/ledger controls and clock results. The predecessor retained UNMEASURED after receipt publication; the successor recovered ordered completion without overwriting timeout. The actual initializer refused a second initialization without changing any clock bytes. With the measured 112-second notification delay and capture at leg-start +7, the old allocation is −4 seconds and the new allocation is 90 seconds. No product, firewall, signing or field operation was invoked.\r\n- **The outer-clock blocker, not fixed by the inner clock.** A receipt follows execution: **112 + 120 = 232 seconds** cannot fit the retained 120-second setup handoff. Keeping a 300-second activity window and refusing every GO would be a correct refusal of the wrong shape, not an executable field design. `P9RLK4VU` therefore re-derives future activity as **630 seconds**: pre-dispatch **74** (54 observed +20 margin), setup handoff **240** (112 latency +120 leg +8 margin), post-receipt probes **200**, t2 **100**, final transition **16**. Only setup supersedes the prior 120-second handoff cap; other handoffs retain it.\r\n- **Measured basis and explicit allowance.** The fifth timeline records portfields calls at up to **45 seconds**, census **46 seconds**, and t3 **25 seconds**; the earlier `20260913T041410Z` capture also took 25 seconds. Two analogous portfields calls plus census give **136 seconds**; another **64 seconds** is a labelled allowance for identity capture, D1 and bookkeeping, not a claimed complete post-receipt measurement. T2 receives a **90-second native ceiling**, **5-second launcher reporting reserve** and **5-second shell/reporting margin**. The post-receipt probe deadline cannot spend t2's allocation; t2 cannot spend the final transition reserve.\r\n- **Derived-window controls.** `P9RLK4VU-controls/result.json` records **16 passing controls**, executing extracted real Bash predicates and the wait loop against a virtual wall clock. The complete 630-second window and the measured 54-second pre-dispatch cost pass; 555 seconds remaining fails against the 556-second dispatch requirement, while 556 fits. The actual gate refuses before GO/mutation markers. A receipt after 112-second latency plus 120-second execution fits the new setup allowance; PREPARE and cleanup retain their 120-second caps. Published request and phase deadlines still truncate waits. Preparation remains **600 seconds** and cleanup remains **180 seconds including its 30-second ledger reserve**; an observation deadline cannot override cleanup. No product or field operation was executed.\r\n- **Separate product finding.** Candidate `b8482445` logged one `verify-query` completed at **2650 ms**, followed by a second pre-write snapshot killed at **3027 ms** under its **3000 ms** budget; no reconcile-write ran. The budget **starts before spawn and includes output collection** (`run_ps_inner`, source timing supplied by doyle in `IRXYIJHS`); spawn is not outside this clock. The successor ledger records this query kill separately from handoff/capture failure. Fifth-window cleanup was subsequently closed on existing measurements as **NOTHING_TO_REMOVE**; its original PENDING ledger was not rewritten.\r\n- **Kin:** [[IR-126]] (execution receives leftover scheduling time), [[IR-124]] (cleanup must not race unproven setup). **Rule:** measure execution from execution, preserve timeout and late completion as separate facts, and do not let an instrumentation repair erase a product failure.\r\n\r\n### IR-135 — checker pin and runner installation can disagree, and the repair path disguises that version mismatch as an authentication failure\r\n\r\n- **Status:** CI precheck remedy implemented in the IR-135 lane; workflow execution awaits integration. Measured by doyle in S4 golden `34946493637`, 2026-09-15; filed by hertz from `3HHHPWCR`. The immediate box mismatch was repaired by hand-install.\r\n- **Instance and mechanism.** The #304 candidate carried `71caedd4`, setting `WANT=0.4.1` in `golden.yml`/`ci.yml`, while kitsubito's `~/.local/bin/traceable-reqs` was **0.2.0**. The install step's mismatch path attempted a private clone without a provisioned `TRACEABLE_REQS_TOKEN` and exited **128 before any check**. The visible failure named authentication, not the wanted and installed versions. A checked-in pin is not evidence that the runner can supply it; the fallback requires a second, independently missing prerequisite.\r\n- **Implemented remedy (QD54OM7S).** Both workflows run an explicit pin/runner precheck and use `.github/ci/traceable-reqs.sh` as the single pin/install owner. It reports the actual version and native version exit; matching requires literal equality and exit zero. A mismatch without `TRACEABLE_REQS_TOKEN` refuses before clone/build, naming the version disagreement and missing credential separately. With a token present, source repair remains available and native clone failure is preserved; token presence never claims access. The installed version is checked before coverage. On kitsubito, eight isolated shell controls passed: matching precheck/install without a token, stale/missing/failing/lookalike versions refused, authenticated repair admission, and clone exit128 retained. The predecessor failed the stale/no-token discriminator with128; the successor refused with1 and both diagnostics. A separate smoke used kitsubito's real0.4.1 binary through both entry points without a token, exit0. No live credential was provisioned or private-source build exercised. Contract and reproduction command: `docs/TRACEABILITY.md` §CI checker admission and installation. PAT provisioning remains the operator's decision, banked since2026-07-30.\r\n- **Kin:** [[IR-104]] (the checker version changes what counts as evidence), [[IR-109]] (the #304 pin is already live). **Ripe when:** the next checker pin or golden-intake/install-step change. **Size:** a version diagnostic and intake assertion; credential provisioning is separate operator work.\r\n\r\n### IR-136 — a broker bound under the seed socket's name is not seed control, so a URL-minting rig can omit the very listener contract the product queries\r\n\r\n- **Status:** Instance fixed in S5 **`ddd7fc7f070667524578c282894dd44a2e36062f`**, test-only atop S4; S5 golden34957614641 passed, including both twohost roles. Shared fixture-composition remedy implemented and Linux-verified in the IR-136 lane. Origin: doyle's S4 golden `34946493637` twohost helper red, 2026-09-15.\r\n- **Mechanism.** Role B hosted broker IPC under an invented name, with neither `seedmap::serve_seed_control` nor a docs listener. `REQ-WEB-URL-BOUND-PORT` requires `serve_for` to ask the canonical seed-control plane for `DocsStatus` before publishing a URL; the missing plane returned `DOCS_PORT_DISCOVERY_FAILED: Connection refused (os error 111)`. Merely renaming a Broker to `seed_socket_name()` does not provide that protocol: `serve_request` is dispatched by seed control, not Broker. The docs-server fixture had already encountered the same trap. The last green twohost run predated this bound-port contract.\r\n- **Discriminator and scope.** Todlando's unchanged-S4 Linux fixture failed at the exact discovery seam without seed control/listener (**native 101**) and returned `Registered` at the actual bound port **33319** when those fixtures were added (**native 0**); both arms retained the invented B broker name. Evidence: `.spt/preserved/304-web-helper-rca/linux/`. S5 gives B distinct canonical broker/seed sockets, real seed control, a broker-backed ephemeral docs listener, and a discovered-port equality precondition. Helper expectations stay unchanged. A's helper cell relays B's returned URL and does not query its own DocsStatus; its existing broker-on-seed-name path is not this failure. The seven unopted-in Windows passes do not exercise the role-gated twohost bodies.\r\n<!-- [doc->REQ-SERVING-FIXTURE-CONTROL-PLANE] -->\r\n- **Shared remedy (P2Y2GWUP).** `crates/spt-daemon/tests/support/serving.rs` provides `ServingFixture`, included by both `docs_server_e2e` and `twohost_web` rather than exported as product surface. `start` composes the distinct canonical broker and real seed control, waits for seed readiness, binds broker-backed docs on port0, and asserts that seed-control `DocsStatus` returns that actual port. The caller supplies its private home, journal and optional NetHost; socket spelling is no longer a caller choice. `stop` stops and joins both IPC accept loops. The docs listener remains process-lifetime under the existing production interface, so tests require process-per-test isolation and one broker-backed listener per process.\r\n- **Negative-state coverage retained.** The docs fixture uses the separate `control` stage only to distinguish absent control (offline fallback permitted) from running control without a listener (fallback refused); its normal serving case uses the same complete constructor as role B. Role A's seed-named proxy Broker and the standalone docs-less listener remain intentionally separate: neither is the owner's URL-minting control plane. No default/configured port substitutes for discovery, and no production protocol changes.\r\n- **Shared-fixture proof (2026-09-15).** Kitsubito, private tree/target, jobs2: targeted clippy with `-D warnings` **0**; nextest, both migrated binaries, one test thread and zero retries **0**. All **3 docs cases** exercised their real bodies: absent-vs-unbound discovery, HTTP published-surface/security checks through the complete fixture, and the standalone docs-less pointer. The other **7 twohost cases** returned through their unopted role gate; these are compile coverage, not a new cross-host execution claim. Traceable0.4.1: **920complete/0findings**. Raw exits/output/hashes: `.spt/preserved/hertz-ir136-fixture/linux-v2/`; the initial wrapper PATH failure started no cargo and is preserved separately.\r\n- **Ripe when:** another URL-producing fixture is added. Use the shared complete constructor rather than rebuilding its three planes independently; use the partial stage only when missing-listener behavior is the test subject.\r\n\r\n### IR-137 — a redirected Start-Process child can share the tool call's console lifetime and die when that call returns\r\n\r\n- **Status:** RETIRED, 2026-09-15, doyle ruling `YPLFG3CG`: **no tracked callsite; discipline recorded + receipt**. This closes a Windows ad-hoc rig-craft item, not a CI or candidate defect; no helper or product change.\r\n- **Mechanism and rule.** `Start-Process` with redirected output from a PowerShell tool call was observed to end with **`STATUS_CONTROL_C_EXIT`** when the tool call ended: a returned child PID did not establish detachment. The reported detached form uses a **hidden window without redirects**. Where a child must outlive the call, qualify its survival after the caller returns and give it a durable output path of its own; do not treat process creation or a hidden window alone as lifetime evidence.\r\n- **Origin clarified (YPLFG3CG).** Claude Code PowerShell tool host, 2026-09-15T07:17Z, #304 S3 Windows attempt-2 launch A: redirected `Start-Process pwsh` PID47560; `rustc` exited `0xc000013a` seconds after the tool returned, driver receipt contained only its start line and no refusal file. The same driver relaunched with `-WindowStyle Hidden -PassThru` and no redirects (PID37536) ran25minutes to exit0. There is no tracked failing launcher to repair; the existing tracked g6 launcher already uses the reported good shape.\r\n- **Discipline and receipt.** [Windows ad-hoc rig launch discipline](GOLDEN-CI.md#windows-ad-hoc-rigs-that-outlive-the-tool-call) states the shape, child-owned durable output and post-return PID/birth/output qualification. Preserved harmless-child receipt: `.spt/preserved/hertz-ir137-caller-return/receipt.json`, SHA256 **`e1c9b207544e6313eac5421ebb692786ec18b3a165756b451bff3a704899b178`**. Both valid arms survived under **OMP**, wrote post-return events and exited0; an initial observer-handshake timeout is excluded. All3probe children ended and native handles closed. This does not reproduce the **Claude Code** failure; the host boundary stays explicit. Reopen only for a newly owned callsite or contrary evidence, not to build an unused helper.\r","truncated":true,"truncatedBy":"lines","totalLines":170,"totalBytes":54464,"outputLines":169,"outputBytes":54464,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6938,"displayContent":{"text":"### IR-122 — the field rig's isolated-daemon stop cannot run from an spt-hosted session, so every run leaves a live daemon holding the subject exe inside the pool it just released\r\n\r\n- **Status:** OPEN, recurring. Instance 1 attempt 2 (`rig/arm2-driver-stdout.txt`: `RIG_DAEMON_STOP_REFUSED_OR_ERRORED — reported, not forced`). Instance 2 run `20260912T231404Z` under frozen r10 (`rig_daemon_stop_EXIT=3`, `cleanup-failures.txt`, `rig-daemon-stop.err`). Recorded by hertz 2026-09-12 23:50Z at doyle's direction; **this is a RIG defect, and any product-surface change requires a separate contract review.**\r\n- **The refusal.** `DAEMON_STOP_REFUSED: a broker-stopping command is never run by an spt endpoint ($OWL_SESSION_ID is set). ... No flag overrides this, --force included.` The guard keys on the CALLER'S SESSION ENV, so it fires identically no matter which rig step reaches it and no matter what `SPT_HOME` the command targets.\r\n- **Not a new fault, and not an accident.** `readiness-r4-as-read.md:107-109` already states it: v9 DELIBERATELY leaves `OWL_SESSION_ID` set, the refusal is expected to recur, and it is \"reported, never worked around silently.\" The rig chooses a loud known refusal over an unproven workaround — that choice is right, and it is the reason this entry is about the leftover, not about the refusal.\r\n- **What it actually costs.** Cleanup completes with `steps_failed=1` and the isolated daemon SURVIVES. Measured in instance 2: supervisor `daemon run --detached` and its child `daemon brain --generation 0 --start-reason cold`, born 331 ms apart, both executing `<worktree>/target/release/spt.exe`. They hold the SUBJECT exe open inside a pool `pool_release` has already returned, so the next build into that pool can fail on a locked `spt.exe` — a red belonging to neither lane. See memory [[live-agents-lock-target-debug-spt-exe]], [[shared-target-two-live-trees]].\r\n- **The counterfactual the refusal does NOT license (doyle, correcting hertz in this instance).** That the guard refused does not prove the isolated-target command *would have* stopped the resident broker. The guard reads the env, not the routing; establishing what the command would have reached needs routing evidence nobody has gathered. State the refusal, never the averted disaster.\r\n- **Disposal, and it is the same four-field procedure both times** (`readiness-r4-as-read.md:110-118`): identify on pid, `CreationDate`, exact `ExecutablePath` and `CommandLine` — a bare pid match is unsound because pid reuse on this box is measured, see [[pid-reuse-across-reboot]]. The supervisor must still equal `<isolated-home>/daemon.pid`, and the brain's parent must be that supervisor. Then a fresh authorization NAMING THE NEW PIDS (the prior one is pid-specific and spent), supervisor first so the brain cannot respawn, `Stop-Process -Id` alone — never a tree kill, an image-name kill, or any action against the resident node daemon, which is a DIFFERENT binary under `AppData\\Local\\spt-core\\bin\\`. Post-state ASSERTED, not announced, or it is [[watchdog-reports-a-kill-it-never-made]].\r\n- **Mechanism.** A cleanup step that is structurally unrunnable in the environment the rig always runs in. It cannot be fixed by retrying, it never fails loudly enough to block the run, and its residue lands in a shared build pool rather than in the run's own directory — so the cost is paid by whoever builds next, not by the run that caused it.\r\n- **Rule (scoped by doyle 2026-09-12 — a bare pid-file kill is NOT approved as sufficient).** A rig that starts a daemon owns stopping it by a route that works from the rig's own environment, and `<isolated-home>/daemon.pid` is the pid SOURCE, never the authorization. Any rig cleanup that terminates a process must, at the moment of acting: re-read creation time, exact `ExecutablePath`, `CommandLine` and isolated-home association FRESH; confirm the supervisor still equals the pid file and the brain's parent is that supervisor; stop SUPERVISOR-FIRST so no child respawns; and report failure EXPLICITLY rather than escalating scope. Any mismatch or unreadable identity STOPS the action. No PID-only automation and no product-guard bypass is approved. A cleanup step whose failure leaves state in a SHARED resource reports that residue as an identity the next consumer can act on — pid, path, command line — not merely as a failed step.\r\n- **Kin:** [[IR-42]] (pool enforcement speaks at the next build, not at claim time), memory rig-ownership-reap-only-your-own, reap-root-needs-authenticated-ancestry, e2e-leaked-daemons-shared-box, no-machinewide-killon-shared-runner.\r\n- **Ripe when:** before the next field run. NOT a one-line change: the stop route is small, but the identity re-verification, supervisor-first ordering and explicit failure reporting above are part of the fix and are what make it safe. · **Size:** small.\r\n\r\n### IR-123 — a helper that LOGS cannot also RETURN through stdout: `record` tees, so `face=$(face_report ...)` captures the log block and the acceptance gate can never pass\r\n\r\n- **Status:** OPEN, mechanism recorded 2026-09-13 (hertz, found by exercising the D2 successor; confirmed by doyle from a direct source read of frozen r10). **Frozen r10 is PRESERVED as-is**; the return channel is corrected in its successor only.\r\n- **Instance.** `record()` is `echo \"$1\" | tee -a \"$R/findings.txt\"` — it writes to the log AND to stdout, deliberately, so a live operator sees the run. `face_report()` calls `record` twice (a FACE_COUNTS line and a FACE= line) and then `echo`es the face as its return value. The single caller reads it as `setup_face=$(face_report \"$SETUP_OUT\" \"$SETUP_ERR\" \"SETUP\" bootstrap)`, so the captured value is **the whole tee'd log block with the face appended**, and `[ \"$setup_face\" != reconciled ]` is true no matter what the product printed. The Arm-B acceptance gate — rc 0 AND face reconciled AND pair written, all three required — is therefore **unpassable on the ACCEPTED path**.\r\n- **Why no rig run caught it.** The stub cases that reached this line were REFUSALS, whose expected outcome is exactly the branch the defect forces (exit 3, Arm B held). A gate that always refuses looks identical to a gate that correctly refused a refusal. The accepted path had no arm at all until the D2 successor's control ran one with `LAN_FIREWALL_RECONCILED`, exit 0 and a pair measured present — see memory `setup-suppresses-failing-arm`.\r\n- **The same shape, twice more, in the successor's own new code** (both caught by the same control, both mine): `D2_T1_VALID=$(d2_validate_at t1)` captured the validator's tee'd log ahead of its verdict; and `local point=\"$1\" doc=\"$R/d2-$point.json\"` rebuilt [[IR-121]]'s declaration-ordering defect, so three documents present on disk all read `NO_DOCUMENT`. The precedent for the fix was already in the same file: r10's own `handoff_request` comment records that `spec=$(handoff_request ...)` was broken by exactly this tee and was repaired by setting parent globals and returning nothing on stdout.\r\n- **Scope of what this does and does not invalidate (doyle).** It does NOT invalidate r10's observed product refusal: the named rule reported `[5, 20]` and positive reconciliation was independently absent. It DOES invalidate any claim that the frozen rig could have admitted a successful setup — that path was never reachable.\r\n- **Mechanism.** A dual-purpose channel: the same stream carries human-readable logging and a machine-read value, so any helper that logs before returning hands its caller both. It fails silently and in the direction that looks conservative (a gate that refuses), which is why it survives review and why refusal-only exercises confirm it.\r\n- **Rule.** A function that calls `record` (or any logger that writes to stdout) **returns nothing on stdout**: it sets a named global, or writes its value to a file the caller reads. Every acceptance gate is exercised on BOTH paths — an accepting arm with real positive evidence and a refusing arm — because an acceptance test alone cannot distinguish a working gate from one that accepts everything, and a refusal test alone cannot distinguish a working gate from one that refuses everything.\r\n- **Kin:** [[IR-121]] (a wrong value with no error, same file), [[IR-118]], memory setup-suppresses-failing-arm, make-a-new-rig-red-on-purpose, every-return-arm-is-a-copy, zero-match-filter-reads-as-absent.\r\n- **Ripe when:** now — the successor already carries the fix at its call sites and in its own helper; the register entry is the part that outlives this lane. · **Size:** procedure.\r\n\r\n### IR-124 — a cleanup that runs `serve lan --stop` UNCONDITIONALLY creates the daemon it exists to remove, when the setup it is cleaning up after never ran\r\n\r\n- **Status:** OPEN, measured once in the field. D2 field run `20260913T041410Z`, driver `2e3aec1b`, recorded by hertz 2026-09-13 at doyle's direction. Archive `.spt/preserved/hertz-fp-driver-review/d2/field-run-20260913T041410Z/` (72 files, manifest `defa5d29…`). **This is a RIG defect. It is mine — I wrote the driver — and doyle's admission review missed the unconditional stop path as well; both are recorded because a review that misses a path is part of the mechanism, not an aside.**\r\n- **Instance.** The elevated setup was **DECLINED and NOT STARTED** by liam at 04:18:55Z — measured, unambiguous, and the right call: his leg was ready at 04:18:35Z against a hard 04:19:10Z expiry and he refused rather than race the teardown. Nothing ran, nothing mutated. The driver then entered cleanup and executed its own unconditional `env SPT_INSTALL_NO_FIREWALL=1 SPT_HOME=<isolated-home> <exe> serve lan --stop`, which dispatched through the daemon (`ensure_running`, `serveverb.rs:191`) and **CREATED** a supervisor (`daemon run --detached`, Windows PID 45944, `04:19:18.0312050Z`) and a brain (`daemon brain --generation 0 --start-reason cold`, PID 22524, `04:19:19.7696380Z`, parent 45944). `fp-home-d2`, measured ABSENT at the 04:13:58Z at-launch recheck, existed with `daemon.pid`, `brain.ready` and a full tree by 04:19:18Z.\r\n- **Why the hold could not stop it.** doyle held the elevated teardown for exactly this reason and liam held all commands. But this stop is **internal to the running driver**, not a handoff, so no authorization gate reached it: the only levers were killing the driver or editing a running script, and both are forbidden. **A guard that only governs dispatched work does not govern a step the subject performs itself.**\r\n- **The pre-dispatch markers named the mechanism and did not prevent it.** `daemon_may_run — serve dispatches through the daemon (ensure_running, serveverb.rs:191); the elevated leg may leave one running` was set BEFORE the setup was requested. The driver correctly refused to infer absence from its own expectation — and then triggered the very mechanism the marker warned about, from the cleanup path, on the branch where the warning did not apply.\r\n- **Three things kept apart, because collapsing any two misstates the run.** (1) Liam's testimony: NOT_STARTED, no mutation — still true, he created none of it. (2) The driver's conservative verdict: `CLEANUP=PENDING`, `residual_state=UNREADABLE`, `residue=UNMEASURED` — an honest refusal to claim clean, not a contradiction of liam. (3) An **actually observed** residual, created by the driver itself. That third thing is a measurement; the first two are testimony and abstention.\r\n- **Mechanism.** A teardown verb that is also a *start* verb. `serve lan --stop` must reach the daemon to ask it to stop, so invoking it when no daemon exists starts one. Cleanup paths are written for the case where setup succeeded, and are reached on every path including the ones where setup never happened; the branch nobody exercises is the branch where cleanup has nothing to clean.\r\n- **Rule.** A cleanup step whose command can CREATE the resource it removes must be **conditional on evidence that the resource exists** — not on the state markers, which say \"may exist\" by design, and not on the fact that cleanup was entered. Where the existence check is itself unavailable, the step is SKIPPED and reported as skipped, because an unnecessary teardown that spawns is strictly worse than a labelled gap. Exercise every cleanup path from the **setup-never-ran** state, not only from the setup-succeeded state.\r\n- **Kin:** [[IR-122]] (the other half: the stop that *cannot* run leaves a daemon; this is the stop that *should not* run and makes one), memory setup-suppresses-failing-arm, gate-against-documented-design, remedy-must-run-from-refusal-state.\r\n- **Ripe when:** before any repeat field run — a repeat under this driver reproduces the residue. · **Size:** small.\r\n\r\n### IR-125 — the driver's own executable sweep reported ZERO processes on the pinned exe while `Win32_Process` showed TWO, at the same instant\r\n\r\n- **Status:** OPEN, measured in D2 field run `20260913T041410Z` (hertz, 2026-09-13). **A FALSE-NEGATIVE SWEEP, not a false CLEAR** (doyle's classification, and the distinction is load-bearing): the ledger's actual verdict was `residual_state=UNREADABLE` / `CLEANUP=PENDING`, which was correct, and the sweep line is explicitly labelled evidence-only in the driver's own output.\r\n- **Instance.** `SUBJECT_EXE_PROBE=OK running_the_pinned_executable=0 enum_total=618` — the probe enumerated 618 processes and concluded none was running the pinned executable. A `Win32_Process` read moments later returned **two**, both with `ExecutablePath` exactly `…\\.worktrees\\304-w2-repr\\target\\release\\spt.exe`: PIDs 45944 and 22524. An independent sweep by path, not by pid, agreed: `count=2`.\r\n- **Why it matters despite being labelled evidence-only.** The line reads as a clean box to anyone skimming, and it is the only line in the run that speaks to \"is anything of ours still running\" in plain terms. It was contradicted only because a native read was performed for a different reason. Had the ledger's verdict logic depended on it, this is a false CLEAR.\r\n- **Candidate cause, NOT diagnosed** (deferred by doyle until cleanup was complete, and still open): the probe's raw path comparison. The Win32 `ExecutablePath` is backslashed Windows form; the driver's pinned `$EXE` is forward-slashed msys-friendly form. A literal comparison between those two spellings of the same file fails for every process. **Unconfirmed** — it is a candidate because it fits, not because it has been measured.\r\n- **Mechanism.** A predicate that can only ever return \"no\" reports a clean zero over a large, healthy-looking enumeration. `enum_total=618` is what makes it convincing: the instrument demonstrably ran and demonstrably saw the machine, and still could not see the thing it was looking for. Same family as the two other instrument-versus-reality mismatches in this lane, and all three were invisible to stubs.\r\n- **Rule.** A sweep that reports zero carries its own **positive control** — in the same run, the same predicate must find something known present, or the zero is UNMEASURED rather than absent. Where a predicate compares paths across the msys/Windows boundary, normalise both sides and prove the normalisation on a known-matching pair; never compare two spellings of a path and call a non-match an absence.\r\n- **Kin:** memory count-predicate-needs-its-own-positive-control, zero-match-filter-reads-as-absent, windows-firewall-census-clean-zeros, verdict-from-probe-competence, [[IR-118]].\r\n- **Ripe when:** with IR-124, before a repeat field run. · **Size:** small.\r\n\r\n### IR-126 — the experimental budget CONTAINED its own read-only preflight, leaving 128 s of a 300 s window for the elevated leg, and the leg was correctly declined\r\n\r\n- **Status:** OPEN, measured in D2 field run `20260913T041410Z` (hertz, 2026-09-13). Boundary NOT moved for that run — doyle refused the change mid-flight and was right to; this entry is the scheduling review he asked to be preserved.\r\n- **Measured, from the run's own timestamps.** Run start `04:14:10Z` · pre-setup absence census `04:16:23Z` · handoff request written `04:17:02Z`. So **172 s of the 300 s experimental budget went to in-budget read-only preflight** — CI axis queried by name across five statuses, ancestry census, six-instrument hashing, subject identity, 5470 guard baseline, pre-setup absence census — and the driver printed the remainder itself: `HANDOFF_WAIT bounded to 128s`.\r\n- **The consequence, and it is not hypothetical.** Liam's leg script was ready at `04:18:35Z`. Setup alone had measured ~9 s, plus four PowerShell stamps, plus a t1 capture of unmeasured duration, against 35 s of remaining clock. He DECLINED without mutation, which was the correct call and the one the instruction asked for. **The window was consumed before the work it existed for could start.**\r\n- **Two overruns recorded beside it, as observations and not as permissions.** Experimental activity ended at **306 s of the 300 s budget** (the deadline exits through the EXIT trap, so cleanup is never skipped, but the boundary was crossed). The driver was still running after its 180 s cleanup reporting bound had elapsed; it exited by `04:23:54Z`. Neither overrun was authorised, taken as an extension, or used to do more work.\r\n- **Mechanism.** A budget defined from process start, over a phase order that puts every read-only admission check inside it, gives the elevated leg whatever is left rather than what it needs. The preflight cost is not waste — those checks are why the run was admissible — but charging them to the same clock makes the window's usable size an accident of how slow the host's firewall enumeration is that minute.\r\n- **Rule.** Bound the ELEVATED LEG on its own clock, sized from its measured duration, and start it when the leg is dispatched. Admission checks get a separate bound. A driver that cannot guarantee a usable handoff window should REFUSE TO DISPATCH rather than dispatch a leg that cannot finish — an operator declining at the deadline is the correct outcome of a wrong window, not a failure of the operator.\r\n- **Kin:** [[IR-122]], memory your-cadence-can-be-the-blocker, reap-step-duration-is-not-the-window, twohost-run-window-discipline.\r\n- **Ripe when:** with IR-124 — a repeat field run under the current budget shape reproduces the squeeze. · **Size:** small.\r\n\r\n### IR-127 — a nested value-type assignment can leave the native job limit unset while the instrument logs the requested flag and a successful setter\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\r\n- **Instance.** The containment probe assigned `$info.BasicLimitInformation.LimitFlags = 0x2000`, logged the requested KILL_ON_JOB_CLOSE flag and `SetInformationJobObject=True`, read both owned processes as job members, closed the handle, and found both still alive. The nested field is a struct: PowerShell changed a copy, not the value subsequently marshalled. The offline discriminator measured `nested_assignment_flags=0`; modifying the nested value and assigning the whole value back measured `whole_value_assignment_flags=8192`.\r\n- **Correction and evidence.** The corrected probe assigns the whole nested value, calls `QueryInformationJobObject`, and refuses unless the kernel's flags equal the requested flags. Readback `0x2000` then preceded both members being measured GONE after close. Initial invalid arm and corrected measurement are preserved separately under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/` (`M3/` and `instrument-repair-20260913T104354Z/M3/`); the latter's `results.txt` carries the offline discriminator.\r\n- **Rule.** Mutating a nested interop value requires assigning that value back to its owner. Successful native setters establish only that the submitted value was accepted: read the effective configuration back and compare it before granting the operation authority. Requested flags are not observed flags.\r\n- **Kin:** [[IR-116]] (a successful call is not a post-state), [[IR-118]] (a complete-looking wrong answer).\r\n- **Ripe when:** any PowerShell/native configuration probe is authored or changed. **Size:** whole-value assignment plus checked native readback; retain the positive and negative discriminator.\r\n\r\n### IR-128 — PowerShell `$null` can become an empty native string, so a failed launch is misread as a policy refusal before the policy is reached\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\r\n- **Instance.** Both breakaway probe arms called a P/Invoke string parameter with PowerShell `$null`; both returned `CreateProcess` error **123** and created no child. This is an invalid-name result, not the **5** required to establish breakaway-policy denial. An offline C# string-parameter discriminator returned `IsNull($null)=False`: the PowerShell binder had supplied an empty string rather than native NULL.\r\n- **Correction and evidence.** A C# helper passes the executable explicitly, uses a mutable `StringBuilder` for `CreateProcessW`'s command line, and supplies C# null for the optional current directory. The repaired no-breakaway arm returned **5**, while the BREAKAWAY_OK contrast created a child measured outside the job and still alive after job closure. Original error-123 arms remain invalid and preserved under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/M5/`; corrected records live in its `instrument-repair-20260913T104354Z/M5-denied/` and `M5-allowed/`.\r\n- **Managed-string recurrence (group N).** The same binder coercion reached `[IO.File]::Replace($tmp, $record, $null)`: the optional backup path became empty, and publication failed with `The path is empty` before any subject was created. The initial N0 gate correctly refused; its partial record and exception are preserved under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T1109444702137Z-N/N0/`. The PowerShell publisher now uses the overwrite-rename overload `[IO.File]::Move($tmp, $record, $true)` instead of passing a nullable string. The corrected N0 reached the intended false coverage assertion; native C# publication retains a real C# null.\r\n- **Rule.** At native string seams, distinguish NULL from the empty string and verify what the language binder supplies. Use a typed native-call helper where this distinction is load-bearing. Classify the actual error code at the failing stage: a launch error before policy evaluation cannot establish a policy refusal. Command buffers documented writable must be mutable.\r\n- **Kin:** [[IR-113]] (a failure at the wrong stage is a void discriminator), [[IR-117]] (name the observation that refutes each branch).\r\n- **Ripe when:** any optional native string argument or process-creation probe crosses PowerShell's binder. **Size:** typed call seam and a null/empty discriminator.\r\n\r\n### IR-129 — JSON date materialization followed by implicit string parsing loses UTC kind and precision, turning a live creation anchor into a false pid-reuse verdict\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`. The first M8 exit 0 is explicitly INVALID.\r\n- **Instance.** `ConvertFrom-Json` materialized an ISO birth string as `DateTime`; `[DateTime]::Parse($id.created)` implicitly formatted that object back to text before parsing it. Kind and fractional precision were lost and local time was reinterpreted. The result printed birth timestamps agreeing within a microsecond but computed roughly seven-hour deltas, mislabelling four live registered identities `GONE_PID_REUSED`. The original output remains at `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/M8/`.\r\n- **Correction and evidence.** The reader handles `DateTime` values directly with `ToUniversalTime`; strings are parsed as `DateTimeOffset` and converted to UTC. Its live-self JSON-roundtrip control measured **9 ticks** difference; a deliberately 500-ms-skewed anchor measured **5,000,009 ticks** and could not match. The corrected final pass covered all **13** registered identities, found every one GONE, and retained the escaped child's earlier SURVIVING readings. Evidence: the same group's `instrument-repair-20260913T104354Z/all-identities-disposition.jsonl` and `final-disposition.stdout`.\r\n- **2026-09-14 recurrence caught before the field window.** The bound promotion instrument repeated the same reader/parse pair at its brain-birth guard. A language-only discriminator using that pair measured **251,998,765,433 ticks** error. Reading JSON with `-DateKind String` instead preserved the timestamp: same-anchor delta **0 ticks**, deliberately wrong 500-ms anchor **5,000,000 ticks** and refused by the unchanged **10-tick** guard. The successor changes only `Read-Json`; the original instrument remains intact. Evidence: `.spt/preserved/hertz-fp-driver-review/d2/promotion-date-discriminator-result.json` and `provision-promote-VGCTKD7A.ps1`. No field process was needed to expose this known hazard.\r\n- **Rule.** Treat deserialization's runtime type as part of the interface. Never reparse a typed date through implicit culture-sensitive formatting. Exercise both a same-process roundtrip and a wrong-anchor negative control; preserve raw timestamps and the computed delta so their agreement can be audited. Match at the actual reader resolution, not by discarding the fractional second.\r\n- **Kin:** [[IR-118]] (successful instrument, wrong answer), [[IR-125]] (an absence predicate needs a known-present control), [[IR-15]] (identity-aware liveness).\r\n- **Ripe when:** any JSON record is used to authenticate process identity or order events. **Size:** type-aware UTC conversion and two local controls.\r\n\r\n### IR-130 — a lowercase `$home` local collides with PowerShell's protected `$HOME`, refusing custody qualification before the signer is reached\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz on 2026-09-13 in the D2 custody lane; narrow correction and one fresh-root attempt authorized by doyle `5FWLC3F2`. Original refusal remains preserved.\r\n- **Instance.** The prepared custody controller passed syntax parsing and compiled its native observer successfully, then exited **1 after 3.33 s** before any custody arm. Its next statement assigned `$home = Join-Path $armRoot 'home'`. PowerShell variable names are case-insensitive: this is an assignment to automatic `$HOME`, whose measured options were **ReadOnly, AllScope**. A separate language-only reproduction returned **VariableNotWritable**. The original catch deliberately omitted exception details, so that error ID belongs to the minimized reproduction; the original record carries the generic refusal and `arms=[]`.\r\n- **Boundary and evidence.** Compiler native exit **0**, `COMPLETE`, `CONFIRMED_GONE`, active processes **0**; a public fixture and empty `custody-normal` directory existed, but no home, subject arguments, dummy EnvironmentFile, observer execution, signer, git child, real key, or field rig existed. Evidence: `.spt/preserved/hertz-fp-driver-review/d2/AZLCQNZL-CUSTODY-REFUSAL.txt`, `AZLCQNZL-home-variable-repro.json`, `AZLCQNZL-custody-failure-inventory.json`, and `controls-out/custody-6U2UZVXK/`.\r\n- **Correction.** Rename the local to `$qualificationHome` at its assignment/directory call and environment-overlay reference (two source lines), re-pin the controller, and use a fresh qualification root. Do not relax automatic-variable protection, reuse the failed root, or classify this as a rejection of the assembled xtask's seed isolation. The authorized retry's result is separate evidence, not a rewrite of the first attempt.\r\n- **Rule.** PowerShell locals share a case-insensitive namespace with automatic variables: use role-specific names rather than `$home`, `$host`, or `$pid`. Syntax acceptance and a successful subordinate compiler do not prove that controller initialization reached its behavioral discriminator. State the last stage actually executed; an empty retirement list is not evidence that secret-bearing processes ran and were cleaned.\r\n- **Kin:** [[IR-113]] (wrong-stage refusal is a void discriminator), [[IR-128]] (language-boundary failure before the intended policy), [[IR-118]] (plausible result without the claimed observation).\r\n- **Ripe when:** any PowerShell orchestration or custody controller is authored or changed. **Size:** two-line naming correction plus retained refusal and fresh-root qualification evidence.\r\n\r\n### IR-131 — a live-agent signing environment leaks into the provisioning process and correctly refuses before the private signer exists\r\n\r\n- **Status:** OPEN, rig invocation-environment defect, not a candidate or disk defect. Measured by hertz on 2026-09-14; classified by doyle in `VGCTKD7A`.\r\n- **Instance.** Second fresh #297 preparation admitted fourteen native leaves at `04:51:39.245Z`. The separate provisioning call launched at `04:51:52.802Z` and returned `STAGING_FAILED_PREFLIGHT`, native exit **1**, after **0.45 s**. No rig, private directory, key or field nonce existed. This was a preflight refusal before the `04:59:31Z` deadline, not a stalled launch.\r\n- **Exact check.** A read-only preflight discriminator surfaced `AMBIENT_SIGNING_SECRET_REFUSED` from `Assert-SeedAbsent`. A names-only environment probe found `SPT_RELEASE_SEED` **present**; `SPT_DEBUG_RELEASE_SEED` and `SPT_RELEASE_SEED_CMD` were absent. No values were emitted or changed. The refusal reproduced with **102,099,394,560 bytes free**, and the failing check reads process environment before filesystem preflight: reclaiming disk cannot cure this guard.\r\n- **Evidence gap.** The original catch persisted a failure JSON only after `$publicReady`, set after preflight. Earlier throws produced only a generic stderr phase and an empty evidence directory. Preserve safe, fixed preflight reasons and caller exit evidence before mutation; silence in the directory is not evidence that the command never ran. Original artifacts remain unchanged under `.spt/preserved/hertz-fp-driver-review/d2/`; see `IH4QFFXS-execution-boundary.json`, `X2LPSQ7A-preflight-only-result.json`, and `X2LPSQ7A-signing-env-presence-result.json`.\r\n- **Rule.** Scrub the environment handed to the **provisioning PowerShell process itself**, not merely its later signer child: remove every ambient `OWL_*`/`SPT_*` key except the leg's declared allowlist, recording names before/after, never values. Preserve the live agent's parent environment and lifecycle. The guard remains strict. The new debug signing seed enters only the controlled signer's private `EnvironmentFile`; it never becomes ambient in the provisioning process or helpers.\r\n- **Scrub qualification.** The fresh-child receipt recorded `before_names=[\"SPT_ENDPOINT_ID\",\"SPT_RELEASE_SEED\"]`, `after_names=[]`, and parent names unchanged. This exposed the next startup error: `Stop-Transcript -ErrorAction SilentlyContinue` throws a terminating exception when the required fresh `-NoProfile` host is not transcribing. The successor removes that invalid stop, not the forced-logging policy checks or seed guard. The complete no-mutation preflight then exited **0** with `PREFLIGHT_ONLY_PASS_NO_MUTATION`; no third preparation clock had begun. Evidence: `VGCTKD7A-preflight-result.json`, `VGCTKD7A-preflight-clean-result.json`, and `VGCTKD7A-preflight-clean-environment.json` plus its exit receipt.\r\n- **Kin:** [[IR-107]] (live-agent identity leaking into consumer/test legs), [[IR-130]] (preflight failure hidden by phase-only reporting), [[IR-122]] (live operational context is not an isolated rig).\r\n- **Ripe when:** any leg is launched from a live-agent session. **Size:** explicit child environment boundary and durable preflight evidence; no candidate change.\r\n\r\n### IR-132 — requiring every live-fleet `spt.exe` image path to be readable permanently refuses an isolated rig's admission\r\n\r\n- **Status:** OPEN, rig-instrument admission defect, not a candidate, environment-scrub or disk defect. Measured by hertz and independently localized by doyle on 2026-09-14; correction ruled in `W8TQ3MZC`, `6IQ4HYIL`, `QKQC2NET` and `MRQX7XEK`.\r\n- **Instance.** Third preparation passed fourteen native admission leaves and genuinely staged the signed set. Promotion then returned `PROMOTION_ADMISSION_FAILED`, native **1**, with `native_records=[]` and shutdown `NOT_STARTED`. Its census required a nonblank CIM `ExecutablePath` for **every** `spt.exe`, not merely one that could belong to the new rig. The read-only predicate replay passed twenty-five preceding statements and failed `SPT_PROCESS_PATH_UNREADABLE` at line 273. No apply, daemon, field nonce or firewall mutation occurred. Receipt: `.spt/preserved/hertz-fp-driver-review/d2/GEL6JAWN-FINAL-REFUSAL.json`.\r\n- **Shared-box mechanism.** The subsequent census exposed persistent PID **52860**, birth `2026-09-12T20:17:00.5331330Z`, with readable birth but unreadable image path; the rig did not exist until `2026-09-14T05:45:32.8201734Z`. Doyle additionally measured blank paths in **12/12** samples, with transient CLI children alongside the persistent process. An image-readability requirement cannot admit this live shared box. Missing per-rig state files remain an independent gate, not a substitute for process-identity reasoning.\r\n- **Correction.** Capture `(pid, CIM CreationDate)` together. A birth provably earlier than rig creation excludes that identity without needing its image; the **10-tick** precision allowance only narrows this exemption. Later or overlapping blank-path identities use the existing limited-query native image/birth/retained-handle seam. A native failure is unresolved, not gone. A successful immediate CIM re-read with a live positive control can establish absence; access-denied or failed queries cannot. PID reuse records the original identity gone and classifies the replacement independently. Unknown birth or a persistent unresolved identity refuses. No fleet-process termination is permitted.\r\n- **Evidence.** Fourteen discriminator cases cover pre-rig exemption, native image resolution, known rig refusal, disappearance versus denied/failed queries, dead-provider control, unknown/equal/precision-overlap births and PID reuse. The final successor passed all fourteen. A read-only live run admitted **17** census hits, including 52860 as `PREDATES_RIG`; actual native self controls measured a **5-tick** CIM/native birth delta, admitted the other-image case and refused the same-image case. Proof: `W8TQ3MZC-census-controls-final.json` and `W8TQ3MZC-census-live-result.json` beside the receipt. Neither proof invoked the product or mutated the rig.\r\n- **Rule.** Admission asks whether an observed identity can belong to the owned rig, not whether the caller can read every process on the host. Preserve query failure, confirmed absence and replacement identity as different outcomes, with pid and birth in the receipt. Re-pin changed instruments; preserve failed windows and obtain a fresh grant rather than extending their clocks.\r\n- **Kin:** [[IR-107]] (live operational context enters the rig), [[IR-129]] (creation-time type/precision), [[IR-125]] (known-present control for absence), [[IR-15]] (identity-aware liveness).\r\n- **Ripe when:** a rig shares a host with elevated perches or short-lived CLI traffic. **Size:** birth-aware census and retained native identity probe, with fail-closed boundary controls.\r\n\r\n### IR-133 — a live capture cannot be read with read-only sharing, and daemon stderr belongs to the owned home\r\n\r\n- **Status:** Corrected in the r9 rig instrument; genuine fifth-window promotion completed with exit **0**, owned shutdown and final provenance. The subsequent field attempt failed its separate setup-handoff deadline, not this promotion read. Fourth #297 preparation measured by hertz on 2026-09-14; sharing failure localized by doyle in `R2VK8FQN`, run-identity binding ruled in `ANR522S5`, successor accepted in `GV3R6QUV`.\r\n- **Instance.** Fourteen admission leaves and genuine staging passed. The candidate applied daemonlessly, transitioned `applied-pending` → `applied`, brought up broker **14704** and brain **45220**, published the pinned generation-zero readiness record and emitted `BRAIN_PROMOTED` before the instrument stopped its owned job. The instrument returned only `OWNED_PROMOTION_READINESS_FAILED`. Six provisioning/promotion native jobs ended `CONFIRMED_GONE`, active counts zero; all nineteen signing-private files were absent. No field, GO or D3 occurred. Original receipt: `.spt/preserved/hertz-fp-driver-review/d2/W8TQ3MZC-FINAL-REFUSAL.json`.\r\n- **Mechanism.** The loop used `File.ReadAllText` on a capture held open for **Write**, with **Read** sharing, by the run-scoped launcher. Windows checks sharing in both directions: the new reader's default **Read** sharing excludes the existing writer, causing `IOException`, `0x80070020`. A completed step hid this defect because its writer had already closed. Changing only the writer's sharing does not repair the reader.\r\n- **Wrong source behind the exception.** The launcher's stderr capture was zero bytes; the daemon redirects stderr to `SPT_HOME/logs/daemon.stderr.log`. Reading the empty capture with compatible sharing would merely reach the later marker timeout. Read the actual owned-home log with `FileStream(Open, Read, FileShare.ReadWrite | FileShare.Delete)`, matching the existing native launcher's `ReadText` pattern; release each read handle before the next poll.\r\n- **Run binding.** A promotion marker counts only after the exact brain header naming the measured membership PID and readiness generation, and before another process header. Markers before that header, without it, or under another PID/generation refuse. A rolled `.1` can contribute only when absent before this owned launch and appearing during it, with the same header binding; preexisting backups cannot prove this run.\r\n- **Failure evidence.** Attach the instrument's constant assertion name and call-site line to its exception. Before cleanup can replace the active error, retain that name, source line, exception type and HResult. Non-assert exceptions have a null assertion name. Never serialize exception messages or environment values.\r\n- **Qualification.** Thirteen controls passed against `provision-promote-R2VK8FQN.ps1`: a live-held writer reproduces `0x80070020` with `ReadAllText`, the shared reader returns its exact bytes while the writer remains open, header/PID/generation/ordering and rolled-history boundaries refuse stale evidence, the actual rollback guard still refuses, and diagnostics omit a message canary. Proof: `R2VK8FQN-live-held-controls/result.json` beneath the receipt directory. No product invocations, rig mutations or fleet terminations.\r\n- **Live verification.** `provision-R2VK8FQN/promotion-complete.json` records `PROMOTION_COMPLETE`; the supervised promotion exited **0** after **12.9 s**. The real candidate passed the shared-log, PID/generation marker, final membership, durable-state and owned-shutdown checks. Its later field ledger remains a separate failed observation contract; successful provisioning does not turn that ledger green.\r\n- **Kin:** [[IR-132]] (instrument census refusal), [[IR-130]] and [[IR-131]] (phase labels lose the failing predicate). **Ripe when:** polling any live writer or accepting logs as run-specific evidence.\r\n\r\n### IR-134 — request latency consumes the elevated capture's execution budget, then a late terminal receipt leaves completed work unmeasured\r\n\r\n- **Status:** Instrument correction qualified without a sixth field window. Doyle accepted the execution-clock repair in principle under `HHDKCRH5`, then identified its still-insufficient receipt budget; the derived-window successor follows ruling `P9RLK4VU` and accepted arithmetic `KZG4IN37`. Candidate/packet/nonce/driver/runner repinning remains one future amendment, separate from field authorization. Fifth #297 field run `20260914T063552Z` remains failed and immutable. Its candidate's independent **PRODUCT RED** finding (`M5XKQ2DN`) is unchanged.\r\n- **Measured sequence.** Setup request `06:41:26Z`, elevated setup `06:43:18Z`–`06:43:24Z`, refused capture launcher `06:43:25Z`–`06:43:26Z`, receipt about `06:43:27Z`. The driver had written the capture deadline from request time: 112 seconds of handoff delay left the launcher's `deadline - now - 5` allocation at **−4 seconds**. No native t1 capture ran. The handoff expired before the receipt; cleanup reread its nonce and exit but retained the earlier `timestamp_order=UNMEASURED`, withholding mutation despite subsequently available terminal stamps.\r\n- **Clock correction.** The executor initializes `setup-start.utc`, `elevated-leg-start.epoch` and `d2-t1.deadline` immediately before `run_exactly`, from one UTC observation, with **CreateNew** writes. The independent allocation is **120 seconds**: the existing 90-second capture ceiling, 9 measured seconds around a refused capture, 5-second termination reserve and 16-second margin. Nine seconds is not a measurement of a successful capture. PREPARE initializes nothing; notification latency consumes only the separately bounded handoff. No preparation or activity window is reset or extended.\r\n- **Terminal evidence correction.** On handoff expiry, cleanup makes one final nonce/exit observation and, if terminal, rereads the six stamps before deciding whether completion is proven. A late observation preserves `handoff_wait=EXPIRED` and the original timeout exit separately from `setup_terminal_exit`; it never resumes activity or treats lateness as timely acceptance. Missing, duplicate or wrong nonce evidence and missing or reversed stamps remain unproven. An exceeded leg clock refuses the capture contract independently of terminal completion.\r\n- **No-field proof.** `.spt/preserved/hertz-fp-driver-review/d2/AQ23KKNI-controls/` preserves the actual extracted predecessor/successor predicates, emitted PowerShell initializer, nine receipt/product controls, five clock/ledger controls and clock results. The predecessor retained UNMEASURED after receipt publication; the successor recovered ordered completion without overwriting timeout. The actual initializer refused a second initialization without changing any clock bytes. With the measured 112-second notification delay and capture at leg-start +7, the old allocation is −4 seconds and the new allocation is 90 seconds. No product, firewall, signing or field operation was invoked.\r\n- **The outer-clock blocker, not fixed by the inner clock.** A receipt follows execution: **112 + 120 = 232 seconds** cannot fit the retained 120-second setup handoff. Keeping a 300-second activity window and refusing every GO would be a correct refusal of the wrong shape, not an executable field design. `P9RLK4VU` therefore re-derives future activity as **630 seconds**: pre-dispatch **74** (54 observed +20 margin), setup handoff **240** (112 latency +120 leg +8 margin), post-receipt probes **200**, t2 **100**, final transition **16**. Only setup supersedes the prior 120-second handoff cap; other handoffs retain it.\r\n- **Measured basis and explicit allowance.** The fifth timeline records portfields calls at up to **45 seconds**, census **46 seconds**, and t3 **25 seconds**; the earlier `20260913T041410Z` capture also took 25 seconds. Two analogous portfields calls plus census give **136 seconds**; another **64 seconds** is a labelled allowance for identity capture, D1 and bookkeeping, not a claimed complete post-receipt measurement. T2 receives a **90-second native ceiling**, **5-second launcher reporting reserve** and **5-second shell/reporting margin**. The post-receipt probe deadline cannot spend t2's allocation; t2 cannot spend the final transition reserve.\r\n- **Derived-window controls.** `P9RLK4VU-controls/result.json` records **16 passing controls**, executing extracted real Bash predicates and the wait loop against a virtual wall clock. The complete 630-second window and the measured 54-second pre-dispatch cost pass; 555 seconds remaining fails against the 556-second dispatch requirement, while 556 fits. The actual gate refuses before GO/mutation markers. A receipt after 112-second latency plus 120-second execution fits the new setup allowance; PREPARE and cleanup retain their 120-second caps. Published request and phase deadlines still truncate waits. Preparation remains **600 seconds** and cleanup remains **180 seconds including its 30-second ledger reserve**; an observation deadline cannot override cleanup. No product or field operation was executed.\r\n- **Separate product finding.** Candidate `b8482445` logged one `verify-query` completed at **2650 ms**, followed by a second pre-write snapshot killed at **3027 ms** under its **3000 ms** budget; no reconcile-write ran. The budget **starts before spawn and includes output collection** (`run_ps_inner`, source timing supplied by doyle in `IRXYIJHS`); spawn is not outside this clock. The successor ledger records this query kill separately from handoff/capture failure. Fifth-window cleanup was subsequently closed on existing measurements as **NOTHING_TO_REMOVE**; its original PENDING ledger was not rewritten.\r\n- **Kin:** [[IR-126]] (execution receives leftover scheduling time), [[IR-124]] (cleanup must not race unproven setup). **Rule:** measure execution from execution, preserve timeout and late completion as separate facts, and do not let an instrumentation repair erase a product failure.\r\n\r\n### IR-135 — checker pin and runner installation can disagree, and the repair path disguises that version mismatch as an authentication failure\r\n\r\n- **Status:** CI precheck remedy implemented in the IR-135 lane; workflow execution awaits integration. Measured by doyle in S4 golden `34946493637`, 2026-09-15; filed by hertz from `3HHHPWCR`. The immediate box mismatch was repaired by hand-install.\r\n- **Instance and mechanism.** The #304 candidate carried `71caedd4`, setting `WANT=0.4.1` in `golden.yml`/`ci.yml`, while kitsubito's `~/.local/bin/traceable-reqs` was **0.2.0**. The install step's mismatch path attempted a private clone without a provisioned `TRACEABLE_REQS_TOKEN` and exited **128 before any check**. The visible failure named authentication, not the wanted and installed versions. A checked-in pin is not evidence that the runner can supply it; the fallback requires a second, independently missing prerequisite.\r\n- **Implemented remedy (QD54OM7S).** Both workflows run an explicit pin/runner precheck and use `.github/ci/traceable-reqs.sh` as the single pin/install owner. It reports the actual version and native version exit; matching requires literal equality and exit zero. A mismatch without `TRACEABLE_REQS_TOKEN` refuses before clone/build, naming the version disagreement and missing credential separately. With a token present, source repair remains available and native clone failure is preserved; token presence never claims access. The installed version is checked before coverage. On kitsubito, eight isolated shell controls passed: matching precheck/install without a token, stale/missing/failing/lookalike versions refused, authenticated repair admission, and clone exit128 retained. The predecessor failed the stale/no-token discriminator with128; the successor refused with1 and both diagnostics. A separate smoke used kitsubito's real0.4.1 binary through both entry points without a token, exit0. No live credential was provisioned or private-source build exercised. Contract and reproduction command: `docs/TRACEABILITY.md` §CI checker admission and installation. PAT provisioning remains the operator's decision, banked since2026-07-30.\r\n- **Kin:** [[IR-104]] (the checker version changes what counts as evidence), [[IR-109]] (the #304 pin is already live). **Ripe when:** the next checker pin or golden-intake/install-step change. **Size:** a version diagnostic and intake assertion; credential provisioning is separate operator work.\r\n\r\n### IR-136 — a broker bound under the seed socket's name is not seed control, so a URL-minting rig can omit the very listener contract the product queries\r\n\r\n- **Status:** Instance fixed in S5 **`ddd7fc7f070667524578c282894dd44a2e36062f`**, test-only atop S4; S5 golden34957614641 passed, including both twohost roles. Shared fixture-composition remedy implemented and Linux-verified in the IR-136 lane. Origin: doyle's S4 golden `34946493637` twohost helper red, 2026-09-15.\r\n- **Mechanism.** Role B hosted broker IPC under an invented name, with neither `seedmap::serve_seed_control` nor a docs listener. `REQ-WEB-URL-BOUND-PORT` requires `serve_for` to ask the canonical seed-control plane for `DocsStatus` before publishing a URL; the missing plane returned `DOCS_PORT_DISCOVERY_FAILED: Connection refused (os error 111)`. Merely renaming a Broker to `seed_socket_name()` does not provide that protocol: `serve_request` is dispatched by seed control, not Broker. The docs-server fixture had already encountered the same trap. The last green twohost run predated this bound-port contract.\r\n- **Discriminator and scope.** Todlando's unchanged-S4 Linux fixture failed at the exact discovery seam without seed control/listener (**native 101**) and returned `Registered` at the actual bound port **33319** when those fixtures were added (**native 0**); both arms retained the invented B broker name. Evidence: `.spt/preserved/304-web-helper-rca/linux/`. S5 gives B distinct canonical broker/seed sockets, real seed control, a broker-backed ephemeral docs listener, and a discovered-port equality precondition. Helper expectations stay unchanged. A's helper cell relays B's returned URL and does not query its own DocsStatus; its existing broker-on-seed-name path is not this failure. The seven unopted-in Windows passes do not exercise the role-gated twohost bodies.\r\n<!-- [doc->REQ-SERVING-FIXTURE-CONTROL-PLANE] -->\r\n- **Shared remedy (P2Y2GWUP).** `crates/spt-daemon/tests/support/serving.rs` provides `ServingFixture`, included by both `docs_server_e2e` and `twohost_web` rather than exported as product surface. `start` composes the distinct canonical broker and real seed control, waits for seed readiness, binds broker-backed docs on port0, and asserts that seed-control `DocsStatus` returns that actual port. The caller supplies its private home, journal and optional NetHost; socket spelling is no longer a caller choice. `stop` stops and joins both IPC accept loops. The docs listener remains process-lifetime under the existing production interface, so tests require process-per-test isolation and one broker-backed listener per process.\r\n- **Negative-state coverage retained.** The docs fixture uses the separate `control` stage only to distinguish absent control (offline fallback permitted) from running control without a listener (fallback refused); its normal serving case uses the same complete constructor as role B. Role A's seed-named proxy Broker and the standalone docs-less listener remain intentionally separate: neither is the owner's URL-minting control plane. No default/configured port substitutes for discovery, and no production protocol changes.\r\n- **Shared-fixture proof (2026-09-15).** Kitsubito, private tree/target, jobs2: targeted clippy with `-D warnings` **0**; nextest, both migrated binaries, one test thread and zero retries **0**. All **3 docs cases** exercised their real bodies: absent-vs-unbound discovery, HTTP published-surface/security checks through the complete fixture, and the standalone docs-less pointer. The other **7 twohost cases** returned through their unopted role gate; these are compile coverage, not a new cross-host execution claim. Traceable0.4.1: **920complete/0findings**. Raw exits/output/hashes: `.spt/preserved/hertz-ir136-fixture/linux-v2/`; the initial wrapper PATH failure started no cargo and is preserved separately.\r\n- **Ripe when:** another URL-producing fixture is added. Use the shared complete constructor rather than rebuilding its three planes independently; use the partial stage only when missing-listener behavior is the test subject.\r\n\r\n### IR-137 — a redirected Start-Process child can share the tool call's console lifetime and die when that call returns\r\n\r\n- **Status:** RETIRED, 2026-09-15, doyle ruling `YPLFG3CG`: **no tracked callsite; discipline recorded + receipt**. This closes a Windows ad-hoc rig-craft item, not a CI or candidate defect; no helper or product change.\r\n- **Mechanism and rule.** `Start-Process` with redirected output from a PowerShell tool call was observed to end with **`STATUS_CONTROL_C_EXIT`** when the tool call ended: a returned child PID did not establish detachment. The reported detached form uses a **hidden window without redirects**. Where a child must outlive the call, qualify its survival after the caller returns and give it a durable output path of its own; do not treat process creation or a hidden window alone as lifetime evidence.\r\n- **Origin clarified (YPLFG3CG).** Claude Code PowerShell tool host, 2026-09-15T07:17Z, #304 S3 Windows attempt-2 launch A: redirected `Start-Process pwsh` PID47560; `rustc` exited `0xc000013a` seconds after the tool returned, driver receipt contained only its start line and no refusal file. The same driver relaunched with `-WindowStyle Hidden -PassThru` and no redirects (PID37536) ran25minutes to exit0. There is no tracked failing launcher to repair; the existing tracked g6 launcher already uses the reported good shape.\r\n- **Discipline and receipt.** [Windows ad-hoc rig launch discipline](GOLDEN-CI.md#windows-ad-hoc-rigs-that-outlive-the-tool-call) states the shape, child-owned durable output and post-return PID/birth/output qualification. Preserved harmless-child receipt: `.spt/preserved/hertz-ir137-caller-return/receipt.json`, SHA256 **`e1c9b207544e6313eac5421ebb692786ec18b3a165756b451bff3a704899b178`**. Both valid arms survived under **OMP**, wrote post-return events and exited0; an initial observer-handshake timeout is excluded. All3probe children ended and native handles closed. This does not reproduce the **Claude Code** failure; the host boundary stays explicit. Reopen only for a newly owned callsite or contrary evidence, not to build an unused helper.\r","startLine":6769,"lineNumbers":[6769,6770,6771,6772,6773,6774,6775,6776,6777,6778,6779,6780,6781,6782,6783,6784,6785,6786,6787,6788,6789,6790,6791,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,6810,6811,6812,6813,6814,6815,6816,6817,6818,6819,6820,6821,6822,6823,6824,6825,6826,6827,6828,6829,6830,6831,6832,6833,6834,6835,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,6847,6848,6849,6850,6851,6852,6853,6854,6855,6856,6857,6858,6859,6860,6861,6862,6863,6864,6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,6878,6879,6880,6881,6882,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893,6894,6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,6905,6906,6907,6908,6909,6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,6921,6922,6923,6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934,6935,6936,6937]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"middle","truncatedBy":"middle","totalLines":169,"totalBytes":54464,"outputLines":123,"outputBytes":40632,"maxBytes":40960,"headRange":{"start":1,"end":68},"tailRange":{"start":116,"end":169},"elidedLines":47,"elidedBytes":13853,"artifactId":"732","nextOffset":6938}}},"isError":false,"timestamp":1789483669346}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_52Jm9jS2HvdzvgO7GV2Jtefh|fc_000c7cef03cac861016aa95aa394a087d1944f537678374a58","toolName":"read","startedAt":"2026-09-15T14:48:03.648Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6567-6711:raw"},"intent":"Recovering omitted policy entries"},"id":"892af14f","parentId":"e10fbab6","timestamp":"2026-09-15T14:48:03.648Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_2IGSye7spdRTE53b7IVjRIX6|fc_000c7cef03cac861016aa95aa394b087d18fd08c07672129b7","toolName":"read","startedAt":"2026-09-15T14:48:03.648Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6837-6888:raw"},"intent":"Recovering instrument corrections"},"id":"c1979897","parentId":"892af14f","timestamp":"2026-09-15T14:48:03.648Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_5SC73LBYbynWTk3TB4TBE7Wq|fc_000c7cef03cac861016aa95aa394b487d19afa73ed25f51f2f","toolName":"grep","startedAt":"2026-09-15T14:48:03.648Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs;.wo…"},"intent":"Checking shipped small remedies"},"id":"fe008097","parentId":"c1979897","timestamp":"2026-09-15T14:48:03.648Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_BWgHB0WgbZ4MGEdGwkEa3y09|fc_000c7cef03cac861016aa95aa394bc87d1bb5dc561ac768e35","toolName":"grep","startedAt":"2026-09-15T14:48:03.649Z","args":{"path":".worktrees/hertz-ir86-disk-delta/AGENTS.md;.worktrees/hertz-ir86-disk-delta/.github;.worktrees/hertz-ir86-disk-delta/xtask/src;.worktrees/hertz-ir86-disk-delta/traceable-reqs.toml;.worktrees/hertz-ir8…"},"intent":"Checking current shared mechanisms"},"id":"4728c1f8","parentId":"fe008097","timestamp":"2026-09-15T14:48:03.649Z"}
{"type":"message","id":"322e9538","parentId":"4728c1f8","timestamp":"2026-09-15T14:48:03.649Z","message":{"role":"assistant","content":[{"type":"toolCall","id":"call_52Jm9jS2HvdzvgO7GV2Jtefh|fc_000c7cef03cac861016aa95aa394a087d1944f537678374a58","name":"read","arguments":{"i":"Recovering omitted policy entries","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6567-6711:raw"},"intent":"Recovering omitted policy entries"},{"type":"toolCall","id":"call_2IGSye7spdRTE53b7IVjRIX6|fc_000c7cef03cac861016aa95aa394b087d18fd08c07672129b7","name":"read","arguments":{"i":"Recovering instrument corrections","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6837-6888:raw"},"intent":"Recovering instrument corrections"},{"type":"toolCall","id":"call_5SC73LBYbynWTk3TB4TBE7Wq|fc_000c7cef03cac861016aa95aa394b487d19afa73ed25f51f2f","name":"grep","arguments":{"i":"Checking shipped small remedies","pattern":"IR.?78|IR.?82|IR.?90|IR.?94|DAEMON_SUCCEEDS_PID|daemon.pid.prev|free.space|disk.*floor","path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs;.worktrees/hertz-ir86-disk-delta/xtask/src/brainread.rs","case":false,"gitignore":false,"skip":null},"intent":"Checking shipped small remedies"},{"type":"toolCall","id":"call_BWgHB0WgbZ4MGEdGwkEa3y09|fc_000c7cef03cac861016aa95aa394bc87d1bb5dc561ac768e35","name":"grep","arguments":{"i":"Checking current shared mechanisms","pattern":"IR.?79|IR.?88|IR.?76|IR.?106|IR.?107|IR.?109|module_banner|DaemonReaper|kill.scop|0\\.4\\.1","path":".worktrees/hertz-ir86-disk-delta/AGENTS.md;.worktrees/hertz-ir86-disk-delta/.github;.worktrees/hertz-ir86-disk-delta/xtask/src;.worktrees/hertz-ir86-disk-delta/traceable-reqs.toml;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/common","case":false,"gitignore":false,"skip":null},"intent":"Checking current shared mechanisms"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":41361,"output":418,"cacheRead":60416,"cacheWrite":0,"totalTokens":102195,"cost":{"input":0.41361000000000003,"output":0.020900000000000002,"cacheRead":0.060416,"cacheWrite":0,"total":0.4949260000000001}},"stopReason":"toolUse","timestamp":1789483669376,"responseId":"resp_000c7cef03cac861016aa95a95a00c87d1a63347ddc47ba755","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"fc_000c7cef03cac861016aa95aa394a087d1944f537678374a58","type":"function_call","status":"completed","arguments":"{\"i\":\"Recovering omitted policy entries\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6567-6711:raw\"}","call_id":"call_52Jm9jS2HvdzvgO7GV2Jtefh","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95aa394b087d18fd08c07672129b7","type":"function_call","status":"completed","arguments":"{\"i\":\"Recovering instrument corrections\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6837-6888:raw\"}","call_id":"call_2IGSye7spdRTE53b7IVjRIX6","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95aa394b487d19afa73ed25f51f2f","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking shipped small remedies\",\"pattern\":\"IR.?78|IR.?82|IR.?90|IR.?94|DAEMON_SUCCEEDS_PID|daemon.pid.prev|free.space|disk.*floor\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs;.worktrees/hertz-ir86-disk-delta/xtask/src/brainread.rs\",\"case\":false,\"gitignore\":false,\"skip\":null}","call_id":"call_5SC73LBYbynWTk3TB4TBE7Wq","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"grep","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95aa394bc87d1bb5dc561ac768e35","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking current shared mechanisms\",\"pattern\":\"IR.?79|IR.?88|IR.?76|IR.?106|IR.?107|IR.?109|module_banner|DaemonReaper|kill.scop|0\\\\.4\\\\.1\",\"path\":\".worktrees/hertz-ir86-disk-delta/AGENTS.md;.worktrees/hertz-ir86-disk-delta/.github;.worktrees/hertz-ir86-disk-delta/xtask/src;.worktrees/hertz-ir86-disk-delta/traceable-reqs.toml;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/common\",\"case\":false,\"gitignore\":false,\"skip\":null}","call_id":"call_BWgHB0WgbZ4MGEdGwkEa3y09","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"grep","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}}]},"duration":14270.163399994373,"ttft":14237.342599987984,"completedAt":1789483683647,"contextSnapshot":{"promptTokens":101777,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"message","id":"a78066f9","parentId":"322e9538","timestamp":"2026-09-15T14:48:03.712Z","message":{"role":"toolResult","toolCallId":"call_52Jm9jS2HvdzvgO7GV2Jtefh|fc_000c7cef03cac861016aa95aa394a087d1944f537678374a58","toolName":"read","content":[{"type":"text","text":"### IR-109 — a manifest `[placement] module_banner = \"accept\"` block LOOSENS the local checker to zero; CI's pinned checker is structurally blind to placement, so the loosening is invisible until the pin moves\n\n- **Status:** OPEN, RATIFIED 12:33Z (doyle, releases#304) as a TRANSITIONAL policy for the #304 head: the 0.4.1 pin stays (a tightening for every new tag), the accept key exempts only the 312 legacy banner tags, and this entry is the retirement ticket. Recorded 2026-09-11 12:10Z (doyle) from hertz's A/B/C and 0.2.0 arms; the commit's \"agreed\" is corrected by the ruling, not by rewriting a measured sha.\n- **Instance.** 33936943 \"chore(traceability): enable agreed placement policy\" (07:38Z, trailer todlando, on\n  feat/304-remote-friction-product and test/304-remote-friction, NOT on main) adds `[placement] enforce = \"on\"`,\n  `module_banner = \"accept\"`. The word \"agreed\" is UNRATIFIED: todlando cannot evidence it (his session that\n  wrote it is gone) and doyle did not rule it.\n- **Measured, same binary 0.4.1, same tree 4b54a95d, manifest the only variable:** as-is exit 1 / 312\n  misplaced_tag; block added exit 0 / 0; `enforce = \"on\"` alone exit 1 / 312. `module_banner` is the sole\n  load-bearing key; enforce is the default already. CI-pinned 0.2.0 (golden.yml WANT=0.2.0) at the same sha:\n  exit 0 / 0 — the `misplaced_tag` kind does not exist in that version; placement lives only in its `review`\n  subcommand, which `check` never reaches. asm-304 (0c05e722, 0.4.1 + the block): exit 0, bought by the key.\n- **Why it matters.** AGENTS.md rule 1: tags sit on the evidence, never at file tops to satisfy coverage. The\n  312 are banner tags that violate it; the accept key retires them by policy rather than by moving one tag, and\n  the gate that CI actually runs cannot see either state.\n- **Rule.** A checker config change that lowers a finding count is a loosening and is ruled on the record\n  before it rides; \"agreed\" in a commit message is not a ruling. The honest statement of a zero under such a\n  config names the config (\"zero under a manifest that accepts module banners\").\n- **Kin:** memory checker-version-must-match-ci-pin (live instance), [[IR-104]].\n- **CORRECTED 12:24Z (doyle):** the pin HAS moved on the W1 lane ancestry — 71caedd4 \"ci: pin traceable-reqs to v0.4.1\" (10:11Z) sits under 697eb398 (not on main), so ci.yml:253 and golden.yml:1424 both read WANT=0.4.1 at the integration head while origin/main reads WANT=0.2.0 at ci.yml:253 and golden.yml:1414. The accept key is therefore LIVE at the assembled golden gate today, not dormant: asm-304 reads 0 [must] under 0.4.1 because of the key. A lane off 697eb398 reads nine further [must] (code-stage tags in docs prose: F-035-CONFLICT, PUMP-W2-DESIGN, DEBUG-CONVERGE-PLAN, INFRA-REGISTER) that the assembly does not: measured at F-035-CONFLICT:47, 697eb398 carries the bracketed tags and origin/main carries them with brackets elided (\"so the checker\" clause), fixed on main between the merge-base f020c4c7 and 4b54a95d. Resolves at assembly by construction; not a fold-lane finding.\n- **Ripe when:** now — the key rides #304 only as a labelled hole named in the golden hand-off; retire by relocating the 312 tags and deleting the key in a lane of its own. · **Size:** 312 tag moves; the key.\n\n### IR-110 — the gater ruled a wave from origin/main's manifest while the milestone's own product lane already carried the surface; a second implementation was built to its W-1 END before the first was noticed\n\n- **Status:** OPEN, STOP LINE on #304 W2 (comment 5634187958). Recorded 2026-09-11 12:10Z (doyle, own instance).\n- **Instance.** feat/304-remote-friction-product @3e7eaf67 implements #297 TCP admission under\n  REQ-WEB-LAN-BOOTSTRAP-FIREWALL (bootstrap_firewall.rs + windows.rs + linux.rs, lanhost/servehost/serveverb/cli\n  call sites, docs-site section, ADR-0059 \"Amendment 2\" at d71df7aa): program-scoped Windows effector, all\n  profiles, no remote restriction, zero tests in the module (six guard-level cells arrive with hertz 7b098cc2,\n  none on scope). doyle deactivated its int stage the same morning and then ruled W2 fork (i) and let four\n  REQ-LAN-BOOTSTRAP-* ids mint from ORIGIN/MAIN's manifest, where the id is absent (0 occurrences). todlando\n  built build/304-w2-bootstrap-tcp @fe427497: a second, tested (E4 red at the bound-port assertion, 5/5, 981==981)\n  netsh implementation, port+remote scoped, never program, a second \"## Amendment 2\" in the same ADR file.\n  He found the collision at his W-1 END by reading the product lane, and touched nothing.\n- **Mechanism.** IR-106 from the gater's chair: the population enumerated (main's manifest) was not the\n  population the claim was about (the milestone head's). The tell was available all morning — the gater's own\n  deactivation note names the id — and a grep of the assembly worktree (asm-304) instead of the main checkout\n  would have returned 1.\n- **Consequence.** The two texts disagree on a FACT (which rule shape admits TCP over the tailnet on this box;\n  W-0 measured program scope admitting nothing for UDP only), both amendments share a heading, and an\n  assembled head would run both start paths and write two rule sets.\n- **Rule.** Before minting or activating any id for a milestone wave, enumerate the ASSEMBLY head's manifest\n  (asm-<milestone>), not main's; a wave that \"closes\" a surface names the id it closes and greps the milestone\n  head for it first. A fork ruling states the tree it enumerated.\n- **Kin:** [[IR-106]], [[IR-107]] (same day, same class in three chairs).\n- **Ripe when:** now — W-2a discriminating measurement in flight (arms A-D on the installed 5470 listener from\n  kitsubito), then the fold ruling (one id, one ADR section, the tested decision seam + cells attached to the\n  surviving effector). · **Size:** one measurement; one fold commit on the W2 lane; the ADR merge is a content\n  decision, not a merge decision.\n- **Labelled hole (12:14Z):** bootstrap_firewall/linux.rs (676 lines) has ZERO #[test]; all six cells sit in bootstrap_firewall.rs and windows.rs. Under cfg the Linux arm is invisible to this box's unit lane, so the surviving id's unit stage reads green over an untested Linux backend set. Closed by a hertz cells lane run on kitsubito against ufw_scope / owned / backend (queued 12:14Z; ten cells red-first at be99017f, 12:41Z). RULE learned there: `ci.yml` lint runs clippy `--all-targets -D warnings` on kitsubito ONLY, and `--all-targets` lints cells as hard as product — a Linux-only red that no Windows gate sees caught todlando's `needless_borrow` (linux.rs:293, fixed be99017f) and hertz's own `cloned_ref_to_slice_refs` (linux.rs:891, test module) one hour apart; nextest 10/10 said nothing about either. Cells in a cfg-gated module pass clippy on that platform before the lane is clean. Structural fold ruling issued 12:13Z: surviving id REQ-WEB-LAN-BOOTSTRAP-FIREWALL, W1 CIM effector + pure RuleSpec/desired_spec/spec_satisfied_by seam, W2 netsh section removed, four minted ids deleted; scope constants and prose wait for W-2a arm C.\n\n### IR-111 — the installed product's own inbound UDP rule reads Duplicate / Inactive in ActiveStore, shadowed by the fallback rule; a by-name probe reads it green\n\n- **Status:** OPEN, product-side backlog candidate (REQ-INBOUND-WINDOWS-RULE-BINDER-PATH-MATCH family). Recorded\n  2026-09-11 12:14Z (doyle) from an unelevated `Get-NetFirewallRule` read of both stores on HFENDULEAM.\n- **Instance.** ActiveStore: `spt-core inbound UDP` (Program = installed spt.exe, Profile Any, UDP, Remote Any)\n  Enabled=True, **Enforcement=Duplicate, PrimaryStatus=Inactive**; `spt-fallback inbound UDP` (same program,\n  Profile Any) Enforcement=ProfileInactive Enforced, Status OK. PersistentStore shows both as\n  Enforcement=NotApplicable, Status OK — the persistent view cannot see the shadowing at all.\n- **Why it matters.** The product's reconcile and the `inbound_block_hint` probe key on the product rule's NAME.\n  The rule that is doing the work is the other one; delete or repoint the fallback and the product rule may\n  become the enforced one with no change in what the name probe reports, or the reverse. Kin to the W1\n  effector's own comment (\"never certify a rule which ActiveStore reports as ignored or ineffective\") — the\n  UDP side never reads ActiveStore.\n- **Also seen, same read:** ~26 enforced program-scoped Private rules naming target/debug and actions-runner\n  test binaries (spt_net-*, spt_daemon-*, spt.exe), Proto TCP+UDP, LPort Any, Remote Any — the rig-rule\n  population the hfenduleam program-scope memory describes; none admits the tailnet.\n- **Rule.** A rule probe that certifies anything reads ActiveStore EnforcementStatus, not PersistentStore\n  presence and not the name.\n- **Kin:** [[IR-110]], memory hfenduleam-program-scoped-firewall-rules-do-not-admit-tailnet.\n- **Ripe when:** the next inbound-rule wave, or when the W1 CIM two-store query is generalised to the UDP side.\n  · **Size:** one ActiveStore read in the probe; one dedupe decision.\n\n### IR-112 — bare `cargo test -p spt-daemon --lib` reds two process-global cells on Linux at a sha where nextest is green; libtest is not a sound gate for this crate\n\n- **Status:** OPEN, rig rule (CI unaffected: `ci.yml` runs `kind(lib)` under nextest). Recorded 2026-09-11 12:46Z\n  (doyle) from hertz's Linux cells lane END on kitsubito.\n- **Instance.** At 697eb398 on kitsubito: `cargo nextest list -p spt-daemon --lib` = 989 ids; `cargo test -p\n  spt-daemon --lib` = 989 run, 987 passed, **2 FAILED, exit 101**:\n  `answerop::tests::an_approval_notifies_a_plain_knocker_with_no_pre_authorization` (answerop.rs:324, \"expected\n  exactly one courtesy: [] left: 0 right: 1\") and\n  `brainproc::tests::the_ready_breadcrumb_tells_a_computed_hash_from_a_cached_one` (brainproc.rs:2347, \"the FIRST\n  ready write in a process pays for the digest\"). Both PASS under nextest with the identical filter, exit 0.\n- **Mechanism.** Process-per-test vs one shared libtest process: both cells read process-global state (the\n  brainproc one says so in its own panic text); under libtest a sibling's write is visible. IR-108's leaky-cell\n  class, measured on Linux. Kin memory bystander-test-reads-process-global, daemon-lib-tests-deadlock-on-live-host.\n- **Rule.** A gate or rig over spt-daemon's lib runs NEXTEST; a `cargo test --lib` red on this crate is a rig\n  fault until discriminated under nextest with the same filter. Count agreement (list == run) says nothing about\n  exit agreement — check both.\n- **Kin:** [[IR-108]], [[IR-100]].\n- **Ripe when:** a sweep makes those two cells hermetic (the fix belongs to the cells, not the gate). · **Size:**\n  two fixtures.\n\n### IR-113 — a killed mutation arm does not unwind: the subject stays mutated and the NEXT arm measures a tree nobody declared; and a mutation that reds on a compile error is a void arm that \"it compiled\" cannot detect\n\n- **Status:** OPEN, rig rule for every mutation driver. Recorded 2026-09-11 13:05Z (doyle) from todlando's FOLD-1b\n  window (fold/304-w2-admission, windows.rs).\n- **Instance.** A first M1 injected an early return through a struct literal naming a helper that does not exist —\n  a mutation that would red on E0425, not at the cell's assertion, i.e. a void red-first arm. The job was stopped\n  mid-run; the driver's restore is its LAST line, so the kill left the MUTATED file on disk: working oid d8ddfdf3\n  against pristine 1f475a80, two residue markers present. Caught only because the next act was an oid compare, not\n  the next arm. Restored and re-measured identical (residue 0, 786 == 786 lines). Second half: clippy on the\n  mutated tree exited 0, so \"it compiled\" would not have exposed the void arm either.\n- **Mechanism.** Mutate → run → restore is not transactional; any exit before the last line (kill, timeout, crash,\n  nextest hang) strands the mutation. A void arm is one whose red is not AT the assertion the prediction named.\n- **Rule.** (1) A mutation driver restores in a finally/trap path, and every arm BEGINS by asserting the subject's\n  oid equals the declared pristine oid — the previous arm's revert is proven at the next arm's start, not trusted.\n  (2) A red-first arm is accepted only when the artifact names the predicted assertion line; a compile-error red,\n  a panic elsewhere, or a red at a different line is VOID, not a pass and not a fail. (3) Mutations are one-token\n  edits with an anchor count asserted at 1; an arm that did not change the file voids itself loudly.\n- **Kin:** [[IR-107]] (revert proven by oid AND byte shape), memory scripted-edit-zero-match-refusal,\n  make-a-new-rig-red-on-purpose.\n- **Ripe when:** now — the rule is cheap and the drivers exist; every lane's driver adopts it at its next edit. ·\n  **Size:** a trap/finally and one oid compare per arm.\n\n### IR-114 — three hands wrote one firewall rule set inside ninety seconds under two directors; every census was true at its instant and false a minute later\n\n- **Status:** OPEN, procedure ruled 2026-09-12 00:50Z (doyle) on todlando's reconciliation; recorded 00:52Z.\n- **Instance.** #304 W-2a arms on HFENDULEAM: ~00:44Z todlando asked the operator to delete spt-w2a-C so B would stand alone; ~00:45Z the operator said \"C down\" and todlando's census read B present / C absent (true then); 00:45:05Z liam ADDED C at doyle's direction (doyle had been idle 11 h and did not know the operator's window); 00:46:14Z liam DELETED B at doyle's direction; 00:49:09Z todlando re-measured C present / B absent. Nobody was wrong; the population was not stable. Every fetch todlando reported had an adjacent census and stands; a long background census that straddled the writes returned no spt-w2a rows at all and is UNMEASURED. Separately, doyle's drop-log arm crossed liam's revert in flight: three fetches ran with logging already off — a void arm, redone.\n- **Mechanism.** Two directors (operator, gater) each driving a different elevated hand against the same shared host state, neither seeing the other's window; a census taken as a separate earlier step and carried forward.\n- **Rule.** For any arm on shared host state: ONE WRITER; the census is taken BY THE FETCHER in the SAME command as the fetch, before and after; the prediction names the exact expected population (an unexpected row is a red); every write is announced with its UTC time to every party; a director resuming after a gap re-measures the population before issuing a write. Kin: memory verify-the-subject-not-just-the-measurement, name-the-file-and-sha.\n- **Also measured tonight (todlando):** 'spt-core daemon' (proto Any, Private, remote Any, program = the listener's exe) covers the Private-classified Tailscale interface while TCP 5470 times out from kitsubito and the LAN address answers 200 with ICMP alive — so W-0 measured the tailnet ACL, not program scoping, and DESIRED_PROGRAM=false's cited justification is VOID (the constant may still be right; its citation is not). The shape question moves to a throwaway port and listener over the LAN (arm E).\n- **Ripe when:** now — the rule costs nothing. · **Size:** procedure.\n\n### IR-115 — a firewall census whose port test is DENIED reads every rule as port=Any and counts port-scoped rules as blanket; a `netsh show rule` without `verbose` omits Program and reads every rule as program=Any; a control count that merges two agents' reads is nobody's control\n\n- **Status:** OPEN, mechanisms recorded 2026-09-12 01:14Z (doyle) from todlando's and liam's own corrections during #304 arm E.\n- **Instances.** (1) todlando's first census A (\"26 blanket rules\") and B (\"occupied LocalPort set: EMPTY\"): `Get-NetFirewallPortFilter -All` returns \"Access is denied\" unelevated, the probe swallowed the denial, every rule read as port=Any, and B's positive control (the hand rule carries LocalPort 5470) is what caught it. (2) His replacement pass: `netsh advfirewall firewall show rule name=all` without `verbose` prints no Program line, so it reported 417 blankets and ZERO rules naming spt.exe — provably false, caught by the same control. The third pass (`dir=in verbose`) passed both controls (port-5470 rows = 1, spt.exe rows = 7) and was the census used. (3) doyle's fetcher: first census predicate listed port-covering and program-covering rules as two separate sets; the reaching set is their CONJUNCTION (plus LocalIP, which the first predicate lacked and which is what scopes `Tailscale-In` to the tailnet address only). (4) liam's \"3/3 200\" loopback count merged two of his reads with three of doyle's re-reads as reported; liam corrected it himself. (5) doyle's one in-arm loopback read of 000 at 01:04:22Z had no exit code captured; it is carried as a labelled hole, not classified by a later burst (a later instant cannot classify an earlier read).\n- **Mechanism.** A denied or under-scoped read does not error; it returns the permissive default for the field it could not see, so the census reads MORE admits than exist and a shape question gets decided on a phantom population. Kin: memory a-predicate-without-its-tool-is-not-evidence, verdict-from-probe-competence, zero-match-filter-reads-as-absent.\n- **Rule.** A firewall census names its tool and privilege and carries two positive controls in the SAME dump: one rule known to carry a specific LocalPort, one known to name a specific Program. A census that cannot see both has not seen the population. The reaching predicate is port-covers AND program-covers AND LocalIP-covers AND profile-covers, one set. Every loopback and remote read records its curl exit code. Counts are per agent; a merged count is restated per agent or discarded.\n- **Ripe when:** now — the rule costs one grep. · **Size:** procedure.\n\n- **Addendum 2026-09-12 03:20Z (doyle, #304 W-2 A5/A4): the Windows Firewall event log is DIRECTION-BLIND, so a rig that keys \"written\" or \"removed\" on it cannot fail in the direction it claims.** Population controlled over one read (2011x48 / 2052x6 / 2097x6, a 400-event re-read of the same window returning the identical six): id 2052 fires on creates AND deletes in the observed population, id 2097 is create-specific, and NOTHING observed is delete-specific. The CENSUS carries the sign; the log carries only the instant. The same read established a MEASURED gap (zero events between A5's end and A4's start) and that nothing commits after the client dies — both usable, neither a direction. Kin: the firewall status fields do not discriminate either, since an admitting hand rule reads the same `PrimaryStatus`/`EnforcementStatus` strings as a non-admitting product pair on the same query.\n\n### IR-116 — a watchdog that calls a killer and then echoes success reports a kill it never made; `pkill` is absent in msys, so the guard logged \"stopped\" while the arm it guarded ran on\n\n- **Status:** OPEN, mechanism recorded 2026-09-12 01:24Z (todlando) from his own guard during #304 FOLD-2's Windows arm at 7357ea32; doyle asked for the line.\n- **Instance.** todlando armed a watchdog to stop a test arm before it reached `cargo test --workspace --lib`, because spt-daemon lib tests deadlock on a live host. Shape: `if grep -q \"CLIPPY_EXIT=\" log; then pkill -f \"bash /tmp/arms.sh\" 2>/dev/null; echo \"GUARD: arms.sh stopped after clippy at $(date -u)\"`. It printed `GUARD: arms.sh stopped after clippy at 01:24:06Z`. Nothing was stopped: `pkill` does not exist in this msys/Git-Bash environment (`command not found`, exit 127), `2>/dev/null` ate the message, and the `echo` was never gated on the killer's exit. The arm ran on into its compile phase and was found by tailing the build log, not by the guard — whose only output was a green.\n- **Mechanism.** Two defects stack, and either alone would have been caught by the other: a missing binary, and a success line that cannot fail. Same family as IR-107 seen from the other side — there a trailing command's exit was mistaken for the producer's; here no exit was consulted at all. The aggravating factor is WHERE it lives: a guard is written while thinking about the hazard it guards, not about the guard, and a guard that never fires looks identical to a guard that works. Kin: memory watchdog-reports-a-kill-it-never-made, verdict-from-exit-not-from-silence, a-predicate-without-its-tool-is-not-evidence.\n- **Rule.** A watchdog asserts the POST-STATE and never echoes after the call: `kill …; sleep 1; if still_running; then echo \"GUARD FAILED\"; exit 1; fi`. On msys use `kill -9 <pid>` with a pid you resolved yourself, or `taskkill //PID <p> //T //F`; do not assume `pkill`/`pgrep` exist — check the tool before building a guard on it. Reap your own tree only: resolve the pid and its children, never a machine-wide sweep on a shared box.\n- **Second-order, and it bit me inside this very entry.** `git checkout -- <file>` restores from the INDEX, not HEAD. Having staged a first draft, I \"reverted\" it and appended a rewrite — producing a file carrying BOTH. Caught by the diffstat (49 insertions for a ten-line entry). Restore from `HEAD --` when HEAD is what you mean; the diffstat is the control.\n- **Corollary, accepted by doyle.** The killed arm reported `TEST_EXIT=137`. That is the SIGKILL, delivered during compilation with ZERO tests executed (last lines `Compiling acto / iroh-dns / wmi`) — a VOID arm, not a red. A 137 sitting in a log over a test arm is precisely the number quoted later as a product failure. Same family as IR-113 (a killed mutation arm does not unwind).\n- **Instance 2 — a DIFFERENT tool surface, 2026-09-12 03:39Z (hertz).** The mechanism is not a property of todlando's guard. hertz ran a recursive `grep -rl` over the project tree; it exceeded the foreground timeout and the harness backgrounded it. `TaskStop` returned `{\"message\":\"Successfully stopped task: bn74vtqn0\"}` — a structured success from the harness itself, not a hand-rolled echo. The process was still in the table two minutes later: pid 35104, StartTime 03:37:20Z, **CPU 13.25 s**, killed only by an explicit `Stop-Process -Id 35104 -Force` and confirmed gone by a post-state count of 0 against a live positive control (`pwsh` count 12). So a first-party tool's success object is no better warranted than an `echo`, and the rule generalises: **read the post-state after every stop, whatever the stopping tool said.** Aggravating detail worth its own note — hertz had todlando's disclosure of this exact shape in context and ran it anyway four minutes later; a hazard report describes a SHAPE, and remembering the INSTANCE is not being inoculated against the shape.\n- **Ripe when:** now — the rule costs three lines in any guard. · **Size:** procedure.\n\n\n[Showing lines 6567-6711 of 6938. Use :6712 to continue]"}],"details":{"truncation":{"content":"### IR-109 — a manifest `[placement] module_banner = \"accept\"` block LOOSENS the local checker to zero; CI's pinned checker is structurally blind to placement, so the loosening is invisible until the pin moves\r\n\r\n- **Status:** OPEN, RATIFIED 12:33Z (doyle, releases#304) as a TRANSITIONAL policy for the #304 head: the 0.4.1 pin stays (a tightening for every new tag), the accept key exempts only the 312 legacy banner tags, and this entry is the retirement ticket. Recorded 2026-09-11 12:10Z (doyle) from hertz's A/B/C and 0.2.0 arms; the commit's \"agreed\" is corrected by the ruling, not by rewriting a measured sha.\r\n- **Instance.** 33936943 \"chore(traceability): enable agreed placement policy\" (07:38Z, trailer todlando, on\r\n  feat/304-remote-friction-product and test/304-remote-friction, NOT on main) adds `[placement] enforce = \"on\"`,\r\n  `module_banner = \"accept\"`. The word \"agreed\" is UNRATIFIED: todlando cannot evidence it (his session that\r\n  wrote it is gone) and doyle did not rule it.\r\n- **Measured, same binary 0.4.1, same tree 4b54a95d, manifest the only variable:** as-is exit 1 / 312\r\n  misplaced_tag; block added exit 0 / 0; `enforce = \"on\"` alone exit 1 / 312. `module_banner` is the sole\r\n  load-bearing key; enforce is the default already. CI-pinned 0.2.0 (golden.yml WANT=0.2.0) at the same sha:\r\n  exit 0 / 0 — the `misplaced_tag` kind does not exist in that version; placement lives only in its `review`\r\n  subcommand, which `check` never reaches. asm-304 (0c05e722, 0.4.1 + the block): exit 0, bought by the key.\r\n- **Why it matters.** AGENTS.md rule 1: tags sit on the evidence, never at file tops to satisfy coverage. The\r\n  312 are banner tags that violate it; the accept key retires them by policy rather than by moving one tag, and\r\n  the gate that CI actually runs cannot see either state.\r\n- **Rule.** A checker config change that lowers a finding count is a loosening and is ruled on the record\r\n  before it rides; \"agreed\" in a commit message is not a ruling. The honest statement of a zero under such a\r\n  config names the config (\"zero under a manifest that accepts module banners\").\r\n- **Kin:** memory checker-version-must-match-ci-pin (live instance), [[IR-104]].\r\n- **CORRECTED 12:24Z (doyle):** the pin HAS moved on the W1 lane ancestry — 71caedd4 \"ci: pin traceable-reqs to v0.4.1\" (10:11Z) sits under 697eb398 (not on main), so ci.yml:253 and golden.yml:1424 both read WANT=0.4.1 at the integration head while origin/main reads WANT=0.2.0 at ci.yml:253 and golden.yml:1414. The accept key is therefore LIVE at the assembled golden gate today, not dormant: asm-304 reads 0 [must] under 0.4.1 because of the key. A lane off 697eb398 reads nine further [must] (code-stage tags in docs prose: F-035-CONFLICT, PUMP-W2-DESIGN, DEBUG-CONVERGE-PLAN, INFRA-REGISTER) that the assembly does not: measured at F-035-CONFLICT:47, 697eb398 carries the bracketed tags and origin/main carries them with brackets elided (\"so the checker\" clause), fixed on main between the merge-base f020c4c7 and 4b54a95d. Resolves at assembly by construction; not a fold-lane finding.\r\n- **Ripe when:** now — the key rides #304 only as a labelled hole named in the golden hand-off; retire by relocating the 312 tags and deleting the key in a lane of its own. · **Size:** 312 tag moves; the key.\r\n\r\n### IR-110 — the gater ruled a wave from origin/main's manifest while the milestone's own product lane already carried the surface; a second implementation was built to its W-1 END before the first was noticed\r\n\r\n- **Status:** OPEN, STOP LINE on #304 W2 (comment 5634187958). Recorded 2026-09-11 12:10Z (doyle, own instance).\r\n- **Instance.** feat/304-remote-friction-product @3e7eaf67 implements #297 TCP admission under\r\n  REQ-WEB-LAN-BOOTSTRAP-FIREWALL (bootstrap_firewall.rs + windows.rs + linux.rs, lanhost/servehost/serveverb/cli\r\n  call sites, docs-site section, ADR-0059 \"Amendment 2\" at d71df7aa): program-scoped Windows effector, all\r\n  profiles, no remote restriction, zero tests in the module (six guard-level cells arrive with hertz 7b098cc2,\r\n  none on scope). doyle deactivated its int stage the same morning and then ruled W2 fork (i) and let four\r\n  REQ-LAN-BOOTSTRAP-* ids mint from ORIGIN/MAIN's manifest, where the id is absent (0 occurrences). todlando\r\n  built build/304-w2-bootstrap-tcp @fe427497: a second, tested (E4 red at the bound-port assertion, 5/5, 981==981)\r\n  netsh implementation, port+remote scoped, never program, a second \"## Amendment 2\" in the same ADR file.\r\n  He found the collision at his W-1 END by reading the product lane, and touched nothing.\r\n- **Mechanism.** IR-106 from the gater's chair: the population enumerated (main's manifest) was not the\r\n  population the claim was about (the milestone head's). The tell was available all morning — the gater's own\r\n  deactivation note names the id — and a grep of the assembly worktree (asm-304) instead of the main checkout\r\n  would have returned 1.\r\n- **Consequence.** The two texts disagree on a FACT (which rule shape admits TCP over the tailnet on this box;\r\n  W-0 measured program scope admitting nothing for UDP only), both amendments share a heading, and an\r\n  assembled head would run both start paths and write two rule sets.\r\n- **Rule.** Before minting or activating any id for a milestone wave, enumerate the ASSEMBLY head's manifest\r\n  (asm-<milestone>), not main's; a wave that \"closes\" a surface names the id it closes and greps the milestone\r\n  head for it first. A fork ruling states the tree it enumerated.\r\n- **Kin:** [[IR-106]], [[IR-107]] (same day, same class in three chairs).\r\n- **Ripe when:** now — W-2a discriminating measurement in flight (arms A-D on the installed 5470 listener from\r\n  kitsubito), then the fold ruling (one id, one ADR section, the tested decision seam + cells attached to the\r\n  surviving effector). · **Size:** one measurement; one fold commit on the W2 lane; the ADR merge is a content\r\n  decision, not a merge decision.\r\n- **Labelled hole (12:14Z):** bootstrap_firewall/linux.rs (676 lines) has ZERO #[test]; all six cells sit in bootstrap_firewall.rs and windows.rs. Under cfg the Linux arm is invisible to this box's unit lane, so the surviving id's unit stage reads green over an untested Linux backend set. Closed by a hertz cells lane run on kitsubito against ufw_scope / owned / backend (queued 12:14Z; ten cells red-first at be99017f, 12:41Z). RULE learned there: `ci.yml` lint runs clippy `--all-targets -D warnings` on kitsubito ONLY, and `--all-targets` lints cells as hard as product — a Linux-only red that no Windows gate sees caught todlando's `needless_borrow` (linux.rs:293, fixed be99017f) and hertz's own `cloned_ref_to_slice_refs` (linux.rs:891, test module) one hour apart; nextest 10/10 said nothing about either. Cells in a cfg-gated module pass clippy on that platform before the lane is clean. Structural fold ruling issued 12:13Z: surviving id REQ-WEB-LAN-BOOTSTRAP-FIREWALL, W1 CIM effector + pure RuleSpec/desired_spec/spec_satisfied_by seam, W2 netsh section removed, four minted ids deleted; scope constants and prose wait for W-2a arm C.\r\n\r\n### IR-111 — the installed product's own inbound UDP rule reads Duplicate / Inactive in ActiveStore, shadowed by the fallback rule; a by-name probe reads it green\r\n\r\n- **Status:** OPEN, product-side backlog candidate (REQ-INBOUND-WINDOWS-RULE-BINDER-PATH-MATCH family). Recorded\r\n  2026-09-11 12:14Z (doyle) from an unelevated `Get-NetFirewallRule` read of both stores on HFENDULEAM.\r\n- **Instance.** ActiveStore: `spt-core inbound UDP` (Program = installed spt.exe, Profile Any, UDP, Remote Any)\r\n  Enabled=True, **Enforcement=Duplicate, PrimaryStatus=Inactive**; `spt-fallback inbound UDP` (same program,\r\n  Profile Any) Enforcement=ProfileInactive Enforced, Status OK. PersistentStore shows both as\r\n  Enforcement=NotApplicable, Status OK — the persistent view cannot see the shadowing at all.\r\n- **Why it matters.** The product's reconcile and the `inbound_block_hint` probe key on the product rule's NAME.\r\n  The rule that is doing the work is the other one; delete or repoint the fallback and the product rule may\r\n  become the enforced one with no change in what the name probe reports, or the reverse. Kin to the W1\r\n  effector's own comment (\"never certify a rule which ActiveStore reports as ignored or ineffective\") — the\r\n  UDP side never reads ActiveStore.\r\n- **Also seen, same read:** ~26 enforced program-scoped Private rules naming target/debug and actions-runner\r\n  test binaries (spt_net-*, spt_daemon-*, spt.exe), Proto TCP+UDP, LPort Any, Remote Any — the rig-rule\r\n  population the hfenduleam program-scope memory describes; none admits the tailnet.\r\n- **Rule.** A rule probe that certifies anything reads ActiveStore EnforcementStatus, not PersistentStore\r\n  presence and not the name.\r\n- **Kin:** [[IR-110]], memory hfenduleam-program-scoped-firewall-rules-do-not-admit-tailnet.\r\n- **Ripe when:** the next inbound-rule wave, or when the W1 CIM two-store query is generalised to the UDP side.\r\n  · **Size:** one ActiveStore read in the probe; one dedupe decision.\r\n\r\n### IR-112 — bare `cargo test -p spt-daemon --lib` reds two process-global cells on Linux at a sha where nextest is green; libtest is not a sound gate for this crate\r\n\r\n- **Status:** OPEN, rig rule (CI unaffected: `ci.yml` runs `kind(lib)` under nextest). Recorded 2026-09-11 12:46Z\r\n  (doyle) from hertz's Linux cells lane END on kitsubito.\r\n- **Instance.** At 697eb398 on kitsubito: `cargo nextest list -p spt-daemon --lib` = 989 ids; `cargo test -p\r\n  spt-daemon --lib` = 989 run, 987 passed, **2 FAILED, exit 101**:\r\n  `answerop::tests::an_approval_notifies_a_plain_knocker_with_no_pre_authorization` (answerop.rs:324, \"expected\r\n  exactly one courtesy: [] left: 0 right: 1\") and\r\n  `brainproc::tests::the_ready_breadcrumb_tells_a_computed_hash_from_a_cached_one` (brainproc.rs:2347, \"the FIRST\r\n  ready write in a process pays for the digest\"). Both PASS under nextest with the identical filter, exit 0.\r\n- **Mechanism.** Process-per-test vs one shared libtest process: both cells read process-global state (the\r\n  brainproc one says so in its own panic text); under libtest a sibling's write is visible. IR-108's leaky-cell\r\n  class, measured on Linux. Kin memory bystander-test-reads-process-global, daemon-lib-tests-deadlock-on-live-host.\r\n- **Rule.** A gate or rig over spt-daemon's lib runs NEXTEST; a `cargo test --lib` red on this crate is a rig\r\n  fault until discriminated under nextest with the same filter. Count agreement (list == run) says nothing about\r\n  exit agreement — check both.\r\n- **Kin:** [[IR-108]], [[IR-100]].\r\n- **Ripe when:** a sweep makes those two cells hermetic (the fix belongs to the cells, not the gate). · **Size:**\r\n  two fixtures.\r\n\r\n### IR-113 — a killed mutation arm does not unwind: the subject stays mutated and the NEXT arm measures a tree nobody declared; and a mutation that reds on a compile error is a void arm that \"it compiled\" cannot detect\r\n\r\n- **Status:** OPEN, rig rule for every mutation driver. Recorded 2026-09-11 13:05Z (doyle) from todlando's FOLD-1b\r\n  window (fold/304-w2-admission, windows.rs).\r\n- **Instance.** A first M1 injected an early return through a struct literal naming a helper that does not exist —\r\n  a mutation that would red on E0425, not at the cell's assertion, i.e. a void red-first arm. The job was stopped\r\n  mid-run; the driver's restore is its LAST line, so the kill left the MUTATED file on disk: working oid d8ddfdf3\r\n  against pristine 1f475a80, two residue markers present. Caught only because the next act was an oid compare, not\r\n  the next arm. Restored and re-measured identical (residue 0, 786 == 786 lines). Second half: clippy on the\r\n  mutated tree exited 0, so \"it compiled\" would not have exposed the void arm either.\r\n- **Mechanism.** Mutate → run → restore is not transactional; any exit before the last line (kill, timeout, crash,\r\n  nextest hang) strands the mutation. A void arm is one whose red is not AT the assertion the prediction named.\r\n- **Rule.** (1) A mutation driver restores in a finally/trap path, and every arm BEGINS by asserting the subject's\r\n  oid equals the declared pristine oid — the previous arm's revert is proven at the next arm's start, not trusted.\r\n  (2) A red-first arm is accepted only when the artifact names the predicted assertion line; a compile-error red,\r\n  a panic elsewhere, or a red at a different line is VOID, not a pass and not a fail. (3) Mutations are one-token\r\n  edits with an anchor count asserted at 1; an arm that did not change the file voids itself loudly.\r\n- **Kin:** [[IR-107]] (revert proven by oid AND byte shape), memory scripted-edit-zero-match-refusal,\r\n  make-a-new-rig-red-on-purpose.\r\n- **Ripe when:** now — the rule is cheap and the drivers exist; every lane's driver adopts it at its next edit. ·\r\n  **Size:** a trap/finally and one oid compare per arm.\r\n\r\n### IR-114 — three hands wrote one firewall rule set inside ninety seconds under two directors; every census was true at its instant and false a minute later\r\n\r\n- **Status:** OPEN, procedure ruled 2026-09-12 00:50Z (doyle) on todlando's reconciliation; recorded 00:52Z.\r\n- **Instance.** #304 W-2a arms on HFENDULEAM: ~00:44Z todlando asked the operator to delete spt-w2a-C so B would stand alone; ~00:45Z the operator said \"C down\" and todlando's census read B present / C absent (true then); 00:45:05Z liam ADDED C at doyle's direction (doyle had been idle 11 h and did not know the operator's window); 00:46:14Z liam DELETED B at doyle's direction; 00:49:09Z todlando re-measured C present / B absent. Nobody was wrong; the population was not stable. Every fetch todlando reported had an adjacent census and stands; a long background census that straddled the writes returned no spt-w2a rows at all and is UNMEASURED. Separately, doyle's drop-log arm crossed liam's revert in flight: three fetches ran with logging already off — a void arm, redone.\r\n- **Mechanism.** Two directors (operator, gater) each driving a different elevated hand against the same shared host state, neither seeing the other's window; a census taken as a separate earlier step and carried forward.\r\n- **Rule.** For any arm on shared host state: ONE WRITER; the census is taken BY THE FETCHER in the SAME command as the fetch, before and after; the prediction names the exact expected population (an unexpected row is a red); every write is announced with its UTC time to every party; a director resuming after a gap re-measures the population before issuing a write. Kin: memory verify-the-subject-not-just-the-measurement, name-the-file-and-sha.\r\n- **Also measured tonight (todlando):** 'spt-core daemon' (proto Any, Private, remote Any, program = the listener's exe) covers the Private-classified Tailscale interface while TCP 5470 times out from kitsubito and the LAN address answers 200 with ICMP alive — so W-0 measured the tailnet ACL, not program scoping, and DESIRED_PROGRAM=false's cited justification is VOID (the constant may still be right; its citation is not). The shape question moves to a throwaway port and listener over the LAN (arm E).\r\n- **Ripe when:** now — the rule costs nothing. · **Size:** procedure.\r\n\r\n### IR-115 — a firewall census whose port test is DENIED reads every rule as port=Any and counts port-scoped rules as blanket; a `netsh show rule` without `verbose` omits Program and reads every rule as program=Any; a control count that merges two agents' reads is nobody's control\r\n\r\n- **Status:** OPEN, mechanisms recorded 2026-09-12 01:14Z (doyle) from todlando's and liam's own corrections during #304 arm E.\r\n- **Instances.** (1) todlando's first census A (\"26 blanket rules\") and B (\"occupied LocalPort set: EMPTY\"): `Get-NetFirewallPortFilter -All` returns \"Access is denied\" unelevated, the probe swallowed the denial, every rule read as port=Any, and B's positive control (the hand rule carries LocalPort 5470) is what caught it. (2) His replacement pass: `netsh advfirewall firewall show rule name=all` without `verbose` prints no Program line, so it reported 417 blankets and ZERO rules naming spt.exe — provably false, caught by the same control. The third pass (`dir=in verbose`) passed both controls (port-5470 rows = 1, spt.exe rows = 7) and was the census used. (3) doyle's fetcher: first census predicate listed port-covering and program-covering rules as two separate sets; the reaching set is their CONJUNCTION (plus LocalIP, which the first predicate lacked and which is what scopes `Tailscale-In` to the tailnet address only). (4) liam's \"3/3 200\" loopback count merged two of his reads with three of doyle's re-reads as reported; liam corrected it himself. (5) doyle's one in-arm loopback read of 000 at 01:04:22Z had no exit code captured; it is carried as a labelled hole, not classified by a later burst (a later instant cannot classify an earlier read).\r\n- **Mechanism.** A denied or under-scoped read does not error; it returns the permissive default for the field it could not see, so the census reads MORE admits than exist and a shape question gets decided on a phantom population. Kin: memory a-predicate-without-its-tool-is-not-evidence, verdict-from-probe-competence, zero-match-filter-reads-as-absent.\r\n- **Rule.** A firewall census names its tool and privilege and carries two positive controls in the SAME dump: one rule known to carry a specific LocalPort, one known to name a specific Program. A census that cannot see both has not seen the population. The reaching predicate is port-covers AND program-covers AND LocalIP-covers AND profile-covers, one set. Every loopback and remote read records its curl exit code. Counts are per agent; a merged count is restated per agent or discarded.\r\n- **Ripe when:** now — the rule costs one grep. · **Size:** procedure.\r\n\r\n- **Addendum 2026-09-12 03:20Z (doyle, #304 W-2 A5/A4): the Windows Firewall event log is DIRECTION-BLIND, so a rig that keys \"written\" or \"removed\" on it cannot fail in the direction it claims.** Population controlled over one read (2011x48 / 2052x6 / 2097x6, a 400-event re-read of the same window returning the identical six): id 2052 fires on creates AND deletes in the observed population, id 2097 is create-specific, and NOTHING observed is delete-specific. The CENSUS carries the sign; the log carries only the instant. The same read established a MEASURED gap (zero events between A5's end and A4's start) and that nothing commits after the client dies — both usable, neither a direction. Kin: the firewall status fields do not discriminate either, since an admitting hand rule reads the same `PrimaryStatus`/`EnforcementStatus` strings as a non-admitting product pair on the same query.\r\n\r\n### IR-116 — a watchdog that calls a killer and then echoes success reports a kill it never made; `pkill` is absent in msys, so the guard logged \"stopped\" while the arm it guarded ran on\r\n\r\n- **Status:** OPEN, mechanism recorded 2026-09-12 01:24Z (todlando) from his own guard during #304 FOLD-2's Windows arm at 7357ea32; doyle asked for the line.\r\n- **Instance.** todlando armed a watchdog to stop a test arm before it reached `cargo test --workspace --lib`, because spt-daemon lib tests deadlock on a live host. Shape: `if grep -q \"CLIPPY_EXIT=\" log; then pkill -f \"bash /tmp/arms.sh\" 2>/dev/null; echo \"GUARD: arms.sh stopped after clippy at $(date -u)\"`. It printed `GUARD: arms.sh stopped after clippy at 01:24:06Z`. Nothing was stopped: `pkill` does not exist in this msys/Git-Bash environment (`command not found`, exit 127), `2>/dev/null` ate the message, and the `echo` was never gated on the killer's exit. The arm ran on into its compile phase and was found by tailing the build log, not by the guard — whose only output was a green.\r\n- **Mechanism.** Two defects stack, and either alone would have been caught by the other: a missing binary, and a success line that cannot fail. Same family as IR-107 seen from the other side — there a trailing command's exit was mistaken for the producer's; here no exit was consulted at all. The aggravating factor is WHERE it lives: a guard is written while thinking about the hazard it guards, not about the guard, and a guard that never fires looks identical to a guard that works. Kin: memory watchdog-reports-a-kill-it-never-made, verdict-from-exit-not-from-silence, a-predicate-without-its-tool-is-not-evidence.\r\n- **Rule.** A watchdog asserts the POST-STATE and never echoes after the call: `kill …; sleep 1; if still_running; then echo \"GUARD FAILED\"; exit 1; fi`. On msys use `kill -9 <pid>` with a pid you resolved yourself, or `taskkill //PID <p> //T //F`; do not assume `pkill`/`pgrep` exist — check the tool before building a guard on it. Reap your own tree only: resolve the pid and its children, never a machine-wide sweep on a shared box.\r\n- **Second-order, and it bit me inside this very entry.** `git checkout -- <file>` restores from the INDEX, not HEAD. Having staged a first draft, I \"reverted\" it and appended a rewrite — producing a file carrying BOTH. Caught by the diffstat (49 insertions for a ten-line entry). Restore from `HEAD --` when HEAD is what you mean; the diffstat is the control.\r\n- **Corollary, accepted by doyle.** The killed arm reported `TEST_EXIT=137`. That is the SIGKILL, delivered during compilation with ZERO tests executed (last lines `Compiling acto / iroh-dns / wmi`) — a VOID arm, not a red. A 137 sitting in a log over a test arm is precisely the number quoted later as a product failure. Same family as IR-113 (a killed mutation arm does not unwind).\r\n- **Instance 2 — a DIFFERENT tool surface, 2026-09-12 03:39Z (hertz).** The mechanism is not a property of todlando's guard. hertz ran a recursive `grep -rl` over the project tree; it exceeded the foreground timeout and the harness backgrounded it. `TaskStop` returned `{\"message\":\"Successfully stopped task: bn74vtqn0\"}` — a structured success from the harness itself, not a hand-rolled echo. The process was still in the table two minutes later: pid 35104, StartTime 03:37:20Z, **CPU 13.25 s**, killed only by an explicit `Stop-Process -Id 35104 -Force` and confirmed gone by a post-state count of 0 against a live positive control (`pwsh` count 12). So a first-party tool's success object is no better warranted than an `echo`, and the rule generalises: **read the post-state after every stop, whatever the stopping tool said.** Aggravating detail worth its own note — hertz had todlando's disclosure of this exact shape in context and ran it anyway four minutes later; a hazard report describes a SHAPE, and remembering the INSTANCE is not being inoculated against the shape.\r\n- **Ripe when:** now — the rule costs three lines in any guard. · **Size:** procedure.\r\n\r","truncated":true,"truncatedBy":"lines","totalLines":372,"totalBytes":22853,"outputLines":145,"outputBytes":22853,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6938,"displayContent":{"text":"### IR-109 — a manifest `[placement] module_banner = \"accept\"` block LOOSENS the local checker to zero; CI's pinned checker is structurally blind to placement, so the loosening is invisible until the pin moves\r\n\r\n- **Status:** OPEN, RATIFIED 12:33Z (doyle, releases#304) as a TRANSITIONAL policy for the #304 head: the 0.4.1 pin stays (a tightening for every new tag), the accept key exempts only the 312 legacy banner tags, and this entry is the retirement ticket. Recorded 2026-09-11 12:10Z (doyle) from hertz's A/B/C and 0.2.0 arms; the commit's \"agreed\" is corrected by the ruling, not by rewriting a measured sha.\r\n- **Instance.** 33936943 \"chore(traceability): enable agreed placement policy\" (07:38Z, trailer todlando, on\r\n  feat/304-remote-friction-product and test/304-remote-friction, NOT on main) adds `[placement] enforce = \"on\"`,\r\n  `module_banner = \"accept\"`. The word \"agreed\" is UNRATIFIED: todlando cannot evidence it (his session that\r\n  wrote it is gone) and doyle did not rule it.\r\n- **Measured, same binary 0.4.1, same tree 4b54a95d, manifest the only variable:** as-is exit 1 / 312\r\n  misplaced_tag; block added exit 0 / 0; `enforce = \"on\"` alone exit 1 / 312. `module_banner` is the sole\r\n  load-bearing key; enforce is the default already. CI-pinned 0.2.0 (golden.yml WANT=0.2.0) at the same sha:\r\n  exit 0 / 0 — the `misplaced_tag` kind does not exist in that version; placement lives only in its `review`\r\n  subcommand, which `check` never reaches. asm-304 (0c05e722, 0.4.1 + the block): exit 0, bought by the key.\r\n- **Why it matters.** AGENTS.md rule 1: tags sit on the evidence, never at file tops to satisfy coverage. The\r\n  312 are banner tags that violate it; the accept key retires them by policy rather than by moving one tag, and\r\n  the gate that CI actually runs cannot see either state.\r\n- **Rule.** A checker config change that lowers a finding count is a loosening and is ruled on the record\r\n  before it rides; \"agreed\" in a commit message is not a ruling. The honest statement of a zero under such a\r\n  config names the config (\"zero under a manifest that accepts module banners\").\r\n- **Kin:** memory checker-version-must-match-ci-pin (live instance), [[IR-104]].\r\n- **CORRECTED 12:24Z (doyle):** the pin HAS moved on the W1 lane ancestry — 71caedd4 \"ci: pin traceable-reqs to v0.4.1\" (10:11Z) sits under 697eb398 (not on main), so ci.yml:253 and golden.yml:1424 both read WANT=0.4.1 at the integration head while origin/main reads WANT=0.2.0 at ci.yml:253 and golden.yml:1414. The accept key is therefore LIVE at the assembled golden gate today, not dormant: asm-304 reads 0 [must] under 0.4.1 because of the key. A lane off 697eb398 reads nine further [must] (code-stage tags in docs prose: F-035-CONFLICT, PUMP-W2-DESIGN, DEBUG-CONVERGE-PLAN, INFRA-REGISTER) that the assembly does not: measured at F-035-CONFLICT:47, 697eb398 carries the bracketed tags and origin/main carries them with brackets elided (\"so the checker\" clause), fixed on main between the merge-base f020c4c7 and 4b54a95d. Resolves at assembly by construction; not a fold-lane finding.\r\n- **Ripe when:** now — the key rides #304 only as a labelled hole named in the golden hand-off; retire by relocating the 312 tags and deleting the key in a lane of its own. · **Size:** 312 tag moves; the key.\r\n\r\n### IR-110 — the gater ruled a wave from origin/main's manifest while the milestone's own product lane already carried the surface; a second implementation was built to its W-1 END before the first was noticed\r\n\r\n- **Status:** OPEN, STOP LINE on #304 W2 (comment 5634187958). Recorded 2026-09-11 12:10Z (doyle, own instance).\r\n- **Instance.** feat/304-remote-friction-product @3e7eaf67 implements #297 TCP admission under\r\n  REQ-WEB-LAN-BOOTSTRAP-FIREWALL (bootstrap_firewall.rs + windows.rs + linux.rs, lanhost/servehost/serveverb/cli\r\n  call sites, docs-site section, ADR-0059 \"Amendment 2\" at d71df7aa): program-scoped Windows effector, all\r\n  profiles, no remote restriction, zero tests in the module (six guard-level cells arrive with hertz 7b098cc2,\r\n  none on scope). doyle deactivated its int stage the same morning and then ruled W2 fork (i) and let four\r\n  REQ-LAN-BOOTSTRAP-* ids mint from ORIGIN/MAIN's manifest, where the id is absent (0 occurrences). todlando\r\n  built build/304-w2-bootstrap-tcp @fe427497: a second, tested (E4 red at the bound-port assertion, 5/5, 981==981)\r\n  netsh implementation, port+remote scoped, never program, a second \"## Amendment 2\" in the same ADR file.\r\n  He found the collision at his W-1 END by reading the product lane, and touched nothing.\r\n- **Mechanism.** IR-106 from the gater's chair: the population enumerated (main's manifest) was not the\r\n  population the claim was about (the milestone head's). The tell was available all morning — the gater's own\r\n  deactivation note names the id — and a grep of the assembly worktree (asm-304) instead of the main checkout\r\n  would have returned 1.\r\n- **Consequence.** The two texts disagree on a FACT (which rule shape admits TCP over the tailnet on this box;\r\n  W-0 measured program scope admitting nothing for UDP only), both amendments share a heading, and an\r\n  assembled head would run both start paths and write two rule sets.\r\n- **Rule.** Before minting or activating any id for a milestone wave, enumerate the ASSEMBLY head's manifest\r\n  (asm-<milestone>), not main's; a wave that \"closes\" a surface names the id it closes and greps the milestone\r\n  head for it first. A fork ruling states the tree it enumerated.\r\n- **Kin:** [[IR-106]], [[IR-107]] (same day, same class in three chairs).\r\n- **Ripe when:** now — W-2a discriminating measurement in flight (arms A-D on the installed 5470 listener from\r\n  kitsubito), then the fold ruling (one id, one ADR section, the tested decision seam + cells attached to the\r\n  surviving effector). · **Size:** one measurement; one fold commit on the W2 lane; the ADR merge is a content\r\n  decision, not a merge decision.\r\n- **Labelled hole (12:14Z):** bootstrap_firewall/linux.rs (676 lines) has ZERO #[test]; all six cells sit in bootstrap_firewall.rs and windows.rs. Under cfg the Linux arm is invisible to this box's unit lane, so the surviving id's unit stage reads green over an untested Linux backend set. Closed by a hertz cells lane run on kitsubito against ufw_scope / owned / backend (queued 12:14Z; ten cells red-first at be99017f, 12:41Z). RULE learned there: `ci.yml` lint runs clippy `--all-targets -D warnings` on kitsubito ONLY, and `--all-targets` lints cells as hard as product — a Linux-only red that no Windows gate sees caught todlando's `needless_borrow` (linux.rs:293, fixed be99017f) and hertz's own `cloned_ref_to_slice_refs` (linux.rs:891, test module) one hour apart; nextest 10/10 said nothing about either. Cells in a cfg-gated module pass clippy on that platform before the lane is clean. Structural fold ruling issued 12:13Z: surviving id REQ-WEB-LAN-BOOTSTRAP-FIREWALL, W1 CIM effector + pure RuleSpec/desired_spec/spec_satisfied_by seam, W2 netsh section removed, four minted ids deleted; scope constants and prose wait for W-2a arm C.\r\n\r\n### IR-111 — the installed product's own inbound UDP rule reads Duplicate / Inactive in ActiveStore, shadowed by the fallback rule; a by-name probe reads it green\r\n\r\n- **Status:** OPEN, product-side backlog candidate (REQ-INBOUND-WINDOWS-RULE-BINDER-PATH-MATCH family). Recorded\r\n  2026-09-11 12:14Z (doyle) from an unelevated `Get-NetFirewallRule` read of both stores on HFENDULEAM.\r\n- **Instance.** ActiveStore: `spt-core inbound UDP` (Program = installed spt.exe, Profile Any, UDP, Remote Any)\r\n  Enabled=True, **Enforcement=Duplicate, PrimaryStatus=Inactive**; `spt-fallback inbound UDP` (same program,\r\n  Profile Any) Enforcement=ProfileInactive Enforced, Status OK. PersistentStore shows both as\r\n  Enforcement=NotApplicable, Status OK — the persistent view cannot see the shadowing at all.\r\n- **Why it matters.** The product's reconcile and the `inbound_block_hint` probe key on the product rule's NAME.\r\n  The rule that is doing the work is the other one; delete or repoint the fallback and the product rule may\r\n  become the enforced one with no change in what the name probe reports, or the reverse. Kin to the W1\r\n  effector's own comment (\"never certify a rule which ActiveStore reports as ignored or ineffective\") — the\r\n  UDP side never reads ActiveStore.\r\n- **Also seen, same read:** ~26 enforced program-scoped Private rules naming target/debug and actions-runner\r\n  test binaries (spt_net-*, spt_daemon-*, spt.exe), Proto TCP+UDP, LPort Any, Remote Any — the rig-rule\r\n  population the hfenduleam program-scope memory describes; none admits the tailnet.\r\n- **Rule.** A rule probe that certifies anything reads ActiveStore EnforcementStatus, not PersistentStore\r\n  presence and not the name.\r\n- **Kin:** [[IR-110]], memory hfenduleam-program-scoped-firewall-rules-do-not-admit-tailnet.\r\n- **Ripe when:** the next inbound-rule wave, or when the W1 CIM two-store query is generalised to the UDP side.\r\n  · **Size:** one ActiveStore read in the probe; one dedupe decision.\r\n\r\n### IR-112 — bare `cargo test -p spt-daemon --lib` reds two process-global cells on Linux at a sha where nextest is green; libtest is not a sound gate for this crate\r\n\r\n- **Status:** OPEN, rig rule (CI unaffected: `ci.yml` runs `kind(lib)` under nextest). Recorded 2026-09-11 12:46Z\r\n  (doyle) from hertz's Linux cells lane END on kitsubito.\r\n- **Instance.** At 697eb398 on kitsubito: `cargo nextest list -p spt-daemon --lib` = 989 ids; `cargo test -p\r\n  spt-daemon --lib` = 989 run, 987 passed, **2 FAILED, exit 101**:\r\n  `answerop::tests::an_approval_notifies_a_plain_knocker_with_no_pre_authorization` (answerop.rs:324, \"expected\r\n  exactly one courtesy: [] left: 0 right: 1\") and\r\n  `brainproc::tests::the_ready_breadcrumb_tells_a_computed_hash_from_a_cached_one` (brainproc.rs:2347, \"the FIRST\r\n  ready write in a process pays for the digest\"). Both PASS under nextest with the identical filter, exit 0.\r\n- **Mechanism.** Process-per-test vs one shared libtest process: both cells read process-global state (the\r\n  brainproc one says so in its own panic text); under libtest a sibling's write is visible. IR-108's leaky-cell\r\n  class, measured on Linux. Kin memory bystander-test-reads-process-global, daemon-lib-tests-deadlock-on-live-host.\r\n- **Rule.** A gate or rig over spt-daemon's lib runs NEXTEST; a `cargo test --lib` red on this crate is a rig\r\n  fault until discriminated under nextest with the same filter. Count agreement (list == run) says nothing about\r\n  exit agreement — check both.\r\n- **Kin:** [[IR-108]], [[IR-100]].\r\n- **Ripe when:** a sweep makes those two cells hermetic (the fix belongs to the cells, not the gate). · **Size:**\r\n  two fixtures.\r\n\r\n### IR-113 — a killed mutation arm does not unwind: the subject stays mutated and the NEXT arm measures a tree nobody declared; and a mutation that reds on a compile error is a void arm that \"it compiled\" cannot detect\r\n\r\n- **Status:** OPEN, rig rule for every mutation driver. Recorded 2026-09-11 13:05Z (doyle) from todlando's FOLD-1b\r\n  window (fold/304-w2-admission, windows.rs).\r\n- **Instance.** A first M1 injected an early return through a struct literal naming a helper that does not exist —\r\n  a mutation that would red on E0425, not at the cell's assertion, i.e. a void red-first arm. The job was stopped\r\n  mid-run; the driver's restore is its LAST line, so the kill left the MUTATED file on disk: working oid d8ddfdf3\r\n  against pristine 1f475a80, two residue markers present. Caught only because the next act was an oid compare, not\r\n  the next arm. Restored and re-measured identical (residue 0, 786 == 786 lines). Second half: clippy on the\r\n  mutated tree exited 0, so \"it compiled\" would not have exposed the void arm either.\r\n- **Mechanism.** Mutate → run → restore is not transactional; any exit before the last line (kill, timeout, crash,\r\n  nextest hang) strands the mutation. A void arm is one whose red is not AT the assertion the prediction named.\r\n- **Rule.** (1) A mutation driver restores in a finally/trap path, and every arm BEGINS by asserting the subject's\r\n  oid equals the declared pristine oid — the previous arm's revert is proven at the next arm's start, not trusted.\r\n  (2) A red-first arm is accepted only when the artifact names the predicted assertion line; a compile-error red,\r\n  a panic elsewhere, or a red at a different line is VOID, not a pass and not a fail. (3) Mutations are one-token\r\n  edits with an anchor count asserted at 1; an arm that did not change the file voids itself loudly.\r\n- **Kin:** [[IR-107]] (revert proven by oid AND byte shape), memory scripted-edit-zero-match-refusal,\r\n  make-a-new-rig-red-on-purpose.\r\n- **Ripe when:** now — the rule is cheap and the drivers exist; every lane's driver adopts it at its next edit. ·\r\n  **Size:** a trap/finally and one oid compare per arm.\r\n\r\n### IR-114 — three hands wrote one firewall rule set inside ninety seconds under two directors; every census was true at its instant and false a minute later\r\n\r\n- **Status:** OPEN, procedure ruled 2026-09-12 00:50Z (doyle) on todlando's reconciliation; recorded 00:52Z.\r\n- **Instance.** #304 W-2a arms on HFENDULEAM: ~00:44Z todlando asked the operator to delete spt-w2a-C so B would stand alone; ~00:45Z the operator said \"C down\" and todlando's census read B present / C absent (true then); 00:45:05Z liam ADDED C at doyle's direction (doyle had been idle 11 h and did not know the operator's window); 00:46:14Z liam DELETED B at doyle's direction; 00:49:09Z todlando re-measured C present / B absent. Nobody was wrong; the population was not stable. Every fetch todlando reported had an adjacent census and stands; a long background census that straddled the writes returned no spt-w2a rows at all and is UNMEASURED. Separately, doyle's drop-log arm crossed liam's revert in flight: three fetches ran with logging already off — a void arm, redone.\r\n- **Mechanism.** Two directors (operator, gater) each driving a different elevated hand against the same shared host state, neither seeing the other's window; a census taken as a separate earlier step and carried forward.\r\n- **Rule.** For any arm on shared host state: ONE WRITER; the census is taken BY THE FETCHER in the SAME command as the fetch, before and after; the prediction names the exact expected population (an unexpected row is a red); every write is announced with its UTC time to every party; a director resuming after a gap re-measures the population before issuing a write. Kin: memory verify-the-subject-not-just-the-measurement, name-the-file-and-sha.\r\n- **Also measured tonight (todlando):** 'spt-core daemon' (proto Any, Private, remote Any, program = the listener's exe) covers the Private-classified Tailscale interface while TCP 5470 times out from kitsubito and the LAN address answers 200 with ICMP alive — so W-0 measured the tailnet ACL, not program scoping, and DESIRED_PROGRAM=false's cited justification is VOID (the constant may still be right; its citation is not). The shape question moves to a throwaway port and listener over the LAN (arm E).\r\n- **Ripe when:** now — the rule costs nothing. · **Size:** procedure.\r\n\r\n### IR-115 — a firewall census whose port test is DENIED reads every rule as port=Any and counts port-scoped rules as blanket; a `netsh show rule` without `verbose` omits Program and reads every rule as program=Any; a control count that merges two agents' reads is nobody's control\r\n\r\n- **Status:** OPEN, mechanisms recorded 2026-09-12 01:14Z (doyle) from todlando's and liam's own corrections during #304 arm E.\r\n- **Instances.** (1) todlando's first census A (\"26 blanket rules\") and B (\"occupied LocalPort set: EMPTY\"): `Get-NetFirewallPortFilter -All` returns \"Access is denied\" unelevated, the probe swallowed the denial, every rule read as port=Any, and B's positive control (the hand rule carries LocalPort 5470) is what caught it. (2) His replacement pass: `netsh advfirewall firewall show rule name=all` without `verbose` prints no Program line, so it reported 417 blankets and ZERO rules naming spt.exe — provably false, caught by the same control. The third pass (`dir=in verbose`) passed both controls (port-5470 rows = 1, spt.exe rows = 7) and was the census used. (3) doyle's fetcher: first census predicate listed port-covering and program-covering rules as two separate sets; the reaching set is their CONJUNCTION (plus LocalIP, which the first predicate lacked and which is what scopes `Tailscale-In` to the tailnet address only). (4) liam's \"3/3 200\" loopback count merged two of his reads with three of doyle's re-reads as reported; liam corrected it himself. (5) doyle's one in-arm loopback read of 000 at 01:04:22Z had no exit code captured; it is carried as a labelled hole, not classified by a later burst (a later instant cannot classify an earlier read).\r\n- **Mechanism.** A denied or under-scoped read does not error; it returns the permissive default for the field it could not see, so the census reads MORE admits than exist and a shape question gets decided on a phantom population. Kin: memory a-predicate-without-its-tool-is-not-evidence, verdict-from-probe-competence, zero-match-filter-reads-as-absent.\r\n- **Rule.** A firewall census names its tool and privilege and carries two positive controls in the SAME dump: one rule known to carry a specific LocalPort, one known to name a specific Program. A census that cannot see both has not seen the population. The reaching predicate is port-covers AND program-covers AND LocalIP-covers AND profile-covers, one set. Every loopback and remote read records its curl exit code. Counts are per agent; a merged count is restated per agent or discarded.\r\n- **Ripe when:** now — the rule costs one grep. · **Size:** procedure.\r\n\r\n- **Addendum 2026-09-12 03:20Z (doyle, #304 W-2 A5/A4): the Windows Firewall event log is DIRECTION-BLIND, so a rig that keys \"written\" or \"removed\" on it cannot fail in the direction it claims.** Population controlled over one read (2011x48 / 2052x6 / 2097x6, a 400-event re-read of the same window returning the identical six): id 2052 fires on creates AND deletes in the observed population, id 2097 is create-specific, and NOTHING observed is delete-specific. The CENSUS carries the sign; the log carries only the instant. The same read established a MEASURED gap (zero events between A5's end and A4's start) and that nothing commits after the client dies — both usable, neither a direction. Kin: the firewall status fields do not discriminate either, since an admitting hand rule reads the same `PrimaryStatus`/`EnforcementStatus` strings as a non-admitting product pair on the same query.\r\n\r\n### IR-116 — a watchdog that calls a killer and then echoes success reports a kill it never made; `pkill` is absent in msys, so the guard logged \"stopped\" while the arm it guarded ran on\r\n\r\n- **Status:** OPEN, mechanism recorded 2026-09-12 01:24Z (todlando) from his own guard during #304 FOLD-2's Windows arm at 7357ea32; doyle asked for the line.\r\n- **Instance.** todlando armed a watchdog to stop a test arm before it reached `cargo test --workspace --lib`, because spt-daemon lib tests deadlock on a live host. Shape: `if grep -q \"CLIPPY_EXIT=\" log; then pkill -f \"bash /tmp/arms.sh\" 2>/dev/null; echo \"GUARD: arms.sh stopped after clippy at $(date -u)\"`. It printed `GUARD: arms.sh stopped after clippy at 01:24:06Z`. Nothing was stopped: `pkill` does not exist in this msys/Git-Bash environment (`command not found`, exit 127), `2>/dev/null` ate the message, and the `echo` was never gated on the killer's exit. The arm ran on into its compile phase and was found by tailing the build log, not by the guard — whose only output was a green.\r\n- **Mechanism.** Two defects stack, and either alone would have been caught by the other: a missing binary, and a success line that cannot fail. Same family as IR-107 seen from the other side — there a trailing command's exit was mistaken for the producer's; here no exit was consulted at all. The aggravating factor is WHERE it lives: a guard is written while thinking about the hazard it guards, not about the guard, and a guard that never fires looks identical to a guard that works. Kin: memory watchdog-reports-a-kill-it-never-made, verdict-from-exit-not-from-silence, a-predicate-without-its-tool-is-not-evidence.\r\n- **Rule.** A watchdog asserts the POST-STATE and never echoes after the call: `kill …; sleep 1; if still_running; then echo \"GUARD FAILED\"; exit 1; fi`. On msys use `kill -9 <pid>` with a pid you resolved yourself, or `taskkill //PID <p> //T //F`; do not assume `pkill`/`pgrep` exist — check the tool before building a guard on it. Reap your own tree only: resolve the pid and its children, never a machine-wide sweep on a shared box.\r\n- **Second-order, and it bit me inside this very entry.** `git checkout -- <file>` restores from the INDEX, not HEAD. Having staged a first draft, I \"reverted\" it and appended a rewrite — producing a file carrying BOTH. Caught by the diffstat (49 insertions for a ten-line entry). Restore from `HEAD --` when HEAD is what you mean; the diffstat is the control.\r\n- **Corollary, accepted by doyle.** The killed arm reported `TEST_EXIT=137`. That is the SIGKILL, delivered during compilation with ZERO tests executed (last lines `Compiling acto / iroh-dns / wmi`) — a VOID arm, not a red. A 137 sitting in a log over a test arm is precisely the number quoted later as a product failure. Same family as IR-113 (a killed mutation arm does not unwind).\r\n- **Instance 2 — a DIFFERENT tool surface, 2026-09-12 03:39Z (hertz).** The mechanism is not a property of todlando's guard. hertz ran a recursive `grep -rl` over the project tree; it exceeded the foreground timeout and the harness backgrounded it. `TaskStop` returned `{\"message\":\"Successfully stopped task: bn74vtqn0\"}` — a structured success from the harness itself, not a hand-rolled echo. The process was still in the table two minutes later: pid 35104, StartTime 03:37:20Z, **CPU 13.25 s**, killed only by an explicit `Stop-Process -Id 35104 -Force` and confirmed gone by a post-state count of 0 against a live positive control (`pwsh` count 12). So a first-party tool's success object is no better warranted than an `echo`, and the rule generalises: **read the post-state after every stop, whatever the stopping tool said.** Aggravating detail worth its own note — hertz had todlando's disclosure of this exact shape in context and ran it anyway four minutes later; a hazard report describes a SHAPE, and remembering the INSTANCE is not being inoculated against the shape.\r\n- **Ripe when:** now — the rule costs three lines in any guard. · **Size:** procedure.\r\n\r","startLine":6567,"lineNumbers":[6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,6609,6610,6611,6612,6613,6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,6624,6625,6626,6627,6628,6629,6630,6631,6632,6633,6634,6635,6636,6637,6638,6639,6640,6641,6642,6643,6644,6645,6646,6647,6648,6649,6650,6651,6652,6653,6654,6655,6656,6657,6658,6659,6660,6661,6662,6663,6664,6665,6666,6667,6668,6669,6670,6671,6672,6673,6674,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":6938,"totalBytes":22853,"outputLines":145,"outputBytes":22853,"shownRange":{"start":6567,"end":6711},"nextOffset":6712}}},"isError":false,"timestamp":1789483683711}}
{"type":"message","id":"da6c549e","parentId":"a78066f9","timestamp":"2026-09-15T14:48:03.717Z","message":{"role":"toolResult","toolCallId":"call_2IGSye7spdRTE53b7IVjRIX6|fc_000c7cef03cac861016aa95aa394b087d18fd08c07672129b7","toolName":"read","content":[{"type":"text","text":"### IR-128 — PowerShell `$null` can become an empty native string, so a failed launch is misread as a policy refusal before the policy is reached\n\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\n- **Instance.** Both breakaway probe arms called a P/Invoke string parameter with PowerShell `$null`; both returned `CreateProcess` error **123** and created no child. This is an invalid-name result, not the **5** required to establish breakaway-policy denial. An offline C# string-parameter discriminator returned `IsNull($null)=False`: the PowerShell binder had supplied an empty string rather than native NULL.\n- **Correction and evidence.** A C# helper passes the executable explicitly, uses a mutable `StringBuilder` for `CreateProcessW`'s command line, and supplies C# null for the optional current directory. The repaired no-breakaway arm returned **5**, while the BREAKAWAY_OK contrast created a child measured outside the job and still alive after job closure. Original error-123 arms remain invalid and preserved under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/M5/`; corrected records live in its `instrument-repair-20260913T104354Z/M5-denied/` and `M5-allowed/`.\n- **Managed-string recurrence (group N).** The same binder coercion reached `[IO.File]::Replace($tmp, $record, $null)`: the optional backup path became empty, and publication failed with `The path is empty` before any subject was created. The initial N0 gate correctly refused; its partial record and exception are preserved under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T1109444702137Z-N/N0/`. The PowerShell publisher now uses the overwrite-rename overload `[IO.File]::Move($tmp, $record, $true)` instead of passing a nullable string. The corrected N0 reached the intended false coverage assertion; native C# publication retains a real C# null.\n- **Rule.** At native string seams, distinguish NULL from the empty string and verify what the language binder supplies. Use a typed native-call helper where this distinction is load-bearing. Classify the actual error code at the failing stage: a launch error before policy evaluation cannot establish a policy refusal. Command buffers documented writable must be mutable.\n- **Kin:** [[IR-113]] (a failure at the wrong stage is a void discriminator), [[IR-117]] (name the observation that refutes each branch).\n- **Ripe when:** any optional native string argument or process-creation probe crosses PowerShell's binder. **Size:** typed call seam and a null/empty discriminator.\n\n### IR-129 — JSON date materialization followed by implicit string parsing loses UTC kind and precision, turning a live creation anchor into a false pid-reuse verdict\n\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`. The first M8 exit 0 is explicitly INVALID.\n- **Instance.** `ConvertFrom-Json` materialized an ISO birth string as `DateTime`; `[DateTime]::Parse($id.created)` implicitly formatted that object back to text before parsing it. Kind and fractional precision were lost and local time was reinterpreted. The result printed birth timestamps agreeing within a microsecond but computed roughly seven-hour deltas, mislabelling four live registered identities `GONE_PID_REUSED`. The original output remains at `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/M8/`.\n- **Correction and evidence.** The reader handles `DateTime` values directly with `ToUniversalTime`; strings are parsed as `DateTimeOffset` and converted to UTC. Its live-self JSON-roundtrip control measured **9 ticks** difference; a deliberately 500-ms-skewed anchor measured **5,000,009 ticks** and could not match. The corrected final pass covered all **13** registered identities, found every one GONE, and retained the escaped child's earlier SURVIVING readings. Evidence: the same group's `instrument-repair-20260913T104354Z/all-identities-disposition.jsonl` and `final-disposition.stdout`.\n- **2026-09-14 recurrence caught before the field window.** The bound promotion instrument repeated the same reader/parse pair at its brain-birth guard. A language-only discriminator using that pair measured **251,998,765,433 ticks** error. Reading JSON with `-DateKind String` instead preserved the timestamp: same-anchor delta **0 ticks**, deliberately wrong 500-ms anchor **5,000,000 ticks** and refused by the unchanged **10-tick** guard. The successor changes only `Read-Json`; the original instrument remains intact. Evidence: `.spt/preserved/hertz-fp-driver-review/d2/promotion-date-discriminator-result.json` and `provision-promote-VGCTKD7A.ps1`. No field process was needed to expose this known hazard.\n- **Rule.** Treat deserialization's runtime type as part of the interface. Never reparse a typed date through implicit culture-sensitive formatting. Exercise both a same-process roundtrip and a wrong-anchor negative control; preserve raw timestamps and the computed delta so their agreement can be audited. Match at the actual reader resolution, not by discarding the fractional second.\n- **Kin:** [[IR-118]] (successful instrument, wrong answer), [[IR-125]] (an absence predicate needs a known-present control), [[IR-15]] (identity-aware liveness).\n- **Ripe when:** any JSON record is used to authenticate process identity or order events. **Size:** type-aware UTC conversion and two local controls.\n\n### IR-130 — a lowercase `$home` local collides with PowerShell's protected `$HOME`, refusing custody qualification before the signer is reached\n\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz on 2026-09-13 in the D2 custody lane; narrow correction and one fresh-root attempt authorized by doyle `5FWLC3F2`. Original refusal remains preserved.\n- **Instance.** The prepared custody controller passed syntax parsing and compiled its native observer successfully, then exited **1 after 3.33 s** before any custody arm. Its next statement assigned `$home = Join-Path $armRoot 'home'`. PowerShell variable names are case-insensitive: this is an assignment to automatic `$HOME`, whose measured options were **ReadOnly, AllScope**. A separate language-only reproduction returned **VariableNotWritable**. The original catch deliberately omitted exception details, so that error ID belongs to the minimized reproduction; the original record carries the generic refusal and `arms=[]`.\n- **Boundary and evidence.** Compiler native exit **0**, `COMPLETE`, `CONFIRMED_GONE`, active processes **0**; a public fixture and empty `custody-normal` directory existed, but no home, subject arguments, dummy EnvironmentFile, observer execution, signer, git child, real key, or field rig existed. Evidence: `.spt/preserved/hertz-fp-driver-review/d2/AZLCQNZL-CUSTODY-REFUSAL.txt`, `AZLCQNZL-home-variable-repro.json`, `AZLCQNZL-custody-failure-inventory.json`, and `controls-out/custody-6U2UZVXK/`.\n- **Correction.** Rename the local to `$qualificationHome` at its assignment/directory call and environment-overlay reference (two source lines), re-pin the controller, and use a fresh qualification root. Do not relax automatic-variable protection, reuse the failed root, or classify this as a rejection of the assembled xtask's seed isolation. The authorized retry's result is separate evidence, not a rewrite of the first attempt.\n- **Rule.** PowerShell locals share a case-insensitive namespace with automatic variables: use role-specific names rather than `$home`, `$host`, or `$pid`. Syntax acceptance and a successful subordinate compiler do not prove that controller initialization reached its behavioral discriminator. State the last stage actually executed; an empty retirement list is not evidence that secret-bearing processes ran and were cleaned.\n- **Kin:** [[IR-113]] (wrong-stage refusal is a void discriminator), [[IR-128]] (language-boundary failure before the intended policy), [[IR-118]] (plausible result without the claimed observation).\n- **Ripe when:** any PowerShell orchestration or custody controller is authored or changed. **Size:** two-line naming correction plus retained refusal and fresh-root qualification evidence.\n\n### IR-131 — a live-agent signing environment leaks into the provisioning process and correctly refuses before the private signer exists\n\n- **Status:** OPEN, rig invocation-environment defect, not a candidate or disk defect. Measured by hertz on 2026-09-14; classified by doyle in `VGCTKD7A`.\n- **Instance.** Second fresh #297 preparation admitted fourteen native leaves at `04:51:39.245Z`. The separate provisioning call launched at `04:51:52.802Z` and returned `STAGING_FAILED_PREFLIGHT`, native exit **1**, after **0.45 s**. No rig, private directory, key or field nonce existed. This was a preflight refusal before the `04:59:31Z` deadline, not a stalled launch.\n- **Exact check.** A read-only preflight discriminator surfaced `AMBIENT_SIGNING_SECRET_REFUSED` from `Assert-SeedAbsent`. A names-only environment probe found `SPT_RELEASE_SEED` **present**; `SPT_DEBUG_RELEASE_SEED` and `SPT_RELEASE_SEED_CMD` were absent. No values were emitted or changed. The refusal reproduced with **102,099,394,560 bytes free**, and the failing check reads process environment before filesystem preflight: reclaiming disk cannot cure this guard.\n- **Evidence gap.** The original catch persisted a failure JSON only after `$publicReady`, set after preflight. Earlier throws produced only a generic stderr phase and an empty evidence directory. Preserve safe, fixed preflight reasons and caller exit evidence before mutation; silence in the directory is not evidence that the command never ran. Original artifacts remain unchanged under `.spt/preserved/hertz-fp-driver-review/d2/`; see `IH4QFFXS-execution-boundary.json`, `X2LPSQ7A-preflight-only-result.json`, and `X2LPSQ7A-signing-env-presence-result.json`.\n- **Rule.** Scrub the environment handed to the **provisioning PowerShell process itself**, not merely its later signer child: remove every ambient `OWL_*`/`SPT_*` key except the leg's declared allowlist, recording names before/after, never values. Preserve the live agent's parent environment and lifecycle. The guard remains strict. The new debug signing seed enters only the controlled signer's private `EnvironmentFile`; it never becomes ambient in the provisioning process or helpers.\n- **Scrub qualification.** The fresh-child receipt recorded `before_names=[\"SPT_ENDPOINT_ID\",\"SPT_RELEASE_SEED\"]`, `after_names=[]`, and parent names unchanged. This exposed the next startup error: `Stop-Transcript -ErrorAction SilentlyContinue` throws a terminating exception when the required fresh `-NoProfile` host is not transcribing. The successor removes that invalid stop, not the forced-logging policy checks or seed guard. The complete no-mutation preflight then exited **0** with `PREFLIGHT_ONLY_PASS_NO_MUTATION`; no third preparation clock had begun. Evidence: `VGCTKD7A-preflight-result.json`, `VGCTKD7A-preflight-clean-result.json`, and `VGCTKD7A-preflight-clean-environment.json` plus its exit receipt.\n- **Kin:** [[IR-107]] (live-agent identity leaking into consumer/test legs), [[IR-130]] (preflight failure hidden by phase-only reporting), [[IR-122]] (live operational context is not an isolated rig).\n- **Ripe when:** any leg is launched from a live-agent session. **Size:** explicit child environment boundary and durable preflight evidence; no candidate change.\n\n### IR-132 — requiring every live-fleet `spt.exe` image path to be readable permanently refuses an isolated rig's admission\n\n- **Status:** OPEN, rig-instrument admission defect, not a candidate, environment-scrub or disk defect. Measured by hertz and independently localized by doyle on 2026-09-14; correction ruled in `W8TQ3MZC`, `6IQ4HYIL`, `QKQC2NET` and `MRQX7XEK`.\n- **Instance.** Third preparation passed fourteen native admission leaves and genuinely staged the signed set. Promotion then returned `PROMOTION_ADMISSION_FAILED`, native **1**, with `native_records=[]` and shutdown `NOT_STARTED`. Its census required a nonblank CIM `ExecutablePath` for **every** `spt.exe`, not merely one that could belong to the new rig. The read-only predicate replay passed twenty-five preceding statements and failed `SPT_PROCESS_PATH_UNREADABLE` at line 273. No apply, daemon, field nonce or firewall mutation occurred. Receipt: `.spt/preserved/hertz-fp-driver-review/d2/GEL6JAWN-FINAL-REFUSAL.json`.\n- **Shared-box mechanism.** The subsequent census exposed persistent PID **52860**, birth `2026-09-12T20:17:00.5331330Z`, with readable birth but unreadable image path; the rig did not exist until `2026-09-14T05:45:32.8201734Z`. Doyle additionally measured blank paths in **12/12** samples, with transient CLI children alongside the persistent process. An image-readability requirement cannot admit this live shared box. Missing per-rig state files remain an independent gate, not a substitute for process-identity reasoning.\n- **Correction.** Capture `(pid, CIM CreationDate)` together. A birth provably earlier than rig creation excludes that identity without needing its image; the **10-tick** precision allowance only narrows this exemption. Later or overlapping blank-path identities use the existing limited-query native image/birth/retained-handle seam. A native failure is unresolved, not gone. A successful immediate CIM re-read with a live positive control can establish absence; access-denied or failed queries cannot. PID reuse records the original identity gone and classifies the replacement independently. Unknown birth or a persistent unresolved identity refuses. No fleet-process termination is permitted.\n- **Evidence.** Fourteen discriminator cases cover pre-rig exemption, native image resolution, known rig refusal, disappearance versus denied/failed queries, dead-provider control, unknown/equal/precision-overlap births and PID reuse. The final successor passed all fourteen. A read-only live run admitted **17** census hits, including 52860 as `PREDATES_RIG`; actual native self controls measured a **5-tick** CIM/native birth delta, admitted the other-image case and refused the same-image case. Proof: `W8TQ3MZC-census-controls-final.json` and `W8TQ3MZC-census-live-result.json` beside the receipt. Neither proof invoked the product or mutated the rig.\n- **Rule.** Admission asks whether an observed identity can belong to the owned rig, not whether the caller can read every process on the host. Preserve query failure, confirmed absence and replacement identity as different outcomes, with pid and birth in the receipt. Re-pin changed instruments; preserve failed windows and obtain a fresh grant rather than extending their clocks.\n- **Kin:** [[IR-107]] (live operational context enters the rig), [[IR-129]] (creation-time type/precision), [[IR-125]] (known-present control for absence), [[IR-15]] (identity-aware liveness).\n- **Ripe when:** a rig shares a host with elevated perches or short-lived CLI traffic. **Size:** birth-aware census and retained native identity probe, with fail-closed boundary controls.\n\n\n[Showing lines 6837-6888 of 6938. Use :6889 to continue]"}],"details":{"truncation":{"content":"### IR-128 — PowerShell `$null` can become an empty native string, so a failed launch is misread as a policy refusal before the policy is reached\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\r\n- **Instance.** Both breakaway probe arms called a P/Invoke string parameter with PowerShell `$null`; both returned `CreateProcess` error **123** and created no child. This is an invalid-name result, not the **5** required to establish breakaway-policy denial. An offline C# string-parameter discriminator returned `IsNull($null)=False`: the PowerShell binder had supplied an empty string rather than native NULL.\r\n- **Correction and evidence.** A C# helper passes the executable explicitly, uses a mutable `StringBuilder` for `CreateProcessW`'s command line, and supplies C# null for the optional current directory. The repaired no-breakaway arm returned **5**, while the BREAKAWAY_OK contrast created a child measured outside the job and still alive after job closure. Original error-123 arms remain invalid and preserved under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/M5/`; corrected records live in its `instrument-repair-20260913T104354Z/M5-denied/` and `M5-allowed/`.\r\n- **Managed-string recurrence (group N).** The same binder coercion reached `[IO.File]::Replace($tmp, $record, $null)`: the optional backup path became empty, and publication failed with `The path is empty` before any subject was created. The initial N0 gate correctly refused; its partial record and exception are preserved under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T1109444702137Z-N/N0/`. The PowerShell publisher now uses the overwrite-rename overload `[IO.File]::Move($tmp, $record, $true)` instead of passing a nullable string. The corrected N0 reached the intended false coverage assertion; native C# publication retains a real C# null.\r\n- **Rule.** At native string seams, distinguish NULL from the empty string and verify what the language binder supplies. Use a typed native-call helper where this distinction is load-bearing. Classify the actual error code at the failing stage: a launch error before policy evaluation cannot establish a policy refusal. Command buffers documented writable must be mutable.\r\n- **Kin:** [[IR-113]] (a failure at the wrong stage is a void discriminator), [[IR-117]] (name the observation that refutes each branch).\r\n- **Ripe when:** any optional native string argument or process-creation probe crosses PowerShell's binder. **Size:** typed call seam and a null/empty discriminator.\r\n\r\n### IR-129 — JSON date materialization followed by implicit string parsing loses UTC kind and precision, turning a live creation anchor into a false pid-reuse verdict\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`. The first M8 exit 0 is explicitly INVALID.\r\n- **Instance.** `ConvertFrom-Json` materialized an ISO birth string as `DateTime`; `[DateTime]::Parse($id.created)` implicitly formatted that object back to text before parsing it. Kind and fractional precision were lost and local time was reinterpreted. The result printed birth timestamps agreeing within a microsecond but computed roughly seven-hour deltas, mislabelling four live registered identities `GONE_PID_REUSED`. The original output remains at `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/M8/`.\r\n- **Correction and evidence.** The reader handles `DateTime` values directly with `ToUniversalTime`; strings are parsed as `DateTimeOffset` and converted to UTC. Its live-self JSON-roundtrip control measured **9 ticks** difference; a deliberately 500-ms-skewed anchor measured **5,000,009 ticks** and could not match. The corrected final pass covered all **13** registered identities, found every one GONE, and retained the escaped child's earlier SURVIVING readings. Evidence: the same group's `instrument-repair-20260913T104354Z/all-identities-disposition.jsonl` and `final-disposition.stdout`.\r\n- **2026-09-14 recurrence caught before the field window.** The bound promotion instrument repeated the same reader/parse pair at its brain-birth guard. A language-only discriminator using that pair measured **251,998,765,433 ticks** error. Reading JSON with `-DateKind String` instead preserved the timestamp: same-anchor delta **0 ticks**, deliberately wrong 500-ms anchor **5,000,000 ticks** and refused by the unchanged **10-tick** guard. The successor changes only `Read-Json`; the original instrument remains intact. Evidence: `.spt/preserved/hertz-fp-driver-review/d2/promotion-date-discriminator-result.json` and `provision-promote-VGCTKD7A.ps1`. No field process was needed to expose this known hazard.\r\n- **Rule.** Treat deserialization's runtime type as part of the interface. Never reparse a typed date through implicit culture-sensitive formatting. Exercise both a same-process roundtrip and a wrong-anchor negative control; preserve raw timestamps and the computed delta so their agreement can be audited. Match at the actual reader resolution, not by discarding the fractional second.\r\n- **Kin:** [[IR-118]] (successful instrument, wrong answer), [[IR-125]] (an absence predicate needs a known-present control), [[IR-15]] (identity-aware liveness).\r\n- **Ripe when:** any JSON record is used to authenticate process identity or order events. **Size:** type-aware UTC conversion and two local controls.\r\n\r\n### IR-130 — a lowercase `$home` local collides with PowerShell's protected `$HOME`, refusing custody qualification before the signer is reached\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz on 2026-09-13 in the D2 custody lane; narrow correction and one fresh-root attempt authorized by doyle `5FWLC3F2`. Original refusal remains preserved.\r\n- **Instance.** The prepared custody controller passed syntax parsing and compiled its native observer successfully, then exited **1 after 3.33 s** before any custody arm. Its next statement assigned `$home = Join-Path $armRoot 'home'`. PowerShell variable names are case-insensitive: this is an assignment to automatic `$HOME`, whose measured options were **ReadOnly, AllScope**. A separate language-only reproduction returned **VariableNotWritable**. The original catch deliberately omitted exception details, so that error ID belongs to the minimized reproduction; the original record carries the generic refusal and `arms=[]`.\r\n- **Boundary and evidence.** Compiler native exit **0**, `COMPLETE`, `CONFIRMED_GONE`, active processes **0**; a public fixture and empty `custody-normal` directory existed, but no home, subject arguments, dummy EnvironmentFile, observer execution, signer, git child, real key, or field rig existed. Evidence: `.spt/preserved/hertz-fp-driver-review/d2/AZLCQNZL-CUSTODY-REFUSAL.txt`, `AZLCQNZL-home-variable-repro.json`, `AZLCQNZL-custody-failure-inventory.json`, and `controls-out/custody-6U2UZVXK/`.\r\n- **Correction.** Rename the local to `$qualificationHome` at its assignment/directory call and environment-overlay reference (two source lines), re-pin the controller, and use a fresh qualification root. Do not relax automatic-variable protection, reuse the failed root, or classify this as a rejection of the assembled xtask's seed isolation. The authorized retry's result is separate evidence, not a rewrite of the first attempt.\r\n- **Rule.** PowerShell locals share a case-insensitive namespace with automatic variables: use role-specific names rather than `$home`, `$host`, or `$pid`. Syntax acceptance and a successful subordinate compiler do not prove that controller initialization reached its behavioral discriminator. State the last stage actually executed; an empty retirement list is not evidence that secret-bearing processes ran and were cleaned.\r\n- **Kin:** [[IR-113]] (wrong-stage refusal is a void discriminator), [[IR-128]] (language-boundary failure before the intended policy), [[IR-118]] (plausible result without the claimed observation).\r\n- **Ripe when:** any PowerShell orchestration or custody controller is authored or changed. **Size:** two-line naming correction plus retained refusal and fresh-root qualification evidence.\r\n\r\n### IR-131 — a live-agent signing environment leaks into the provisioning process and correctly refuses before the private signer exists\r\n\r\n- **Status:** OPEN, rig invocation-environment defect, not a candidate or disk defect. Measured by hertz on 2026-09-14; classified by doyle in `VGCTKD7A`.\r\n- **Instance.** Second fresh #297 preparation admitted fourteen native leaves at `04:51:39.245Z`. The separate provisioning call launched at `04:51:52.802Z` and returned `STAGING_FAILED_PREFLIGHT`, native exit **1**, after **0.45 s**. No rig, private directory, key or field nonce existed. This was a preflight refusal before the `04:59:31Z` deadline, not a stalled launch.\r\n- **Exact check.** A read-only preflight discriminator surfaced `AMBIENT_SIGNING_SECRET_REFUSED` from `Assert-SeedAbsent`. A names-only environment probe found `SPT_RELEASE_SEED` **present**; `SPT_DEBUG_RELEASE_SEED` and `SPT_RELEASE_SEED_CMD` were absent. No values were emitted or changed. The refusal reproduced with **102,099,394,560 bytes free**, and the failing check reads process environment before filesystem preflight: reclaiming disk cannot cure this guard.\r\n- **Evidence gap.** The original catch persisted a failure JSON only after `$publicReady`, set after preflight. Earlier throws produced only a generic stderr phase and an empty evidence directory. Preserve safe, fixed preflight reasons and caller exit evidence before mutation; silence in the directory is not evidence that the command never ran. Original artifacts remain unchanged under `.spt/preserved/hertz-fp-driver-review/d2/`; see `IH4QFFXS-execution-boundary.json`, `X2LPSQ7A-preflight-only-result.json`, and `X2LPSQ7A-signing-env-presence-result.json`.\r\n- **Rule.** Scrub the environment handed to the **provisioning PowerShell process itself**, not merely its later signer child: remove every ambient `OWL_*`/`SPT_*` key except the leg's declared allowlist, recording names before/after, never values. Preserve the live agent's parent environment and lifecycle. The guard remains strict. The new debug signing seed enters only the controlled signer's private `EnvironmentFile`; it never becomes ambient in the provisioning process or helpers.\r\n- **Scrub qualification.** The fresh-child receipt recorded `before_names=[\"SPT_ENDPOINT_ID\",\"SPT_RELEASE_SEED\"]`, `after_names=[]`, and parent names unchanged. This exposed the next startup error: `Stop-Transcript -ErrorAction SilentlyContinue` throws a terminating exception when the required fresh `-NoProfile` host is not transcribing. The successor removes that invalid stop, not the forced-logging policy checks or seed guard. The complete no-mutation preflight then exited **0** with `PREFLIGHT_ONLY_PASS_NO_MUTATION`; no third preparation clock had begun. Evidence: `VGCTKD7A-preflight-result.json`, `VGCTKD7A-preflight-clean-result.json`, and `VGCTKD7A-preflight-clean-environment.json` plus its exit receipt.\r\n- **Kin:** [[IR-107]] (live-agent identity leaking into consumer/test legs), [[IR-130]] (preflight failure hidden by phase-only reporting), [[IR-122]] (live operational context is not an isolated rig).\r\n- **Ripe when:** any leg is launched from a live-agent session. **Size:** explicit child environment boundary and durable preflight evidence; no candidate change.\r\n\r\n### IR-132 — requiring every live-fleet `spt.exe` image path to be readable permanently refuses an isolated rig's admission\r\n\r\n- **Status:** OPEN, rig-instrument admission defect, not a candidate, environment-scrub or disk defect. Measured by hertz and independently localized by doyle on 2026-09-14; correction ruled in `W8TQ3MZC`, `6IQ4HYIL`, `QKQC2NET` and `MRQX7XEK`.\r\n- **Instance.** Third preparation passed fourteen native admission leaves and genuinely staged the signed set. Promotion then returned `PROMOTION_ADMISSION_FAILED`, native **1**, with `native_records=[]` and shutdown `NOT_STARTED`. Its census required a nonblank CIM `ExecutablePath` for **every** `spt.exe`, not merely one that could belong to the new rig. The read-only predicate replay passed twenty-five preceding statements and failed `SPT_PROCESS_PATH_UNREADABLE` at line 273. No apply, daemon, field nonce or firewall mutation occurred. Receipt: `.spt/preserved/hertz-fp-driver-review/d2/GEL6JAWN-FINAL-REFUSAL.json`.\r\n- **Shared-box mechanism.** The subsequent census exposed persistent PID **52860**, birth `2026-09-12T20:17:00.5331330Z`, with readable birth but unreadable image path; the rig did not exist until `2026-09-14T05:45:32.8201734Z`. Doyle additionally measured blank paths in **12/12** samples, with transient CLI children alongside the persistent process. An image-readability requirement cannot admit this live shared box. Missing per-rig state files remain an independent gate, not a substitute for process-identity reasoning.\r\n- **Correction.** Capture `(pid, CIM CreationDate)` together. A birth provably earlier than rig creation excludes that identity without needing its image; the **10-tick** precision allowance only narrows this exemption. Later or overlapping blank-path identities use the existing limited-query native image/birth/retained-handle seam. A native failure is unresolved, not gone. A successful immediate CIM re-read with a live positive control can establish absence; access-denied or failed queries cannot. PID reuse records the original identity gone and classifies the replacement independently. Unknown birth or a persistent unresolved identity refuses. No fleet-process termination is permitted.\r\n- **Evidence.** Fourteen discriminator cases cover pre-rig exemption, native image resolution, known rig refusal, disappearance versus denied/failed queries, dead-provider control, unknown/equal/precision-overlap births and PID reuse. The final successor passed all fourteen. A read-only live run admitted **17** census hits, including 52860 as `PREDATES_RIG`; actual native self controls measured a **5-tick** CIM/native birth delta, admitted the other-image case and refused the same-image case. Proof: `W8TQ3MZC-census-controls-final.json` and `W8TQ3MZC-census-live-result.json` beside the receipt. Neither proof invoked the product or mutated the rig.\r\n- **Rule.** Admission asks whether an observed identity can belong to the owned rig, not whether the caller can read every process on the host. Preserve query failure, confirmed absence and replacement identity as different outcomes, with pid and birth in the receipt. Re-pin changed instruments; preserve failed windows and obtain a fresh grant rather than extending their clocks.\r\n- **Kin:** [[IR-107]] (live operational context enters the rig), [[IR-129]] (creation-time type/precision), [[IR-125]] (known-present control for absence), [[IR-15]] (identity-aware liveness).\r\n- **Ripe when:** a rig shares a host with elevated perches or short-lived CLI traffic. **Size:** birth-aware census and retained native identity probe, with fail-closed boundary controls.\r\n\r","truncated":true,"truncatedBy":"lines","totalLines":102,"totalBytes":15276,"outputLines":52,"outputBytes":15276,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6938,"displayContent":{"text":"### IR-128 — PowerShell `$null` can become an empty native string, so a failed launch is misread as a policy refusal before the policy is reached\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`.\r\n- **Instance.** Both breakaway probe arms called a P/Invoke string parameter with PowerShell `$null`; both returned `CreateProcess` error **123** and created no child. This is an invalid-name result, not the **5** required to establish breakaway-policy denial. An offline C# string-parameter discriminator returned `IsNull($null)=False`: the PowerShell binder had supplied an empty string rather than native NULL.\r\n- **Correction and evidence.** A C# helper passes the executable explicitly, uses a mutable `StringBuilder` for `CreateProcessW`'s command line, and supplies C# null for the optional current directory. The repaired no-breakaway arm returned **5**, while the BREAKAWAY_OK contrast created a child measured outside the job and still alive after job closure. Original error-123 arms remain invalid and preserved under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/M5/`; corrected records live in its `instrument-repair-20260913T104354Z/M5-denied/` and `M5-allowed/`.\r\n- **Managed-string recurrence (group N).** The same binder coercion reached `[IO.File]::Replace($tmp, $record, $null)`: the optional backup path became empty, and publication failed with `The path is empty` before any subject was created. The initial N0 gate correctly refused; its partial record and exception are preserved under `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T1109444702137Z-N/N0/`. The PowerShell publisher now uses the overwrite-rename overload `[IO.File]::Move($tmp, $record, $true)` instead of passing a nullable string. The corrected N0 reached the intended false coverage assertion; native C# publication retains a real C# null.\r\n- **Rule.** At native string seams, distinguish NULL from the empty string and verify what the language binder supplies. Use a typed native-call helper where this distinction is load-bearing. Classify the actual error code at the failing stage: a launch error before policy evaluation cannot establish a policy refusal. Command buffers documented writable must be mutable.\r\n- **Kin:** [[IR-113]] (a failure at the wrong stage is a void discriminator), [[IR-117]] (name the observation that refutes each branch).\r\n- **Ripe when:** any optional native string argument or process-creation probe crosses PowerShell's binder. **Size:** typed call seam and a null/empty discriminator.\r\n\r\n### IR-129 — JSON date materialization followed by implicit string parsing loses UTC kind and precision, turning a live creation anchor into a false pid-reuse verdict\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz in group M, 2026-09-13; accepted by doyle in `3XE67XYP`. The first M8 exit 0 is explicitly INVALID.\r\n- **Instance.** `ConvertFrom-Json` materialized an ISO birth string as `DateTime`; `[DateTime]::Parse($id.created)` implicitly formatted that object back to text before parsing it. Kind and fractional precision were lost and local time was reinterpreted. The result printed birth timestamps agreeing within a microsecond but computed roughly seven-hour deltas, mislabelling four live registered identities `GONE_PID_REUSED`. The original output remains at `.spt/preserved/hertz-fp-driver-review/d2/controls-out/20260913T103751Z-M/M8/`.\r\n- **Correction and evidence.** The reader handles `DateTime` values directly with `ToUniversalTime`; strings are parsed as `DateTimeOffset` and converted to UTC. Its live-self JSON-roundtrip control measured **9 ticks** difference; a deliberately 500-ms-skewed anchor measured **5,000,009 ticks** and could not match. The corrected final pass covered all **13** registered identities, found every one GONE, and retained the escaped child's earlier SURVIVING readings. Evidence: the same group's `instrument-repair-20260913T104354Z/all-identities-disposition.jsonl` and `final-disposition.stdout`.\r\n- **2026-09-14 recurrence caught before the field window.** The bound promotion instrument repeated the same reader/parse pair at its brain-birth guard. A language-only discriminator using that pair measured **251,998,765,433 ticks** error. Reading JSON with `-DateKind String` instead preserved the timestamp: same-anchor delta **0 ticks**, deliberately wrong 500-ms anchor **5,000,000 ticks** and refused by the unchanged **10-tick** guard. The successor changes only `Read-Json`; the original instrument remains intact. Evidence: `.spt/preserved/hertz-fp-driver-review/d2/promotion-date-discriminator-result.json` and `provision-promote-VGCTKD7A.ps1`. No field process was needed to expose this known hazard.\r\n- **Rule.** Treat deserialization's runtime type as part of the interface. Never reparse a typed date through implicit culture-sensitive formatting. Exercise both a same-process roundtrip and a wrong-anchor negative control; preserve raw timestamps and the computed delta so their agreement can be audited. Match at the actual reader resolution, not by discarding the fractional second.\r\n- **Kin:** [[IR-118]] (successful instrument, wrong answer), [[IR-125]] (an absence predicate needs a known-present control), [[IR-15]] (identity-aware liveness).\r\n- **Ripe when:** any JSON record is used to authenticate process identity or order events. **Size:** type-aware UTC conversion and two local controls.\r\n\r\n### IR-130 — a lowercase `$home` local collides with PowerShell's protected `$HOME`, refusing custody qualification before the signer is reached\r\n\r\n- **Status:** OPEN, rig-instrument hazard, not a product finding. Measured by hertz on 2026-09-13 in the D2 custody lane; narrow correction and one fresh-root attempt authorized by doyle `5FWLC3F2`. Original refusal remains preserved.\r\n- **Instance.** The prepared custody controller passed syntax parsing and compiled its native observer successfully, then exited **1 after 3.33 s** before any custody arm. Its next statement assigned `$home = Join-Path $armRoot 'home'`. PowerShell variable names are case-insensitive: this is an assignment to automatic `$HOME`, whose measured options were **ReadOnly, AllScope**. A separate language-only reproduction returned **VariableNotWritable**. The original catch deliberately omitted exception details, so that error ID belongs to the minimized reproduction; the original record carries the generic refusal and `arms=[]`.\r\n- **Boundary and evidence.** Compiler native exit **0**, `COMPLETE`, `CONFIRMED_GONE`, active processes **0**; a public fixture and empty `custody-normal` directory existed, but no home, subject arguments, dummy EnvironmentFile, observer execution, signer, git child, real key, or field rig existed. Evidence: `.spt/preserved/hertz-fp-driver-review/d2/AZLCQNZL-CUSTODY-REFUSAL.txt`, `AZLCQNZL-home-variable-repro.json`, `AZLCQNZL-custody-failure-inventory.json`, and `controls-out/custody-6U2UZVXK/`.\r\n- **Correction.** Rename the local to `$qualificationHome` at its assignment/directory call and environment-overlay reference (two source lines), re-pin the controller, and use a fresh qualification root. Do not relax automatic-variable protection, reuse the failed root, or classify this as a rejection of the assembled xtask's seed isolation. The authorized retry's result is separate evidence, not a rewrite of the first attempt.\r\n- **Rule.** PowerShell locals share a case-insensitive namespace with automatic variables: use role-specific names rather than `$home`, `$host`, or `$pid`. Syntax acceptance and a successful subordinate compiler do not prove that controller initialization reached its behavioral discriminator. State the last stage actually executed; an empty retirement list is not evidence that secret-bearing processes ran and were cleaned.\r\n- **Kin:** [[IR-113]] (wrong-stage refusal is a void discriminator), [[IR-128]] (language-boundary failure before the intended policy), [[IR-118]] (plausible result without the claimed observation).\r\n- **Ripe when:** any PowerShell orchestration or custody controller is authored or changed. **Size:** two-line naming correction plus retained refusal and fresh-root qualification evidence.\r\n\r\n### IR-131 — a live-agent signing environment leaks into the provisioning process and correctly refuses before the private signer exists\r\n\r\n- **Status:** OPEN, rig invocation-environment defect, not a candidate or disk defect. Measured by hertz on 2026-09-14; classified by doyle in `VGCTKD7A`.\r\n- **Instance.** Second fresh #297 preparation admitted fourteen native leaves at `04:51:39.245Z`. The separate provisioning call launched at `04:51:52.802Z` and returned `STAGING_FAILED_PREFLIGHT`, native exit **1**, after **0.45 s**. No rig, private directory, key or field nonce existed. This was a preflight refusal before the `04:59:31Z` deadline, not a stalled launch.\r\n- **Exact check.** A read-only preflight discriminator surfaced `AMBIENT_SIGNING_SECRET_REFUSED` from `Assert-SeedAbsent`. A names-only environment probe found `SPT_RELEASE_SEED` **present**; `SPT_DEBUG_RELEASE_SEED` and `SPT_RELEASE_SEED_CMD` were absent. No values were emitted or changed. The refusal reproduced with **102,099,394,560 bytes free**, and the failing check reads process environment before filesystem preflight: reclaiming disk cannot cure this guard.\r\n- **Evidence gap.** The original catch persisted a failure JSON only after `$publicReady`, set after preflight. Earlier throws produced only a generic stderr phase and an empty evidence directory. Preserve safe, fixed preflight reasons and caller exit evidence before mutation; silence in the directory is not evidence that the command never ran. Original artifacts remain unchanged under `.spt/preserved/hertz-fp-driver-review/d2/`; see `IH4QFFXS-execution-boundary.json`, `X2LPSQ7A-preflight-only-result.json`, and `X2LPSQ7A-signing-env-presence-result.json`.\r\n- **Rule.** Scrub the environment handed to the **provisioning PowerShell process itself**, not merely its later signer child: remove every ambient `OWL_*`/`SPT_*` key except the leg's declared allowlist, recording names before/after, never values. Preserve the live agent's parent environment and lifecycle. The guard remains strict. The new debug signing seed enters only the controlled signer's private `EnvironmentFile`; it never becomes ambient in the provisioning process or helpers.\r\n- **Scrub qualification.** The fresh-child receipt recorded `before_names=[\"SPT_ENDPOINT_ID\",\"SPT_RELEASE_SEED\"]`, `after_names=[]`, and parent names unchanged. This exposed the next startup error: `Stop-Transcript -ErrorAction SilentlyContinue` throws a terminating exception when the required fresh `-NoProfile` host is not transcribing. The successor removes that invalid stop, not the forced-logging policy checks or seed guard. The complete no-mutation preflight then exited **0** with `PREFLIGHT_ONLY_PASS_NO_MUTATION`; no third preparation clock had begun. Evidence: `VGCTKD7A-preflight-result.json`, `VGCTKD7A-preflight-clean-result.json`, and `VGCTKD7A-preflight-clean-environment.json` plus its exit receipt.\r\n- **Kin:** [[IR-107]] (live-agent identity leaking into consumer/test legs), [[IR-130]] (preflight failure hidden by phase-only reporting), [[IR-122]] (live operational context is not an isolated rig).\r\n- **Ripe when:** any leg is launched from a live-agent session. **Size:** explicit child environment boundary and durable preflight evidence; no candidate change.\r\n\r\n### IR-132 — requiring every live-fleet `spt.exe` image path to be readable permanently refuses an isolated rig's admission\r\n\r\n- **Status:** OPEN, rig-instrument admission defect, not a candidate, environment-scrub or disk defect. Measured by hertz and independently localized by doyle on 2026-09-14; correction ruled in `W8TQ3MZC`, `6IQ4HYIL`, `QKQC2NET` and `MRQX7XEK`.\r\n- **Instance.** Third preparation passed fourteen native admission leaves and genuinely staged the signed set. Promotion then returned `PROMOTION_ADMISSION_FAILED`, native **1**, with `native_records=[]` and shutdown `NOT_STARTED`. Its census required a nonblank CIM `ExecutablePath` for **every** `spt.exe`, not merely one that could belong to the new rig. The read-only predicate replay passed twenty-five preceding statements and failed `SPT_PROCESS_PATH_UNREADABLE` at line 273. No apply, daemon, field nonce or firewall mutation occurred. Receipt: `.spt/preserved/hertz-fp-driver-review/d2/GEL6JAWN-FINAL-REFUSAL.json`.\r\n- **Shared-box mechanism.** The subsequent census exposed persistent PID **52860**, birth `2026-09-12T20:17:00.5331330Z`, with readable birth but unreadable image path; the rig did not exist until `2026-09-14T05:45:32.8201734Z`. Doyle additionally measured blank paths in **12/12** samples, with transient CLI children alongside the persistent process. An image-readability requirement cannot admit this live shared box. Missing per-rig state files remain an independent gate, not a substitute for process-identity reasoning.\r\n- **Correction.** Capture `(pid, CIM CreationDate)` together. A birth provably earlier than rig creation excludes that identity without needing its image; the **10-tick** precision allowance only narrows this exemption. Later or overlapping blank-path identities use the existing limited-query native image/birth/retained-handle seam. A native failure is unresolved, not gone. A successful immediate CIM re-read with a live positive control can establish absence; access-denied or failed queries cannot. PID reuse records the original identity gone and classifies the replacement independently. Unknown birth or a persistent unresolved identity refuses. No fleet-process termination is permitted.\r\n- **Evidence.** Fourteen discriminator cases cover pre-rig exemption, native image resolution, known rig refusal, disappearance versus denied/failed queries, dead-provider control, unknown/equal/precision-overlap births and PID reuse. The final successor passed all fourteen. A read-only live run admitted **17** census hits, including 52860 as `PREDATES_RIG`; actual native self controls measured a **5-tick** CIM/native birth delta, admitted the other-image case and refused the same-image case. Proof: `W8TQ3MZC-census-controls-final.json` and `W8TQ3MZC-census-live-result.json` beside the receipt. Neither proof invoked the product or mutated the rig.\r\n- **Rule.** Admission asks whether an observed identity can belong to the owned rig, not whether the caller can read every process on the host. Preserve query failure, confirmed absence and replacement identity as different outcomes, with pid and birth in the receipt. Re-pin changed instruments; preserve failed windows and obtain a fresh grant rather than extending their clocks.\r\n- **Kin:** [[IR-107]] (live operational context enters the rig), [[IR-129]] (creation-time type/precision), [[IR-125]] (known-present control for absence), [[IR-15]] (identity-aware liveness).\r\n- **Ripe when:** a rig shares a host with elevated perches or short-lived CLI traffic. **Size:** birth-aware census and retained native identity probe, with fail-closed boundary controls.\r\n\r","startLine":6837,"lineNumbers":[6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,6847,6848,6849,6850,6851,6852,6853,6854,6855,6856,6857,6858,6859,6860,6861,6862,6863,6864,6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,6878,6879,6880,6881,6882,6883,6884,6885,6886,6887,6888]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":6938,"totalBytes":15276,"outputLines":52,"outputBytes":15276,"shownRange":{"start":6837,"end":6888},"nextOffset":6889}}},"isError":false,"timestamp":1789483683717}}
{"type":"message","id":"397f1935","parentId":"da6c549e","timestamp":"2026-09-15T14:48:03.759Z","message":{"role":"toolResult","toolCallId":"call_5SC73LBYbynWTk3TB4TBE7Wq|fc_000c7cef03cac861016aa95aa394b487d19afa73ed25f51f2f","toolName":"grep","content":[{"type":"text","text":"No matches found\nSkipped missing paths: .worktrees/hertz-ir86-disk-delta/xtask/src/brainread.rs"}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs, .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs, .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs","searchPath":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\crates\\spt-daemon","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core","matchCount":0,"fileCount":0,"files":[],"truncated":false,"missingPaths":[".worktrees/hertz-ir86-disk-delta/xtask/src/brainread.rs"]},"isError":false,"useless":true,"timestamp":1789483683759}}
{"type":"message","id":"14cca78f","parentId":"397f1935","timestamp":"2026-09-15T14:48:03.944Z","message":{"role":"toolResult","toolCallId":"call_BWgHB0WgbZ4MGEdGwkEa3y09|fc_000c7cef03cac861016aa95aa394bc87d1bb5dc561ac768e35","toolName":"grep","content":[{"type":"text","text":"# .worktrees/hertz-ir86-disk-delta/\n## traceable-reqs.toml\n 24|enforce = \"on\"\n*25|module_banner = \"accept\"\n 26|\n 27|[[requirements]]\n 28|id = \"REQ-STATUS-LIVE-SUPERVISOR-PID\"\n...\n 1176|required_stages = [\"doc\", \"impl\", \"unit\"]  # doc activated restoration D1 (KNOWN-HAZARDS 6.8 + ADR-0018 + design doc V1). impl/unit activated restoration D6-3 (the one D6 toml activation): impl = rollback_compat.rs (the pre-ready durable-file registry PRE_READY_DURABLE_FILES — the enumerated guard surface) + the two-phase AppliedRecord (relcache.rs, additive durable state); unit = the rollback_compat tripwire (every current pre-ready file shape is additive / N-1-readable; a non-additive pre-ready chang...\n*1177|# --- Added 2026-06-11 (v0.4.2): the v0.4.1 fleet-roll Linux brain-respawn blocker (ADR-0018 Q3 amendment); rule 3 register-before-satisfy, rule 5 activate per task ---\n 1178|[[requirements]]\n 1179|id = \"REQ-HAZARD-BRAIN-RESPAWN-PATH\"\n 1180|title = \"The broker respawns the brain onto the APPLIED bytes, not the renamed old binary: the candidate-binary default is the canonical exe path captured ONCE at broker start, never a per-spawn std::env::current_exe() — on Linux current_exe (readlink /proc/self/exe) is inode-tracking and follows the `apply` rename (spt -> spt.old-N), so a resident broker would respawn the brain onto OLD bytes while recording `applied` (Windows GetModuleFileName is path-at-start, so Windows was green; ADR-0018 Q3 silen...\n*1181|required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]  # activated v0.4.2 (2026-06-11): minted from the v0.4.1 fleet-roll blocker. doc = KNOWN-HAZARDS 6.11 + ADR-0018 Q3 amendment; int = brain_respawn_rename.rs (real broker process, in-place rename P->P.old-N + new bytes at P, respawn must run B not A — fails Linux pre-fix). Stages: impl = brainproc.rs canonical-exe capture at spawn_brain_supervisor + promotion bytes-gate in supervise_brain Promoted arm (TrialEnv ready_exe_hash/staged_artifact_hash); unit =...\n 1182|# --- Added 2026-06-03 from grill-with-docs (ADR-0012, hazard 7.3); inactive until M4-D7.5 ---\n 1183|[[requirements]]\n 1184|id = \"REQ-HAZARD-PSYCHE-OUTBOUND-PROXY\"\n...\n 3061|id = \"REQ-CI-POSTJOB-DAEMON-REAP\"\n*3062|title = \"A CI job REAPS ITS OWN test-spawned daemons at battery end, in-job, and logs a process census at job start AND job end so contamination and reap effectiveness are visible in every run's log. (Load-flake family leg 1, doyle-ratified 2026-07-22 from deployah's third-run analysis.) THE SIGNATURE THIS CLOSES: a DIFFERENT single daemon-spawning test dying per run with a bare exit 1 and NO assertion output — process-level death, not a failed assert — while sibling tests in the same families pass a...\n 3063|required_stages = [\"impl\"]  # LOAD-FLAKE leg 1 ACTIVATED on build branch (todlando 2026-07-22). impl = .github/ci/reap-census.ps1 + .github/ci/reap-census.sh (scope roots, per-pid re-verification at kill time, hard exclusions, bounded settle, start/end census) wired into ci.yml's `test` and `n1-gate` jobs on both runners, the end step under always(). No unit stage: the evidence is a recipe the runner executes, and the acceptance is a census diff read off live run logs (zero test-spawned daemons surviving...\n 3064|\n 3065|[[requirements]]\n...\n 3266|id = \"REQ-DAEMON-BITS-AMBIGUITY\"\n*3267|title = \"SEED (inactive, RCA-first — do NOT close on agreement): nothing on a node surfaces WHICH BITS ARE SERVING, and the same silent wrong-state shape bit twice in one day (2026-07-25). Case 1 (adapter-side echo): a post-reboot ensure race left a dev-build alchemy Hub Daemon serving release shells — version skew visible only by manually comparing process image paths. Case 2 (core, field-measured by flynn): TWO spt daemons resident with live brains on one node — the installed main daemon (owning ...\n 3268|required_stages = []  # rule 5: INACTIVE — RCA-first; activate when a milestone owns the daemon-identity observability question.\n 3269|\n 3270|# --- Seeded 2026-07-25 (doyle) from the operator's account of the 17:47 restart failure\n\n## .github/ci/\n### reap-census.ps1\n 25|\n*26|  KILL SCOPE IS PATH-VERIFIED AND NARROW, per-pid, AT KILL TIME — never machine-wide.\n 27|  A process is eligible only if its on-disk image sits under one of this run's own build\n 28|  roots (workspace, CARGO_TARGET_DIR, the notify-adapter checkout's target, RUNNER_TEMP,\n 29|  the pinned n1 old-broker build cache). Two hard exclusions are checked even for a\n### reap-census.sh\n 24|#   3. The obvious patch — `pgrep -f` — is WORSE, not better: full-cmdline substring matching\n*25|#      is precisely the machine-wide-match class this script's own kill-scope rules forbid.\n 26|#\n 27|# Walking /proc and classifying on the exe path makes that path the SINGLE SOURCE OF TRUTH\n 28|# for both membership and scope, and the 15-char limit stops existing. comm is consulted\n...\n 35|#\n*36|# KILL SCOPE IS PATH-VERIFIED AND NARROW, re-resolved per-pid at kill time via\n 37|# /proc/<pid>/exe — never a bare `pkill spt`. Live infra under a `spt-core/bin/` install\n 38|# prefix and any `owl` binary are hard-excluded even if a root is ever computed too wide,\n 39|# and a process whose exe link cannot be read is reported but never killed: unreadable\n### traceable-reqs-selftest.sh\n 40|  # authentication/build, not just report an unrelated downstream exit 128.\n*41|  case \"$out\" in *\"pin=0.4.1\"*) ;; *) printf 'FAIL missing pin: %s\\n' \"$out\"; exit 1;; esac\n 42|  case \"$out\" in *\"box=\"*) ;; *) printf 'FAIL missing box: %s\\n' \"$out\"; exit 1;; esac\n 43|  if [ \"$label\" = stale-no-token ]; then\n 44|    case \"$out\" in *\"0.2.0\"*\"TRACEABLE_REQS_TOKEN\"*) ;; *) printf 'FAIL mismatch/auth diagnostic: %s\\n' \"$out\"; exit 1;; esac\n...\n 51|  if [ \"$mode\" = install ] && [ \"$rc\" = 0 ]; then\n*52|    [ \"$(\"$root/checkout/traceable-reqs\" --version)\" = 'traceable-reqs 0.4.1' ]\n 53|  else\n 54|    [ ! -e \"$root/checkout/traceable-reqs\" ]\n 55|  fi\n...\n 60|run_case stale-no-token 'traceable-reqs 0.2.0' 0 '' precheck 1\n*61|run_case matching-no-token 'traceable-reqs 0.4.1' 0 '' precheck 0\n*62|run_case matching-install 'traceable-reqs 0.4.1' 0 '' install 0\n 63|run_case missing-no-token missing 0 '' install 1\n*64|run_case failed-version 'traceable-reqs 0.4.1' 7 '' precheck 1\n 65|run_case regex-lookalike 'traceable-reqs 0x4x1' 0 '' precheck 1\n 66|run_case repair-admitted 'traceable-reqs 0.2.0' 0 TOKEN_CANARY precheck 0\n 67|run_case clone-refusal 'traceable-reqs 0.2.0' 0 TOKEN_CANARY install 128\n### traceable-reqs.sh\n 4|set -euo pipefail\n*5|# 0.4.1 fixes file-root enumeration dropping present doc evidence (IR-109).\n*6|WANT=0.4.1\n 7|BIN=\"$HOME/.local/bin/traceable-reqs\"\n 8|mode=\"${1:-precheck}\"\n 9|case \"$mode\" in precheck|install) ;; *) echo 'usage: traceable-reqs.sh [precheck|install]' >&2; exit 2;; esac\n### ws272-w0.py\n 4|--preflight-only makes no build claim and runs no cargo. --self-test exercises\n*5|all three IR-76 decisions without network access. --run requires the explicit\n 6|hold-release acknowledgement and repeats the live meter before each cargo leg.\n 7|Every leg retains its raw output and actual subprocess exit code beside it.\n 8|\n### ws272-w1.py\n 3|\n*4|Same shape as ws272-w0.py: the IR-76 three-arm pre-flight, the lane lock, the env\n 5|scrub, the cold-pool bootstrap. W1 adds spt-net to the nextest population (the\n 6|`web` record family lives there) and runs the new `twohost_web` bin ALONE as its\n 7|own leg, never beside the unit leg (it is env-gated and a silent no-op without\n...\n 10|--preflight-only makes no build claim and runs no cargo. --self-test exercises\n*11|all three IR-76 decisions without network access. --run requires the explicit\n 12|hold-release acknowledgement and repeats the live meter before each cargo leg.\n 13|Every leg retains its raw output and actual subprocess exit code beside it.\n 14|\n### ws272-w2.py\n 3|\n*4|Same shape as ws272-w2.py — the IR-76 three-arm pre-flight, the lane lock, the env\n 5|scrub, the cold-pool bootstrap — with ONE deliberate difference: the nextest leg is\n 6|TARGETED, not a workspace sweep (gater ruling 2026-09-07 02:40Z). W2 shares the W1\n 7|pool (176 GB) on a box measuring ~28 GB free against CI's 32 GiB floor, and a full\n...\n 17|--preflight-only makes no build claim and runs no cargo. --self-test exercises\n*18|all three IR-76 decisions without network access. --run requires the explicit\n 19|hold-release acknowledgement and repeats the live meter before each cargo leg.\n 20|Every leg retains its raw output and actual subprocess exit code beside it.\n 21|\n\nSkipped missing paths: .worktrees/hertz-ir86-disk-delta/xtask/src\n\n[Some lines truncated to 512 chars]"}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/AGENTS.md, .worktrees/hertz-ir86-disk-delta/.github, .worktrees/hertz-ir86-disk-delta/traceable-reqs.toml, .worktrees/hertz-ir86-disk-delta/crates/spt/tests/common","searchPath":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core","matchCount":20,"fileCount":8,"files":[".worktrees/hertz-ir86-disk-delta/.github/ci/reap-census.ps1",".worktrees/hertz-ir86-disk-delta/.github/ci/reap-census.sh",".worktrees/hertz-ir86-disk-delta/.github/ci/traceable-reqs-selftest.sh",".worktrees/hertz-ir86-disk-delta/.github/ci/traceable-reqs.sh",".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w0.py",".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w1.py",".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w2.py",".worktrees/hertz-ir86-disk-delta/traceable-reqs.toml"],"fileMatches":[{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/reap-census.ps1","count":1},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/reap-census.sh","count":2},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/traceable-reqs-selftest.sh","count":5},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/traceable-reqs.sh","count":2},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w0.py","count":1},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w1.py","count":2},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w2.py","count":2},{"path":".worktrees/hertz-ir86-disk-delta/traceable-reqs.toml","count":5}],"truncated":true,"displayContent":"# .worktrees/hertz-ir86-disk-delta/\n## traceable-reqs.toml\n   24│enforce = \"on\"\n  *25│module_banner = \"accept\"\n   26│\n   27│[[requirements]]\n   28│id = \"REQ-STATUS-LIVE-SUPERVISOR-PID\"\n     │...\n 1176│required_stages = [\"doc\", \"impl\", \"unit\"]  # doc activated restoration D1 (KNOWN-HAZARDS 6.8 + ADR-0018 + design doc V1). impl/unit activated restoration D6-3 (the one D6 toml activation): impl = rollback_compat.rs (the pre-ready durable-file registry PRE_READY_DURABLE_FILES — the enumerated guard surface) + the two-phase AppliedRecord (relcache.rs, additive durable state); unit = the rollback_compat tripwire (every current pre-ready file shape is additive / N-1-readable; a non-additive pre-ready chang...\n*1177│# --- Added 2026-06-11 (v0.4.2): the v0.4.1 fleet-roll Linux brain-respawn blocker (ADR-0018 Q3 amendment); rule 3 register-before-satisfy, rule 5 activate per task ---\n 1178│[[requirements]]\n 1179│id = \"REQ-HAZARD-BRAIN-RESPAWN-PATH\"\n 1180│title = \"The broker respawns the brain onto the APPLIED bytes, not the renamed old binary: the candidate-binary default is the canonical exe path captured ONCE at broker start, never a per-spawn std::env::current_exe() — on Linux current_exe (readlink /proc/self/exe) is inode-tracking and follows the `apply` rename (spt -> spt.old-N), so a resident broker would respawn the brain onto OLD bytes while recording `applied` (Windows GetModuleFileName is path-at-start, so Windows was green; ADR-0018 Q3 silen...\n*1181│required_stages = [\"doc\", \"impl\", \"unit\", \"int\"]  # activated v0.4.2 (2026-06-11): minted from the v0.4.1 fleet-roll blocker. doc = KNOWN-HAZARDS 6.11 + ADR-0018 Q3 amendment; int = brain_respawn_rename.rs (real broker process, in-place rename P->P.old-N + new bytes at P, respawn must run B not A — fails Linux pre-fix). Stages: impl = brainproc.rs canonical-exe capture at spawn_brain_supervisor + promotion bytes-gate in supervise_brain Promoted arm (TrialEnv ready_exe_hash/staged_artifact_hash); unit =...\n 1182│# --- Added 2026-06-03 from grill-with-docs (ADR-0012, hazard 7.3); inactive until M4-D7.5 ---\n 1183│[[requirements]]\n 1184│id = \"REQ-HAZARD-PSYCHE-OUTBOUND-PROXY\"\n     │...\n 3061│id = \"REQ-CI-POSTJOB-DAEMON-REAP\"\n*3062│title = \"A CI job REAPS ITS OWN test-spawned daemons at battery end, in-job, and logs a process census at job start AND job end so contamination and reap effectiveness are visible in every run's log. (Load-flake family leg 1, doyle-ratified 2026-07-22 from deployah's third-run analysis.) THE SIGNATURE THIS CLOSES: a DIFFERENT single daemon-spawning test dying per run with a bare exit 1 and NO assertion output — process-level death, not a failed assert — while sibling tests in the same families pass a...\n 3063│required_stages = [\"impl\"]  # LOAD-FLAKE leg 1 ACTIVATED on build branch (todlando 2026-07-22). impl = .github/ci/reap-census.ps1 + .github/ci/reap-census.sh (scope roots, per-pid re-verification at kill time, hard exclusions, bounded settle, start/end census) wired into ci.yml's `test` and `n1-gate` jobs on both runners, the end step under always(). No unit stage: the evidence is a recipe the runner executes, and the acceptance is a census diff read off live run logs (zero test-spawned daemons surviving...\n 3064│\n 3065│[[requirements]]\n     │...\n 3266│id = \"REQ-DAEMON-BITS-AMBIGUITY\"\n*3267│title = \"SEED (inactive, RCA-first — do NOT close on agreement): nothing on a node surfaces WHICH BITS ARE SERVING, and the same silent wrong-state shape bit twice in one day (2026-07-25). Case 1 (adapter-side echo): a post-reboot ensure race left a dev-build alchemy Hub Daemon serving release shells — version skew visible only by manually comparing process image paths. Case 2 (core, field-measured by flynn): TWO spt daemons resident with live brains on one node — the installed main daemon (owning ...\n 3268│required_stages = []  # rule 5: INACTIVE — RCA-first; activate when a milestone owns the daemon-identity observability question.\n 3269│\n 3270│# --- Seeded 2026-07-25 (doyle) from the operator's account of the 17:47 restart failure\n\n## .github/ci/\n### reap-census.ps1\n 25│\n*26│  KILL SCOPE IS PATH-VERIFIED AND NARROW, per-pid, AT KILL TIME — never machine-wide.\n 27│  A process is eligible only if its on-disk image sits under one of this run's own build\n 28│  roots (workspace, CARGO_TARGET_DIR, the notify-adapter checkout's target, RUNNER_TEMP,\n 29│  the pinned n1 old-broker build cache). Two hard exclusions are checked even for a\n### reap-census.sh\n 24│#   3. The obvious patch — `pgrep -f` — is WORSE, not better: full-cmdline substring matching\n*25│#      is precisely the machine-wide-match class this script's own kill-scope rules forbid.\n 26│#\n 27│# Walking /proc and classifying on the exe path makes that path the SINGLE SOURCE OF TRUTH\n 28│# for both membership and scope, and the 15-char limit stops existing. comm is consulted\n   │...\n 35│#\n*36│# KILL SCOPE IS PATH-VERIFIED AND NARROW, re-resolved per-pid at kill time via\n 37│# /proc/<pid>/exe — never a bare `pkill spt`. Live infra under a `spt-core/bin/` install\n 38│# prefix and any `owl` binary are hard-excluded even if a root is ever computed too wide,\n 39│# and a process whose exe link cannot be read is reported but never killed: unreadable\n### traceable-reqs-selftest.sh\n 40│  # authentication/build, not just report an unrelated downstream exit 128.\n*41│  case \"$out\" in *\"pin=0.4.1\"*) ;; *) printf 'FAIL missing pin: %s\\n' \"$out\"; exit 1;; esac\n 42│  case \"$out\" in *\"box=\"*) ;; *) printf 'FAIL missing box: %s\\n' \"$out\"; exit 1;; esac\n 43│  if [ \"$label\" = stale-no-token ]; then\n 44│    case \"$out\" in *\"0.2.0\"*\"TRACEABLE_REQS_TOKEN\"*) ;; *) printf 'FAIL mismatch/auth diagnostic: %s\\n' \"$out\"; exit 1;; esac\n   │...\n 51│  if [ \"$mode\" = install ] && [ \"$rc\" = 0 ]; then\n*52│    [ \"$(\"$root/checkout/traceable-reqs\" --version)\" = 'traceable-reqs 0.4.1' ]\n 53│  else\n 54│    [ ! -e \"$root/checkout/traceable-reqs\" ]\n 55│  fi\n   │...\n 60│run_case stale-no-token 'traceable-reqs 0.2.0' 0 '' precheck 1\n*61│run_case matching-no-token 'traceable-reqs 0.4.1' 0 '' precheck 0\n*62│run_case matching-install 'traceable-reqs 0.4.1' 0 '' install 0\n 63│run_case missing-no-token missing 0 '' install 1\n*64│run_case failed-version 'traceable-reqs 0.4.1' 7 '' precheck 1\n 65│run_case regex-lookalike 'traceable-reqs 0x4x1' 0 '' precheck 1\n 66│run_case repair-admitted 'traceable-reqs 0.2.0' 0 TOKEN_CANARY precheck 0\n 67│run_case clone-refusal 'traceable-reqs 0.2.0' 0 TOKEN_CANARY install 128\n### traceable-reqs.sh\n 4│set -euo pipefail\n*5│# 0.4.1 fixes file-root enumeration dropping present doc evidence (IR-109).\n*6│WANT=0.4.1\n 7│BIN=\"$HOME/.local/bin/traceable-reqs\"\n 8│mode=\"${1:-precheck}\"\n 9│case \"$mode\" in precheck|install) ;; *) echo 'usage: traceable-reqs.sh [precheck|install]' >&2; exit 2;; esac\n### ws272-w0.py\n 4│--preflight-only makes no build claim and runs no cargo. --self-test exercises\n*5│all three IR-76 decisions without network access. --run requires the explicit\n 6│hold-release acknowledgement and repeats the live meter before each cargo leg.\n 7│Every leg retains its raw output and actual subprocess exit code beside it.\n 8│\n### ws272-w1.py\n  3│\n *4│Same shape as ws272-w0.py: the IR-76 three-arm pre-flight, the lane lock, the env\n  5│scrub, the cold-pool bootstrap. W1 adds spt-net to the nextest population (the\n  6│`web` record family lives there) and runs the new `twohost_web` bin ALONE as its\n  7│own leg, never beside the unit leg (it is env-gated and a silent no-op without\n   │...\n 10│--preflight-only makes no build claim and runs no cargo. --self-test exercises\n*11│all three IR-76 decisions without network access. --run requires the explicit\n 12│hold-release acknowledgement and repeats the live meter before each cargo leg.\n 13│Every leg retains its raw output and actual subprocess exit code beside it.\n 14│\n### ws272-w2.py\n  3│\n *4│Same shape as ws272-w2.py — the IR-76 three-arm pre-flight, the lane lock, the env\n  5│scrub, the cold-pool bootstrap — with ONE deliberate difference: the nextest leg is\n  6│TARGETED, not a workspace sweep (gater ruling 2026-09-07 02:40Z). W2 shares the W1\n  7│pool (176 GB) on a box measuring ~28 GB free against CI's 32 GiB floor, and a full\n   │...\n 17│--preflight-only makes no build claim and runs no cargo. --self-test exercises\n*18│all three IR-76 decisions without network access. --run requires the explicit\n 19│hold-release acknowledgement and repeats the live meter before each cargo leg.\n 20│Every leg retains its raw output and actual subprocess exit code beside it.\n 21│","missingPaths":[".worktrees/hertz-ir86-disk-delta/xtask/src"],"linesTruncated":true,"meta":{"limits":{"columnTruncated":{"maxColumn":512}}}},"isError":false,"timestamp":1789483683943}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_LSsdWOUS92qzkbZeHEmIMANj|fc_000c7cef03cac861016aa95ab3f0f487d186dfb8587f6291d4","toolName":"glob","startedAt":"2026-09-15T14:48:20.444Z","args":{"path":".worktrees/hertz-ir86-disk-delta/**/brainread*;.worktrees/hertz-ir86-disk-delta/**/common*;.worktrees/hertz-ir86-disk-delta/**/pool*.rs"},"intent":"Locating source seams"},"id":"de8ed0e5","parentId":"14cca78f","timestamp":"2026-09-15T14:48:20.444Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_qjddaxyctVVq1q5bXueyVdUm|fc_000c7cef03cac861016aa95ab3f10487d18fdb80e2835f7b83","toolName":"grep","startedAt":"2026-09-15T14:48:20.444Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs;.wo…"},"intent":"Finding current remedy implementations"},"id":"731f20c0","parentId":"de8ed0e5","timestamp":"2026-09-15T14:48:20.445Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Ql1a5zFwhmaAWjY87WJIPBjJ|fc_000c7cef03cac861016aa95ab3f10c87d1821a480a12e9d8e9","toolName":"grep","startedAt":"2026-09-15T14:48:20.447Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/spt/tests/projindex_writer_e2e.rs;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/projindex_reader_e2e.rs;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/br…"},"intent":"Checking adopted guards and recipe"},"id":"93070db2","parentId":"731f20c0","timestamp":"2026-09-15T14:48:20.447Z"}
{"type":"message","id":"f38b6591","parentId":"93070db2","timestamp":"2026-09-15T14:48:20.468Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Locating actual xtask crates**"},{"type":"toolCall","id":"call_LSsdWOUS92qzkbZeHEmIMANj|fc_000c7cef03cac861016aa95ab3f0f487d186dfb8587f6291d4","name":"glob","arguments":{"i":"Locating source seams","path":".worktrees/hertz-ir86-disk-delta/**/brainread*;.worktrees/hertz-ir86-disk-delta/**/common*;.worktrees/hertz-ir86-disk-delta/**/pool*.rs","hidden":true,"gitignore":false,"limit":60},"intent":"Locating source seams"},{"type":"toolCall","id":"call_qjddaxyctVVq1q5bXueyVdUm|fc_000c7cef03cac861016aa95ab3f10487d18fdb80e2835f7b83","name":"grep","arguments":{"i":"Finding current remedy implementations","pattern":"resolve_daemon_docs_port|daemon_pid_path|try_spt_hosted_inject|IO_KIND_MSG_IN|disk|free_space|available_space","path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/twohost.rs","case":false,"gitignore":false,"skip":null},"intent":"Finding current remedy implementations"},{"type":"toolCall","id":"call_Ql1a5zFwhmaAWjY87WJIPBjJ|fc_000c7cef03cac861016aa95ab3f10c87d1821a480a12e9d8e9","name":"grep","arguments":{"i":"Checking adopted guards and recipe","pattern":"DaemonReaper|impl Drop|pool-release|release.before|prebuilt|outside.*repo|git toplevel|quiet.window|IR-76|IR-106","path":".worktrees/hertz-ir86-disk-delta/crates/spt/tests/projindex_writer_e2e.rs;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/projindex_reader_e2e.rs;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/brain_split.rs;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/brain_respawn_rename.rs;.worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md;.worktrees/hertz-ir86-disk-delta/AGENTS.md","case":false,"gitignore":false,"skip":null},"intent":"Checking adopted guards and recipe"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":12700,"output":481,"cacheRead":101632,"cacheWrite":0,"totalTokens":114813,"reasoningTokens":11,"cost":{"input":0.127,"output":0.024050000000000002,"cacheRead":0.101632,"cacheWrite":0,"total":0.252682}},"stopReason":"toolUse","timestamp":1789483683982,"responseId":"resp_000c7cef03cac861016aa95aa44ef087d1890e7bea2457026b","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_000c7cef03cac861016aa95aa5872c87d19040dc7171f9fe67","type":"reasoning","content":[],"encrypted_content":"gAAAAABqqVqz-Yp38ne-2koX4-0t5h1mQnx4zzy7doymsmt4FQVgo8FkpLL69FdRT1ctqCJZ1_Mn9OdetTw2lLHuhWSnBqYa8z1RNBqJlgFJ-M556I227EEDtZ0OpTemex-vNRlNXgQv52HcXgMtSljxU64xOK4YcRRSdaSeZfbYdV-3w4lIWuyVkJAxBsNuBd-EqAtXzp2chjCEDhoqMmVSTF630OVM1u_xuhXBc-vWoM4aftm0EEYhbIIW746a4Wf2cW9Dwz1pj9TNHhyiW6u8xjcBE3w7or2Y7ndHSLnxGK9EyaPe1JUxm7TNwtYdfs_ScPqRO5Qobt4MmuVJ5h1Y8I45GkVpFOkiDdJwwHrxvFES9V5E7tjxcATEKdgQeijHMI-Tljl9ruFGCKXvogcJBaZBaRIdg1MwT7FtveV2pijj-loebOoTJyPrUI9U4be0NfuPV3-PXSXRmfEvkfQ5vlJPaqd3Wd1PGslbByIORaNXqwao1tvT9Z57tkYan_YB3M9Y2kWZvPdaz8iLVKW3mDb7E6oLSHN31T7-WxP0QY9837oVucND3FFil7IXeZtXDbaH3H8-vAZh04VJhRZlBtKkTpEBVjT_WNXWyGxVyY9oQqkFibneaYGuQgjMUQD9SyyoHPmmVZoXUQN435ThnLaivHtrcrFn3PBk6wctJmPneskbY9LrcdtFl-7hAzYou8wBPwp60qfiU2J5dj0KaaGuLD-OJ7O6pEzkRDCi6zztyQw9igJliWeiUFVG2ALjeLOFMsjEvhuciiTEIVBvonbzy-qFOuZMtqWJg-JxJSsoFKaPvyXqDFK9QeDqoMLR1_w1T8lUueK-Lm9oFnyKdl-C7XJV0fco61toD-sEz3xVso4ofw_CwQp1q57gUd0xvOua0a6mwZJzI_JDvl8gOt8HfGvkkeTDkXoW-Vu4eehEX-p0eUK8Gk8CXPWUddGj_sASeGDTcrUV8QGjWXLFWzONKimy-ybnC8GppMdf6U2qiHF5puqDiUSoOU8D89Go70A4pIxDi7KTWTZrKdd6NGpXqwtPSH9evFfSTeZg6TG-V3uTEnx6yWamnDLGYJAiZJ0f35drVqRNS-HJfvDP77e9_Dbc4dY2fdErKiP_YbdM1AhvKZmX-DlUljlwgyBfObFAPJRz0GHHG3H2bZWKbwS5MwTwkJbPq8MAfsnP14-D1r0f-UoXZ2Sl7vzV1N2DAuzrmPk9ahZ3uWJuaBtJ1nMMA__UfmHevVXVOWx6o2Ngi95K6Zmum59XUv2JpZtIMw8rsNRKQd3QD9GTuuGiyFJkCLJYH0Dfo3qZZG8MSG61-oBzSbHAUwiXKQu9732HE-O2N2zz","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"summary":[{"type":"summary_text","text":"**Locating actual xtask crates**"}],"metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ab3f0f487d186dfb8587f6291d4","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating source seams\",\"path\":\".worktrees/hertz-ir86-disk-delta/**/brainread*;.worktrees/hertz-ir86-disk-delta/**/common*;.worktrees/hertz-ir86-disk-delta/**/pool*.rs\",\"hidden\":true,\"gitignore\":false,\"limit\":60}","call_id":"call_LSsdWOUS92qzkbZeHEmIMANj","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"glob","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ab3f10487d18fdb80e2835f7b83","type":"function_call","status":"completed","arguments":"{\"i\":\"Finding current remedy implementations\",\"pattern\":\"resolve_daemon_docs_port|daemon_pid_path|try_spt_hosted_inject|IO_KIND_MSG_IN|disk|free_space|available_space\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/twohost.rs\",\"case\":false,\"gitignore\":false,\"skip\":null}","call_id":"call_qjddaxyctVVq1q5bXueyVdUm","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"grep","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ab3f10c87d1821a480a12e9d8e9","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking adopted guards and recipe\",\"pattern\":\"DaemonReaper|impl Drop|pool-release|release.before|prebuilt|outside.*repo|git toplevel|quiet.window|IR-76|IR-106\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt/tests/projindex_writer_e2e.rs;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/projindex_reader_e2e.rs;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/brain_split.rs;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/brain_respawn_rename.rs;.worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md;.worktrees/hertz-ir86-disk-delta/AGENTS.md\",\"case\":false,\"gitignore\":false,\"skip\":null}","call_id":"call_Ql1a5zFwhmaAWjY87WJIPBjJ","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"grep","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}}]},"duration":16436.875100016594,"ttft":1571.6533000171185,"completedAt":1789483700440,"contextSnapshot":{"promptTokens":114332,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"message","id":"b23bed1a","parentId":"f38b6591","timestamp":"2026-09-15T14:48:20.498Z","message":{"role":"toolResult","toolCallId":"call_LSsdWOUS92qzkbZeHEmIMANj|fc_000c7cef03cac861016aa95ab3f0f487d186dfb8587f6291d4","toolName":"glob","content":[{"type":"text","text":"# .worktrees/hertz-ir86-disk-delta/crates/\n## xtask/\n### src/\nbrainread.rs\n### tests/\npool_claim.rs\n## spt/tests/common/\n## spt-store/tests/\npool_guard_canary.rs"}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/**/brainread*, .worktrees/hertz-ir86-disk-delta/**/common*, .worktrees/hertz-ir86-disk-delta/**/pool*.rs","fileCount":4,"files":[".worktrees/hertz-ir86-disk-delta/crates/xtask/src/brainread.rs",".worktrees/hertz-ir86-disk-delta/crates/spt/tests/common/",".worktrees/hertz-ir86-disk-delta/crates/spt-store/tests/pool_guard_canary.rs",".worktrees/hertz-ir86-disk-delta/crates/xtask/tests/pool_claim.rs"],"truncated":false,"cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core"},"isError":false,"timestamp":1789483700497}}
{"type":"message","id":"0f8bad5b","parentId":"b23bed1a","timestamp":"2026-09-15T14:48:20.520Z","message":{"role":"toolResult","toolCallId":"call_qjddaxyctVVq1q5bXueyVdUm|fc_000c7cef03cac861016aa95ab3f10487d18fdb80e2835f7b83","toolName":"grep","content":[{"type":"text","text":"# .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/\n\n## src/\n### docshost.rs\n 113|// [impl->REQ-TEST-DAEMON-EPHEMERAL-ADVISORY-PORTS]\n*114|pub fn resolve_daemon_docs_port(\n 115|    config_port: Option<u16>,\n 116|    env_value: Option<&str>,\n 117|    ephemeral_advisory_ports: bool,\n...\n 620|        let selected =\n*621|            resolve_daemon_docs_port(Some(occupied_port), Some(\"not-a-port\"), true);\n 622|        assert_eq!(selected, 0, \"rig posture wins over every fixed-port layer\");\n 623|\n 624|        let docs = tempfile::tempdir().expect(\"temp docs root\");\n### daemon.rs\n 29|use crate::endpoint::{\n*30|    broker_socket_name, daemon_pid_path, digest_socket_name, drive_socket_name, seed_socket_name,\n 31|};\n 32|use crate::nethost::{NetConfig, NetHost};\n 33|use crate::seedmap::{self, SeedRegistry};\n...\n 247|                    // the controller slot, the viewer map, and the viewer origin\n*248|                    // nodes retained on `ViewerSink`. A disk reconciler could not\n 249|                    // compose its frame, and snapshotting attachment identity to\n*250|                    // disk for one to read was refused. Background + best-effort:\n 251|                    // a spawn failure logs loud and the daemon runs on, exactly\n 252|                    // like the docs server below — shells simply do not learn who\n 253|                    // is watching, which degrades a signal rather than a surface.\n...\n 282|                        crate::lanhost::capture_canonical_exe();\n*283|                        let port = crate::docshost::resolve_daemon_docs_port(\n 284|                            crate::config::DaemonConfig::load().docs_port,\n 285|                            std::env::var(crate::docshost::DOCS_PORT_ENV).ok().as_deref(),\n 286|                            std::env::var_os(\n...\n 396|        // resource, which is the ADR-0018 Q2/Q5 broker-side test. The shellwake\n*397|        // Q5 exception reads \"a pure disk-reconciler\" and this is not one. Hosting\n 398|        // it in the restartable brain would also make every routine brain restart\n 399|        // — `StartReason::Update` is exactly that — bounce every resident service\n 400|        // through the orphan path with no quiesce, no grace and no hold, which is\n...\n 432|        // D2-2): shellwake is brain-owned logic (ADR-0018 Q5 exception), a pure\n*433|        // disk-reconciler whose boot sweep re-reconciles the watcher children on\n 434|        // every brain start. The broker no longer hosts it; see\n 435|        // [`crate::brainproc::run_brain`].\n 436|        // [impl->REQ-HAZARD-BROKER-PROCESS-ISOLATION]\n...\n 475|        // is the socket ping, never this file, so a stale value is harmless.\n*476|        let _ = std::fs::write(daemon_pid_path(), std::process::id().to_string());\n 477|\n 478|        // The seed-control channel is the foreground loop. Binding it is what\n 479|        // arbitrates the single-daemon-per-home invariant: a second daemon racing\n...\n 2049|/// The Win32 `GetFileType` result for a PIPE handle — the ONLY std-handle sink that\n*2050|/// BLOCKS when it fills. (DISK=1, CHAR=2, PIPE=3, UNKNOWN=0.)\n 2051|pub const FILE_TYPE_PIPE: u32 = 0x0003;\n 2052|\n 2053|/// Decide whether `daemon run` must NULL its std handles as a detached-in-fact\n...\n 2056|/// daemon once full. Every OTHER sink is safe and MUST survive: a FILE (`2>run.log`,\n*2057|/// AND every int test's `Stdio::from(file)` brain-log capture) is a disk handle that\n 2058|/// never blocks; a CONSOLE scrolls; a NULL/absent handle (the DETACHED_PROCESS rungs)\n 2059|/// already discards. So we DELIBERATELY do NOT gate on \"no console\" (`GetConsoleWindow`):\n 2060|/// a CREATE_NO_WINDOW daemon has no console window yet a perfectly-drained FILE stderr\n...\n 2078|/// pipe-tee ergonomics. The SANCTIONED foreground-capture form is a FILE redirect\n*2079|/// (`spt daemon run 2>run.log`): a disk handle is not a pipe, so it survives (this is\n 2080|/// exactly why the int-test brain-log capture is safe). Called unconditionally at\n 2081|/// `daemon run` startup. // [impl->REQ-HAZARD-DETACHED-DAEMON-STDIO]\n 2082|#[cfg(windows)]\n...\n 3084|        const FILE_TYPE_UNKNOWN: u32 = 0x0000;\n*3085|        const FILE_TYPE_DISK: u32 = 0x0001;\n 3086|        const FILE_TYPE_CHAR: u32 = 0x0002;\n 3087|        assert!(should_null_std_handles(FILE_TYPE_PIPE), \"an undrained pipe blocks ⇒ null\");\n 3088|        assert!(\n*3089|            !should_null_std_handles(FILE_TYPE_DISK),\n*3090|            \"a FILE redirect (2>run.log / the int-test brain-log) is disk ⇒ survives\"\n 3091|        );\n 3092|        assert!(\n 3093|            !should_null_std_handles(FILE_TYPE_CHAR),\n### inject.rs\n 74|// [impl->REQ-SEND-SPT-HOSTED]\n*75|pub fn try_spt_hosted_inject(\n 76|    target: &str,\n 77|    from: &str,\n 78|    body: &str,\n...\n 100|            .and_then(|parsed| parsed.attr(spt_proto::event::EVENT_ATTR_MSG_ID).map(str::to_owned));\n*101|        let event = crate::iobus::IoEvent::new(target, spt_proto::ioevent::IO_KIND_MSG_IN, body)\n 102|            .with_peer(from)\n 103|            .with_msg_id(msg_id);\n 104|        for published in crate::iobus::default_bus(owlery, now_ms()).publish(&event) {\n...\n 117|/// an operator poke. Identical mechanic to the F-023 idle-EDGE drain: CLAIM the pending\n*118|/// rows (audited, idle-inject leg), offer each through [`try_spt_hosted_inject`]\n 119|/// (`native=false` — the genuine idle window), and on the first miss (no live\n 120|/// translation binary, or the broker still views the endpoint ACTIVE) RELEASE the row\n 121|/// plus all not-yet-attempted back to the spool intact (v0.14.3 LAW: spooled loud, never\n...\n 185|    for (msg_id, from, body) in rest.by_ref() {\n*186|        match try_spt_hosted_inject(id, &from, &body, owlery, native) {\n 187|            Some((true, _)) => delivered += 1,\n 188|            _ => {\n 189|                release_ids.push(msg_id);\n...\n 250|\n*251|    /// Establish an on-disk perch that reads ONLINE + broker-PTY-controllable: the\n 252|    /// class the inject leg targets.\n 253|    fn establish_hosted(id: &str) -> std::path::PathBuf {\n 254|        let perch_path = perch::resolve_perch_path(id, ParentHint::Infer);\n\n## tests/\n### twohost.rs\n 180|// process-global SPT_HOME, so B projects from a store A can already see. Here the\n*181|// logs, the idle sentinel and the projection are on the OTHER HOST's disk.\n 182|//\n 183|// Its OWN endpoint on purpose: writing a `.idle` sentinel onto ID_B would change\n 184|// delivery routing under the message/presence rungs, and a digest.log would ride\n...\n 284|/// A→B store-state signal (the rung-7 replicated-notif pattern): A has sent AND\n*285|/// has read its own correlation row back off disk. B may now answer. Without the\n 286|/// barrier B would race the write whose effect the rung exists to measure, and a\n 287|/// refused answer would read as the defect rather than as the race.\n 288|const SIG_REPLY_RECORDED: &str = \"twohost-reply-outbound-recorded-at-a\";\n...\n 2997|\n*2998|        // The barrier is the fact this rung rests on, read back off disk rather\n 2999|        // than inferred from the send having returned: `request_wan` writing the\n 3000|        // row IS the change under test, so assuming it here would make the\n 3001|        // cross-node arm the only thing that could fail and give a missing write\n...\n 3059|    // digest; B's logs, B's idle sentinel and B's projection are all on the other\n*3060|    // machine's disk — the part the hermetic single-box rig cannot prove, since\n 3061|    // there both \"nodes\" share one process-global SPT_HOME.\n 3062|    //\n 3063|    // The composition this pins (ADR-0048's own note): seal-on-idle's stable seqs\n...\n 3138|            Some(DIGEST_INPUT),\n*3139|            \"the turn text is the one B wrote on ITS disk\"\n 3140|        );\n 3141|\n 3142|        // The SEAL crossed intact: B reported idle, so the trailing turn arrives"}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs, .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs, .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs, .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs, .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/twohost.rs","searchPath":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\crates\\spt-daemon","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core","matchCount":25,"fileCount":4,"files":[".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs",".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs",".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs",".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/twohost.rs"],"fileMatches":[{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs","count":2},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs","count":13},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs","count":5},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/twohost.rs","count":5}],"truncated":false,"displayContent":"# .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/\n\n## src/\n### docshost.rs\n 113│// [impl->REQ-TEST-DAEMON-EPHEMERAL-ADVISORY-PORTS]\n*114│pub fn resolve_daemon_docs_port(\n 115│    config_port: Option<u16>,\n 116│    env_value: Option<&str>,\n 117│    ephemeral_advisory_ports: bool,\n    │...\n 620│        let selected =\n*621│            resolve_daemon_docs_port(Some(occupied_port), Some(\"not-a-port\"), true);\n 622│        assert_eq!(selected, 0, \"rig posture wins over every fixed-port layer\");\n 623│\n 624│        let docs = tempfile::tempdir().expect(\"temp docs root\");\n### daemon.rs\n   29│use crate::endpoint::{\n  *30│    broker_socket_name, daemon_pid_path, digest_socket_name, drive_socket_name, seed_socket_name,\n   31│};\n   32│use crate::nethost::{NetConfig, NetHost};\n   33│use crate::seedmap::{self, SeedRegistry};\n     │...\n  247│                    // the controller slot, the viewer map, and the viewer origin\n *248│                    // nodes retained on `ViewerSink`. A disk reconciler could not\n  249│                    // compose its frame, and snapshotting attachment identity to\n *250│                    // disk for one to read was refused. Background + best-effort:\n  251│                    // a spawn failure logs loud and the daemon runs on, exactly\n  252│                    // like the docs server below — shells simply do not learn who\n  253│                    // is watching, which degrades a signal rather than a surface.\n     │...\n  282│                        crate::lanhost::capture_canonical_exe();\n *283│                        let port = crate::docshost::resolve_daemon_docs_port(\n  284│                            crate::config::DaemonConfig::load().docs_port,\n  285│                            std::env::var(crate::docshost::DOCS_PORT_ENV).ok().as_deref(),\n  286│                            std::env::var_os(\n     │...\n  396│        // resource, which is the ADR-0018 Q2/Q5 broker-side test. The shellwake\n *397│        // Q5 exception reads \"a pure disk-reconciler\" and this is not one. Hosting\n  398│        // it in the restartable brain would also make every routine brain restart\n  399│        // — `StartReason::Update` is exactly that — bounce every resident service\n  400│        // through the orphan path with no quiesce, no grace and no hold, which is\n     │...\n  432│        // D2-2): shellwake is brain-owned logic (ADR-0018 Q5 exception), a pure\n *433│        // disk-reconciler whose boot sweep re-reconciles the watcher children on\n  434│        // every brain start. The broker no longer hosts it; see\n  435│        // [`crate::brainproc::run_brain`].\n  436│        // [impl->REQ-HAZARD-BROKER-PROCESS-ISOLATION]\n     │...\n  475│        // is the socket ping, never this file, so a stale value is harmless.\n *476│        let _ = std::fs::write(daemon_pid_path(), std::process::id().to_string());\n  477│\n  478│        // The seed-control channel is the foreground loop. Binding it is what\n  479│        // arbitrates the single-daemon-per-home invariant: a second daemon racing\n     │...\n 2049│/// The Win32 `GetFileType` result for a PIPE handle — the ONLY std-handle sink that\n*2050│/// BLOCKS when it fills. (DISK=1, CHAR=2, PIPE=3, UNKNOWN=0.)\n 2051│pub const FILE_TYPE_PIPE: u32 = 0x0003;\n 2052│\n 2053│/// Decide whether `daemon run` must NULL its std handles as a detached-in-fact\n     │...\n 2056│/// daemon once full. Every OTHER sink is safe and MUST survive: a FILE (`2>run.log`,\n*2057│/// AND every int test's `Stdio::from(file)` brain-log capture) is a disk handle that\n 2058│/// never blocks; a CONSOLE scrolls; a NULL/absent handle (the DETACHED_PROCESS rungs)\n 2059│/// already discards. So we DELIBERATELY do NOT gate on \"no console\" (`GetConsoleWindow`):\n 2060│/// a CREATE_NO_WINDOW daemon has no console window yet a perfectly-drained FILE stderr\n     │...\n 2078│/// pipe-tee ergonomics. The SANCTIONED foreground-capture form is a FILE redirect\n*2079│/// (`spt daemon run 2>run.log`): a disk handle is not a pipe, so it survives (this is\n 2080│/// exactly why the int-test brain-log capture is safe). Called unconditionally at\n 2081│/// `daemon run` startup. // [impl->REQ-HAZARD-DETACHED-DAEMON-STDIO]\n 2082│#[cfg(windows)]\n     │...\n 3084│        const FILE_TYPE_UNKNOWN: u32 = 0x0000;\n*3085│        const FILE_TYPE_DISK: u32 = 0x0001;\n 3086│        const FILE_TYPE_CHAR: u32 = 0x0002;\n 3087│        assert!(should_null_std_handles(FILE_TYPE_PIPE), \"an undrained pipe blocks ⇒ null\");\n 3088│        assert!(\n*3089│            !should_null_std_handles(FILE_TYPE_DISK),\n*3090│            \"a FILE redirect (2>run.log / the int-test brain-log) is disk ⇒ survives\"\n 3091│        );\n 3092│        assert!(\n 3093│            !should_null_std_handles(FILE_TYPE_CHAR),\n### inject.rs\n  74│// [impl->REQ-SEND-SPT-HOSTED]\n *75│pub fn try_spt_hosted_inject(\n  76│    target: &str,\n  77│    from: &str,\n  78│    body: &str,\n    │...\n 100│            .and_then(|parsed| parsed.attr(spt_proto::event::EVENT_ATTR_MSG_ID).map(str::to_owned));\n*101│        let event = crate::iobus::IoEvent::new(target, spt_proto::ioevent::IO_KIND_MSG_IN, body)\n 102│            .with_peer(from)\n 103│            .with_msg_id(msg_id);\n 104│        for published in crate::iobus::default_bus(owlery, now_ms()).publish(&event) {\n    │...\n 117│/// an operator poke. Identical mechanic to the F-023 idle-EDGE drain: CLAIM the pending\n*118│/// rows (audited, idle-inject leg), offer each through [`try_spt_hosted_inject`]\n 119│/// (`native=false` — the genuine idle window), and on the first miss (no live\n 120│/// translation binary, or the broker still views the endpoint ACTIVE) RELEASE the row\n 121│/// plus all not-yet-attempted back to the spool intact (v0.14.3 LAW: spooled loud, never\n    │...\n 185│    for (msg_id, from, body) in rest.by_ref() {\n*186│        match try_spt_hosted_inject(id, &from, &body, owlery, native) {\n 187│            Some((true, _)) => delivered += 1,\n 188│            _ => {\n 189│                release_ids.push(msg_id);\n    │...\n 250│\n*251│    /// Establish an on-disk perch that reads ONLINE + broker-PTY-controllable: the\n 252│    /// class the inject leg targets.\n 253│    fn establish_hosted(id: &str) -> std::path::PathBuf {\n 254│        let perch_path = perch::resolve_perch_path(id, ParentHint::Infer);\n\n## tests/\n### twohost.rs\n  180│// process-global SPT_HOME, so B projects from a store A can already see. Here the\n *181│// logs, the idle sentinel and the projection are on the OTHER HOST's disk.\n  182│//\n  183│// Its OWN endpoint on purpose: writing a `.idle` sentinel onto ID_B would change\n  184│// delivery routing under the message/presence rungs, and a digest.log would ride\n     │...\n  284│/// A→B store-state signal (the rung-7 replicated-notif pattern): A has sent AND\n *285│/// has read its own correlation row back off disk. B may now answer. Without the\n  286│/// barrier B would race the write whose effect the rung exists to measure, and a\n  287│/// refused answer would read as the defect rather than as the race.\n  288│const SIG_REPLY_RECORDED: &str = \"twohost-reply-outbound-recorded-at-a\";\n     │...\n 2997│\n*2998│        // The barrier is the fact this rung rests on, read back off disk rather\n 2999│        // than inferred from the send having returned: `request_wan` writing the\n 3000│        // row IS the change under test, so assuming it here would make the\n 3001│        // cross-node arm the only thing that could fail and give a missing write\n     │...\n 3059│    // digest; B's logs, B's idle sentinel and B's projection are all on the other\n*3060│    // machine's disk — the part the hermetic single-box rig cannot prove, since\n 3061│    // there both \"nodes\" share one process-global SPT_HOME.\n 3062│    //\n 3063│    // The composition this pins (ADR-0048's own note): seal-on-idle's stable seqs\n     │...\n 3138│            Some(DIGEST_INPUT),\n*3139│            \"the turn text is the one B wrote on ITS disk\"\n 3140│        );\n 3141│\n 3142│        // The SEAL crossed intact: B reported idle, so the trailing turn arrives"},"isError":false,"timestamp":1789483700519}}
{"type":"message","id":"a7d11eaf","parentId":"0f8bad5b","timestamp":"2026-09-15T14:48:20.546Z","message":{"role":"toolResult","toolCallId":"call_Ql1a5zFwhmaAWjY87WJIPBjJ|fc_000c7cef03cac861016aa95ab3f10c87d1821a480a12e9d8e9","toolName":"grep","content":[{"type":"text","text":"# .worktrees/hertz-ir86-disk-delta/\n## AGENTS.md\n 39|<!-- [doc->REQ-POOL-FOREIGN-TREE-REFUSED] -->\n*40|- **Build-cache pools (binding, releases#103):** a cargo `target/` directory belongs to ONE source tree. Two trees building into one pool overwrite each other's artifacts and fabricate reds that belong to neither — the v0.51.0 W1/H1 `E0308` that vanished on re-run. **The rule is about the RELATIONSHIP, not the path:** a junction and a `CARGO_TARGET_DIR` env var reach the same hazard, and the env var leaves no directory entry to notice afterwards, so \"is this dir under `.worktrees/`\" never was the quest...\n 41|- **Target-tree teardown (releases#103, same lane):** never delete a `target/` you have not classified. Check OUTBOUND first (`Get-Item -Force`: a junction is deleted as a link, a real dir as a tree), then sweep INBOUND for reparse points aimed at it before removing a real one, and measure size and free space before and after so the reclaim is a number rather than a claim. Reap the target SUBTREE, never a session or worktree directory around it. Do not point `CARGO_TARGET_DIR` into a scratchpad (v0.50.0 ...\n 42|- **CI / merge strategy:** golden CI (ADR-0050, ruled 2026-07-27) — milestone-batch golden runs, thin-lane PRs, ff-only main (tested sha == merged sha). Piloting from the next milestone; read the ADR before shaping a PR lane.\n 43|\n\n## docs/\n### GOLDEN-CI.md\n 25|\n*26|## Shared-runner quiet-window predicate\n 27|\n 28|<!-- [doc->REQ-GOLDEN-CI-LANE] -->\n 29|\n\n[Some lines truncated to 512 chars]"}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/crates/spt/tests/projindex_writer_e2e.rs, .worktrees/hertz-ir86-disk-delta/crates/spt/tests/projindex_reader_e2e.rs, .worktrees/hertz-ir86-disk-delta/crates/spt/tests/brain_split.rs, .worktrees/hertz-ir86-disk-delta/crates/spt/tests/brain_respawn_rename.rs, .worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md, .worktrees/hertz-ir86-disk-delta/AGENTS.md","searchPath":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core","matchCount":2,"fileCount":2,"files":[".worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md",".worktrees/hertz-ir86-disk-delta/AGENTS.md"],"fileMatches":[{"path":".worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md","count":1},{"path":".worktrees/hertz-ir86-disk-delta/AGENTS.md","count":1}],"truncated":true,"displayContent":"# .worktrees/hertz-ir86-disk-delta/\n## AGENTS.md\n 39│<!-- [doc->REQ-POOL-FOREIGN-TREE-REFUSED] -->\n*40│- **Build-cache pools (binding, releases#103):** a cargo `target/` directory belongs to ONE source tree. Two trees building into one pool overwrite each other's artifacts and fabricate reds that belong to neither — the v0.51.0 W1/H1 `E0308` that vanished on re-run. **The rule is about the RELATIONSHIP, not the path:** a junction and a `CARGO_TARGET_DIR` env var reach the same hazard, and the env var leaves no directory entry to notice afterwards, so \"is this dir under `.worktrees/`\" never was the quest...\n 41│- **Target-tree teardown (releases#103, same lane):** never delete a `target/` you have not classified. Check OUTBOUND first (`Get-Item -Force`: a junction is deleted as a link, a real dir as a tree), then sweep INBOUND for reparse points aimed at it before removing a real one, and measure size and free space before and after so the reclaim is a number rather than a claim. Reap the target SUBTREE, never a session or worktree directory around it. Do not point `CARGO_TARGET_DIR` into a scratchpad (v0.50.0 ...\n 42│- **CI / merge strategy:** golden CI (ADR-0050, ruled 2026-07-27) — milestone-batch golden runs, thin-lane PRs, ff-only main (tested sha == merged sha). Piloting from the next milestone; read the ADR before shaping a PR lane.\n 43│\n\n## docs/\n### GOLDEN-CI.md\n 25│\n*26│## Shared-runner quiet-window predicate\n 27│\n 28│<!-- [doc->REQ-GOLDEN-CI-LANE] -->\n 29│","linesTruncated":true,"meta":{"limits":{"columnTruncated":{"maxColumn":512}}}},"isError":false,"timestamp":1789483700545}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_wxE2LgQMqRc85Bpwo9CjKNxK|fc_000c7cef03cac861016aa95ab8be8c87d1bba64c77f539d59d","toolName":"hub","startedAt":"2026-09-15T14:48:26.070Z","intent":"Flagging already shipped inject remedy"},"id":"2fbecc9b","parentId":"a7d11eaf","timestamp":"2026-09-15T14:48:26.070Z"}
{"type":"message","id":"e3747261","parentId":"2fbecc9b","timestamp":"2026-09-15T14:48:26.071Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Recovering truncated entries**"},{"type":"toolCall","id":"call_wxE2LgQMqRc85Bpwo9CjKNxK|fc_000c7cef03cac861016aa95ab8be8c87d1bba64c77f539d59d","name":"hub","arguments":{"i":"Flagging already shipped inject remedy","op":"send","to":"Main","message":"IR92 register stale: fixed-tree crates/spt-daemon/src/inject.rs:95-109 already publishes MSG_IN at successful try_spt_hosted_inject chokepoint. Do not redispatch. IR109 accept key still live (traceable-reqs.toml:25); IR90 remains absent in inspected sync/twohost source. Full 67-ID disposition follows."},"intent":"Flagging already shipped inject remedy"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":3340,"output":144,"cacheRead":114176,"cacheWrite":0,"totalTokens":117660,"reasoningTokens":30,"cost":{"input":0.033400000000000006,"output":0.007200000000000001,"cacheRead":0.114176,"cacheWrite":0,"total":0.154776}},"stopReason":"toolUse","timestamp":1789483700581,"responseId":"resp_000c7cef03cac861016aa95ab4c5a887d1bc23c07752d2d35e","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_000c7cef03cac861016aa95ab5b04087d1a10a5c72a323d406","type":"reasoning","content":[],"encrypted_content":"gAAAAABqqVq4j0UbEzqfTR_s0_tH5S_5KLv_obIR0xLnDWA6ais3VcnJrfgGt8vKjY0fMDxrc78sB8QhX1VYJuhzLZqDSXlTFkgj0m-zseUm2weulMjTfpQ9hLciRqqmvzG_Wnyn4ER9CaRKHe9GGN0mADtlkdxkAlMpU73QG13SG_WkTWtKXgJpMFG0mD7wGxxnE7ZIfi84bo4Mhxg5H6d_e11Bw65D9nFa4imdVHUVn45ErI_cQUUz1gGt4mOErNJaadURyizV3jzN1dvRAHMYn9QAewuBwFbiqotFQWR-VTMKeQcnrpOsgrubCT9z-9UIVzAufGjtUXNaTVZ1mWxfh4MCU7oPu_aDvPxof28zVXoEy2ZBq20P36ih68v_xvpFq-u6C-pwVgm4I3ZWvmvO6Mj9F0jJ5_-r8FB5d5idvkycSTBEllswdxT6__-DynTTexO-WNB3_OGj4uautEIL5Pra8CVEganc8fwahw9jVg18bEZBNOz0XI4dqdDqOgCgw41KOUY2LKN7F3N-vfblADADMu0SRSGc3YHjEaIViA8GJrbNOdHpvzVnvaavh0cUym9ayrZgKi5m28WiJKKUMgzf5WplxkEZiBH1A4GlNXsKPkAGFkRIA9gXfGTPFwd4BBxUksPdUOWqLIPVuKBujCPZatkgUu2xXtaMvrQIDgi_FzS9W70Snn5q_PvCuAhpBN_cAL4FVX9KG8T0OE2N-tjfMINuhTLKslTk4RIx4vM3mVGnoMfldif0306Gttzm0bQBWWkYjD56cn0kdeuGT79F3OzSp21NJ41bWxSbhq1Umz7ClVx0UaT3X03HZpt9qApb5cjZ-MgwBsXMRuB63XoiHXuC_WY3Bd_vrVfCtIvvvOUS7GZsj8lhwuH1UEbx7xGXFLBnnC4f7Y2tzs648hiAZUIInszjH6yl4g6Q9R_Ef8DIrIoEo_ZXs3e364SjBxlGBOQ7GcRc-olE-9SjMUcQPV6D1KqeomQHr3bGjbuYuFC48Xb-ELjifQgOSSe3cca5-7_D7gRovX83oO6MGhICWWVu3yGg5qccWzJfEuatpVYgKMQ-9M-iCrpjZUqN8Tpw0Um8yEW3ZarRIuWiId6KE5cEMqzAqwOsS0Z4Ro09zB5hidQ3u6-PZjwWZuLF6324ESnQkEMqShRHcvbIPucZYxSEUufobdcxLFL-1QeJUFOMDOkDZRA3yBmeXA_IxRqx4Z8X-oztdqhBrcJ8K5BqnO6BdN5804FS2z7_8OkRXBe_hGFJuC1lwMVXZ0r4IppPwkzhUBqrrlEOFSUb795yaRQ3M5HXPG09kCjSpEcli05SdbsOlzySzMPp8iA19Iq5GCEfeFr101zNGSAqjDhWpZ9FqZKx4vtGRnVoA5t0E4eyj__faErPWtFQvdasqCTmCrD5FL3MA-YTLSH8S6G9nWXERX6Dhf3lcjurf1amWbZ9aZ8=","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"summary":[{"type":"summary_text","text":"**Recovering truncated entries**"}],"metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ab8be8c87d1bba64c77f539d59d","type":"function_call","status":"completed","arguments":"{\"i\":\"Flagging already shipped inject remedy\",\"op\":\"send\",\"to\":\"Main\",\"message\":\"IR92 register stale: fixed-tree crates/spt-daemon/src/inject.rs:95-109 already publishes MSG_IN at successful try_spt_hosted_inject chokepoint. Do not redispatch. IR109 accept key still live (traceable-reqs.toml:25); IR90 remains absent in inspected sync/twohost source. Full 67-ID disposition follows.\"}","call_id":"call_wxE2LgQMqRc85Bpwo9CjKNxK","internal_chat_message_metadata_passthrough":{"create_time":1789483700.935775,"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"hub","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}}]},"duration":5488.231799989939,"ttft":2234.0937999784946,"completedAt":1789483706070,"contextSnapshot":{"promptTokens":117516,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"message","id":"05a4e0aa","parentId":"e3747261","timestamp":"2026-09-15T14:48:26.073Z","message":{"role":"toolResult","toolCallId":"call_wxE2LgQMqRc85Bpwo9CjKNxK|fc_000c7cef03cac861016aa95ab8be8c87d1bba64c77f539d59d","toolName":"hub","content":[{"type":"text","text":"Delivered to 1 peer(s):\n- Main: injected"}],"details":{"op":"send","from":"RegisterLater","to":"Main","receipts":[{"to":"Main","outcome":"injected"}]},"isError":false,"timestamp":1789483706072}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_1Ox1qSbJQ9WWw9iZRexzhaOz|fc_000c7cef03cac861016aa95ac70d1887d185c3abb948d98674","toolName":"read","startedAt":"2026-09-15T14:48:39.137Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs:104-135"},"intent":"Reading candidate implementation boundaries"},"id":"51acab71","parentId":"05a4e0aa","timestamp":"2026-09-15T14:48:39.137Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_i0CaS7AiD7lyaEwc1XYUxGT1|fc_000c7cef03cac861016aa95ac70d3087d18b184d3f5ffd1e1c","toolName":"read","startedAt":"2026-09-15T14:48:39.137Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs:75-112"},"intent":"Reading inject publication boundary"},"id":"036b2863","parentId":"51acab71","timestamp":"2026-09-15T14:48:39.137Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_aIK7qRHtqSCJn7EBShPXraxe|fc_000c7cef03cac861016aa95ac70d3887d1a82878cf1c1893e1","toolName":"read","startedAt":"2026-09-15T14:48:39.137Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/brainread.rs:1-185"},"intent":"Reading brainread gate population"},"id":"1e3a0429","parentId":"036b2863","timestamp":"2026-09-15T14:48:39.137Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_UCvDs7ofV3cynhAzSxs7ofql|fc_000c7cef03cac861016aa95ac70d4087d1b7d0404c61cea686","toolName":"grep","startedAt":"2026-09-15T14:48:39.138Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/common;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests;.worktrees/hertz-ir86-disk-delta/cra…"},"intent":"Checking residual gates and fixtures"},"id":"c26da3b4","parentId":"1e3a0429","timestamp":"2026-09-15T14:48:39.138Z"}
{"type":"message","id":"d8729f9f","parentId":"c26da3b4","timestamp":"2026-09-15T14:48:39.138Z","message":{"role":"assistant","content":[{"type":"toolCall","id":"call_1Ox1qSbJQ9WWw9iZRexzhaOz|fc_000c7cef03cac861016aa95ac70d1887d185c3abb948d98674","name":"read","arguments":{"i":"Reading candidate implementation boundaries","path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs:104-135"},"intent":"Reading candidate implementation boundaries"},{"type":"toolCall","id":"call_i0CaS7AiD7lyaEwc1XYUxGT1|fc_000c7cef03cac861016aa95ac70d3087d18b184d3f5ffd1e1c","name":"read","arguments":{"i":"Reading inject publication boundary","path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs:75-112"},"intent":"Reading inject publication boundary"},{"type":"toolCall","id":"call_aIK7qRHtqSCJn7EBShPXraxe|fc_000c7cef03cac861016aa95ac70d3887d1a82878cf1c1893e1","name":"read","arguments":{"i":"Reading brainread gate population","path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/brainread.rs:1-185"},"intent":"Reading brainread gate population"},{"type":"toolCall","id":"call_UCvDs7ofV3cynhAzSxs7ofql|fc_000c7cef03cac861016aa95ac70d4087d1b7d0404c61cea686","name":"grep","arguments":{"i":"Checking residual gates and fixtures","pattern":"kill.scop|IR.?81|free_space|available_space|RESOURCE=disk|10\\s*\\*\\s*1024|DaemonReaper|struct .*Reaper|outside.*repo|git toplevel","path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/common;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.rs","case":false,"gitignore":false,"skip":null},"intent":"Checking residual gates and fixtures"},{"type":"toolCall","id":"call_8EPJvsNB7nS8ILWFgqU2hHqL|fc_000c7cef03cac861016aa95ac70d4887d19b9c3fbc7e2981b9","name":"read","arguments":{"i":"Recovering long amendment details","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6467-6480,6505-6506,6753-6767:raw"},"intent":"Recovering long amendment details"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":306,"output":392,"cacheRead":117376,"cacheWrite":0,"totalTokens":118074,"cost":{"input":0.0030600000000000002,"output":0.0196,"cacheRead":0.117376,"cacheWrite":0,"total":0.140036}},"stopReason":"toolUse","timestamp":1789483706082,"responseId":"resp_000c7cef03cac861016aa95aba575c87d181acb616db6e85f2","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"fc_000c7cef03cac861016aa95ac70d1887d185c3abb948d98674","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading candidate implementation boundaries\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs:104-135\"}","call_id":"call_1Ox1qSbJQ9WWw9iZRexzhaOz","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ac70d3087d18b184d3f5ffd1e1c","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading inject publication boundary\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs:75-112\"}","call_id":"call_i0CaS7AiD7lyaEwc1XYUxGT1","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ac70d3887d1a82878cf1c1893e1","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading brainread gate population\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/xtask/src/brainread.rs:1-185\"}","call_id":"call_aIK7qRHtqSCJn7EBShPXraxe","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ac70d4087d1b7d0404c61cea686","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking residual gates and fixtures\",\"pattern\":\"kill.scop|IR.?81|free_space|available_space|RESOURCE=disk|10\\\\s*\\\\*\\\\s*1024|DaemonReaper|struct .*Reaper|outside.*repo|git toplevel\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/xtask/src;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/common;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.rs\",\"case\":false,\"gitignore\":false,\"skip\":null}","call_id":"call_UCvDs7ofV3cynhAzSxs7ofql","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"grep","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ac70d4887d19b9c3fbc7e2981b9","type":"function_call","status":"completed","arguments":"{\"i\":\"Recovering long amendment details\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6467-6480,6505-6506,6753-6767:raw\"}","call_id":"call_8EPJvsNB7nS8ILWFgqU2hHqL","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}}]},"duration":13052.795399993658,"ttft":13007.482499986887,"completedAt":1789483719136,"contextSnapshot":{"promptTokens":117682,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_8EPJvsNB7nS8ILWFgqU2hHqL|fc_000c7cef03cac861016aa95ac70d4887d19b9c3fbc7e2981b9","toolName":"read","startedAt":"2026-09-15T14:48:39.138Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6467-6480,6505-6506,6753-6767:raw"},"intent":"Recovering long amendment details"},"id":"e3c4091d","parentId":"d8729f9f","timestamp":"2026-09-15T14:48:39.138Z"}
{"type":"message","id":"9dd8ca6d","parentId":"e3c4091d","timestamp":"2026-09-15T14:48:39.157Z","message":{"role":"toolResult","toolCallId":"call_i0CaS7AiD7lyaEwc1XYUxGT1|fc_000c7cef03cac861016aa95ac70d3087d18b184d3f5ffd1e1c","toolName":"read","content":[{"type":"text","text":"// [impl->REQ-SEND-SPT-HOSTED]\npub fn try_spt_hosted_inject(\n    target: &str,\n    from: &str,\n    body: &str,\n    owlery: &Path,\n    native: bool,\n) -> Option<(bool, bool)> {\n    if !is_spt_hosted_no_relay(target, owlery) {\n        return None;\n    }\n    // The envelope renders FOR `target` — the recipient whose mind is read for a\n    // monic about this sender (REQ-MONIC-DELIVERY-TRIGGER).\n    let mut bytes = spt_msg::emit::render_event_whole_for(target, from, body);\n    bytes.push('\\n');\n    let outcome = match Brain::cold_start(&broker_socket_name(), now_ms()) {\n        Ok(mut brain) => brain.inject_endpoint(target, bytes.as_bytes(), native).ok(),\n        Err(_) => None,\n    };\n    // The inject verdict is authoritative. A failed or deferred offer owes no\n    // arrival; every successful caller, including spool drains, crosses here.\n    // Publication follows injection and never changes its verdict.\n    // [impl->REQ-IO-MSG-EDGES]\n    // [impl->REQ-IO-EVENT-BUS]\n    if matches!(outcome, Some((true, _))) {\n        let msg_id = spt_proto::event::parse_event(body)\n            .and_then(|parsed| parsed.attr(spt_proto::event::EVENT_ATTR_MSG_ID).map(str::to_owned));\n        let event = crate::iobus::IoEvent::new(target, spt_proto::ioevent::IO_KIND_MSG_IN, body)\n            .with_peer(from)\n            .with_msg_id(msg_id);\n        for published in crate::iobus::default_bus(owlery, now_ms()).publish(&event) {\n            if let Err(error) = published.result {\n                spt_proto::emit_line_err!(\"IO_SINK_WARN:{}: {error}\", published.sink);\n            }\n        }\n    }\n    outcome\n}\n\n/// Drain an already-idle spt-hosted endpoint's pending spool through the inject leg\n/// (W5, REQ-IDLE-PARKED-DELIVERY) — the shared core behind BOTH the send-time\n/// already-idle path AND the pulse-tick re-offer belt, so a message QUEUED to a session\n\n[Showing lines 74-115 of 361. Use :116 to continue]"}],"details":{"truncation":{"content":"// [impl->REQ-SEND-SPT-HOSTED]\r\npub fn try_spt_hosted_inject(\r\n    target: &str,\r\n    from: &str,\r\n    body: &str,\r\n    owlery: &Path,\r\n    native: bool,\r\n) -> Option<(bool, bool)> {\r\n    if !is_spt_hosted_no_relay(target, owlery) {\r\n        return None;\r\n    }\r\n    // The envelope renders FOR `target` — the recipient whose mind is read for a\r\n    // monic about this sender (REQ-MONIC-DELIVERY-TRIGGER).\r\n    let mut bytes = spt_msg::emit::render_event_whole_for(target, from, body);\r\n    bytes.push('\\n');\r\n    let outcome = match Brain::cold_start(&broker_socket_name(), now_ms()) {\r\n        Ok(mut brain) => brain.inject_endpoint(target, bytes.as_bytes(), native).ok(),\r\n        Err(_) => None,\r\n    };\r\n    // The inject verdict is authoritative. A failed or deferred offer owes no\r\n    // arrival; every successful caller, including spool drains, crosses here.\r\n    // Publication follows injection and never changes its verdict.\r\n    // [impl->REQ-IO-MSG-EDGES]\r\n    // [impl->REQ-IO-EVENT-BUS]\r\n    if matches!(outcome, Some((true, _))) {\r\n        let msg_id = spt_proto::event::parse_event(body)\r\n            .and_then(|parsed| parsed.attr(spt_proto::event::EVENT_ATTR_MSG_ID).map(str::to_owned));\r\n        let event = crate::iobus::IoEvent::new(target, spt_proto::ioevent::IO_KIND_MSG_IN, body)\r\n            .with_peer(from)\r\n            .with_msg_id(msg_id);\r\n        for published in crate::iobus::default_bus(owlery, now_ms()).publish(&event) {\r\n            if let Err(error) = published.result {\r\n                spt_proto::emit_line_err!(\"IO_SINK_WARN:{}: {error}\", published.sink);\r\n            }\r\n        }\r\n    }\r\n    outcome\r\n}\r\n\r\n/// Drain an already-idle spt-hosted endpoint's pending spool through the inject leg\r\n/// (W5, REQ-IDLE-PARKED-DELIVERY) — the shared core behind BOTH the send-time\r\n/// already-idle path AND the pulse-tick re-offer belt, so a message QUEUED to a session\r","truncated":true,"truncatedBy":"lines","totalLines":288,"totalBytes":1911,"outputLines":42,"outputBytes":1911,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":361,"displayContent":{"text":"// [impl->REQ-SEND-SPT-HOSTED]\r\npub fn try_spt_hosted_inject(\r\n    target: &str,\r\n    from: &str,\r\n    body: &str,\r\n    owlery: &Path,\r\n    native: bool,\r\n) -> Option<(bool, bool)> {\r\n    if !is_spt_hosted_no_relay(target, owlery) {\r\n        return None;\r\n    }\r\n    // The envelope renders FOR `target` — the recipient whose mind is read for a\r\n    // monic about this sender (REQ-MONIC-DELIVERY-TRIGGER).\r\n    let mut bytes = spt_msg::emit::render_event_whole_for(target, from, body);\r\n    bytes.push('\\n');\r\n    let outcome = match Brain::cold_start(&broker_socket_name(), now_ms()) {\r\n        Ok(mut brain) => brain.inject_endpoint(target, bytes.as_bytes(), native).ok(),\r\n        Err(_) => None,\r\n    };\r\n    // The inject verdict is authoritative. A failed or deferred offer owes no\r\n    // arrival; every successful caller, including spool drains, crosses here.\r\n    // Publication follows injection and never changes its verdict.\r\n    // [impl->REQ-IO-MSG-EDGES]\r\n    // [impl->REQ-IO-EVENT-BUS]\r\n    if matches!(outcome, Some((true, _))) {\r\n        let msg_id = spt_proto::event::parse_event(body)\r\n            .and_then(|parsed| parsed.attr(spt_proto::event::EVENT_ATTR_MSG_ID).map(str::to_owned));\r\n        let event = crate::iobus::IoEvent::new(target, spt_proto::ioevent::IO_KIND_MSG_IN, body)\r\n            .with_peer(from)\r\n            .with_msg_id(msg_id);\r\n        for published in crate::iobus::default_bus(owlery, now_ms()).publish(&event) {\r\n            if let Err(error) = published.result {\r\n                spt_proto::emit_line_err!(\"IO_SINK_WARN:{}: {error}\", published.sink);\r\n            }\r\n        }\r\n    }\r\n    outcome\r\n}\r\n\r\n/// Drain an already-idle spt-hosted endpoint's pending spool through the inject leg\r\n/// (W5, REQ-IDLE-PARKED-DELIVERY) — the shared core behind BOTH the send-time\r\n/// already-idle path AND the pulse-tick re-offer belt, so a message QUEUED to a session\r","startLine":74,"lineNumbers":[74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115]},"fileSize":18494,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\crates\\spt-daemon\\src\\inject.rs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":361,"totalBytes":1911,"outputLines":42,"outputBytes":1911,"shownRange":{"start":74,"end":115},"nextOffset":116}}},"isError":false,"timestamp":1789483719157}}
{"type":"message","id":"ce18f8a0","parentId":"9dd8ca6d","timestamp":"2026-09-15T14:48:39.163Z","message":{"role":"toolResult","toolCallId":"call_aIK7qRHtqSCJn7EBShPXraxe|fc_000c7cef03cac861016aa95ac70d3887d1a82878cf1c1893e1","toolName":"read","content":[{"type":"text","text":"//! #293 static policy audit. Runtime tests cannot distinguish an explicit None\n//! from call_deadline() on a Whole carrier. This gate checks that distinction;\n//! its unit cells exercise synthetic source, never repository contents.\n\nuse std::path::Path;\n\n#[derive(Debug, PartialEq, Eq)]\npub struct Finding {\n    pub line: usize,\n    pub message: String,\n}\n\n#[derive(Clone, Debug)]\nstruct Token<'a> {\n    text: &'a str,\n    line: usize,\n}\n\n// Lex only what the census needs. Comments (including nested block comments),\n// strings, raw strings, and characters are opaque; lifetimes are not characters.\nfn tokens(src: &str) -> Result<Vec<Token<'_>>, String> {\n    let b = src.as_bytes();\n    let mut out = Vec::new();\n    let (mut i, mut line) = (0, 1);\n    while i < b.len() {\n        let start = i;\n        if b[i..].starts_with(b\"//\") {\n            while i < b.len() && b[i] != b'\\n' {\n                i += 1;\n            }\n        } else if b[i..].starts_with(b\"/*\") {\n            i += 2;\n            let mut depth = 1;\n            while i < b.len() && depth > 0 {\n                if b[i..].starts_with(b\"/*\") {\n                    depth += 1;\n                    i += 2;\n                } else if b[i..].starts_with(b\"*/\") {\n                    depth -= 1;\n                    i += 2;\n                } else {\n                    i += 1;\n                }\n            }\n            if depth != 0 {\n                return Err(format!(\"line {line}: unclosed comment\"));\n            }\n        } else {\n            let raw_start = if b[i..].starts_with(b\"br\") || b[i..].starts_with(b\"cr\") {\n                Some(i + 2)\n            } else if b[i] == b'r' {\n                Some(i + 1)\n            } else {\n                None\n            };\n            let raw = raw_start.and_then(|hash_start| {\n                let mut end = hash_start;\n                while end < b.len() && b[end] == b'#' {\n                    end += 1;\n                }\n                (b.get(end) == Some(&b'\"')).then_some((end, end - hash_start))\n            });\n            if let Some((quote, hashes)) = raw {\n                let marker = format!(\"\\\"{}\", \"#\".repeat(hashes));\n                let rest = &src[quote + 1..];\n                let end = rest\n                    .find(&marker)\n                    .ok_or_else(|| format!(\"line {line}: unclosed raw string\"))?;\n                i = quote + 1 + end + marker.len();\n            } else if b[i] == b'\"' {\n                i += 1;\n                while i < b.len() && b[i] != b'\"' {\n                    i += if b[i] == b'\\\\' { 2 } else { 1 };\n                }\n                if i >= b.len() {\n                    return Err(format!(\"line {line}: unclosed string\"));\n                }\n                i += 1;\n            } else if b[i] == b'\\'' && char_end(src, i).is_some() {\n                i = char_end(src, i).unwrap();\n            } else if b[i].is_ascii_whitespace() {\n                i += 1;\n            } else {\n                let token_start = if b[i..].starts_with(b\"r#\")\n                    && b.get(i + 2)\n                        .is_some_and(|c| c.is_ascii_alphabetic() || *c == b'_')\n                {\n                    i += 2;\n                    i\n                } else {\n                    start\n                };\n                if b[i].is_ascii_alphabetic() || b[i] == b'_' {\n                    i += 1;\n                    while i < b.len() && (b[i].is_ascii_alphanumeric() || b[i] == b'_') {\n                        i += 1;\n                    }\n                } else {\n                    i += src[i..].chars().next().unwrap().len_utf8();\n                }\n                out.push(Token {\n                    text: &src[token_start..i],\n                    line,\n                });\n            }\n        }\n        line += b[start..i].iter().filter(|&&c| c == b'\\n').count();\n    }\n    Ok(out)\n}\n\nfn char_end(src: &str, start: usize) -> Option<usize> {\n    let b = src.as_bytes();\n    let mut i = start + 1;\n    if *b.get(i)? == b'\\\\' {\n        i += 1;\n        match *b.get(i)? {\n            b'u' if b.get(i + 1) == Some(&b'{') => {\n                i += 2;\n                while *b.get(i)? != b'}' {\n                    i += 1;\n                }\n                i += 1;\n            }\n            b'x' => i += 3,\n            _ => i += 1,\n        }\n    } else {\n        i += src.get(i..)?.chars().next()?.len_utf8();\n    }\n    (b.get(i) == Some(&b'\\'')).then_some(i + 1)\n}\n\nstruct Function<'a> {\n    name: &'a str,\n    line: usize,\n    body: &'a [Token<'a>],\n}\n\nfn functions<'a>(words: &'a [Token<'a>]) -> Result<Vec<Function<'a>>, String> {\n    let mut out = Vec::new();\n    for i in 0..words.len().saturating_sub(2) {\n        if words[i].text != \"fn\" || ![\"(\", \"<\"].contains(&words[i + 2].text) {\n            continue;\n        }\n        let Some(start) = (i + 2..words.len()).find(|&j| [\"{\", \";\"].contains(&words[j].text))\n        else {\n            continue;\n        };\n        if words[start].text == \";\" {\n            continue;\n        }\n        let mut depth = 1;\n        let mut end = start + 1;\n        while end < words.len() && depth != 0 {\n            match words[end].text {\n                \"{\" => depth += 1,\n                \"}\" => depth -= 1,\n                _ => {}\n            }\n            end += 1;\n        }\n        if depth != 0 {\n            return Err(format!(\"line {}: unclosed function body\", words[i].line));\n        }\n        out.push(Function {\n            name: words[i + 1].text,\n            line: words[i].line,\n            body: &words[start + 1..end - 1],\n        });\n    }\n    Ok(out)\n}\n\nfn has(words: &[Token<'_>], sequence: &[&str]) -> bool {\n    words\n        .windows(sequence.len())\n        .any(|window| window.iter().map(|t| t.text).eq(sequence.iter().copied()))\n}\n\n/// Retired member calls, associated calls and declarations, including test code.\npub fn read_event_sites(src: &str) -> Result<Vec<Finding>, String> {\n    let words = tokens(src)?;\n    Ok(words\n        .windows(2)\n        .filter(|w| w[1].text == \"read_event\" && [\".\", \":\", \"fn\"].contains(&w[0].text))\n        .map(|w| Finding {\n            line: w[1].line,\n…\n        })\n        .collect())\n}\n\n[Showing lines 1-188 of 396. Use :189 to continue]"}],"details":{"truncation":{"content":"//! #293 static policy audit. Runtime tests cannot distinguish an explicit None\r\n//! from call_deadline() on a Whole carrier. This gate checks that distinction;\r\n//! its unit cells exercise synthetic source, never repository contents.\r\n\r\nuse std::path::Path;\r\n\r\n#[derive(Debug, PartialEq, Eq)]\r\npub struct Finding {\r\n    pub line: usize,\r\n    pub message: String,\r\n}\r\n\r\n#[derive(Clone, Debug)]\r\nstruct Token<'a> {\r\n    text: &'a str,\r\n    line: usize,\r\n}\r\n\r\n// Lex only what the census needs. Comments (including nested block comments),\r\n// strings, raw strings, and characters are opaque; lifetimes are not characters.\r\nfn tokens(src: &str) -> Result<Vec<Token<'_>>, String> {\r\n    let b = src.as_bytes();\r\n    let mut out = Vec::new();\r\n    let (mut i, mut line) = (0, 1);\r\n    while i < b.len() {\r\n        let start = i;\r\n        if b[i..].starts_with(b\"//\") {\r\n            while i < b.len() && b[i] != b'\\n' {\r\n                i += 1;\r\n            }\r\n        } else if b[i..].starts_with(b\"/*\") {\r\n            i += 2;\r\n            let mut depth = 1;\r\n            while i < b.len() && depth > 0 {\r\n                if b[i..].starts_with(b\"/*\") {\r\n                    depth += 1;\r\n                    i += 2;\r\n                } else if b[i..].starts_with(b\"*/\") {\r\n                    depth -= 1;\r\n                    i += 2;\r\n                } else {\r\n                    i += 1;\r\n                }\r\n            }\r\n            if depth != 0 {\r\n                return Err(format!(\"line {line}: unclosed comment\"));\r\n            }\r\n        } else {\r\n            let raw_start = if b[i..].starts_with(b\"br\") || b[i..].starts_with(b\"cr\") {\r\n                Some(i + 2)\r\n            } else if b[i] == b'r' {\r\n                Some(i + 1)\r\n            } else {\r\n                None\r\n            };\r\n            let raw = raw_start.and_then(|hash_start| {\r\n                let mut end = hash_start;\r\n                while end < b.len() && b[end] == b'#' {\r\n                    end += 1;\r\n                }\r\n                (b.get(end) == Some(&b'\"')).then_some((end, end - hash_start))\r\n            });\r\n            if let Some((quote, hashes)) = raw {\r\n                let marker = format!(\"\\\"{}\", \"#\".repeat(hashes));\r\n                let rest = &src[quote + 1..];\r\n                let end = rest\r\n                    .find(&marker)\r\n                    .ok_or_else(|| format!(\"line {line}: unclosed raw string\"))?;\r\n                i = quote + 1 + end + marker.len();\r\n            } else if b[i] == b'\"' {\r\n                i += 1;\r\n                while i < b.len() && b[i] != b'\"' {\r\n                    i += if b[i] == b'\\\\' { 2 } else { 1 };\r\n                }\r\n                if i >= b.len() {\r\n                    return Err(format!(\"line {line}: unclosed string\"));\r\n                }\r\n                i += 1;\r\n            } else if b[i] == b'\\'' && char_end(src, i).is_some() {\r\n                i = char_end(src, i).unwrap();\r\n            } else if b[i].is_ascii_whitespace() {\r\n                i += 1;\r\n            } else {\r\n                let token_start = if b[i..].starts_with(b\"r#\")\r\n                    && b.get(i + 2)\r\n                        .is_some_and(|c| c.is_ascii_alphabetic() || *c == b'_')\r\n                {\r\n                    i += 2;\r\n                    i\r\n                } else {\r\n                    start\r\n                };\r\n                if b[i].is_ascii_alphabetic() || b[i] == b'_' {\r\n                    i += 1;\r\n                    while i < b.len() && (b[i].is_ascii_alphanumeric() || b[i] == b'_') {\r\n                        i += 1;\r\n                    }\r\n                } else {\r\n                    i += src[i..].chars().next().unwrap().len_utf8();\r\n                }\r\n                out.push(Token {\r\n                    text: &src[token_start..i],\r\n                    line,\r\n                });\r\n            }\r\n        }\r\n        line += b[start..i].iter().filter(|&&c| c == b'\\n').count();\r\n    }\r\n    Ok(out)\r\n}\r\n\r\nfn char_end(src: &str, start: usize) -> Option<usize> {\r\n    let b = src.as_bytes();\r\n    let mut i = start + 1;\r\n    if *b.get(i)? == b'\\\\' {\r\n        i += 1;\r\n        match *b.get(i)? {\r\n            b'u' if b.get(i + 1) == Some(&b'{') => {\r\n                i += 2;\r\n                while *b.get(i)? != b'}' {\r\n                    i += 1;\r\n                }\r\n                i += 1;\r\n            }\r\n            b'x' => i += 3,\r\n            _ => i += 1,\r\n        }\r\n    } else {\r\n        i += src.get(i..)?.chars().next()?.len_utf8();\r\n    }\r\n    (b.get(i) == Some(&b'\\'')).then_some(i + 1)\r\n}\r\n\r\nstruct Function<'a> {\r\n    name: &'a str,\r\n    line: usize,\r\n    body: &'a [Token<'a>],\r\n}\r\n\r\nfn functions<'a>(words: &'a [Token<'a>]) -> Result<Vec<Function<'a>>, String> {\r\n    let mut out = Vec::new();\r\n    for i in 0..words.len().saturating_sub(2) {\r\n        if words[i].text != \"fn\" || ![\"(\", \"<\"].contains(&words[i + 2].text) {\r\n            continue;\r\n        }\r\n        let Some(start) = (i + 2..words.len()).find(|&j| [\"{\", \";\"].contains(&words[j].text))\r\n        else {\r\n            continue;\r\n        };\r\n        if words[start].text == \";\" {\r\n            continue;\r\n        }\r\n        let mut depth = 1;\r\n        let mut end = start + 1;\r\n        while end < words.len() && depth != 0 {\r\n            match words[end].text {\r\n                \"{\" => depth += 1,\r\n                \"}\" => depth -= 1,\r\n                _ => {}\r\n            }\r\n            end += 1;\r\n        }\r\n        if depth != 0 {\r\n            return Err(format!(\"line {}: unclosed function body\", words[i].line));\r\n        }\r\n        out.push(Function {\r\n            name: words[i + 1].text,\r\n            line: words[i].line,\r\n            body: &words[start + 1..end - 1],\r\n        });\r\n    }\r\n    Ok(out)\r\n}\r\n\r\nfn has(words: &[Token<'_>], sequence: &[&str]) -> bool {\r\n    words\r\n        .windows(sequence.len())\r\n        .any(|window| window.iter().map(|t| t.text).eq(sequence.iter().copied()))\r\n}\r\n\r\n/// Retired member calls, associated calls and declarations, including test code.\r\npub fn read_event_sites(src: &str) -> Result<Vec<Finding>, String> {\r\n    let words = tokens(src)?;\r\n    Ok(words\r\n        .windows(2)\r\n        .filter(|w| w[1].text == \"read_event\" && [\".\", \":\", \"fn\"].contains(&w[0].text))\r\n        .map(|w| Finding {\r\n            line: w[1].line,\r","truncated":true,"truncatedBy":"lines","totalLines":396,"totalBytes":6308,"outputLines":188,"outputBytes":6308,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":396,"displayContent":{"text":"//! #293 static policy audit. Runtime tests cannot distinguish an explicit None\r\n//! from call_deadline() on a Whole carrier. This gate checks that distinction;\r\n//! its unit cells exercise synthetic source, never repository contents.\r\n\r\nuse std::path::Path;\r\n\r\n#[derive(Debug, PartialEq, Eq)]\r\npub struct Finding {\r\n    pub line: usize,\r\n    pub message: String,\r\n}\r\n\r\n#[derive(Clone, Debug)]\r\nstruct Token<'a> {\r\n    text: &'a str,\r\n    line: usize,\r\n}\r\n\r\n// Lex only what the census needs. Comments (including nested block comments),\r\n// strings, raw strings, and characters are opaque; lifetimes are not characters.\r\nfn tokens(src: &str) -> Result<Vec<Token<'_>>, String> {\r\n    let b = src.as_bytes();\r\n    let mut out = Vec::new();\r\n    let (mut i, mut line) = (0, 1);\r\n    while i < b.len() {\r\n        let start = i;\r\n        if b[i..].starts_with(b\"//\") {\r\n            while i < b.len() && b[i] != b'\\n' {\r\n                i += 1;\r\n            }\r\n        } else if b[i..].starts_with(b\"/*\") {\r\n            i += 2;\r\n            let mut depth = 1;\r\n            while i < b.len() && depth > 0 {\r\n                if b[i..].starts_with(b\"/*\") {\r\n                    depth += 1;\r\n                    i += 2;\r\n                } else if b[i..].starts_with(b\"*/\") {\r\n                    depth -= 1;\r\n                    i += 2;\r\n                } else {\r\n                    i += 1;\r\n                }\r\n            }\r\n            if depth != 0 {\r\n                return Err(format!(\"line {line}: unclosed comment\"));\r\n            }\r\n        } else {\r\n            let raw_start = if b[i..].starts_with(b\"br\") || b[i..].starts_with(b\"cr\") {\r\n                Some(i + 2)\r\n            } else if b[i] == b'r' {\r\n                Some(i + 1)\r\n            } else {\r\n                None\r\n            };\r\n            let raw = raw_start.and_then(|hash_start| {\r\n                let mut end = hash_start;\r\n                while end < b.len() && b[end] == b'#' {\r\n                    end += 1;\r\n                }\r\n                (b.get(end) == Some(&b'\"')).then_some((end, end - hash_start))\r\n            });\r\n            if let Some((quote, hashes)) = raw {\r\n                let marker = format!(\"\\\"{}\", \"#\".repeat(hashes));\r\n                let rest = &src[quote + 1..];\r\n                let end = rest\r\n                    .find(&marker)\r\n                    .ok_or_else(|| format!(\"line {line}: unclosed raw string\"))?;\r\n                i = quote + 1 + end + marker.len();\r\n            } else if b[i] == b'\"' {\r\n                i += 1;\r\n                while i < b.len() && b[i] != b'\"' {\r\n                    i += if b[i] == b'\\\\' { 2 } else { 1 };\r\n                }\r\n                if i >= b.len() {\r\n                    return Err(format!(\"line {line}: unclosed string\"));\r\n                }\r\n                i += 1;\r\n            } else if b[i] == b'\\'' && char_end(src, i).is_some() {\r\n                i = char_end(src, i).unwrap();\r\n            } else if b[i].is_ascii_whitespace() {\r\n                i += 1;\r\n            } else {\r\n                let token_start = if b[i..].starts_with(b\"r#\")\r\n                    && b.get(i + 2)\r\n                        .is_some_and(|c| c.is_ascii_alphabetic() || *c == b'_')\r\n                {\r\n                    i += 2;\r\n                    i\r\n                } else {\r\n                    start\r\n                };\r\n                if b[i].is_ascii_alphabetic() || b[i] == b'_' {\r\n                    i += 1;\r\n                    while i < b.len() && (b[i].is_ascii_alphanumeric() || b[i] == b'_') {\r\n                        i += 1;\r\n                    }\r\n                } else {\r\n                    i += src[i..].chars().next().unwrap().len_utf8();\r\n                }\r\n                out.push(Token {\r\n                    text: &src[token_start..i],\r\n                    line,\r\n                });\r\n            }\r\n        }\r\n        line += b[start..i].iter().filter(|&&c| c == b'\\n').count();\r\n    }\r\n    Ok(out)\r\n}\r\n\r\nfn char_end(src: &str, start: usize) -> Option<usize> {\r\n    let b = src.as_bytes();\r\n    let mut i = start + 1;\r\n    if *b.get(i)? == b'\\\\' {\r\n        i += 1;\r\n        match *b.get(i)? {\r\n            b'u' if b.get(i + 1) == Some(&b'{') => {\r\n                i += 2;\r\n                while *b.get(i)? != b'}' {\r\n                    i += 1;\r\n                }\r\n                i += 1;\r\n            }\r\n            b'x' => i += 3,\r\n            _ => i += 1,\r\n        }\r\n    } else {\r\n        i += src.get(i..)?.chars().next()?.len_utf8();\r\n    }\r\n    (b.get(i) == Some(&b'\\'')).then_some(i + 1)\r\n}\r\n\r\nstruct Function<'a> {\r\n    name: &'a str,\r\n    line: usize,\r\n    body: &'a [Token<'a>],\r\n}\r\n\r\nfn functions<'a>(words: &'a [Token<'a>]) -> Result<Vec<Function<'a>>, String> {\r\n    let mut out = Vec::new();\r\n    for i in 0..words.len().saturating_sub(2) {\r\n        if words[i].text != \"fn\" || ![\"(\", \"<\"].contains(&words[i + 2].text) {\r\n            continue;\r\n        }\r\n        let Some(start) = (i + 2..words.len()).find(|&j| [\"{\", \";\"].contains(&words[j].text))\r\n        else {\r\n            continue;\r\n        };\r\n        if words[start].text == \";\" {\r\n            continue;\r\n        }\r\n        let mut depth = 1;\r\n        let mut end = start + 1;\r\n        while end < words.len() && depth != 0 {\r\n            match words[end].text {\r\n                \"{\" => depth += 1,\r\n                \"}\" => depth -= 1,\r\n                _ => {}\r\n            }\r\n            end += 1;\r\n        }\r\n        if depth != 0 {\r\n            return Err(format!(\"line {}: unclosed function body\", words[i].line));\r\n        }\r\n        out.push(Function {\r\n            name: words[i + 1].text,\r\n            line: words[i].line,\r\n            body: &words[start + 1..end - 1],\r\n        });\r\n    }\r\n    Ok(out)\r\n}\r\n\r\nfn has(words: &[Token<'_>], sequence: &[&str]) -> bool {\r\n    words\r\n        .windows(sequence.len())\r\n        .any(|window| window.iter().map(|t| t.text).eq(sequence.iter().copied()))\r\n}\r\n\r\n/// Retired member calls, associated calls and declarations, including test code.\r\npub fn read_event_sites(src: &str) -> Result<Vec<Finding>, String> {\r\n    let words = tokens(src)?;\r\n    Ok(words\r\n        .windows(2)\r\n        .filter(|w| w[1].text == \"read_event\" && [\".\", \":\", \"fn\"].contains(&w[0].text))\r\n        .map(|w| Finding {\r\n            line: w[1].line,\r\n…\n        })\n        .collect())\n}","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,null,190,191,192]},"fileSize":14300,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\crates\\xtask\\src\\brainread.rs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":396,"totalBytes":6308,"outputLines":188,"outputBytes":6308,"shownRange":{"start":1,"end":188},"nextOffset":189}}},"isError":false,"timestamp":1789483719162}}
{"type":"message","id":"108f3ff4","parentId":"ce18f8a0","timestamp":"2026-09-15T14:48:39.168Z","message":{"role":"toolResult","toolCallId":"call_1Ox1qSbJQ9WWw9iZRexzhaOz|fc_000c7cef03cac861016aa95ac70d1887d185c3abb948d98674","toolName":"read","content":[{"type":"text","text":"pub fn resolve_docs_port(config_port: Option<u16>, env_value: Option<&str>) -> u16 {\n    if let Some(v) = env_value {\n        if let Ok(p) = v.trim().parse::<u16>() {\n            if p != 0 {\n                return p;\n            }\n        }\n    }\n    config_port.unwrap_or(DEFAULT_DOCS_PORT)\n}\n\n/// Daemon-side resolution adds the rig's ephemeral-port posture without\n/// changing the public `SPT_DOCS_PORT=0` contract used by `spt docs url`.\n// [impl->REQ-TEST-DAEMON-EPHEMERAL-ADVISORY-PORTS]\npub fn resolve_daemon_docs_port(\n    config_port: Option<u16>,\n    env_value: Option<&str>,\n    ephemeral_advisory_ports: bool,\n) -> u16 {\n    if ephemeral_advisory_ports {\n        return 0;\n    }\n    resolve_docs_port(config_port, env_value)\n}\n\n/// The canonical node-prefixed URL printed by `spt docs url`.\n// [impl->REQ-DOCS-LOCAL-SERVER]\n// [impl->REQ-WEB-URL-NODE-PREFIX]\npub fn docs_url(node: &str, port: u16) -> String {\n    let node = spt_store::serving::encode_url_segment(&node.to_ascii_lowercase());\n    format!(\"http://localhost:{port}/{node}/docs/\")\n}\n\n/// Percent-decode a URI path (the sanitizer runs AFTER decoding, so\n/// `%2e%2e` cannot smuggle a traversal). Invalid escapes ⇒ `None` (reject).\nfn percent_decode(path: &str) -> Option<String> {\n    let bytes = path.as_bytes();\n    let mut out = Vec::with_capacity(bytes.len());\n    let mut i = 0;\n…\n}\n\n[Showing lines 103-138 of 765. Use :139 to continue]"}],"details":{"truncation":{"content":"            if p != 0 {\r\n                return p;\r\n            }\r\n        }\r\n    }\r\n    config_port.unwrap_or(DEFAULT_DOCS_PORT)\r\n}\r\n\r\n/// Daemon-side resolution adds the rig's ephemeral-port posture without\r\n/// changing the public `SPT_DOCS_PORT=0` contract used by `spt docs url`.\r\n// [impl->REQ-TEST-DAEMON-EPHEMERAL-ADVISORY-PORTS]\r\npub fn resolve_daemon_docs_port(\r\n    config_port: Option<u16>,\r\n    env_value: Option<&str>,\r\n    ephemeral_advisory_ports: bool,\r\n) -> u16 {\r\n    if ephemeral_advisory_ports {\r\n        return 0;\r\n    }\r\n    resolve_docs_port(config_port, env_value)\r\n}\r\n\r\n/// The canonical node-prefixed URL printed by `spt docs url`.\r\n// [impl->REQ-DOCS-LOCAL-SERVER]\r\n// [impl->REQ-WEB-URL-NODE-PREFIX]\r\npub fn docs_url(node: &str, port: u16) -> String {\r\n    let node = spt_store::serving::encode_url_segment(&node.to_ascii_lowercase());\r\n    format!(\"http://localhost:{port}/{node}/docs/\")\r\n}\r\n\r\n/// Percent-decode a URI path (the sanitizer runs AFTER decoding, so\r\n/// `%2e%2e` cannot smuggle a traversal). Invalid escapes ⇒ `None` (reject).\r\nfn percent_decode(path: &str) -> Option<String> {\r\n    let bytes = path.as_bytes();\r\n    let mut out = Vec::with_capacity(bytes.len());\r\n    let mut i = 0;\r","truncated":true,"truncatedBy":"lines","totalLines":663,"totalBytes":1230,"outputLines":36,"outputBytes":1230,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":765,"displayContent":{"text":"pub fn resolve_docs_port(config_port: Option<u16>, env_value: Option<&str>) -> u16 {\n    if let Some(v) = env_value {\n        if let Ok(p) = v.trim().parse::<u16>() {\n            if p != 0 {\r\n                return p;\r\n            }\r\n        }\r\n    }\r\n    config_port.unwrap_or(DEFAULT_DOCS_PORT)\r\n}\r\n\r\n/// Daemon-side resolution adds the rig's ephemeral-port posture without\r\n/// changing the public `SPT_DOCS_PORT=0` contract used by `spt docs url`.\r\n// [impl->REQ-TEST-DAEMON-EPHEMERAL-ADVISORY-PORTS]\r\npub fn resolve_daemon_docs_port(\r\n    config_port: Option<u16>,\r\n    env_value: Option<&str>,\r\n    ephemeral_advisory_ports: bool,\r\n) -> u16 {\r\n    if ephemeral_advisory_ports {\r\n        return 0;\r\n    }\r\n    resolve_docs_port(config_port, env_value)\r\n}\r\n\r\n/// The canonical node-prefixed URL printed by `spt docs url`.\r\n// [impl->REQ-DOCS-LOCAL-SERVER]\r\n// [impl->REQ-WEB-URL-NODE-PREFIX]\r\npub fn docs_url(node: &str, port: u16) -> String {\r\n    let node = spt_store::serving::encode_url_segment(&node.to_ascii_lowercase());\r\n    format!(\"http://localhost:{port}/{node}/docs/\")\r\n}\r\n\r\n/// Percent-decode a URI path (the sanitizer runs AFTER decoding, so\r\n/// `%2e%2e` cannot smuggle a traversal). Invalid escapes ⇒ `None` (reject).\r\nfn percent_decode(path: &str) -> Option<String> {\r\n    let bytes = path.as_bytes();\r\n    let mut out = Vec::with_capacity(bytes.len());\r\n    let mut i = 0;\r\n…\n}","startLine":100,"lineNumbers":[100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,null,151]},"fileSize":32476,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\crates\\spt-daemon\\src\\docshost.rs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":765,"totalBytes":1230,"outputLines":36,"outputBytes":1230,"shownRange":{"start":103,"end":138},"nextOffset":139}}},"isError":false,"timestamp":1789483719167}}
{"type":"message","id":"c876ddbc","parentId":"108f3ff4","timestamp":"2026-09-15T14:48:39.184Z","message":{"role":"toolResult","toolCallId":"call_8EPJvsNB7nS8ILWFgqU2hHqL|fc_000c7cef03cac861016aa95ac70d4887d19b9c3fbc7e2981b9","toolName":"read","content":[{"type":"text","text":"  `display_from_url(remote)` are the two observed strings exactly, and the folder-name fallback could\n  not have produced either (candidate folder names: 304-product, hertz-304, spt-core). So git got as\n  far as step ONE of the derivation. The first mechanism offered (\"any in-repo cwd\") was killed by one\n  datum: ci.yml:143 runs `kind(lib)` unfiltered on this runner with an in-repo cwd and passed at\n  6a7dd6b7. The variable was the FIXTURE's location, never the process cwd.\n- **Instrument defects in this lane today, all hertz's, all closed:** (window 5) `cargo ... | tail;\n  echo $?` reports tail's status (memory \"render-not-read-pipefail\") — the compile gate was in fact\n  green, so that reading was VOID evidence rather than a masked red; the same construct one command\n  later printed 0 over a checker [must] finding, a true exit 1 — the hazard is that an exit read\n  through a pipe certifies nothing, not that it hides reds. (window 4 START gate, 10:26Z) a negative\n  control that returned at the refusal branch vouched for nothing about the send arm, which then\n  crashed on a NameError on the first real launch (memory \"make a new rig red on purpose\",\n  refinement). (window 8, premise lane, 12:14Z) a FOURTH void-exit instance in one day — `$?` and `${PIPESTATUS[0]}` both read a later command, a backgrounded python traceback surfaced as exit 0; every verdict rests on the producer's own recorded exit file or cargo's Finished line. Also: the window driver crashed at its END on a stale dict key AFTER json.dump had written the report — report-before-print is load-bearing and was right by accident; ordered the other way six measured arms evaporate at the summary line. (Linux cells lane, 12:46Z) fifth and sixth: a python driver died on a SyntaxError while the shell reported exit 0 (exposed only by STALE red logs from the previous sha), and a census script stalled mid-run while its ssh reported exit 0. Both caught by reading the artifact; neither would have been caught by the exit. (13:16Z, FOLD-1b last arm) seventh: non-interactive ssh to kitsubito returned 0 while both producers wrote 127 (`cargo: command not found`, PATH not sourced) — a green whose population was empty, on the one arm whose purpose is to see what the Windows box cannot; caught by the producer-written exit files. Same window, same class in the other direction: a census line cited a positive control that another agent had run on another box, attached to one's own zero; deleted before sending, the real control then showed the zero was timing luck. Rule: the exit is the PRODUCER's file beside its log; the control is YOUR run on THIS box. (13:18Z) eighth, and the more dangerous SHAPE: `git rebase ... | tail` under set -e — the rebase failed (no git identity on kitsubito), the pipeline exit was tail's 0, and the downstream assertions ran against a tree that was never created, printing \"DIFFERS - rebase touched linux.rs\" and \"tests: 0\": a FORGED RED. A false red is not obviously an instrument failure; it reads as a finding. Rule: no pipe on the producer whose exit decides the arm; a red is accepted only after the subject it describes is proven to exist (oid).\n- **Third instrument defect, same window (hertz, 11:25Z):** a mutation driver's revert check was\n\n…\n\n\n- **Linux consumer recurrence (todlando, 2026-09-13, #304 at `b8482445`).**\n\n…\n\n- **Status:** OPEN, mechanisms recorded 2026-09-12 09:05Z. Instance 1 found by hertz in todlando's driver and confirmed by doyle; repaired as a separately pinned revision (v6 `dcfb732a…` → v7 `927eafb9…`) per the standing rule that a demonstrated execution incompatibility gets a new hash and renewed verification rather than an in-place accommodation. Instance 2 is todlando's own, found while reading the repair site.\n- **Instance 1 — the id that looked right.** `trial()` opened with `local arm=\"$1\" n=\"$2\" id=\"$arm-$n\"`. A single declaration command expands EVERY right-hand side before assigning any of its names, so `$arm` was still unset when `id` was built — but `$n` was **not** empty, because the caller is `for n in 1 2 3; do trial a \"$n\"; done` and `n` is a GLOBAL at that point. The id therefore read `-1`, not the empty-ish `-` that would have been noticed: a plausible, consistently-formed, wrong identity. Both arms produced `-1,-2,-3`, so every per-trial artifact keyed on id — captures, stop captures, census tags, portfields snapshots, cpu brackets — collided, and **Arm B overwrote Arm A in place** with nothing downstream able to tell them apart. `arm` itself was correct at every site that used it directly, so the defect surfaced ONLY through the derived ids. Reproduced independently on msys bash 5.2.21 at both LF and CRLF (igncr is not a valid shopt there): old shape → 3 distinct ids for 6 trials, split shape → 6.\n- **The audit the one fix does not discharge.** A predicate was written over the whole delivered set — any `local`/`declare`/`typeset`/`export`/`readonly` whose later right-hand side references a name assigned earlier in the SAME command — with a positive control broken on purpose (plain `local`, `declare`, and the `${name}` brace form: 3 arms) and a negative control of the same declarations split (0 hits). v6 = 2 hits, both that one line; v7 = 0; v5 = the same single site. Stated over-report: the predicate does not split on `;`, so two correct statements on one physical line read as a dependency — the real site was confirmed not to be that shape. The PowerShell and Python helpers got their own predicates (zero multi-target assignments across four `.ps1`, proven live against a control that has one; the single Python tuple unpack takes its values from one call and references none of its own targets), because a bash declaration rule measures nothing in another language.\n- **Instance 2 — the byte reader that was not one.** The repair site was first read with `sed -n '869,880p' file | cat -A`, which printed `$` at every line end — i.e. LF. The file is CRLF throughout (measured: 1117 CR = 1117 LF = 1117 CRLF). msys `sed` reads in text mode and drops the CRs, so `cat -A` faithfully rendered bytes that `sed` had already removed. The project's own rule (\"after any scripted edit, verify the BYTES\") was followed and still defeated, because the verification ran downstream of a text-mode filter.\n- **Third consequence of instance 1, and the worse half of it (hertz, measured independently; re-measured here).** The bad id does not only collide the arms — it begins with a DASH, so every artifact is named `-1.out`, `-2.err`, `-1.stop.out`. Measured in a throwaway dir: `sha256sum *.out` over such a population exits 1 with `unknown option -- 1` and hashes NOTHING (control: the same command over `a-1.out` alone exits 0 and hashes it); `grep -c x -1.out` exits 2 having measured nothing; `sha256sum ./*.out` is the repair. That is the LOUD form. The dangerous form is the one hertz's own detector took: it returned a clean EMPTY snapshot — \"0 artifacts altered\" — in the arm that was supposed to be red, because its glob handed the dashes to a tool that consumed them as flags. So a defective identity scheme does not merely lose evidence, it makes every downstream census over that run read either as a refusal or as a confident zero, depending on the consumer. Any id that can reach a filesystem is checked for a leading dash, and any glob feeding a census is written `./*` so its members cannot be parsed as options.\n- **Mechanism.** Both are a wrong answer with no error: a declaration whose dependency is satisfied by an unrelated variable that happens to exist, and a byte census whose bytes were filtered before they were counted. Neither is detectable from its own output — the id is well-formed, the `cat -A` dump is honest about what reached it.\n- **Fourth instance, in the very commit that recorded this entry (todlando, self-reported).** The amendment above was applied with a Python text-mode read (`open(p).read()`, universal newlines) and written back with `newline='\n'`. This register carried **two lone CR bytes** - `\n\n- **Instances 9-11` and `\n\n- **Addendum 2026-09-12 03:20Z` - present since at least `7cdcf5da`. Universal newlines translated each bare CR into a newline, so the commit silently rewrote two lines belonging to OTHER entries (net: 2 stray CRs removed, 2 blank lines added; markdown-harmless, still undeclared). Caught by reading the commit's own diff rather than trusting the insertion count: a one-bullet append that reports **5 insertions, 2 deletions** is telling you it touched something else. A text-mode read is a WRITE hazard, not only a measurement hazard - edit a file whose byte shape you have not measured in binary, and review the diff, never the intent.\n- **Rule.** (1) A declaration that depends on a name is its OWN statement; never share a `local` with the name it reads. (2) Derive an identity used as an artifact key ONLY after its parts are assigned, and guard it against its expected shape — a key that can go wrong silently overwrites evidence rather than failing. (3) A negative control for an id scheme must carry the caller's real variable environment: with the caller's global `n` absent, this defect reads as the harmless `-` and is easy to dismiss. (4) Read bytes with a byte reader — `python3` on the raw file, or `od`/`xxd` — never through msys `sed`, `grep`, or any text-mode filter; if a CR/LF count is the claim, count CR and LF bytes and state both.\n- **Kin:** [[IR-118]] (a complete-looking wrong answer from an instrument that succeeded), memory count-predicate-needs-its-own-positive-control, make-a-new-rig-red-on-purpose, scripted-edit-zero-match-refusal, render-not-read-pipefail, windows-firewall-census-clean-zeros.\n- **Ripe when:** now — (1) and (4) are habits, (2) is three lines in any rig. · **Size:** procedure."}],"details":{"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"}}},"isError":false,"timestamp":1789483719183}}
{"type":"message","id":"97f8472b","parentId":"c876ddbc","timestamp":"2026-09-15T14:48:40.015Z","message":{"role":"toolResult","toolCallId":"call_UCvDs7ofV3cynhAzSxs7ofql|fc_000c7cef03cac861016aa95ac70d4087d1b7d0404c61cea686","toolName":"grep","content":[{"type":"text","text":"# .worktrees/hertz-ir86-disk-delta/crates/\n\n## xtask/src/\n### diskfloor.rs\n 19|//! step prints `disk preflight: drive=<d> free_bytes=<n> floor_bytes=<n>` and\n*20|//! fails with `RESOURCE=disk drive=<d> free_bytes=<n> floor_bytes=<n>`; this\n 21|//! verb prints the same keys so one grep reads local rig logs and CI logs\n 22|//! alike. (Cited by text, not by line number — that step moves.)\n 23|// [impl->REQ-DISK-FLOOR-PREFLIGHT]\n...\n 62|/// EXIT: 0 when the run may start (always, under `--floor-gb 0`); 1 under the\n*63|/// floor, with the golden runner's `RESOURCE=disk` diagnostic; 2 on usage.\n 64|pub fn disk_floor(args: &[String]) {\n 65|    let path = flag(args, \"--path\")\n 66|        .map(PathBuf::from)\n...\n 79|\n*80|    let free_bytes = match fs2::available_space(&path) {\n 81|        Ok(n) => n,\n 82|        Err(e) => {\n 83|            eprintln!(\"disk-floor: cannot read free space at {}: {e}\", path.display());\n...\n 99|        eprintln!(\n*100|            \"RESOURCE=disk drive={drive} free_bytes={free_bytes} floor_bytes={floor_bytes} — this run starts under the floor; reds it produces are uninterpretable and must be re-run, not re-read\"\n 101|        );\n 102|        std::process::exit(1);\n 103|    }\n...\n 207|        let tmp = tempfile::tempdir().expect(\"temp dir\");\n*208|        let free = fs2::available_space(tmp.path()).expect(\"read free space\");\n 209|        assert!(free > 0, \"a writable temp dir reports free space\");\n 210|    }\n 211|}\n\n## spt-daemon/src/\n### registryhost.rs\n 1362|        std::fs::create_dir_all(&perch).unwrap();\n*1363|        // Real project dirs OUTSIDE any repo → project_id_for_dir falls back to the\n*1364|        // folder name (no remote, no git toplevel).\n 1365|        let work = root.join(\"work\");\n 1366|        for p in [\"alpha\", \"beta\", \"gamma\"] {\n 1367|            std::fs::create_dir_all(work.join(p)).unwrap();"}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/crates/xtask/src, .worktrees/hertz-ir86-disk-delta/crates/spt/tests/common, .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests, .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs, .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.rs","searchPath":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\crates","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core","matchCount":7,"fileCount":2,"files":[".worktrees/hertz-ir86-disk-delta/crates/xtask/src/diskfloor.rs",".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs"],"fileMatches":[{"path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/diskfloor.rs","count":5},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs","count":2}],"truncated":false,"displayContent":"# .worktrees/hertz-ir86-disk-delta/crates/\n\n## xtask/src/\n### diskfloor.rs\n  19│//! step prints `disk preflight: drive=<d> free_bytes=<n> floor_bytes=<n>` and\n *20│//! fails with `RESOURCE=disk drive=<d> free_bytes=<n> floor_bytes=<n>`; this\n  21│//! verb prints the same keys so one grep reads local rig logs and CI logs\n  22│//! alike. (Cited by text, not by line number — that step moves.)\n  23│// [impl->REQ-DISK-FLOOR-PREFLIGHT]\n    │...\n  62│/// EXIT: 0 when the run may start (always, under `--floor-gb 0`); 1 under the\n *63│/// floor, with the golden runner's `RESOURCE=disk` diagnostic; 2 on usage.\n  64│pub fn disk_floor(args: &[String]) {\n  65│    let path = flag(args, \"--path\")\n  66│        .map(PathBuf::from)\n    │...\n  79│\n *80│    let free_bytes = match fs2::available_space(&path) {\n  81│        Ok(n) => n,\n  82│        Err(e) => {\n  83│            eprintln!(\"disk-floor: cannot read free space at {}: {e}\", path.display());\n    │...\n  99│        eprintln!(\n*100│            \"RESOURCE=disk drive={drive} free_bytes={free_bytes} floor_bytes={floor_bytes} — this run starts under the floor; reds it produces are uninterpretable and must be re-run, not re-read\"\n 101│        );\n 102│        std::process::exit(1);\n 103│    }\n    │...\n 207│        let tmp = tempfile::tempdir().expect(\"temp dir\");\n*208│        let free = fs2::available_space(tmp.path()).expect(\"read free space\");\n 209│        assert!(free > 0, \"a writable temp dir reports free space\");\n 210│    }\n 211│}\n\n## spt-daemon/src/\n### registryhost.rs\n 1362│        std::fs::create_dir_all(&perch).unwrap();\n*1363│        // Real project dirs OUTSIDE any repo → project_id_for_dir falls back to the\n*1364│        // folder name (no remote, no git toplevel).\n 1365│        let work = root.join(\"work\");\n 1366│        for p in [\"alpha\", \"beta\", \"gamma\"] {\n 1367│            std::fs::create_dir_all(work.join(p)).unwrap();"},"isError":false,"timestamp":1789483720014}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_De3ToMeth5sgNRma5gIqyrug|fc_000c7cef03cac861016aa95ad81b1c87d1b729d1f25099241d","toolName":"read","startedAt":"2026-09-15T14:48:56.184Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/brainread.rs:190-310"},"intent":"Reading gate classification and registry"},"id":"9ccc233b","parentId":"97f8472b","timestamp":"2026-09-15T14:48:56.184Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_pnCLQlvySNRAWVGozmIUYMEo|fc_000c7cef03cac861016aa95ad81b3487d19052aec29d0cf75b","toolName":"read","startedAt":"2026-09-15T14:48:56.184Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/diskfloor.rs:1-105"},"intent":"Reading shipped disk floor seam"},"id":"ef64ca05","parentId":"9ccc233b","timestamp":"2026-09-15T14:48:56.184Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_eSJjaOjRS6EBKgWPWeZqMDVN|fc_000c7cef03cac861016aa95ad81b4487d1a48ceb1f04af34b7","toolName":"grep","startedAt":"2026-09-15T14:48:56.184Z","args":{"path":".worktrees/hertz-ir86-disk-delta/.github/ci;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/common;.worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md;.worktrees/hertz-ir86-disk-delta/AGENTS.md;.work…"},"intent":"Locating disk guard adoption"},"id":"360a4fcd","parentId":"ef64ca05","timestamp":"2026-09-15T14:48:56.184Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_Y4ghvkwQjrnLATzXftSxoZRu|fc_000c7cef03cac861016aa95ad81b4c87d18615fea1728a0594","toolName":"read","startedAt":"2026-09-15T14:48:56.184Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md:26-85"},"intent":"Reading current runner covenant"},"id":"4805f89b","parentId":"360a4fcd","timestamp":"2026-09-15T14:48:56.184Z"}
{"type":"message","id":"0acb2376","parentId":"4805f89b","timestamp":"2026-09-15T14:48:56.184Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Inspecting common patterns**"},{"type":"toolCall","id":"call_De3ToMeth5sgNRma5gIqyrug|fc_000c7cef03cac861016aa95ad81b1c87d1b729d1f25099241d","name":"read","arguments":{"i":"Reading gate classification and registry","path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/brainread.rs:190-310"},"intent":"Reading gate classification and registry"},{"type":"toolCall","id":"call_pnCLQlvySNRAWVGozmIUYMEo|fc_000c7cef03cac861016aa95ad81b3487d19052aec29d0cf75b","name":"read","arguments":{"i":"Reading shipped disk floor seam","path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/diskfloor.rs:1-105"},"intent":"Reading shipped disk floor seam"},{"type":"toolCall","id":"call_eSJjaOjRS6EBKgWPWeZqMDVN|fc_000c7cef03cac861016aa95ad81b4487d1a48ceb1f04af34b7","name":"grep","arguments":{"i":"Locating disk guard adoption","pattern":"disk-floor|IR.?90|IR.?88|pool-release|DaemonReaper|Reaper|Drop for","path":".worktrees/hertz-ir86-disk-delta/.github/ci;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/common;.worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md;.worktrees/hertz-ir86-disk-delta/AGENTS.md;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/projindex_writer_e2e.rs","case":false,"gitignore":false,"skip":null},"intent":"Locating disk guard adoption"},{"type":"toolCall","id":"call_Y4ghvkwQjrnLATzXftSxoZRu|fc_000c7cef03cac861016aa95ad81b4c87d18615fea1728a0594","name":"read","arguments":{"i":"Reading current runner covenant","path":".worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md:26-85"},"intent":"Reading current runner covenant"},{"type":"toolCall","id":"call_nFoNv8zrzhtHjqBnNgdnSZNP|fc_000c7cef03cac861016aa95ad81b5887d1b64780f9a0b8e70e","name":"grep","arguments":{"i":"Checking latest register amendments","pattern":"IR.?78|IR.?79|IR.?81|IR.?82|IR.?87|IR.?90|IR.?94|IR.?107|IR.?130|IR.?134","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:1-3887","case":false,"gitignore":false,"skip":null},"intent":"Checking latest register amendments"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":123610,"output":431,"cacheRead":0,"cacheWrite":0,"totalTokens":124041,"reasoningTokens":31,"cost":{"input":1.2361000000000002,"output":0.02155,"cacheRead":0,"cacheWrite":0,"total":1.2576500000000002}},"stopReason":"toolUse","timestamp":1789483720048,"responseId":"resp_000c7cef03cac861016aa95ac8458087d1a9a7219af26a7f02","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_000c7cef03cac861016aa95acb33f487d188453423e1a0d3e7","type":"reasoning","content":[],"encrypted_content":"gAAAAABqqVrYAT6VfwlTysRQrQ6wvQQcUBhh582kTLP-eJCLC5agYxIGtx-icMh5nC9EHrpLz-hNekex_vj_INa_uLgDdqgI8ykyPwnRlA61l-OxFH_7b1xd9t0I8k1n78akmGNehPmKDnJRdnJPA1Ctrj8qEnWNhm7XML5ovDoMGD-3zrVrK_-olYVbyDIKzZ_08ioV1XJCNi2cRAsBsWRqzrnn1LO8caVTKZY1BnMgZpckyU8VKt3KBuGqUHpmRGtIjUjQfK7iVDBHLrV3nDVIjMq7VwPllXmrsdYO2tLaUBxRVSAvUJ_py9dptLn9xhAphJL0MMAAWlBAAL3xVW3XirR-tsX8Yg6JX7lZnxclqi35pP5a_Xc4aAGXzsw9Immh09u_jQwmbnZVdDSw0wT2xC4mfOvSkm09AEdUf6UNAD6g5D5vxQK_WYerYRMYGzmB8iVh2tlaey4WCuKP1PtQMJGNJla0AxZISreEhTYXabcohSVfFAngyt6kQY00Z4uR4bHgyzbIu_TBZjmRXurXSfeiO03e4z_sh6Kt81iMy2PtvDw_BeHyXJ7DmbknHmLdb5KxvSiXyVvchjcUxMCfaYjFBSe6d4PlKnaqBPU51O7TnZWrJMUnoWz2U0MUtM6YSS0g4-_3aCAF291Wmb-Bxqw6zsnXJALOljZYsZOqvySM1Lf73_0DmAoRR7PHkNvhvrttiih6AdP3Do9in1UqkRV6Xx8NUf-HS4XJ_oOW2zfcsHf5tf_cZbVbwOMiz35khtNXdalFgveixoQ9tkaCqOQRjHsEJyNt3rtGHtQHdFAq557WEoR9N99hdKUiwDcWnEh8e6zYywe5MfSx9Inpsw6iJtf6D4GPEOjhJb8LCDfVUr7q3GQsaT5kzzvDstjWd2tSXvBUDexuryEonvcjNgsuSWn4GIpn3_Da8sPdoVEliJRq-AdBOyz0I4wLMtXFdravoKwy4_LV8ffuORpO8LWZiSv6CncT8zVVm1WY2JxyIXvex6LJW1moPaFwUIuNbRfYD1SYg3pjxFrcpD9xJSae1T_seC4Ln6ubjPkUgtnpe5HNssGok2l35ALZOvbchjl1AW4c6x0TSfT8RzBvjEvmTkOEHjk7rbXOU9hQFR1xW2gbm-IQne_Oekq9zBQAfavNRoQnkKlrO0k6Ai7cECEh6ozU8-9eJ5WSgX15_2bILIRSOCIwY_f13LBnaxtqfbElVRTebbIJmO73JT_AoHU_wlQM0ofS659SZBAlyoLSUEuQPZHxwHn0YxOEouder-Axj6ccH-d5Vps5IovjRrMO7vuVKwc3BqTfFXMFFx2CV2bBwWloW8I9MwqZy5t4g3UBAFpRPjRng1Xc8Bf6iZmDe5IwsGEM_39xz0LpLwhXuD-3TfxaKMJXCSHx0mtvGIi66uqWoNrLh6MvZjbfpWqX8wI8bJqS5b4UBchwEiCrYN7Irhr1o7jQxe9-oGfkE7Le0zwbxb7acVL4JBMKRwAK_I9GyA==","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"summary":[{"type":"summary_text","text":"**Inspecting common patterns**"}],"metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ad81b1c87d1b729d1f25099241d","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading gate classification and registry\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/xtask/src/brainread.rs:190-310\"}","call_id":"call_De3ToMeth5sgNRma5gIqyrug","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ad81b3487d19052aec29d0cf75b","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading shipped disk floor seam\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/xtask/src/diskfloor.rs:1-105\"}","call_id":"call_pnCLQlvySNRAWVGozmIUYMEo","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ad81b4487d1a48ceb1f04af34b7","type":"function_call","status":"completed","arguments":"{\"i\":\"Locating disk guard adoption\",\"pattern\":\"disk-floor|IR.?90|IR.?88|pool-release|DaemonReaper|Reaper|Drop for\",\"path\":\".worktrees/hertz-ir86-disk-delta/.github/ci;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/common;.worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md;.worktrees/hertz-ir86-disk-delta/AGENTS.md;.worktrees/hertz-ir86-disk-delta/crates/spt/tests/projindex_writer_e2e.rs\",\"case\":false,\"gitignore\":false,\"skip\":null}","call_id":"call_eSJjaOjRS6EBKgWPWeZqMDVN","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"grep","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ad81b4c87d18615fea1728a0594","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading current runner covenant\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md:26-85\"}","call_id":"call_Y4ghvkwQjrnLATzXftSxoZRu","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ad81b5887d1b64780f9a0b8e70e","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking latest register amendments\",\"pattern\":\"IR.?78|IR.?79|IR.?81|IR.?82|IR.?87|IR.?90|IR.?94|IR.?107|IR.?130|IR.?134\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:1-3887\",\"case\":false,\"gitignore\":false,\"skip\":null}","call_id":"call_nFoNv8zrzhtHjqBnNgdnSZNP","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"grep","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}}]},"duration":16133.497000008821,"ttft":3182.1265000104904,"completedAt":1789483736182,"contextSnapshot":{"promptTokens":123610,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_nFoNv8zrzhtHjqBnNgdnSZNP|fc_000c7cef03cac861016aa95ad81b5887d1b64780f9a0b8e70e","toolName":"grep","startedAt":"2026-09-15T14:48:56.184Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:1-3887"},"intent":"Checking latest register amendments"},"id":"eae955b3","parentId":"0acb2376","timestamp":"2026-09-15T14:48:56.184Z"}
{"type":"message","id":"0dfb2c5a","parentId":"eae955b3","timestamp":"2026-09-15T14:48:56.188Z","message":{"role":"toolResult","toolCallId":"call_De3ToMeth5sgNRma5gIqyrug|fc_000c7cef03cac861016aa95ad81b1c87d1b729d1f25099241d","toolName":"read","content":[{"type":"text","text":"pub fn read_event_sites(src: &str) -> Result<Vec<Finding>, String> {\n…\n    Ok(words\n…\n        .map(|w| Finding {\n…\n            message: \"retired read_event symbol\".into(),\n        })\n        .collect())\n}\n\n/// Includes all future serve_*_feed bodies, not merely the current nine.\npub fn feed_bodies_calling_call_deadline(src: &str) -> Result<Vec<Finding>, String> {\n    let words = tokens(src)?;\n    let mut findings = Vec::new();\n    for f in functions(&words)? {\n        if (f.name.starts_with(\"serve_\") && f.name.ends_with(\"_feed\")) || f.name == \"serve_attach\" {\n            for token in f.body.iter().filter(|t| t.text == \"call_deadline\") {\n                findings.push(Finding {\n                    line: token.line,\n                    message: format!(\"{}: stream lifetime must not use call_deadline\", f.name),\n                });\n            }\n        }\n    }\n    Ok(findings)\n}\n\nfn policy_controls(\n    src: &str,\n    streams: &[&str],\n    replies: &[(&str, &str)],\n) -> Result<Vec<Finding>, String> {\n    let words = tokens(src)?;\n    let funcs = functions(&words)?;\n    let mut findings = Vec::new();\n    for &name in streams.iter().chain(replies.iter().map(|(name, _)| name)) {\n        let matching: Vec<_> = funcs.iter().filter(|f| f.name == name).collect();\n        if matching.len() != 1 {\n            findings.push(Finding {\n                line: 1,\n                message: format!(\"expected exactly one {name}, found {}\", matching.len()),\n            });\n            continue;\n        }\n        let f = matching[0];\n        let binding = if let Some((_, receiver)) = replies.iter().find(|(n, _)| *n == name) {\n            vec![\n                \"let\",\n                \"deadline\",\n                \"=\",\n                receiver,\n                \".\",\n                \"call_deadline\",\n                \"(\",\n                \")\",\n                \";\",\n                \"loop\",\n                \"{\",\n            ]\n        } else {\n            vec![\n                \"let\", \"deadline\", \":\", \"Option\", \"<\", \"Instant\", \">\", \"=\", \"None\", \";\", \"loop\",\n                \"{\",\n            ]\n        };\n        if !has(f.body, &binding) || !has(f.body, &[\"read_event_until\", \"(\", \"deadline\", \")\"]) {\n            findings.push(Finding {\n                line: f.line,\n                message: format!(\"{name}: explicit stream/reply deadline control missing\"),\n            });\n        }\n    }\n    Ok(findings)\n}\n\n/// Apply the pure predicates to every crate Rust source, including tests.\n/// Caller prints the returned diagnostics and exits nonzero on Err.\n// [impl->REQ-BRAIN-READ-BOUNDED-PER-CALL]\npub fn check(root: &Path) -> Result<String, String> {\n    fn collect(dir: &Path, files: &mut Vec<std::path::PathBuf>) -> Result<(), String> {\n        for entry in std::fs::read_dir(dir).map_err(|e| format!(\"{}: {e}\", dir.display()))? {\n            let entry = entry.map_err(|e| e.to_string())?;\n            let kind = entry.file_type().map_err(|e| e.to_string())?;\n            if kind.is_dir() {\n                collect(&entry.path(), files)?;\n            } else if entry.path().extension().is_some_and(|ext| ext == \"rs\") {\n                files.push(entry.path());\n            }\n        }\n        Ok(())\n    }\n    let mut files = Vec::new();\n    collect(&root.join(\"crates\"), &mut files)?;\n    files.sort();\n    if files.is_empty() {\n        return Err(\"BRAIN_READ_AUDIT: no Rust sources\".into());\n    }\n    let mut errors = Vec::new();\n    for path in &files {\n        let src = std::fs::read_to_string(path).map_err(|e| format!(\"{}: {e}\", path.display()))?;\n        let mut findings = read_event_sites(&src)?;\n        findings.extend(feed_bodies_calling_call_deadline(&src)?);\n        for finding in findings {\n            errors.push(format!(\n                \"{}:{}: {}\",\n                path.strip_prefix(root).unwrap_or(path).display(),\n                finding.line,\n                finding.message\n            ));\n        }\n    }\n    let feeds = [\n        \"serve_registry_feed\",\n        \"serve_notif_feed\",\n        \"serve_seal_feed\",\n        \"serve_knock_feed\",\n        \"serve_fork_feed\",\n        \"serve_redeem_feed\",\n        \"serve_answer_feed\",\n        \"serve_presence_feed\",\n        \"serve_wan_feed\",\n    ];\n    for (relative, streams, replies) in [\n        (\n            \"crates/spt-daemon/src/dispatch.rs\",\n            feeds.as_slice(),\n            vec![(\"peek_first_line\", \"brain\")],\n        ),\n        (\n            \"crates/spt-daemon/src/attach.rs\",\n…\n        ),\n…\n    ] {\n…\n    }\n…\n}\n\n[Showing lines 189-313 of 396. Use :314 to continue]"}],"details":{"truncation":{"content":"            message: \"retired read_event symbol\".into(),\r\n        })\r\n        .collect())\r\n}\r\n\r\n/// Includes all future serve_*_feed bodies, not merely the current nine.\r\npub fn feed_bodies_calling_call_deadline(src: &str) -> Result<Vec<Finding>, String> {\r\n    let words = tokens(src)?;\r\n    let mut findings = Vec::new();\r\n    for f in functions(&words)? {\r\n        if (f.name.starts_with(\"serve_\") && f.name.ends_with(\"_feed\")) || f.name == \"serve_attach\" {\r\n            for token in f.body.iter().filter(|t| t.text == \"call_deadline\") {\r\n                findings.push(Finding {\r\n                    line: token.line,\r\n                    message: format!(\"{}: stream lifetime must not use call_deadline\", f.name),\r\n                });\r\n            }\r\n        }\r\n    }\r\n    Ok(findings)\r\n}\r\n\r\nfn policy_controls(\r\n    src: &str,\r\n    streams: &[&str],\r\n    replies: &[(&str, &str)],\r\n) -> Result<Vec<Finding>, String> {\r\n    let words = tokens(src)?;\r\n    let funcs = functions(&words)?;\r\n    let mut findings = Vec::new();\r\n    for &name in streams.iter().chain(replies.iter().map(|(name, _)| name)) {\r\n        let matching: Vec<_> = funcs.iter().filter(|f| f.name == name).collect();\r\n        if matching.len() != 1 {\r\n            findings.push(Finding {\r\n                line: 1,\r\n                message: format!(\"expected exactly one {name}, found {}\", matching.len()),\r\n            });\r\n            continue;\r\n        }\r\n        let f = matching[0];\r\n        let binding = if let Some((_, receiver)) = replies.iter().find(|(n, _)| *n == name) {\r\n            vec![\r\n                \"let\",\r\n                \"deadline\",\r\n                \"=\",\r\n                receiver,\r\n                \".\",\r\n                \"call_deadline\",\r\n                \"(\",\r\n                \")\",\r\n                \";\",\r\n                \"loop\",\r\n                \"{\",\r\n            ]\r\n        } else {\r\n            vec![\r\n                \"let\", \"deadline\", \":\", \"Option\", \"<\", \"Instant\", \">\", \"=\", \"None\", \";\", \"loop\",\r\n                \"{\",\r\n            ]\r\n        };\r\n        if !has(f.body, &binding) || !has(f.body, &[\"read_event_until\", \"(\", \"deadline\", \")\"]) {\r\n            findings.push(Finding {\r\n                line: f.line,\r\n                message: format!(\"{name}: explicit stream/reply deadline control missing\"),\r\n            });\r\n        }\r\n    }\r\n    Ok(findings)\r\n}\r\n\r\n/// Apply the pure predicates to every crate Rust source, including tests.\r\n/// Caller prints the returned diagnostics and exits nonzero on Err.\r\n// [impl->REQ-BRAIN-READ-BOUNDED-PER-CALL]\r\npub fn check(root: &Path) -> Result<String, String> {\r\n    fn collect(dir: &Path, files: &mut Vec<std::path::PathBuf>) -> Result<(), String> {\r\n        for entry in std::fs::read_dir(dir).map_err(|e| format!(\"{}: {e}\", dir.display()))? {\r\n            let entry = entry.map_err(|e| e.to_string())?;\r\n            let kind = entry.file_type().map_err(|e| e.to_string())?;\r\n            if kind.is_dir() {\r\n                collect(&entry.path(), files)?;\r\n            } else if entry.path().extension().is_some_and(|ext| ext == \"rs\") {\r\n                files.push(entry.path());\r\n            }\r\n        }\r\n        Ok(())\r\n    }\r\n    let mut files = Vec::new();\r\n    collect(&root.join(\"crates\"), &mut files)?;\r\n    files.sort();\r\n    if files.is_empty() {\r\n        return Err(\"BRAIN_READ_AUDIT: no Rust sources\".into());\r\n    }\r\n    let mut errors = Vec::new();\r\n    for path in &files {\r\n        let src = std::fs::read_to_string(path).map_err(|e| format!(\"{}: {e}\", path.display()))?;\r\n        let mut findings = read_event_sites(&src)?;\r\n        findings.extend(feed_bodies_calling_call_deadline(&src)?);\r\n        for finding in findings {\r\n            errors.push(format!(\r\n                \"{}:{}: {}\",\r\n                path.strip_prefix(root).unwrap_or(path).display(),\r\n                finding.line,\r\n                finding.message\r\n            ));\r\n        }\r\n    }\r\n    let feeds = [\r\n        \"serve_registry_feed\",\r\n        \"serve_notif_feed\",\r\n        \"serve_seal_feed\",\r\n        \"serve_knock_feed\",\r\n        \"serve_fork_feed\",\r\n        \"serve_redeem_feed\",\r\n        \"serve_answer_feed\",\r\n        \"serve_presence_feed\",\r\n        \"serve_wan_feed\",\r\n    ];\r\n    for (relative, streams, replies) in [\r\n        (\r\n            \"crates/spt-daemon/src/dispatch.rs\",\r\n            feeds.as_slice(),\r\n            vec![(\"peek_first_line\", \"brain\")],\r\n        ),\r\n        (\r\n            \"crates/spt-daemon/src/attach.rs\",\r","truncated":true,"truncatedBy":"lines","totalLines":208,"totalBytes":4467,"outputLines":125,"outputBytes":4467,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":396,"displayContent":{"text":"pub fn read_event_sites(src: &str) -> Result<Vec<Finding>, String> {\n…\n    Ok(words\n…\n        .map(|w| Finding {\n…\n            message: \"retired read_event symbol\".into(),\r\n        })\r\n        .collect())\r\n}\r\n\r\n/// Includes all future serve_*_feed bodies, not merely the current nine.\r\npub fn feed_bodies_calling_call_deadline(src: &str) -> Result<Vec<Finding>, String> {\r\n    let words = tokens(src)?;\r\n    let mut findings = Vec::new();\r\n    for f in functions(&words)? {\r\n        if (f.name.starts_with(\"serve_\") && f.name.ends_with(\"_feed\")) || f.name == \"serve_attach\" {\r\n            for token in f.body.iter().filter(|t| t.text == \"call_deadline\") {\r\n                findings.push(Finding {\r\n                    line: token.line,\r\n                    message: format!(\"{}: stream lifetime must not use call_deadline\", f.name),\r\n                });\r\n            }\r\n        }\r\n    }\r\n    Ok(findings)\r\n}\r\n\r\nfn policy_controls(\r\n    src: &str,\r\n    streams: &[&str],\r\n    replies: &[(&str, &str)],\r\n) -> Result<Vec<Finding>, String> {\r\n    let words = tokens(src)?;\r\n    let funcs = functions(&words)?;\r\n    let mut findings = Vec::new();\r\n    for &name in streams.iter().chain(replies.iter().map(|(name, _)| name)) {\r\n        let matching: Vec<_> = funcs.iter().filter(|f| f.name == name).collect();\r\n        if matching.len() != 1 {\r\n            findings.push(Finding {\r\n                line: 1,\r\n                message: format!(\"expected exactly one {name}, found {}\", matching.len()),\r\n            });\r\n            continue;\r\n        }\r\n        let f = matching[0];\r\n        let binding = if let Some((_, receiver)) = replies.iter().find(|(n, _)| *n == name) {\r\n            vec![\r\n                \"let\",\r\n                \"deadline\",\r\n                \"=\",\r\n                receiver,\r\n                \".\",\r\n                \"call_deadline\",\r\n                \"(\",\r\n                \")\",\r\n                \";\",\r\n                \"loop\",\r\n                \"{\",\r\n            ]\r\n        } else {\r\n            vec![\r\n                \"let\", \"deadline\", \":\", \"Option\", \"<\", \"Instant\", \">\", \"=\", \"None\", \";\", \"loop\",\r\n                \"{\",\r\n            ]\r\n        };\r\n        if !has(f.body, &binding) || !has(f.body, &[\"read_event_until\", \"(\", \"deadline\", \")\"]) {\r\n            findings.push(Finding {\r\n                line: f.line,\r\n                message: format!(\"{name}: explicit stream/reply deadline control missing\"),\r\n            });\r\n        }\r\n    }\r\n    Ok(findings)\r\n}\r\n\r\n/// Apply the pure predicates to every crate Rust source, including tests.\r\n/// Caller prints the returned diagnostics and exits nonzero on Err.\r\n// [impl->REQ-BRAIN-READ-BOUNDED-PER-CALL]\r\npub fn check(root: &Path) -> Result<String, String> {\r\n    fn collect(dir: &Path, files: &mut Vec<std::path::PathBuf>) -> Result<(), String> {\r\n        for entry in std::fs::read_dir(dir).map_err(|e| format!(\"{}: {e}\", dir.display()))? {\r\n            let entry = entry.map_err(|e| e.to_string())?;\r\n            let kind = entry.file_type().map_err(|e| e.to_string())?;\r\n            if kind.is_dir() {\r\n                collect(&entry.path(), files)?;\r\n            } else if entry.path().extension().is_some_and(|ext| ext == \"rs\") {\r\n                files.push(entry.path());\r\n            }\r\n        }\r\n        Ok(())\r\n    }\r\n    let mut files = Vec::new();\r\n    collect(&root.join(\"crates\"), &mut files)?;\r\n    files.sort();\r\n    if files.is_empty() {\r\n        return Err(\"BRAIN_READ_AUDIT: no Rust sources\".into());\r\n    }\r\n    let mut errors = Vec::new();\r\n    for path in &files {\r\n        let src = std::fs::read_to_string(path).map_err(|e| format!(\"{}: {e}\", path.display()))?;\r\n        let mut findings = read_event_sites(&src)?;\r\n        findings.extend(feed_bodies_calling_call_deadline(&src)?);\r\n        for finding in findings {\r\n            errors.push(format!(\r\n                \"{}:{}: {}\",\r\n                path.strip_prefix(root).unwrap_or(path).display(),\r\n                finding.line,\r\n                finding.message\r\n            ));\r\n        }\r\n    }\r\n    let feeds = [\r\n        \"serve_registry_feed\",\r\n        \"serve_notif_feed\",\r\n        \"serve_seal_feed\",\r\n        \"serve_knock_feed\",\r\n        \"serve_fork_feed\",\r\n        \"serve_redeem_feed\",\r\n        \"serve_answer_feed\",\r\n        \"serve_presence_feed\",\r\n        \"serve_wan_feed\",\r\n    ];\r\n    for (relative, streams, replies) in [\r\n        (\r\n            \"crates/spt-daemon/src/dispatch.rs\",\r\n            feeds.as_slice(),\r\n            vec![(\"peek_first_line\", \"brain\")],\r\n        ),\r\n        (\r\n            \"crates/spt-daemon/src/attach.rs\",\r\n…\n        ),\n…\n    ] {\n…\n    }\n…\n}","startLine":182,"lineNumbers":[182,null,184,null,187,null,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,null,316,null,326,null,332,null,338]},"fileSize":14300,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\crates\\xtask\\src\\brainread.rs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":396,"totalBytes":4467,"outputLines":125,"outputBytes":4467,"shownRange":{"start":189,"end":313},"nextOffset":314}}},"isError":false,"timestamp":1789483736187}}
{"type":"message","id":"29b226fe","parentId":"0dfb2c5a","timestamp":"2026-09-15T14:48:56.212Z","message":{"role":"toolResult","toolCallId":"call_Y4ghvkwQjrnLATzXftSxoZRu|fc_000c7cef03cac861016aa95ad81b4c87d18615fea1728a0594","toolName":"read","content":[{"type":"text","text":"## Step timings leave as an artifact\n…\n\n## Shared-runner quiet-window predicate\n\n<!-- [doc->REQ-GOLDEN-CI-LANE] -->\n\nA shared box is quiet only when **both** conditions hold:\n\n1. zero non-terminal CI runs; and\n2. no local `cargo`, `rustc`, or `cargo-nextest` process alive on the box.\n\nA GitHub-only drain check reads clean while another agent is mid-local-build. That is the contention class that muddied the g6 evidence twice. These axes are proxies for contention, not a definition of quiet; a proxy returning “quiet” is not itself a measurement of quiet.\n\n### Queue status is not occupancy\n\n`gh run list` status is not an occupancy probe. A run can report `queued` while its job is already executing on the box; this was observed on #121/#122 with `Runner.Worker` and `cargo-nextest` live and a suite mid-flight. Therefore `queued` never means “not started,” and an idle-looking queue is not evidence of a deaf runner.\n\nThe authoritative occupancy signal is the process table. `Runner.Worker` means a job is running on this box. `cargo-nextest` means a suite is running, which is the seedmap-starvation collision.\n\n### Attribute process load before counting it\n\nThe two predicate axes are not independent: a CI job manifests in the local process table as `cargo` and `rustc`. Their presence does not imply a second occupant. Walk each PID's parent chain before counting it as new load:\n\n- a chain rooted at `Runner.Worker.exe`, `Runner.Listener.exe`, or `RunnerService.exe` is the CI axis already counted;\n- a chain rooted at a user shell is a genuine second occupant, so hold.\n\nOwner queries alone are insufficient. The runner service account can return empty owner and command-line fields; use the parent chain. Report attributed load, not bare process presence: “live local cargo” and “box free of a second occupant” can both be true.\n\n### The link is a third axis, and it is measured rather than assumed\n\n<!-- [doc->REQ-CI-LINK-HEALTH-PROBE] -->\n\nBoth axes above are process-shaped. A box can be quiet by both and still be a bad place to run a two-host rendezvous, because neither axis can see the link. Run 30771155390 is the specimen: zero non-terminal runs, no local build, and a link so degraded that a 1-second checkout took 321 seconds with bidirectional 10-second QUIC dial timeouts. Its `PUMP_PEER_FAIL` counts moved 0→3→0 on one host and 8→22→8 on the other across green/red/rerun, and the red was triaged as if it were a product failure because nothing in the run recorded what the network was doing.\n\nkitsubito's only link is wifi, indefinitely (operator-confirmed 2026-08-02). The link cannot be hardened, so the predicate has to see it.\n\nBoth two-host jobs therefore probe the peer immediately before rendezvous, via `.github/bench/link-probe.sh` (Linux) and `.github/bench/link-probe.ps1` (Windows), and each writes its result into the run's bench ledger. Read the probe's line like this:\n\n```\nLINK peer=kitsubito ip=100.98.197.12 path=direct samples=5/5 min=10ms med=15ms max=83ms rtts=10,12,15,81,83\n```\n\n- **`path=relay`** means tailscale fell back to DERP. That is a different network than the one the rig's timings were tuned on, and it is the first thing to check when a rendezvous is slow rather than broken.\n- **`samples=n/5` below full** is loss. A rendezvous over a lossy link produces timeouts that look exactly like a product wedge.\n- **`max` far above `med`** is jitter, and jitter is the failure shape here — the motivating run's link mostly worked. A median alone would have read healthy through it, which is why both numbers are carried: the ledger gets `link-rtt-med-<peer>` and `link-rtt-max-<peer>` rows, so the spread is a trend across runs and not one number in one log.\n- **`probe=NO-REPLY` or `probe=UNAVAILABLE`** is a labelled hole, not a silence. The `ok:false` row says a measurement was attempted and did not land, which is a different claim from a run that never probed.\n- **`ip=` must match that job's `SPT_TWO_HOST_PEER_IP`.** The probe names its peer and the rig addresses one; a disagreement means they are not talking about the same box.\n\nThe probe is an instrument, not a gate: it always exits 0, and no threshold refuses a rendezvous today. Whether a number should is a ruling nobody has made, and an instrument that reds a run converts \"the link was slow\" into \"the suite failed\" — the exact confusion it exists to remove.\n\n### Post-restart daemon churn is a known blind spot\n\nThe fleet daemon's own resume storm—reconnects, pulses, and disk I/O for minutes after restart—is real load that neither predicate axis sees. This is an existing 2026-07-27 g6 finding with an existing mitigation, not a new discovery: a timed-window run adjacent to a daemon restart records the fleet-`spt` CPU-seconds delta sampled before and after, so contention is measured rather than inferred. Recording a rediscovery as a discovery loses the mitigation someone already paid for.\n\nThe preserved instruments are `.github/ci/g6-postbounce.ps1`, for the immediate post-restart sample, and `.github/ci/g6-curve.ps1`, for the private-daemon age/CPU dose-response curve. Both require caller-supplied scratch and fixture-worktree paths; neither embeds an expired agent-session scratchpad. The curve's throwaway `SPT_HOME`, home-hashed IPC socket, `daemon run`, and PID-scoped bounce are deliberate safety boundaries: `daemon start` or `daemon stop` may reach the fleet service and are prohibited in this rig.\n\nThis is a second reason never to restart a wedged daemon merely to tidy the box before a run: that trades a known abnormality for an unmeasured one.\n\n## Windows ad-hoc rigs that outlive the tool call\n\n<!-- [doc->REQ-GATE-RIG-DETACHED-LAUNCH-DISCIPLINE] -->\n\nUse `Start-Process` with **`-WindowStyle Hidden -PassThru` and no\n`-RedirectStandardOutput` / `-RedirectStandardError`** when a Windows rig must\noutlive its invoking PowerShell tool call. Give the driver durable output paths\n…\nservice hosting, or product daemons.\n…\n\n\n[Showing lines 25-88 of 163. Use :89 to continue]"}],"details":{"truncation":{"content":"\r\n## Shared-runner quiet-window predicate\r\n\r\n<!-- [doc->REQ-GOLDEN-CI-LANE] -->\r\n\r\nA shared box is quiet only when **both** conditions hold:\r\n\r\n1. zero non-terminal CI runs; and\r\n2. no local `cargo`, `rustc`, or `cargo-nextest` process alive on the box.\r\n\r\nA GitHub-only drain check reads clean while another agent is mid-local-build. That is the contention class that muddied the g6 evidence twice. These axes are proxies for contention, not a definition of quiet; a proxy returning “quiet” is not itself a measurement of quiet.\r\n\r\n### Queue status is not occupancy\r\n\r\n`gh run list` status is not an occupancy probe. A run can report `queued` while its job is already executing on the box; this was observed on #121/#122 with `Runner.Worker` and `cargo-nextest` live and a suite mid-flight. Therefore `queued` never means “not started,” and an idle-looking queue is not evidence of a deaf runner.\r\n\r\nThe authoritative occupancy signal is the process table. `Runner.Worker` means a job is running on this box. `cargo-nextest` means a suite is running, which is the seedmap-starvation collision.\r\n\r\n### Attribute process load before counting it\r\n\r\nThe two predicate axes are not independent: a CI job manifests in the local process table as `cargo` and `rustc`. Their presence does not imply a second occupant. Walk each PID's parent chain before counting it as new load:\r\n\r\n- a chain rooted at `Runner.Worker.exe`, `Runner.Listener.exe`, or `RunnerService.exe` is the CI axis already counted;\r\n- a chain rooted at a user shell is a genuine second occupant, so hold.\r\n\r\nOwner queries alone are insufficient. The runner service account can return empty owner and command-line fields; use the parent chain. Report attributed load, not bare process presence: “live local cargo” and “box free of a second occupant” can both be true.\r\n\r\n### The link is a third axis, and it is measured rather than assumed\r\n\r\n<!-- [doc->REQ-CI-LINK-HEALTH-PROBE] -->\r\n\r\nBoth axes above are process-shaped. A box can be quiet by both and still be a bad place to run a two-host rendezvous, because neither axis can see the link. Run 30771155390 is the specimen: zero non-terminal runs, no local build, and a link so degraded that a 1-second checkout took 321 seconds with bidirectional 10-second QUIC dial timeouts. Its `PUMP_PEER_FAIL` counts moved 0→3→0 on one host and 8→22→8 on the other across green/red/rerun, and the red was triaged as if it were a product failure because nothing in the run recorded what the network was doing.\r\n\r\nkitsubito's only link is wifi, indefinitely (operator-confirmed 2026-08-02). The link cannot be hardened, so the predicate has to see it.\r\n\r\nBoth two-host jobs therefore probe the peer immediately before rendezvous, via `.github/bench/link-probe.sh` (Linux) and `.github/bench/link-probe.ps1` (Windows), and each writes its result into the run's bench ledger. Read the probe's line like this:\r\n\r\n```\r\nLINK peer=kitsubito ip=100.98.197.12 path=direct samples=5/5 min=10ms med=15ms max=83ms rtts=10,12,15,81,83\r\n```\r\n\r\n- **`path=relay`** means tailscale fell back to DERP. That is a different network than the one the rig's timings were tuned on, and it is the first thing to check when a rendezvous is slow rather than broken.\r\n- **`samples=n/5` below full** is loss. A rendezvous over a lossy link produces timeouts that look exactly like a product wedge.\r\n- **`max` far above `med`** is jitter, and jitter is the failure shape here — the motivating run's link mostly worked. A median alone would have read healthy through it, which is why both numbers are carried: the ledger gets `link-rtt-med-<peer>` and `link-rtt-max-<peer>` rows, so the spread is a trend across runs and not one number in one log.\r\n- **`probe=NO-REPLY` or `probe=UNAVAILABLE`** is a labelled hole, not a silence. The `ok:false` row says a measurement was attempted and did not land, which is a different claim from a run that never probed.\r\n- **`ip=` must match that job's `SPT_TWO_HOST_PEER_IP`.** The probe names its peer and the rig addresses one; a disagreement means they are not talking about the same box.\r\n\r\nThe probe is an instrument, not a gate: it always exits 0, and no threshold refuses a rendezvous today. Whether a number should is a ruling nobody has made, and an instrument that reds a run converts \"the link was slow\" into \"the suite failed\" — the exact confusion it exists to remove.\r\n\r\n### Post-restart daemon churn is a known blind spot\r\n\r\nThe fleet daemon's own resume storm—reconnects, pulses, and disk I/O for minutes after restart—is real load that neither predicate axis sees. This is an existing 2026-07-27 g6 finding with an existing mitigation, not a new discovery: a timed-window run adjacent to a daemon restart records the fleet-`spt` CPU-seconds delta sampled before and after, so contention is measured rather than inferred. Recording a rediscovery as a discovery loses the mitigation someone already paid for.\r\n\r\nThe preserved instruments are `.github/ci/g6-postbounce.ps1`, for the immediate post-restart sample, and `.github/ci/g6-curve.ps1`, for the private-daemon age/CPU dose-response curve. Both require caller-supplied scratch and fixture-worktree paths; neither embeds an expired agent-session scratchpad. The curve's throwaway `SPT_HOME`, home-hashed IPC socket, `daemon run`, and PID-scoped bounce are deliberate safety boundaries: `daemon start` or `daemon stop` may reach the fleet service and are prohibited in this rig.\r\n\r\nThis is a second reason never to restart a wedged daemon merely to tidy the box before a run: that trades a known abnormality for an unmeasured one.\r\n\r\n## Windows ad-hoc rigs that outlive the tool call\r\n\r\n<!-- [doc->REQ-GATE-RIG-DETACHED-LAUNCH-DISCIPLINE] -->\r\n\r\nUse `Start-Process` with **`-WindowStyle Hidden -PassThru` and no\r\n`-RedirectStandardOutput` / `-RedirectStandardError`** when a Windows rig must\r\noutlive its invoking PowerShell tool call. Give the driver durable output paths\r","truncated":true,"truncatedBy":"lines","totalLines":139,"totalBytes":5982,"outputLines":64,"outputBytes":5982,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":163,"displayContent":{"text":"## Step timings leave as an artifact\n…\n\r\n## Shared-runner quiet-window predicate\r\n\r\n<!-- [doc->REQ-GOLDEN-CI-LANE] -->\r\n\r\nA shared box is quiet only when **both** conditions hold:\r\n\r\n1. zero non-terminal CI runs; and\r\n2. no local `cargo`, `rustc`, or `cargo-nextest` process alive on the box.\r\n\r\nA GitHub-only drain check reads clean while another agent is mid-local-build. That is the contention class that muddied the g6 evidence twice. These axes are proxies for contention, not a definition of quiet; a proxy returning “quiet” is not itself a measurement of quiet.\r\n\r\n### Queue status is not occupancy\r\n\r\n`gh run list` status is not an occupancy probe. A run can report `queued` while its job is already executing on the box; this was observed on #121/#122 with `Runner.Worker` and `cargo-nextest` live and a suite mid-flight. Therefore `queued` never means “not started,” and an idle-looking queue is not evidence of a deaf runner.\r\n\r\nThe authoritative occupancy signal is the process table. `Runner.Worker` means a job is running on this box. `cargo-nextest` means a suite is running, which is the seedmap-starvation collision.\r\n\r\n### Attribute process load before counting it\r\n\r\nThe two predicate axes are not independent: a CI job manifests in the local process table as `cargo` and `rustc`. Their presence does not imply a second occupant. Walk each PID's parent chain before counting it as new load:\r\n\r\n- a chain rooted at `Runner.Worker.exe`, `Runner.Listener.exe`, or `RunnerService.exe` is the CI axis already counted;\r\n- a chain rooted at a user shell is a genuine second occupant, so hold.\r\n\r\nOwner queries alone are insufficient. The runner service account can return empty owner and command-line fields; use the parent chain. Report attributed load, not bare process presence: “live local cargo” and “box free of a second occupant” can both be true.\r\n\r\n### The link is a third axis, and it is measured rather than assumed\r\n\r\n<!-- [doc->REQ-CI-LINK-HEALTH-PROBE] -->\r\n\r\nBoth axes above are process-shaped. A box can be quiet by both and still be a bad place to run a two-host rendezvous, because neither axis can see the link. Run 30771155390 is the specimen: zero non-terminal runs, no local build, and a link so degraded that a 1-second checkout took 321 seconds with bidirectional 10-second QUIC dial timeouts. Its `PUMP_PEER_FAIL` counts moved 0→3→0 on one host and 8→22→8 on the other across green/red/rerun, and the red was triaged as if it were a product failure because nothing in the run recorded what the network was doing.\r\n\r\nkitsubito's only link is wifi, indefinitely (operator-confirmed 2026-08-02). The link cannot be hardened, so the predicate has to see it.\r\n\r\nBoth two-host jobs therefore probe the peer immediately before rendezvous, via `.github/bench/link-probe.sh` (Linux) and `.github/bench/link-probe.ps1` (Windows), and each writes its result into the run's bench ledger. Read the probe's line like this:\r\n\r\n```\r\nLINK peer=kitsubito ip=100.98.197.12 path=direct samples=5/5 min=10ms med=15ms max=83ms rtts=10,12,15,81,83\r\n```\r\n\r\n- **`path=relay`** means tailscale fell back to DERP. That is a different network than the one the rig's timings were tuned on, and it is the first thing to check when a rendezvous is slow rather than broken.\r\n- **`samples=n/5` below full** is loss. A rendezvous over a lossy link produces timeouts that look exactly like a product wedge.\r\n- **`max` far above `med`** is jitter, and jitter is the failure shape here — the motivating run's link mostly worked. A median alone would have read healthy through it, which is why both numbers are carried: the ledger gets `link-rtt-med-<peer>` and `link-rtt-max-<peer>` rows, so the spread is a trend across runs and not one number in one log.\r\n- **`probe=NO-REPLY` or `probe=UNAVAILABLE`** is a labelled hole, not a silence. The `ok:false` row says a measurement was attempted and did not land, which is a different claim from a run that never probed.\r\n- **`ip=` must match that job's `SPT_TWO_HOST_PEER_IP`.** The probe names its peer and the rig addresses one; a disagreement means they are not talking about the same box.\r\n\r\nThe probe is an instrument, not a gate: it always exits 0, and no threshold refuses a rendezvous today. Whether a number should is a ruling nobody has made, and an instrument that reds a run converts \"the link was slow\" into \"the suite failed\" — the exact confusion it exists to remove.\r\n\r\n### Post-restart daemon churn is a known blind spot\r\n\r\nThe fleet daemon's own resume storm—reconnects, pulses, and disk I/O for minutes after restart—is real load that neither predicate axis sees. This is an existing 2026-07-27 g6 finding with an existing mitigation, not a new discovery: a timed-window run adjacent to a daemon restart records the fleet-`spt` CPU-seconds delta sampled before and after, so contention is measured rather than inferred. Recording a rediscovery as a discovery loses the mitigation someone already paid for.\r\n\r\nThe preserved instruments are `.github/ci/g6-postbounce.ps1`, for the immediate post-restart sample, and `.github/ci/g6-curve.ps1`, for the private-daemon age/CPU dose-response curve. Both require caller-supplied scratch and fixture-worktree paths; neither embeds an expired agent-session scratchpad. The curve's throwaway `SPT_HOME`, home-hashed IPC socket, `daemon run`, and PID-scoped bounce are deliberate safety boundaries: `daemon start` or `daemon stop` may reach the fleet service and are prohibited in this rig.\r\n\r\nThis is a second reason never to restart a wedged daemon merely to tidy the box before a run: that trades a known abnormality for an unmeasured one.\r\n\r\n## Windows ad-hoc rigs that outlive the tool call\r\n\r\n<!-- [doc->REQ-GATE-RIG-DETACHED-LAUNCH-DISCIPLINE] -->\r\n\r\nUse `Start-Process` with **`-WindowStyle Hidden -PassThru` and no\r\n`-RedirectStandardOutput` / `-RedirectStandardError`** when a Windows rig must\r\noutlive its invoking PowerShell tool call. Give the driver durable output paths\r\n…\nservice hosting, or product daemons.\n…\n","startLine":22,"lineNumbers":[22,null,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,null,91,null,125]},"fileSize":16315,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\GOLDEN-CI.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":163,"totalBytes":5982,"outputLines":64,"outputBytes":5982,"shownRange":{"start":25,"end":88},"nextOffset":89}}},"isError":false,"timestamp":1789483736211}}
{"type":"message","id":"21de4f5e","parentId":"29b226fe","timestamp":"2026-09-15T14:48:56.214Z","message":{"role":"toolResult","toolCallId":"call_pnCLQlvySNRAWVGozmIUYMEo|fc_000c7cef03cac861016aa95ad81b3487d19052aec29d0cf75b","toolName":"read","content":[{"type":"text","text":"//! `xtask disk-floor` — record free space at run start, and refuse a run that\n//! starts under the floor (IR-59, the log-the-floor half).\n//!\n//! WHY THIS EXISTS: a full volume reds as a LINKER defect that names no disk —\n//! `LINK: fatal error LNK1318: Unexpected PDB error` (the parenthesised code\n//! varies), beside `LNK4209: debugging information corrupt`, and once as a\n//! `traceable-reqs check` PANIC with `os error 112`. Nothing in any of those\n//! says \"disk\". Two agents spent hours on a mechanism for one of them and\n//! neither read free space; the falsifier was one command away throughout.\n//!\n//! WHY IT IS A VERB AND NOT A LINE IN A SCRIPT: the entry's remedy asks for the\n//! reading in \"the rig/gate preflight path\", and there is no such path in the\n//! tree to amend — the gate legs that hit this ran as PLAIN SCRIPTS, authored\n//! per run, which is the entry's own second face. There is nothing to add a\n//! line to, so the verb IS the template: one command a rig script calls at run\n//! start, carrying the floor with it.\n//!\n//! ITS OUTPUT SHAPE IS GOLDEN'S, DELIBERATELY. The golden runner's preflight\n//! step prints `disk preflight: drive=<d> free_bytes=<n> floor_bytes=<n>` and\n//! fails with `RESOURCE=disk drive=<d> free_bytes=<n> floor_bytes=<n>`; this\n//! verb prints the same keys so one grep reads local rig logs and CI logs\n//! alike. (Cited by text, not by line number — that step moves.)\n// [impl->REQ-DISK-FLOOR-PREFLIGHT]\n\nuse std::path::{Path, PathBuf};\n\n/// The golden runner's floor, in bytes: the observed tens-of-GB full-suite\n/// footprint rounded up. Kept as the default so a local rig and a golden leg\n/// refuse at the same number rather than at two numbers.\npub const DEFAULT_FLOOR_GIB: u64 = 32;\n\nconst GIB: u64 = 1024 * 1024 * 1024;\n\n/// The preflight line, in the golden runner's key shape.\n///\n/// It is printed on EVERY run, passing or not: the point of this half is that\n/// \"was the disk full\" stays answerable after the fact, and a reading that only\n/// appears on refusal leaves every red already in hand uninterpretable.\npub fn preflight_line(drive: &str, free_bytes: u64, floor_bytes: u64, label: Option<&str>) -> String {\n    let mut line =\n        format!(\"disk preflight: drive={drive} free_bytes={free_bytes} floor_bytes={floor_bytes}\");\n    if let Some(label) = label {\n        // Multi-lane boxes put several rigs' readings in one log; without this\n        // the readings are unattributable and read as one lane's history.\n        line.push_str(&format!(\" label={label}\"));\n    }\n    line\n}\n\n/// Whether a run may start.\n///\n/// A floor of ZERO is print-only mode and never refuses — for informational\n/// call sites that want the reading recorded without owning a refusal. The\n/// default floor still refuses, which is golden parity and the\n/// `GATE_ABORTED_DISK_FLOOR` precedent.\npub fn admits(free_bytes: u64, floor_bytes: u64) -> bool {\n    floor_bytes == 0 || free_bytes >= floor_bytes\n}\n\n/// `xtask disk-floor [--path <dir>] [--floor-gb <n>] [--label <lane>]`\n///\n/// EXIT: 0 when the run may start (always, under `--floor-gb 0`); 1 under the\n/// floor, with the golden runner's `RESOURCE=disk` diagnostic; 2 on usage.\npub fn disk_floor(args: &[String]) {\n    let path = flag(args, \"--path\")\n        .map(PathBuf::from)\n        .unwrap_or_else(|| std::env::current_dir().expect(\"cwd\"));\n    let floor_gib = match flag(args, \"--floor-gb\") {\n        Some(v) => match v.parse::<u64>() {\n            Ok(n) => n,\n            Err(_) => {\n                eprintln!(\"disk-floor: --floor-gb takes whole GiB, got {v}\");\n                std::process::exit(2);\n            }\n        },\n        None => DEFAULT_FLOOR_GIB,\n    };\n    let label = flag(args, \"--label\");\n\n    let free_bytes = match fs2::available_space(&path) {\n        Ok(n) => n,\n        Err(e) => {\n            eprintln!(\"disk-floor: cannot read free space at {}: {e}\", path.display());\n            std::process::exit(2);\n        }\n    };\n    let floor_bytes = floor_gib * GIB;\n    let drive = drive_of(&path);\n\n    println!(\n        \"{}\",\n        preflight_line(&drive, free_bytes, floor_bytes, label.as_deref())\n    );\n    // IR-46: one reading is an INSTANT, not headroom. A cold build's danger\n    // window is its TAIL — the 2026-08-22 instance died linking the last and\n    // largest artifact of a 74 GB pool while that same build drained the volume\n    // out from under itself, and a reading taken before it looked fine.\n    if !admits(free_bytes, floor_bytes) {\n        eprintln!(\n            \"RESOURCE=disk drive={drive} free_bytes={free_bytes} floor_bytes={floor_bytes} — this run starts under the floor; reds it produces are uninterpretable and must be re-run, not re-read\"\n        );\n        std::process::exit(1);\n    }\n}\n\n/// The volume a path sits on, for the `drive=` field: the Windows drive\n/// (`C:\\`) or the POSIX root, whichever this platform gives.\n///\n\n[Showing lines 1-108 of 211. Use :109 to continue]"}],"details":{"truncation":{"content":"//! `xtask disk-floor` — record free space at run start, and refuse a run that\r\n//! starts under the floor (IR-59, the log-the-floor half).\r\n//!\r\n//! WHY THIS EXISTS: a full volume reds as a LINKER defect that names no disk —\r\n//! `LINK: fatal error LNK1318: Unexpected PDB error` (the parenthesised code\r\n//! varies), beside `LNK4209: debugging information corrupt`, and once as a\r\n//! `traceable-reqs check` PANIC with `os error 112`. Nothing in any of those\r\n//! says \"disk\". Two agents spent hours on a mechanism for one of them and\r\n//! neither read free space; the falsifier was one command away throughout.\r\n//!\r\n//! WHY IT IS A VERB AND NOT A LINE IN A SCRIPT: the entry's remedy asks for the\r\n//! reading in \"the rig/gate preflight path\", and there is no such path in the\r\n//! tree to amend — the gate legs that hit this ran as PLAIN SCRIPTS, authored\r\n//! per run, which is the entry's own second face. There is nothing to add a\r\n//! line to, so the verb IS the template: one command a rig script calls at run\r\n//! start, carrying the floor with it.\r\n//!\r\n//! ITS OUTPUT SHAPE IS GOLDEN'S, DELIBERATELY. The golden runner's preflight\r\n//! step prints `disk preflight: drive=<d> free_bytes=<n> floor_bytes=<n>` and\r\n//! fails with `RESOURCE=disk drive=<d> free_bytes=<n> floor_bytes=<n>`; this\r\n//! verb prints the same keys so one grep reads local rig logs and CI logs\r\n//! alike. (Cited by text, not by line number — that step moves.)\r\n// [impl->REQ-DISK-FLOOR-PREFLIGHT]\r\n\r\nuse std::path::{Path, PathBuf};\r\n\r\n/// The golden runner's floor, in bytes: the observed tens-of-GB full-suite\r\n/// footprint rounded up. Kept as the default so a local rig and a golden leg\r\n/// refuse at the same number rather than at two numbers.\r\npub const DEFAULT_FLOOR_GIB: u64 = 32;\r\n\r\nconst GIB: u64 = 1024 * 1024 * 1024;\r\n\r\n/// The preflight line, in the golden runner's key shape.\r\n///\r\n/// It is printed on EVERY run, passing or not: the point of this half is that\r\n/// \"was the disk full\" stays answerable after the fact, and a reading that only\r\n/// appears on refusal leaves every red already in hand uninterpretable.\r\npub fn preflight_line(drive: &str, free_bytes: u64, floor_bytes: u64, label: Option<&str>) -> String {\r\n    let mut line =\r\n        format!(\"disk preflight: drive={drive} free_bytes={free_bytes} floor_bytes={floor_bytes}\");\r\n    if let Some(label) = label {\r\n        // Multi-lane boxes put several rigs' readings in one log; without this\r\n        // the readings are unattributable and read as one lane's history.\r\n        line.push_str(&format!(\" label={label}\"));\r\n    }\r\n    line\r\n}\r\n\r\n/// Whether a run may start.\r\n///\r\n/// A floor of ZERO is print-only mode and never refuses — for informational\r\n/// call sites that want the reading recorded without owning a refusal. The\r\n/// default floor still refuses, which is golden parity and the\r\n/// `GATE_ABORTED_DISK_FLOOR` precedent.\r\npub fn admits(free_bytes: u64, floor_bytes: u64) -> bool {\r\n    floor_bytes == 0 || free_bytes >= floor_bytes\r\n}\r\n\r\n/// `xtask disk-floor [--path <dir>] [--floor-gb <n>] [--label <lane>]`\r\n///\r\n/// EXIT: 0 when the run may start (always, under `--floor-gb 0`); 1 under the\r\n/// floor, with the golden runner's `RESOURCE=disk` diagnostic; 2 on usage.\r\npub fn disk_floor(args: &[String]) {\r\n    let path = flag(args, \"--path\")\r\n        .map(PathBuf::from)\r\n        .unwrap_or_else(|| std::env::current_dir().expect(\"cwd\"));\r\n    let floor_gib = match flag(args, \"--floor-gb\") {\r\n        Some(v) => match v.parse::<u64>() {\r\n            Ok(n) => n,\r\n            Err(_) => {\r\n                eprintln!(\"disk-floor: --floor-gb takes whole GiB, got {v}\");\r\n                std::process::exit(2);\r\n            }\r\n        },\r\n        None => DEFAULT_FLOOR_GIB,\r\n    };\r\n    let label = flag(args, \"--label\");\r\n\r\n    let free_bytes = match fs2::available_space(&path) {\r\n        Ok(n) => n,\r\n        Err(e) => {\r\n            eprintln!(\"disk-floor: cannot read free space at {}: {e}\", path.display());\r\n            std::process::exit(2);\r\n        }\r\n    };\r\n    let floor_bytes = floor_gib * GIB;\r\n    let drive = drive_of(&path);\r\n\r\n    println!(\r\n        \"{}\",\r\n        preflight_line(&drive, free_bytes, floor_bytes, label.as_deref())\r\n    );\r\n    // IR-46: one reading is an INSTANT, not headroom. A cold build's danger\r\n    // window is its TAIL — the 2026-08-22 instance died linking the last and\r\n    // largest artifact of a 74 GB pool while that same build drained the volume\r\n    // out from under itself, and a reading taken before it looked fine.\r\n    if !admits(free_bytes, floor_bytes) {\r\n        eprintln!(\r\n            \"RESOURCE=disk drive={drive} free_bytes={free_bytes} floor_bytes={floor_bytes} — this run starts under the floor; reds it produces are uninterpretable and must be re-run, not re-read\"\r\n        );\r\n        std::process::exit(1);\r\n    }\r\n}\r\n\r\n/// The volume a path sits on, for the `drive=` field: the Windows drive\r\n/// (`C:\\`) or the POSIX root, whichever this platform gives.\r\n///\r","truncated":true,"truncatedBy":"lines","totalLines":211,"totalBytes":5026,"outputLines":108,"outputBytes":5026,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":211,"displayContent":{"text":"//! `xtask disk-floor` — record free space at run start, and refuse a run that\r\n//! starts under the floor (IR-59, the log-the-floor half).\r\n//!\r\n//! WHY THIS EXISTS: a full volume reds as a LINKER defect that names no disk —\r\n//! `LINK: fatal error LNK1318: Unexpected PDB error` (the parenthesised code\r\n//! varies), beside `LNK4209: debugging information corrupt`, and once as a\r\n//! `traceable-reqs check` PANIC with `os error 112`. Nothing in any of those\r\n//! says \"disk\". Two agents spent hours on a mechanism for one of them and\r\n//! neither read free space; the falsifier was one command away throughout.\r\n//!\r\n//! WHY IT IS A VERB AND NOT A LINE IN A SCRIPT: the entry's remedy asks for the\r\n//! reading in \"the rig/gate preflight path\", and there is no such path in the\r\n//! tree to amend — the gate legs that hit this ran as PLAIN SCRIPTS, authored\r\n//! per run, which is the entry's own second face. There is nothing to add a\r\n//! line to, so the verb IS the template: one command a rig script calls at run\r\n//! start, carrying the floor with it.\r\n//!\r\n//! ITS OUTPUT SHAPE IS GOLDEN'S, DELIBERATELY. The golden runner's preflight\r\n//! step prints `disk preflight: drive=<d> free_bytes=<n> floor_bytes=<n>` and\r\n//! fails with `RESOURCE=disk drive=<d> free_bytes=<n> floor_bytes=<n>`; this\r\n//! verb prints the same keys so one grep reads local rig logs and CI logs\r\n//! alike. (Cited by text, not by line number — that step moves.)\r\n// [impl->REQ-DISK-FLOOR-PREFLIGHT]\r\n\r\nuse std::path::{Path, PathBuf};\r\n\r\n/// The golden runner's floor, in bytes: the observed tens-of-GB full-suite\r\n/// footprint rounded up. Kept as the default so a local rig and a golden leg\r\n/// refuse at the same number rather than at two numbers.\r\npub const DEFAULT_FLOOR_GIB: u64 = 32;\r\n\r\nconst GIB: u64 = 1024 * 1024 * 1024;\r\n\r\n/// The preflight line, in the golden runner's key shape.\r\n///\r\n/// It is printed on EVERY run, passing or not: the point of this half is that\r\n/// \"was the disk full\" stays answerable after the fact, and a reading that only\r\n/// appears on refusal leaves every red already in hand uninterpretable.\r\npub fn preflight_line(drive: &str, free_bytes: u64, floor_bytes: u64, label: Option<&str>) -> String {\r\n    let mut line =\r\n        format!(\"disk preflight: drive={drive} free_bytes={free_bytes} floor_bytes={floor_bytes}\");\r\n    if let Some(label) = label {\r\n        // Multi-lane boxes put several rigs' readings in one log; without this\r\n        // the readings are unattributable and read as one lane's history.\r\n        line.push_str(&format!(\" label={label}\"));\r\n    }\r\n    line\r\n}\r\n\r\n/// Whether a run may start.\r\n///\r\n/// A floor of ZERO is print-only mode and never refuses — for informational\r\n/// call sites that want the reading recorded without owning a refusal. The\r\n/// default floor still refuses, which is golden parity and the\r\n/// `GATE_ABORTED_DISK_FLOOR` precedent.\r\npub fn admits(free_bytes: u64, floor_bytes: u64) -> bool {\r\n    floor_bytes == 0 || free_bytes >= floor_bytes\r\n}\r\n\r\n/// `xtask disk-floor [--path <dir>] [--floor-gb <n>] [--label <lane>]`\r\n///\r\n/// EXIT: 0 when the run may start (always, under `--floor-gb 0`); 1 under the\r\n/// floor, with the golden runner's `RESOURCE=disk` diagnostic; 2 on usage.\r\npub fn disk_floor(args: &[String]) {\r\n    let path = flag(args, \"--path\")\r\n        .map(PathBuf::from)\r\n        .unwrap_or_else(|| std::env::current_dir().expect(\"cwd\"));\r\n    let floor_gib = match flag(args, \"--floor-gb\") {\r\n        Some(v) => match v.parse::<u64>() {\r\n            Ok(n) => n,\r\n            Err(_) => {\r\n                eprintln!(\"disk-floor: --floor-gb takes whole GiB, got {v}\");\r\n                std::process::exit(2);\r\n            }\r\n        },\r\n        None => DEFAULT_FLOOR_GIB,\r\n    };\r\n    let label = flag(args, \"--label\");\r\n\r\n    let free_bytes = match fs2::available_space(&path) {\r\n        Ok(n) => n,\r\n        Err(e) => {\r\n            eprintln!(\"disk-floor: cannot read free space at {}: {e}\", path.display());\r\n            std::process::exit(2);\r\n        }\r\n    };\r\n    let floor_bytes = floor_gib * GIB;\r\n    let drive = drive_of(&path);\r\n\r\n    println!(\r\n        \"{}\",\r\n        preflight_line(&drive, free_bytes, floor_bytes, label.as_deref())\r\n    );\r\n    // IR-46: one reading is an INSTANT, not headroom. A cold build's danger\r\n    // window is its TAIL — the 2026-08-22 instance died linking the last and\r\n    // largest artifact of a 74 GB pool while that same build drained the volume\r\n    // out from under itself, and a reading taken before it looked fine.\r\n    if !admits(free_bytes, floor_bytes) {\r\n        eprintln!(\r\n            \"RESOURCE=disk drive={drive} free_bytes={free_bytes} floor_bytes={floor_bytes} — this run starts under the floor; reds it produces are uninterpretable and must be re-run, not re-read\"\r\n        );\r\n        std::process::exit(1);\r\n    }\r\n}\r\n\r\n/// The volume a path sits on, for the `drive=` field: the Windows drive\r\n/// (`C:\\`) or the POSIX root, whichever this platform gives.\r\n///\r","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108]},"fileSize":9437,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\crates\\xtask\\src\\diskfloor.rs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":211,"totalBytes":5026,"outputLines":108,"outputBytes":5026,"shownRange":{"start":1,"end":108},"nextOffset":109}}},"isError":false,"timestamp":1789483736214}}
{"type":"message","id":"91c30985","parentId":"21de4f5e","timestamp":"2026-09-15T14:48:56.216Z","message":{"role":"toolResult","toolCallId":"call_nFoNv8zrzhtHjqBnNgdnSZNP|fc_000c7cef03cac861016aa95ad81b5887d1b64780f9a0b8e70e","toolName":"grep","content":[{"type":"text","text":" 50|  IR-85/95/96 are scoped diagnostic continuation, NOT budget widening or a load/disk diagnosis.\n*51|  Todlando owns product-side IR-81/82/92 composition; #285's completion did not build IR-82's\n 52|  predecessor record. Both builders are offline: existing briefs are delivered, unacknowledged,\n 53|  and **not executing**. No board mutation or new run authorization is implied.\n 54|- **Small seam riders remain explicit:** next tooling intake weighs IR-5/6/10/11/32/37/47/58/94"}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md","searchPath":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core","matchCount":1,"fileCount":1,"files":[".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md"],"fileMatches":[{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md","count":1}],"truncated":false,"displayContent":" 50│  IR-85/95/96 are scoped diagnostic continuation, NOT budget widening or a load/disk diagnosis.\n*51│  Todlando owns product-side IR-81/82/92 composition; #285's completion did not build IR-82's\n 52│  predecessor record. Both builders are offline: existing briefs are delivered, unacknowledged,\n 53│  and **not executing**. No board mutation or new run authorization is implied.\n 54│- **Small seam riders remain explicit:** next tooling intake weighs IR-5/6/10/11/32/37/47/58/94"},"isError":false,"timestamp":1789483736215}}
{"type":"message","id":"2c496d1b","parentId":"91c30985","timestamp":"2026-09-15T14:48:56.237Z","message":{"role":"toolResult","toolCallId":"call_eSJjaOjRS6EBKgWPWeZqMDVN|fc_000c7cef03cac861016aa95ad81b4487d1a48ceb1f04af34b7","toolName":"grep","content":[{"type":"text","text":"# .worktrees/hertz-ir86-disk-delta/\n## AGENTS.md\n 39|<!-- [doc->REQ-POOL-FOREIGN-TREE-REFUSED] -->\n*40|- **Build-cache pools (binding, releases#103):** a cargo `target/` directory belongs to ONE source tree. Two trees building into one pool overwrite each other's artifacts and fabricate reds that belong to neither — the v0.51.0 W1/H1 `E0308` that vanished on re-run. **The rule is about the RELATIONSHIP, not the path:** a junction and a `CARGO_TARGET_DIR` env var reach the same hazard, and the env var leaves no directory entry to notice afterwards, so \"is this dir under `.worktrees/`\" never was the quest...\n 41|- **Target-tree teardown (releases#103, same lane):** never delete a `target/` you have not classified. Check OUTBOUND first (`Get-Item -Force`: a junction is deleted as a link, a real dir as a tree), then sweep INBOUND for reparse points aimed at it before removing a real one, and measure size and free space before and after so the reclaim is a number rather than a claim. Reap the target SUBTREE, never a session or worktree directory around it. Do not point `CARGO_TARGET_DIR` into a scratchpad (v0.50.0 ...\n 42|- **CI / merge strategy:** golden CI (ADR-0050, ruled 2026-07-27) — milestone-batch golden runs, thin-lane PRs, ff-only main (tested sha == merged sha). Piloting from the next milestone; read the ADR before shaping a PR lane.\n 43|\n\n## .github/ci/\n### local-lane.py\n 10|Requires the gater's --hold-released acknowledgement. Reuses ws272-w0's quiet\n*11|meter, lane lock, identity scrub and disk-floor meter. Volume movement is aggregate\n*12|capacity evidence, NOT attribution to this lane. Census has the existing reaper's\n 13|explicit scope; an unavailable/incomplete census is never clearance.\n 14|\"\"\"\n 15|import argparse\n...\n 97|def observe_after(root, output, name, env, meter):\n*98|    \"\"\"An unavailable disk observation must not prevent the independent reaper.\"\"\"\n 99|    disk_ok = builders_ok = clear = False\n 100|    try:\n 101|        disk_ok = meter(name + \"-after-producer\")\n...\n 136|    clear = census_clear(raw, code)\n*137|    print(f\"LANE_CENSUS name={name} clear={str(clear).lower()} scope=existing-reaper\", flush=True)\n 138|    return clear\n 139|\n 140|\n...\n 263|            \"cleanup_errors\": cleanup_errors, \"survivors\": survivors,\n*264|            \"scope\": \"sampled-descendants; post-leg reaper census is separate\"})\n 265|    except OSError as error:\n 266|        reason = f\"artifact-write-failed: {error}\"\n 267|        print(reason, file=sys.stderr)\n...\n 283|        raise ValueError(\"plan requires nonempty steps\")\n*284|    names = {\"pool-claim\", \"pool-release\", \"before\", \"start\", \"lane\", \"plan\",\n 285|             \"toolchain\", \"environment-scrub\", \"builders-before\", \"capacity\"}\n 286|    for step in plan[\"steps\"]:\n 287|        if not isinstance(step, dict):\n...\n 405|            try:\n*406|                released = subprocess.run([str(xtask), \"pool-release\", \"--pool\", str(target)], cwd=root, env=env, capture_output=True, text=True, timeout=30)\n*407|                save(output / \"pool-release.json\", {\"exit\": released.returncode, \"stdout\": released.stdout, \"stderr\": released.stderr})\n 408|                result = final_status(result, released.returncode == 0)\n 409|            except (OSError, subprocess.TimeoutExpired) as error:\n 410|                print(f\"POOL_RELEASE_UNPROVEN: {error}\", file=sys.stderr)\n### reaper-breadcrumb-census.ps1\n 30|.EXAMPLE\n*31|  pwsh -File .github/ci/reaper-breadcrumb-census.ps1 -Ref origin/main\n 32|#>\n 33|[CmdletBinding()]\n 34|param(\n...\n 49|    # A TIER-1 member is AUTH when every kill linked to the breadcrumb goes\n*50|    # through the shared authenticated reaper, RAW when any linked kill is a bare\n 51|    # `taskkill`/`kill`/local helper. RAW is the exposed set; the tier alone does\n 52|    # not say that, because a fixed file still kills a breadcrumb-derived pid.\n 53|    AUTH             = 'reap::authenticated_kill|reap::reap_breadcrumb_daemon'\n...\n 66|\n*67|Write-Output \"CENSUS_TOOL=reaper-breadcrumb-census.ps1\"\n 68|Write-Output \"CENSUS_TOOL_VERSION=$ToolVersion\"\n 69|Write-Output \"CENSUS_RUNTIME=PowerShell/$($PSVersionTable.PSVersion) $((git --version))\"\n 70|Write-Output \"CENSUS_REF=$Ref\"\n### ws272-w0.py\n 38|ACTIVE_STATES = (\"in_progress\", \"queued\", \"waiting\", \"pending\", \"requested\")\n*39|# The same floor xtask disk-floor enforces (32 GiB); the bootstrap reading\n 40|# below must never be more lenient than the meter it stands in for.\n 41|FLOOR_BYTES = 32 << 30\n 42|# The perch identity a live agent's shell carries. A battery must never look\n...\n 161|\n*162|# [impl->REQ-DISK-FLOOR-PREFLIGHT]\n 163|def floor_verdict(raw, code):\n 164|    \"\"\"Render GiB from xtask's own byte reading, never a second disk probe.\"\"\"\n 165|    fields = dict(re.findall(r\"\\b(free_bytes|floor_bytes)=(\\d+)\", raw))\n...\n 198|            result = subprocess.run(\n*199|                [str(xtask), \"disk-floor\", \"--path\", str(root), \"--label\", \"ws272-w0\"],\n 200|                cwd=root, capture_output=True, text=True,\n 201|            )\n 202|            raw, code = result.stdout + result.stderr, result.returncode\n...\n 279|    parser.add_argument(\"--xtask\", type=Path,\n*280|                        help=\"prebuilt disk-floor meter; defaults to this lane's debug xtask\")\n 281|    args = parser.parse_args()\n 282|    if args.self_test:\n 283|        self_test()\n### ws272-w1.py\n 44|ACTIVE_STATES = (\"in_progress\", \"queued\", \"waiting\", \"pending\", \"requested\")\n*45|# The same floor xtask disk-floor enforces (32 GiB); the bootstrap reading\n 46|# below must never be more lenient than the meter it stands in for.\n 47|FLOOR_BYTES = 32 << 30\n 48|# The perch identity a live agent's shell carries. A battery must never look\n...\n 167|\n*168|# [impl->REQ-DISK-FLOOR-PREFLIGHT]\n 169|def floor_verdict(raw, code):\n 170|    \"\"\"Render GiB from xtask's own byte reading, never a second disk probe.\"\"\"\n 171|    fields = dict(re.findall(r\"\\b(free_bytes|floor_bytes)=(\\d+)\", raw))\n...\n 204|            result = subprocess.run(\n*205|                [str(xtask), \"disk-floor\", \"--path\", str(root), \"--label\", \"ws272-w1\"],\n 206|                cwd=root, capture_output=True, text=True,\n 207|            )\n 208|            raw, code = result.stdout + result.stderr, result.returncode\n...\n 285|    parser.add_argument(\"--xtask\", type=Path,\n*286|                        help=\"prebuilt disk-floor meter; defaults to this lane's debug xtask\")\n 287|    args = parser.parse_args()\n 288|    if args.self_test:\n 289|        self_test()\n### ws272-w2.py\n 51|ACTIVE_STATES = (\"in_progress\", \"queued\", \"waiting\", \"pending\", \"requested\")\n*52|# The same floor xtask disk-floor enforces (32 GiB); the bootstrap reading\n 53|# below must never be more lenient than the meter it stands in for.\n 54|FLOOR_BYTES = 32 << 30\n 55|# The perch identity a live agent's shell carries. A battery must never look\n...\n 174|\n*175|# [impl->REQ-DISK-FLOOR-PREFLIGHT]\n 176|def floor_verdict(raw, code):\n 177|    \"\"\"Render GiB from xtask's own byte reading, never a second disk probe.\"\"\"\n 178|    fields = dict(re.findall(r\"\\b(free_bytes|floor_bytes)=(\\d+)\", raw))\n...\n 211|            result = subprocess.run(\n*212|                [str(xtask), \"disk-floor\", \"--path\", str(root), \"--label\", \"ws272-w2\"],\n 213|                cwd=root, capture_output=True, text=True,\n 214|            )\n 215|            raw, code = result.stdout + result.stderr, result.returncode\n...\n 338|    parser.add_argument(\"--xtask\", type=Path,\n*339|                        help=\"prebuilt disk-floor meter; defaults to this lane's debug xtask\")\n 340|    args = parser.parse_args()\n 341|    if args.self_test:\n 342|        self_test()\n\n## crates/spt/tests/common/\n### mod.rs\n 15|\n*16|/// The authenticated breadcrumb reaper (`common::reap`) — every test that cleans\n 17|/// up a daemon/brain by its on-disk pid breadcrumb kills through it, so a freed\n 18|/// or recycled pid is refused instead of tree-killed.\n 19|pub mod reap;\n### reap.rs\n*1|//! The AUTHENTICATED breadcrumb reaper shared by the `spt` integration tests.\n 2|//!\n 3|//! An on-disk pid breadcrumb (`<SPT_HOME>/daemon.pid`, the `pid` field of\n 4|//! `brain.ready`) is a NUMBER, not an identity. The process that wrote it exits;\n\n[Some lines truncated to 512 chars]"}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/.github/ci, .worktrees/hertz-ir86-disk-delta/crates/spt/tests/common, .worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md, .worktrees/hertz-ir86-disk-delta/AGENTS.md, .worktrees/hertz-ir86-disk-delta/crates/spt/tests/projindex_writer_e2e.rs","searchPath":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core","matchCount":26,"fileCount":8,"files":[".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py",".worktrees/hertz-ir86-disk-delta/.github/ci/reaper-breadcrumb-census.ps1",".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w0.py",".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w1.py",".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w2.py",".worktrees/hertz-ir86-disk-delta/crates/spt/tests/common/mod.rs",".worktrees/hertz-ir86-disk-delta/crates/spt/tests/common/reap.rs",".worktrees/hertz-ir86-disk-delta/AGENTS.md"],"fileMatches":[{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py","count":8},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/reaper-breadcrumb-census.ps1","count":3},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w0.py","count":4},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w1.py","count":4},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/ws272-w2.py","count":4},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt/tests/common/mod.rs","count":1},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt/tests/common/reap.rs","count":1},{"path":".worktrees/hertz-ir86-disk-delta/AGENTS.md","count":1}],"truncated":true,"displayContent":"# .worktrees/hertz-ir86-disk-delta/\n## AGENTS.md\n 39│<!-- [doc->REQ-POOL-FOREIGN-TREE-REFUSED] -->\n*40│- **Build-cache pools (binding, releases#103):** a cargo `target/` directory belongs to ONE source tree. Two trees building into one pool overwrite each other's artifacts and fabricate reds that belong to neither — the v0.51.0 W1/H1 `E0308` that vanished on re-run. **The rule is about the RELATIONSHIP, not the path:** a junction and a `CARGO_TARGET_DIR` env var reach the same hazard, and the env var leaves no directory entry to notice afterwards, so \"is this dir under `.worktrees/`\" never was the quest...\n 41│- **Target-tree teardown (releases#103, same lane):** never delete a `target/` you have not classified. Check OUTBOUND first (`Get-Item -Force`: a junction is deleted as a link, a real dir as a tree), then sweep INBOUND for reparse points aimed at it before removing a real one, and measure size and free space before and after so the reclaim is a number rather than a claim. Reap the target SUBTREE, never a session or worktree directory around it. Do not point `CARGO_TARGET_DIR` into a scratchpad (v0.50.0 ...\n 42│- **CI / merge strategy:** golden CI (ADR-0050, ruled 2026-07-27) — milestone-batch golden runs, thin-lane PRs, ff-only main (tested sha == merged sha). Piloting from the next milestone; read the ADR before shaping a PR lane.\n 43│\n\n## .github/ci/\n### local-lane.py\n  10│Requires the gater's --hold-released acknowledgement. Reuses ws272-w0's quiet\n *11│meter, lane lock, identity scrub and disk-floor meter. Volume movement is aggregate\n *12│capacity evidence, NOT attribution to this lane. Census has the existing reaper's\n  13│explicit scope; an unavailable/incomplete census is never clearance.\n  14│\"\"\"\n  15│import argparse\n    │...\n  97│def observe_after(root, output, name, env, meter):\n *98│    \"\"\"An unavailable disk observation must not prevent the independent reaper.\"\"\"\n  99│    disk_ok = builders_ok = clear = False\n 100│    try:\n 101│        disk_ok = meter(name + \"-after-producer\")\n    │...\n 136│    clear = census_clear(raw, code)\n*137│    print(f\"LANE_CENSUS name={name} clear={str(clear).lower()} scope=existing-reaper\", flush=True)\n 138│    return clear\n 139│\n 140│\n    │...\n 263│            \"cleanup_errors\": cleanup_errors, \"survivors\": survivors,\n*264│            \"scope\": \"sampled-descendants; post-leg reaper census is separate\"})\n 265│    except OSError as error:\n 266│        reason = f\"artifact-write-failed: {error}\"\n 267│        print(reason, file=sys.stderr)\n    │...\n 283│        raise ValueError(\"plan requires nonempty steps\")\n*284│    names = {\"pool-claim\", \"pool-release\", \"before\", \"start\", \"lane\", \"plan\",\n 285│             \"toolchain\", \"environment-scrub\", \"builders-before\", \"capacity\"}\n 286│    for step in plan[\"steps\"]:\n 287│        if not isinstance(step, dict):\n    │...\n 405│            try:\n*406│                released = subprocess.run([str(xtask), \"pool-release\", \"--pool\", str(target)], cwd=root, env=env, capture_output=True, text=True, timeout=30)\n*407│                save(output / \"pool-release.json\", {\"exit\": released.returncode, \"stdout\": released.stdout, \"stderr\": released.stderr})\n 408│                result = final_status(result, released.returncode == 0)\n 409│            except (OSError, subprocess.TimeoutExpired) as error:\n 410│                print(f\"POOL_RELEASE_UNPROVEN: {error}\", file=sys.stderr)\n### reaper-breadcrumb-census.ps1\n 30│.EXAMPLE\n*31│  pwsh -File .github/ci/reaper-breadcrumb-census.ps1 -Ref origin/main\n 32│#>\n 33│[CmdletBinding()]\n 34│param(\n   │...\n 49│    # A TIER-1 member is AUTH when every kill linked to the breadcrumb goes\n*50│    # through the shared authenticated reaper, RAW when any linked kill is a bare\n 51│    # `taskkill`/`kill`/local helper. RAW is the exposed set; the tier alone does\n 52│    # not say that, because a fixed file still kills a breadcrumb-derived pid.\n 53│    AUTH             = 'reap::authenticated_kill|reap::reap_breadcrumb_daemon'\n   │...\n 66│\n*67│Write-Output \"CENSUS_TOOL=reaper-breadcrumb-census.ps1\"\n 68│Write-Output \"CENSUS_TOOL_VERSION=$ToolVersion\"\n 69│Write-Output \"CENSUS_RUNTIME=PowerShell/$($PSVersionTable.PSVersion) $((git --version))\"\n 70│Write-Output \"CENSUS_REF=$Ref\"\n### ws272-w0.py\n  38│ACTIVE_STATES = (\"in_progress\", \"queued\", \"waiting\", \"pending\", \"requested\")\n *39│# The same floor xtask disk-floor enforces (32 GiB); the bootstrap reading\n  40│# below must never be more lenient than the meter it stands in for.\n  41│FLOOR_BYTES = 32 << 30\n  42│# The perch identity a live agent's shell carries. A battery must never look\n    │...\n 161│\n*162│# [impl->REQ-DISK-FLOOR-PREFLIGHT]\n 163│def floor_verdict(raw, code):\n 164│    \"\"\"Render GiB from xtask's own byte reading, never a second disk probe.\"\"\"\n 165│    fields = dict(re.findall(r\"\\b(free_bytes|floor_bytes)=(\\d+)\", raw))\n    │...\n 198│            result = subprocess.run(\n*199│                [str(xtask), \"disk-floor\", \"--path\", str(root), \"--label\", \"ws272-w0\"],\n 200│                cwd=root, capture_output=True, text=True,\n 201│            )\n 202│            raw, code = result.stdout + result.stderr, result.returncode\n    │...\n 279│    parser.add_argument(\"--xtask\", type=Path,\n*280│                        help=\"prebuilt disk-floor meter; defaults to this lane's debug xtask\")\n 281│    args = parser.parse_args()\n 282│    if args.self_test:\n 283│        self_test()\n### ws272-w1.py\n  44│ACTIVE_STATES = (\"in_progress\", \"queued\", \"waiting\", \"pending\", \"requested\")\n *45│# The same floor xtask disk-floor enforces (32 GiB); the bootstrap reading\n  46│# below must never be more lenient than the meter it stands in for.\n  47│FLOOR_BYTES = 32 << 30\n  48│# The perch identity a live agent's shell carries. A battery must never look\n    │...\n 167│\n*168│# [impl->REQ-DISK-FLOOR-PREFLIGHT]\n 169│def floor_verdict(raw, code):\n 170│    \"\"\"Render GiB from xtask's own byte reading, never a second disk probe.\"\"\"\n 171│    fields = dict(re.findall(r\"\\b(free_bytes|floor_bytes)=(\\d+)\", raw))\n    │...\n 204│            result = subprocess.run(\n*205│                [str(xtask), \"disk-floor\", \"--path\", str(root), \"--label\", \"ws272-w1\"],\n 206│                cwd=root, capture_output=True, text=True,\n 207│            )\n 208│            raw, code = result.stdout + result.stderr, result.returncode\n    │...\n 285│    parser.add_argument(\"--xtask\", type=Path,\n*286│                        help=\"prebuilt disk-floor meter; defaults to this lane's debug xtask\")\n 287│    args = parser.parse_args()\n 288│    if args.self_test:\n 289│        self_test()\n### ws272-w2.py\n  51│ACTIVE_STATES = (\"in_progress\", \"queued\", \"waiting\", \"pending\", \"requested\")\n *52│# The same floor xtask disk-floor enforces (32 GiB); the bootstrap reading\n  53│# below must never be more lenient than the meter it stands in for.\n  54│FLOOR_BYTES = 32 << 30\n  55│# The perch identity a live agent's shell carries. A battery must never look\n    │...\n 174│\n*175│# [impl->REQ-DISK-FLOOR-PREFLIGHT]\n 176│def floor_verdict(raw, code):\n 177│    \"\"\"Render GiB from xtask's own byte reading, never a second disk probe.\"\"\"\n 178│    fields = dict(re.findall(r\"\\b(free_bytes|floor_bytes)=(\\d+)\", raw))\n    │...\n 211│            result = subprocess.run(\n*212│                [str(xtask), \"disk-floor\", \"--path\", str(root), \"--label\", \"ws272-w2\"],\n 213│                cwd=root, capture_output=True, text=True,\n 214│            )\n 215│            raw, code = result.stdout + result.stderr, result.returncode\n    │...\n 338│    parser.add_argument(\"--xtask\", type=Path,\n*339│                        help=\"prebuilt disk-floor meter; defaults to this lane's debug xtask\")\n 340│    args = parser.parse_args()\n 341│    if args.self_test:\n 342│        self_test()\n\n## crates/spt/tests/common/\n### mod.rs\n 15│\n*16│/// The authenticated breadcrumb reaper (`common::reap`) — every test that cleans\n 17│/// up a daemon/brain by its on-disk pid breadcrumb kills through it, so a freed\n 18│/// or recycled pid is refused instead of tree-killed.\n 19│pub mod reap;\n### reap.rs\n*1│//! The AUTHENTICATED breadcrumb reaper shared by the `spt` integration tests.\n 2│//!\n 3│//! An on-disk pid breadcrumb (`<SPT_HOME>/daemon.pid`, the `pid` field of\n 4│//! `brain.ready`) is a NUMBER, not an identity. The process that wrote it exits;","linesTruncated":true,"meta":{"limits":{"columnTruncated":{"maxColumn":512}}}},"isError":false,"timestamp":1789483736237}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_RUQAXfBjPnV1INLph0xhaIJa|fc_000c7cef03cac861016aa95ae3e3d087d18c64a2dfc907eea0","toolName":"read","startedAt":"2026-09-15T14:49:07.959Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:1-73:raw"},"intent":"Reading present sweep rulings"},"id":"20fa5f6c","parentId":"2c496d1b","timestamp":"2026-09-15T14:49:07.959Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_zEXFwESrtfpBOQukzVmbY14n|fc_000c7cef03cac861016aa95ae3e3e087d19baee385c7d2545d","toolName":"grep","startedAt":"2026-09-15T14:49:07.959Z","args":{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py"},"intent":"Checking runner output encoding"},"id":"89c2769b","parentId":"20fa5f6c","timestamp":"2026-09-15T14:49:07.959Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_T9CXtsYjnGboTR5fqDSE539b|fc_000c7cef03cac861016aa95ae3e3e887d1a77c5ad1a3bafa95","toolName":"grep","startedAt":"2026-09-15T14:49:07.960Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-store/src/proc.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.r…"},"intent":"Checking source residual anchors"},"id":"0013b2d8","parentId":"89c2769b","timestamp":"2026-09-15T14:49:07.960Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_ZywYtTguOUFa0Wh2mjdUkPzO|fc_000c7cef03cac861016aa95ae3e3ec87d1a14fa8d859a628fd","toolName":"read","startedAt":"2026-09-15T14:49:07.960Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs:175-230"},"intent":"Reading failure context source"},"id":"68ba0d8b","parentId":"0013b2d8","timestamp":"2026-09-15T14:49:07.960Z"}
{"type":"message","id":"cb27d754","parentId":"68ba0d8b","timestamp":"2026-09-15T14:49:07.960Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Reading relevant status header**"},{"type":"toolCall","id":"call_RUQAXfBjPnV1INLph0xhaIJa|fc_000c7cef03cac861016aa95ae3e3d087d18c64a2dfc907eea0","name":"read","arguments":{"i":"Reading present sweep rulings","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:1-73:raw"},"intent":"Reading present sweep rulings"},{"type":"toolCall","id":"call_zEXFwESrtfpBOQukzVmbY14n|fc_000c7cef03cac861016aa95ae3e3e087d19baee385c7d2545d","name":"grep","arguments":{"i":"Checking runner output encoding","pattern":"reconfigure|encoding|never.started|all-targets|enumerat|between|before-producer|after-producer","path":".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py","case":false,"gitignore":false,"skip":null},"intent":"Checking runner output encoding"},{"type":"toolCall","id":"call_T9CXtsYjnGboTR5fqDSE539b|fc_000c7cef03cac861016aa95ae3e3e887d1a77c5ad1a3bafa95","name":"grep","arguments":{"i":"Checking source residual anchors","pattern":"fn kill_pid|fn kill_pid_tree|expected|authenticated|before.*repo|outside|premise|rev-parse","path":".worktrees/hertz-ir86-disk-delta/crates/spt-store/src/proc.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.rs","case":false,"gitignore":false,"skip":null},"intent":"Checking source residual anchors"},{"type":"toolCall","id":"call_ZywYtTguOUFa0Wh2mjdUkPzO|fc_000c7cef03cac861016aa95ae3e3ec87d1a14fa8d859a628fd","name":"read","arguments":{"i":"Reading failure context source","path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs:175-230"},"intent":"Reading failure context source"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":6829,"output":325,"cacheRead":123520,"cacheWrite":0,"totalTokens":130674,"reasoningTokens":11,"cost":{"input":0.06829,"output":0.01625,"cacheRead":0.12351999999999999,"cacheWrite":0,"total":0.20806}},"stopReason":"toolUse","timestamp":1789483736265,"responseId":"resp_000c7cef03cac861016aa95ad877e887d1b0f18b90cd31f18f","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_000c7cef03cac861016aa95ada2d1487d1a28ea3159b5c4a54","type":"reasoning","content":[],"encrypted_content":"gAAAAABqqVrjxfiPmHr6H_R7mdccGDHRxXwIMqe13ZAC2BehZZv3BwAKajLZeW2WJTEKv4dridXuUb1SDqNIrQifjv7sq-1J6rwHCaJDWf-g-GvtqVuvMInrfI4BKG1jKMnFPWGZKq4SCixlcXlgskX7jyxU52uN-yySvJ4pW1e3xpJ9PoXwUeC6NwNvYKmnvCDFjZtQ-zdka-SUY5tZOpqrm5XJTpgEsV6KTVFbZKcnkeLUSq-u5_Qq9AqqijzayGb6BUXgtYqdpcPI-zWJQn81yhoN6yCHAHZR786WeollvwdDyLT47NljsVK9_hnDHKCesAGkuVgqpRq5NRMXjc-u2GDVvOaFYLk8NKzaOL_zCmpqo1XiXnCkKun4bTmg2p3M4LJCVvywVrqf7qgFWMcEs5yZKzqtpVeDfJawNNg5dFq4ogzzaL-UGoQevBMpBLEu-5gaENeu6o1SlmAItxGbBHZT4TSfFKb-8GM9Yvswe5Evmdpe0RwmN6LkHugkrOROFga28C-R9los3r9gXtYRqLF8XajOB1aQLoNCnz2BPaKT-624-wmRx8QoKjxiGXCqZkgL5o7tr88zjj91mfaVIs1VBMls7hmyLMLEzmOIDnHzZJzaFRCb89eVPNyCeLE-Er5L1fINl45EsLXJFPuaZHFd2cflWZ9KM87LXQDH7D8_1lDSMItvmw0XkxqvuPDrss2Vgz-Fc7k7TZsc-eDNlgiBPX8AjV_ACyK1xhLoC0rOJIdBu__Qpwwo6Z4H1S7JcHea5eUUtaxaqxnPzYiB8av70eQBX3ouWzz1Cp5c8Pufoh3xAwXx-3xZjWUPH2XXylUIdybSBRVnLwazdFbRGxv21erk-uMMjIHwNe6eSngmgpJwpwk3nmyWrmloBtbilv9T_S-_2fBdUZ1Uhugn9Tx9-NnWgmwb8HgcXhePP5qZYkJp83qwoxUWPYsYRabf7mGxxecN4KY_IFilTc1ej63Ulis6VpG6l5zMD_3SvOu1sYCcbsgxd3KvlO76W4Tn1J-_yaQNQS5VWM_AtjHlN5aDJUX40AGM2GF_KCl6wdzwoHfoKHrUH6-TdLwwgqkdjNvg2IjvWuiEVk_St6u3QHy9sIxC1GEFXpDfe-jtlwwqNOhvUDx2wekSAXLxYgdW6ukunD2rQjWPj-Cu81Ey0iXom3d8x9rqNYW8dl_BSxgp_eCiSzOy1GDKughsb4E9n9nfqLj6AW3VrWVFf5RFaV6FFOwFPCyXjjaPTtxZRWJboMrieyUU4MRdvun0VdvB62R7S-96Ku2MNCygTH8opMjk6Ql7JDp0jvfmOrXoF6oI7i-SD9naGPftbvZjdabWRsnGxssX","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"summary":[{"type":"summary_text","text":"**Reading relevant status header**"}],"metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ae3e3d087d18c64a2dfc907eea0","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading present sweep rulings\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:1-73:raw\"}","call_id":"call_RUQAXfBjPnV1INLph0xhaIJa","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ae3e3e087d19baee385c7d2545d","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking runner output encoding\",\"pattern\":\"reconfigure|encoding|never.started|all-targets|enumerat|between|before-producer|after-producer\",\"path\":\".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py\",\"case\":false,\"gitignore\":false,\"skip\":null}","call_id":"call_zEXFwESrtfpBOQukzVmbY14n","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"grep","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ae3e3e887d1a77c5ad1a3bafa95","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking source residual anchors\",\"pattern\":\"fn kill_pid|fn kill_pid_tree|expected|authenticated|before.*repo|outside|premise|rev-parse\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-store/src/proc.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs;.worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.rs\",\"case\":false,\"gitignore\":false,\"skip\":null}","call_id":"call_T9CXtsYjnGboTR5fqDSE539b","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"grep","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95ae3e3ec87d1a14fa8d859a628fd","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading failure context source\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs:175-230\"}","call_id":"call_ZywYtTguOUFa0Wh2mjdUkPzO","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}}]},"duration":11692.346700012684,"ttft":1943.2808000147343,"completedAt":1789483747958,"contextSnapshot":{"promptTokens":130349,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"message","id":"b35bd236","parentId":"cb27d754","timestamp":"2026-09-15T14:49:07.972Z","message":{"role":"toolResult","toolCallId":"call_RUQAXfBjPnV1INLph0xhaIJa|fc_000c7cef03cac861016aa95ae3e3d087d18c64a2dfc907eea0","toolName":"read","content":[{"type":"text","text":"# Infra register — CI / build-pipeline debt\n\nOperator-ruled 2026-08-02: infrastructure and CI-pipeline work items live HERE, not on the\n`spt-bs-releases` board. The board carries product surface the operator triages; this register\ncarries what the gater triages. **Mandate: doyle sweeps this file at every milestone intake and\nevery release close, and composes ripe entries into waves/milestone riders.** An entry leaves\nthis file only by being built (link the lane) or being retired with a stated reason.\n\nEntry format: status · origin · what/why · trigger condition (what makes it ripe) · size guess.\n\nLast sweep: **2026-09-11, v0.69.0 RELEASE CLOSE — FULL REGISTER**, source `e5a2fed9`.\nAll **97 entries (IR-1–97, including headingless IR-31)** read in two disjoint ranges; audit\npopulation checked for missing/duplicate IDs (97 rows, 97 unique, zero missing). Per-entry\ntrigger and disposition evidence: `.spt/preserved/infra-close069-20260911/audit.json`.\nUNKNOWN means no qualifying event established, not a disproved trigger or a discharged debt.\n\n- **Release facts, not a blanket green:** v0.69.0 at `16df0e41`, counter **105**, Latest,\n  11 assets; #294 and all eight members DONE. Explicit operator SHIP overrode the known\n  sync-cell red at candidate `a9e786b2`; the release neither classifies nor closes that defect.\n  Source closeout: releases#294 comment **5628538587**. The scoped four-package `--lib` battery\n  passed **121/121**; push CI **34550282074** passed **3167 Windows units**, then failed the\n  END disk floor (**15,360,114,688 < 34,359,738,368 bytes**). Release build **34550300527**\n  succeeded. Earlier PR unit-red logs remain unavailable/cause-unclassified. These are separate\n  verdict objects; no pass substitutes for a red, missing specimen, or unexecuted acceptance.\n- **Close already-built work, retain residuals:** IR-1/4 stale unlanded headers reconciled to\n  their landed rider and recorded golden exercise. IR-66 CLOSED using its existing two-platform\n  gates and WEBSERVE satisfaction ruling. IR-73 CLOSED: eight post-checkout sites plus both\n  docs-floor rereads are present; IR-86 retains sizing/dependency debt. Other established\n  BUILT/RETIRED decisions stand. IR-18's deferred consolidation and IR-53/62's narrower\n  touch-triggered siblings remain carried; closing their built halves does not erase those.\n- **Do not redispatch existing implementations:** IR-26 build-side identity is committed,\n  but claim-time observation and old-reader issues remain; IR-29's first fix landed, later\n  rung faces remain; IR-33's 16 MiB CLI stack exists, acceptance/margin reconciliation remains.\n  IR-57 `pick-audit`, IR-59 `disk-floor`, and IR-46 workflow floor tokens exist; residual adoption\n  and receipt reconciliation are the work. IR-69's original product lane landed; #243 residuals\n  remain. IR-83's universal LAN-only prescription is superseded by IR-89's layer-specific box\n  proof. IR-89's next-golden trigger has fired; exact step acceptance still needs reconciliation,\n  not a second guard implementation or renewed operator permission.\n- **IR-92 stays OPEN:** core#215 shipped the documentation/register rider, NOT the product\n  remedy; core#217 is the separate brainread audit. `try_spt_hosted_inject` still lacks the\n  MSG_IN publisher. Deployah corrected comment **5628532753** in place and confirmed readback.\n  Inject coverage, relay publication ordering and per-msg-id exact-once are distinct obligations.\n- **Next-intake composition, owned by doyle until accepted:** hertz's driver/workflow package\n  takes IR-31/46/59/60/76/86/87/90/97: aggregate capacity, truthful producer status, existing\n  quiet-window contract, independent rendezvous clocks, and mandatory between-run identity\n  census. IR-88 adopts the already-proven prebuilt release-before-delete recipe; IR-64 remains\n  a separate operator capacity decision. No new loaded comparison before these prerequisites.\n  Hertz's lifecycle package retains IR-7/17/20/22/25/34/35/55/63/79/80; guard adoption must\n  distinguish unwinding from hard process death. IR-74/75 ride the next Linux box audit.\n  IR-85/95/96 are scoped diagnostic continuation, NOT budget widening or a load/disk diagnosis.\n  Todlando owns product-side IR-81/82/92 composition; #285's completion did not build IR-82's\n  predecessor record. Both builders are offline: existing briefs are delivered, unacknowledged,\n  and **not executing**. No board mutation or new run authorization is implied.\n- **Small seam riders remain explicit:** next tooling intake weighs IR-5/6/10/11/32/37/47/58/94\n  (IR-37 upstream release is not downstream adoption: golden still requests 0.2.0).\n  IR-93 remains a separate symbol-packaging decision before a release-workflow rider, not a\n  property proven by a successful release build. All other open entries retain their recorded\n  trigger, residual, and owner where named; the complete audit records each, not a sampled set.\n- **Cleanup is mitigation, not closure:** 38 clean merged worktrees and classified obsolete\n  artifacts removed; dirty/unmerged/retained evidence preserved. Net free-space change\n  **4,532,350,976 bytes**, ending **83,382,472,704 bytes** (concurrent-activity caveat).\n  `.spt/cleanup-20260911.json` is the receipt. Root-target and CI-debug reclaims are separate\n  earlier measurements, not additions to that net. IR-14/26/27/49 remain structurally OPEN.\n\n### Intake addendum — hosted-relay diagnostic capacity hold (2026-09-11)\n\nSourced C: free samples around the intake, each named by file: **19,260,395,520 bytes at\n03:02:33Z** (post-merge run 34556292801, unit job `FLOOR_END`, RED against the\n34,359,738,368-byte floor); **19,907,792,896 bytes at 07:09:57Z**\n(`.spt/preserved/todlando-pool-reclaim-20260911/before.json`); **191,756,984,320 bytes** after\ndeployah's three authorized target reclaims (`.spt/preserved/deployah-rca-reclaim-20260911/reap-results.json`:\nrca-base +11,461,189,632, rca-head +11,371,200,512, gate-293c +94,256,648,192 observed);\n**247,894,224,896 bytes at 08:39:20Z** (hertz, GetDiskFreeSpaceExW, during post-merge run\n\n[Showing lines 1-73 of 6938. Use :74 to continue]"}],"details":{"truncation":{"content":"# Infra register — CI / build-pipeline debt\r\n\r\nOperator-ruled 2026-08-02: infrastructure and CI-pipeline work items live HERE, not on the\r\n`spt-bs-releases` board. The board carries product surface the operator triages; this register\r\ncarries what the gater triages. **Mandate: doyle sweeps this file at every milestone intake and\r\nevery release close, and composes ripe entries into waves/milestone riders.** An entry leaves\r\nthis file only by being built (link the lane) or being retired with a stated reason.\r\n\r\nEntry format: status · origin · what/why · trigger condition (what makes it ripe) · size guess.\r\n\r\nLast sweep: **2026-09-11, v0.69.0 RELEASE CLOSE — FULL REGISTER**, source `e5a2fed9`.\r\nAll **97 entries (IR-1–97, including headingless IR-31)** read in two disjoint ranges; audit\r\npopulation checked for missing/duplicate IDs (97 rows, 97 unique, zero missing). Per-entry\r\ntrigger and disposition evidence: `.spt/preserved/infra-close069-20260911/audit.json`.\r\nUNKNOWN means no qualifying event established, not a disproved trigger or a discharged debt.\r\n\r\n- **Release facts, not a blanket green:** v0.69.0 at `16df0e41`, counter **105**, Latest,\r\n  11 assets; #294 and all eight members DONE. Explicit operator SHIP overrode the known\r\n  sync-cell red at candidate `a9e786b2`; the release neither classifies nor closes that defect.\r\n  Source closeout: releases#294 comment **5628538587**. The scoped four-package `--lib` battery\r\n  passed **121/121**; push CI **34550282074** passed **3167 Windows units**, then failed the\r\n  END disk floor (**15,360,114,688 < 34,359,738,368 bytes**). Release build **34550300527**\r\n  succeeded. Earlier PR unit-red logs remain unavailable/cause-unclassified. These are separate\r\n  verdict objects; no pass substitutes for a red, missing specimen, or unexecuted acceptance.\r\n- **Close already-built work, retain residuals:** IR-1/4 stale unlanded headers reconciled to\r\n  their landed rider and recorded golden exercise. IR-66 CLOSED using its existing two-platform\r\n  gates and WEBSERVE satisfaction ruling. IR-73 CLOSED: eight post-checkout sites plus both\r\n  docs-floor rereads are present; IR-86 retains sizing/dependency debt. Other established\r\n  BUILT/RETIRED decisions stand. IR-18's deferred consolidation and IR-53/62's narrower\r\n  touch-triggered siblings remain carried; closing their built halves does not erase those.\r\n- **Do not redispatch existing implementations:** IR-26 build-side identity is committed,\r\n  but claim-time observation and old-reader issues remain; IR-29's first fix landed, later\r\n  rung faces remain; IR-33's 16 MiB CLI stack exists, acceptance/margin reconciliation remains.\r\n  IR-57 `pick-audit`, IR-59 `disk-floor`, and IR-46 workflow floor tokens exist; residual adoption\r\n  and receipt reconciliation are the work. IR-69's original product lane landed; #243 residuals\r\n  remain. IR-83's universal LAN-only prescription is superseded by IR-89's layer-specific box\r\n  proof. IR-89's next-golden trigger has fired; exact step acceptance still needs reconciliation,\r\n  not a second guard implementation or renewed operator permission.\r\n- **IR-92 stays OPEN:** core#215 shipped the documentation/register rider, NOT the product\r\n  remedy; core#217 is the separate brainread audit. `try_spt_hosted_inject` still lacks the\r\n  MSG_IN publisher. Deployah corrected comment **5628532753** in place and confirmed readback.\r\n  Inject coverage, relay publication ordering and per-msg-id exact-once are distinct obligations.\r\n- **Next-intake composition, owned by doyle until accepted:** hertz's driver/workflow package\r\n  takes IR-31/46/59/60/76/86/87/90/97: aggregate capacity, truthful producer status, existing\r\n  quiet-window contract, independent rendezvous clocks, and mandatory between-run identity\r\n  census. IR-88 adopts the already-proven prebuilt release-before-delete recipe; IR-64 remains\r\n  a separate operator capacity decision. No new loaded comparison before these prerequisites.\r\n  Hertz's lifecycle package retains IR-7/17/20/22/25/34/35/55/63/79/80; guard adoption must\r\n  distinguish unwinding from hard process death. IR-74/75 ride the next Linux box audit.\r\n  IR-85/95/96 are scoped diagnostic continuation, NOT budget widening or a load/disk diagnosis.\r\n  Todlando owns product-side IR-81/82/92 composition; #285's completion did not build IR-82's\r\n  predecessor record. Both builders are offline: existing briefs are delivered, unacknowledged,\r\n  and **not executing**. No board mutation or new run authorization is implied.\r\n- **Small seam riders remain explicit:** next tooling intake weighs IR-5/6/10/11/32/37/47/58/94\r\n  (IR-37 upstream release is not downstream adoption: golden still requests 0.2.0).\r\n  IR-93 remains a separate symbol-packaging decision before a release-workflow rider, not a\r\n  property proven by a successful release build. All other open entries retain their recorded\r\n  trigger, residual, and owner where named; the complete audit records each, not a sampled set.\r\n- **Cleanup is mitigation, not closure:** 38 clean merged worktrees and classified obsolete\r\n  artifacts removed; dirty/unmerged/retained evidence preserved. Net free-space change\r\n  **4,532,350,976 bytes**, ending **83,382,472,704 bytes** (concurrent-activity caveat).\r\n  `.spt/cleanup-20260911.json` is the receipt. Root-target and CI-debug reclaims are separate\r\n  earlier measurements, not additions to that net. IR-14/26/27/49 remain structurally OPEN.\r\n\r\n### Intake addendum — hosted-relay diagnostic capacity hold (2026-09-11)\r\n\r\nSourced C: free samples around the intake, each named by file: **19,260,395,520 bytes at\r\n03:02:33Z** (post-merge run 34556292801, unit job `FLOOR_END`, RED against the\r\n34,359,738,368-byte floor); **19,907,792,896 bytes at 07:09:57Z**\r\n(`.spt/preserved/todlando-pool-reclaim-20260911/before.json`); **191,756,984,320 bytes** after\r\ndeployah's three authorized target reclaims (`.spt/preserved/deployah-rca-reclaim-20260911/reap-results.json`:\r\nrca-base +11,461,189,632, rca-head +11,371,200,512, gate-293c +94,256,648,192 observed);\r\n**247,894,224,896 bytes at 08:39:20Z** (hertz, GetDiskFreeSpaceExW, during post-merge run\r","truncated":true,"truncatedBy":"lines","totalLines":6938,"totalBytes":6169,"outputLines":73,"outputBytes":6169,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6938,"displayContent":{"text":"# Infra register — CI / build-pipeline debt\r\n\r\nOperator-ruled 2026-08-02: infrastructure and CI-pipeline work items live HERE, not on the\r\n`spt-bs-releases` board. The board carries product surface the operator triages; this register\r\ncarries what the gater triages. **Mandate: doyle sweeps this file at every milestone intake and\r\nevery release close, and composes ripe entries into waves/milestone riders.** An entry leaves\r\nthis file only by being built (link the lane) or being retired with a stated reason.\r\n\r\nEntry format: status · origin · what/why · trigger condition (what makes it ripe) · size guess.\r\n\r\nLast sweep: **2026-09-11, v0.69.0 RELEASE CLOSE — FULL REGISTER**, source `e5a2fed9`.\r\nAll **97 entries (IR-1–97, including headingless IR-31)** read in two disjoint ranges; audit\r\npopulation checked for missing/duplicate IDs (97 rows, 97 unique, zero missing). Per-entry\r\ntrigger and disposition evidence: `.spt/preserved/infra-close069-20260911/audit.json`.\r\nUNKNOWN means no qualifying event established, not a disproved trigger or a discharged debt.\r\n\r\n- **Release facts, not a blanket green:** v0.69.0 at `16df0e41`, counter **105**, Latest,\r\n  11 assets; #294 and all eight members DONE. Explicit operator SHIP overrode the known\r\n  sync-cell red at candidate `a9e786b2`; the release neither classifies nor closes that defect.\r\n  Source closeout: releases#294 comment **5628538587**. The scoped four-package `--lib` battery\r\n  passed **121/121**; push CI **34550282074** passed **3167 Windows units**, then failed the\r\n  END disk floor (**15,360,114,688 < 34,359,738,368 bytes**). Release build **34550300527**\r\n  succeeded. Earlier PR unit-red logs remain unavailable/cause-unclassified. These are separate\r\n  verdict objects; no pass substitutes for a red, missing specimen, or unexecuted acceptance.\r\n- **Close already-built work, retain residuals:** IR-1/4 stale unlanded headers reconciled to\r\n  their landed rider and recorded golden exercise. IR-66 CLOSED using its existing two-platform\r\n  gates and WEBSERVE satisfaction ruling. IR-73 CLOSED: eight post-checkout sites plus both\r\n  docs-floor rereads are present; IR-86 retains sizing/dependency debt. Other established\r\n  BUILT/RETIRED decisions stand. IR-18's deferred consolidation and IR-53/62's narrower\r\n  touch-triggered siblings remain carried; closing their built halves does not erase those.\r\n- **Do not redispatch existing implementations:** IR-26 build-side identity is committed,\r\n  but claim-time observation and old-reader issues remain; IR-29's first fix landed, later\r\n  rung faces remain; IR-33's 16 MiB CLI stack exists, acceptance/margin reconciliation remains.\r\n  IR-57 `pick-audit`, IR-59 `disk-floor`, and IR-46 workflow floor tokens exist; residual adoption\r\n  and receipt reconciliation are the work. IR-69's original product lane landed; #243 residuals\r\n  remain. IR-83's universal LAN-only prescription is superseded by IR-89's layer-specific box\r\n  proof. IR-89's next-golden trigger has fired; exact step acceptance still needs reconciliation,\r\n  not a second guard implementation or renewed operator permission.\r\n- **IR-92 stays OPEN:** core#215 shipped the documentation/register rider, NOT the product\r\n  remedy; core#217 is the separate brainread audit. `try_spt_hosted_inject` still lacks the\r\n  MSG_IN publisher. Deployah corrected comment **5628532753** in place and confirmed readback.\r\n  Inject coverage, relay publication ordering and per-msg-id exact-once are distinct obligations.\r\n- **Next-intake composition, owned by doyle until accepted:** hertz's driver/workflow package\r\n  takes IR-31/46/59/60/76/86/87/90/97: aggregate capacity, truthful producer status, existing\r\n  quiet-window contract, independent rendezvous clocks, and mandatory between-run identity\r\n  census. IR-88 adopts the already-proven prebuilt release-before-delete recipe; IR-64 remains\r\n  a separate operator capacity decision. No new loaded comparison before these prerequisites.\r\n  Hertz's lifecycle package retains IR-7/17/20/22/25/34/35/55/63/79/80; guard adoption must\r\n  distinguish unwinding from hard process death. IR-74/75 ride the next Linux box audit.\r\n  IR-85/95/96 are scoped diagnostic continuation, NOT budget widening or a load/disk diagnosis.\r\n  Todlando owns product-side IR-81/82/92 composition; #285's completion did not build IR-82's\r\n  predecessor record. Both builders are offline: existing briefs are delivered, unacknowledged,\r\n  and **not executing**. No board mutation or new run authorization is implied.\r\n- **Small seam riders remain explicit:** next tooling intake weighs IR-5/6/10/11/32/37/47/58/94\r\n  (IR-37 upstream release is not downstream adoption: golden still requests 0.2.0).\r\n  IR-93 remains a separate symbol-packaging decision before a release-workflow rider, not a\r\n  property proven by a successful release build. All other open entries retain their recorded\r\n  trigger, residual, and owner where named; the complete audit records each, not a sampled set.\r\n- **Cleanup is mitigation, not closure:** 38 clean merged worktrees and classified obsolete\r\n  artifacts removed; dirty/unmerged/retained evidence preserved. Net free-space change\r\n  **4,532,350,976 bytes**, ending **83,382,472,704 bytes** (concurrent-activity caveat).\r\n  `.spt/cleanup-20260911.json` is the receipt. Root-target and CI-debug reclaims are separate\r\n  earlier measurements, not additions to that net. IR-14/26/27/49 remain structurally OPEN.\r\n\r\n### Intake addendum — hosted-relay diagnostic capacity hold (2026-09-11)\r\n\r\nSourced C: free samples around the intake, each named by file: **19,260,395,520 bytes at\r\n03:02:33Z** (post-merge run 34556292801, unit job `FLOOR_END`, RED against the\r\n34,359,738,368-byte floor); **19,907,792,896 bytes at 07:09:57Z**\r\n(`.spt/preserved/todlando-pool-reclaim-20260911/before.json`); **191,756,984,320 bytes** after\r\ndeployah's three authorized target reclaims (`.spt/preserved/deployah-rca-reclaim-20260911/reap-results.json`:\r\nrca-base +11,461,189,632, rca-head +11,371,200,512, gate-293c +94,256,648,192 observed);\r\n**247,894,224,896 bytes at 08:39:20Z** (hertz, GetDiskFreeSpaceExW, during post-merge run\r","startLine":1,"lineNumbers":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":6938,"totalBytes":6169,"outputLines":73,"outputBytes":6169,"shownRange":{"start":1,"end":73},"nextOffset":74}}},"isError":false,"timestamp":1789483747971}}
{"type":"message","id":"becd9462","parentId":"b35bd236","timestamp":"2026-09-15T14:49:07.978Z","message":{"role":"toolResult","toolCallId":"call_ZywYtTguOUFa0Wh2mjdUkPzO|fc_000c7cef03cac861016aa95ae3e3ec87d1a14fa8d859a628fd","toolName":"read","content":[{"type":"text","text":"impl PullLink {\n…\n    fn pull(\n…\n    ) -> (spt_daemon::sync::SyncPullReport, SyncServeOutcome) {\n…\n        let skip: Vec<u64> = serve_brain\n…\n            .expect(\"stream snapshot\")\n            .streams\n            .iter()\n            .map(|s| s.stream_id)\n            .collect();\n\n        let mut req_brain = connect_retry(&self.requester);\n        let conn = req_brain\n            .net_dial(addr, Some(MintedOp::new(Minter::Cli, op())))\n            .expect(\"dial\");\n        let refs_owned: Vec<String> = refs.iter().map(|r| r.to_string()).collect();\n        let req_root = self.requester_root.clone();\n        let scratch_req = self.scratch.join(\"req\");\n        let open_op = MintedOp::new(Minter::Pump, op());\n        let puller = thread::spawn(move || {\n            let cs = ContextStore::open_or_init_in(&req_root).unwrap();\n            request_sync(\n                &mut req_brain,\n                conn.conn_id,\n                &refs_owned,\n                open_op,\n                &cs,\n                &scratch_req,\n            )\n            .expect(\"pull\")\n        });\n\n        let (stream, origin) = wait_for_stream_except(&mut serve_brain, &skip);\n        let cs = ContextStore::open_or_init_in(&self.responder_root).unwrap();\n        let outcome = serve_sync(\n            &mut serve_brain,\n            stream,\n            &origin,\n            0,\n            &cs,\n            policy,\n            &self.scratch.join(\"serve\"),\n        )\n        .expect(\"serve\");\n        (puller.join().expect(\"pull thread\"), outcome)\n    }\n}\n\n// [unit->REQ-INST-5] two-tier sync over the wire: a-<id> + p-<project> land\n// byte-identical at the requester, while an unsynced mind (fail-closed: no\n// membership list) and a hidden one are refused SERVER-SIDE even when named in\n// the request — under the handshake-proven origin, never payload bytes.\n// [unit->REQ-NET-3]\n// [unit->REQ-HAZARD-WAN-ORIGIN-AUTH]\n#[test]\nfn two_tier_sync_lands_and_gate_refuses_server_side() {\n    let _home = init_home();\n    let dir = tempfile::tempdir().expect(\"tempdir\");\n    let (name_a, name_b) = (unique_name(), unique_name());\n    let _broker_a = net_broker(&name_a, &dir.path().join(\"a\"));\n    let _broker_b = net_broker(&name_b, &dir.path().join(\"b\"));\n    let (root_a, root_b) = (dir.path().join(\"tracked-a\"), dir.path().join(\"tracked-b\"));\n    let scratch = dir.path().join(\"scratch\");\n    let mut b_from_a = PullLink {\n        requester: name_b.clone(),\n…\n    };\n…\n}\n\n[Showing lines 174-233 of 629. Use :234 to continue]"}],"details":{"truncation":{"content":"            .expect(\"stream snapshot\")\r\n            .streams\r\n            .iter()\r\n            .map(|s| s.stream_id)\r\n            .collect();\r\n\r\n        let mut req_brain = connect_retry(&self.requester);\r\n        let conn = req_brain\r\n            .net_dial(addr, Some(MintedOp::new(Minter::Cli, op())))\r\n            .expect(\"dial\");\r\n        let refs_owned: Vec<String> = refs.iter().map(|r| r.to_string()).collect();\r\n        let req_root = self.requester_root.clone();\r\n        let scratch_req = self.scratch.join(\"req\");\r\n        let open_op = MintedOp::new(Minter::Pump, op());\r\n        let puller = thread::spawn(move || {\r\n            let cs = ContextStore::open_or_init_in(&req_root).unwrap();\r\n            request_sync(\r\n                &mut req_brain,\r\n                conn.conn_id,\r\n                &refs_owned,\r\n                open_op,\r\n                &cs,\r\n                &scratch_req,\r\n            )\r\n            .expect(\"pull\")\r\n        });\r\n\r\n        let (stream, origin) = wait_for_stream_except(&mut serve_brain, &skip);\r\n        let cs = ContextStore::open_or_init_in(&self.responder_root).unwrap();\r\n        let outcome = serve_sync(\r\n            &mut serve_brain,\r\n            stream,\r\n            &origin,\r\n            0,\r\n            &cs,\r\n            policy,\r\n            &self.scratch.join(\"serve\"),\r\n        )\r\n        .expect(\"serve\");\r\n        (puller.join().expect(\"pull thread\"), outcome)\r\n    }\r\n}\r\n\r\n// [unit->REQ-INST-5] two-tier sync over the wire: a-<id> + p-<project> land\r\n// byte-identical at the requester, while an unsynced mind (fail-closed: no\r\n// membership list) and a hidden one are refused SERVER-SIDE even when named in\r\n// the request — under the handshake-proven origin, never payload bytes.\r\n// [unit->REQ-NET-3]\r\n// [unit->REQ-HAZARD-WAN-ORIGIN-AUTH]\r\n#[test]\r\nfn two_tier_sync_lands_and_gate_refuses_server_side() {\r\n    let _home = init_home();\r\n    let dir = tempfile::tempdir().expect(\"tempdir\");\r\n    let (name_a, name_b) = (unique_name(), unique_name());\r\n    let _broker_a = net_broker(&name_a, &dir.path().join(\"a\"));\r\n    let _broker_b = net_broker(&name_b, &dir.path().join(\"b\"));\r\n    let (root_a, root_b) = (dir.path().join(\"tracked-a\"), dir.path().join(\"tracked-b\"));\r\n    let scratch = dir.path().join(\"scratch\");\r\n    let mut b_from_a = PullLink {\r\n        requester: name_b.clone(),\r","truncated":true,"truncatedBy":"lines","totalLines":456,"totalBytes":2355,"outputLines":60,"outputBytes":2355,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":629,"displayContent":{"text":"impl PullLink {\n…\n    fn pull(\n…\n    ) -> (spt_daemon::sync::SyncPullReport, SyncServeOutcome) {\n…\n        let skip: Vec<u64> = serve_brain\n…\n            .expect(\"stream snapshot\")\r\n            .streams\r\n            .iter()\r\n            .map(|s| s.stream_id)\r\n            .collect();\r\n\r\n        let mut req_brain = connect_retry(&self.requester);\r\n        let conn = req_brain\r\n            .net_dial(addr, Some(MintedOp::new(Minter::Cli, op())))\r\n            .expect(\"dial\");\r\n        let refs_owned: Vec<String> = refs.iter().map(|r| r.to_string()).collect();\r\n        let req_root = self.requester_root.clone();\r\n        let scratch_req = self.scratch.join(\"req\");\r\n        let open_op = MintedOp::new(Minter::Pump, op());\r\n        let puller = thread::spawn(move || {\r\n            let cs = ContextStore::open_or_init_in(&req_root).unwrap();\r\n            request_sync(\r\n                &mut req_brain,\r\n                conn.conn_id,\r\n                &refs_owned,\r\n                open_op,\r\n                &cs,\r\n                &scratch_req,\r\n            )\r\n            .expect(\"pull\")\r\n        });\r\n\r\n        let (stream, origin) = wait_for_stream_except(&mut serve_brain, &skip);\r\n        let cs = ContextStore::open_or_init_in(&self.responder_root).unwrap();\r\n        let outcome = serve_sync(\r\n            &mut serve_brain,\r\n            stream,\r\n            &origin,\r\n            0,\r\n            &cs,\r\n            policy,\r\n            &self.scratch.join(\"serve\"),\r\n        )\r\n        .expect(\"serve\");\r\n        (puller.join().expect(\"pull thread\"), outcome)\r\n    }\r\n}\r\n\r\n// [unit->REQ-INST-5] two-tier sync over the wire: a-<id> + p-<project> land\r\n// byte-identical at the requester, while an unsynced mind (fail-closed: no\r\n// membership list) and a hidden one are refused SERVER-SIDE even when named in\r\n// the request — under the handshake-proven origin, never payload bytes.\r\n// [unit->REQ-NET-3]\r\n// [unit->REQ-HAZARD-WAN-ORIGIN-AUTH]\r\n#[test]\r\nfn two_tier_sync_lands_and_gate_refuses_server_side() {\r\n    let _home = init_home();\r\n    let dir = tempfile::tempdir().expect(\"tempdir\");\r\n    let (name_a, name_b) = (unique_name(), unique_name());\r\n    let _broker_a = net_broker(&name_a, &dir.path().join(\"a\"));\r\n    let _broker_b = net_broker(&name_b, &dir.path().join(\"b\"));\r\n    let (root_a, root_b) = (dir.path().join(\"tracked-a\"), dir.path().join(\"tracked-b\"));\r\n    let scratch = dir.path().join(\"scratch\");\r\n    let mut b_from_a = PullLink {\r\n        requester: name_b.clone(),\r\n…\n    };\n…\n}","startLine":157,"lineNumbers":[157,null,165,null,169,null,172,null,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,null,238,null,327]},"fileSize":24288,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\crates\\spt-daemon\\tests\\sync.rs"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":629,"totalBytes":2355,"outputLines":60,"outputBytes":2355,"shownRange":{"start":174,"end":233},"nextOffset":234}}},"isError":false,"timestamp":1789483747978}}
{"type":"message","id":"b31af738","parentId":"becd9462","timestamp":"2026-09-15T14:49:07.986Z","message":{"role":"toolResult","toolCallId":"call_zEXFwESrtfpBOQukzVmbY14n|fc_000c7cef03cac861016aa95ae3e3e087d19baee385c7d2545d","toolName":"grep","content":[{"type":"text","text":" 35|def save(path, value):\n*36|    path.write_text(json.dumps(value, indent=2) + \"\\n\", encoding=\"utf-8\")\n 37|\n 38|\n 39|# [impl->REQ-LOCAL-GATE-EXECUTION-EVIDENCE]\n...\n 100|    try:\n*101|        disk_ok = meter(name + \"-after-producer\")\n 102|    except OSError as error:\n 103|        print(f\"DISK_OBSERVATION_UNPROVEN: {error}\", file=sys.stderr)\n 104|    try:\n...\n 133|        raw, code = f\"CENSUS_UNPROVEN: {error}\\n\", REFUSED\n*134|    (output / f\"{name}.raw\").write_text(raw, encoding=\"utf-8\")\n*135|    (output / f\"{name}.exit\").write_text(f\"{code}\\n\", encoding=\"utf-8\")\n 136|    clear = census_clear(raw, code)\n 137|    print(f\"LANE_CENSUS name={name} clear={str(clear).lower()} scope=existing-reaper\", flush=True)\n 138|    return clear\n...\n 166|        row, admitted = {\"name\": name, \"error\": str(error), \"sample\": \"UNAVAILABLE\"}, False\n*167|    with (output / \"capacity.jsonl\").open(\"a\", encoding=\"utf-8\") as stream:\n 168|        stream.write(json.dumps(row) + \"\\n\")\n 169|    return admitted\n 170|\n...\n 257|        (output / f\"{name}.exit\").write_text(\n*258|            f\"{code}\\n\" if code is not None else \"UNOBSERVED\\n\", encoding=\"utf-8\")\n 259|        save(output / f\"{name}.observation.json\", {\n 260|            \"producer_exit\": code, \"launch_failed\": launch_failed, \"stop_reason\": reason,\n 261|            \"elapsed_seconds\": time.monotonic() - started,\n...\n 322|    root = Path(__file__).resolve().parents[2]\n*323|    plan = json.loads(args.plan.read_text(encoding=\"utf-8\"))\n 324|    validate_plan(plan)\n 325|    target, xtask, output = root / \"target\", args.xtask.resolve(), args.output.resolve()\n 326|    if not xtask.is_file() or not (target / \"debug/deps\").is_dir() or not (target / \".rustc_info.json\").is_file():\n...\n 351|    save(output / \"toolchain.json\", {\"stdout\": actual.stdout, \"stderr\": actual.stderr, \"exit\": actual.returncode})\n*352|    cached = json.loads((target / \".rustc_info.json\").read_text(encoding=\"utf-8\"))\n 353|    cached_outputs = cached.get(\"outputs\", {}).values()\n 354|    if actual.returncode or actual.stdout != plan[\"rustc_version\"] or not any(row.get(\"success\") is True and row.get(\"stdout\") == actual.stdout for row in cached_outputs):\n 355|        raise ValueError(\"toolchain differs from allocated warm cache; allocation invalid\")\n...\n 389|                    break\n*390|                inventory = json.loads((output / f\"{name}-inventory.stdout\").read_text(encoding=\"utf-8\"))\n 391|                save(output / f\"{name}-selection.json\", selected_inventory(inventory))\n 392|            else:\n 393|                argv = step[\"argv\"]\n...\n 413|    try:\n*414|        (output / \"lane.exit\").write_text(f\"{result}\\n\", encoding=\"utf-8\")\n 415|    except OSError as error:\n 416|        print(f\"LANE_STATUS_WRITE_FAILED: {error}; producer/driver exit={result}\", file=sys.stderr)\n 417|        result = final_status(result, False)"}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py","searchPath":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\.github\\ci\\local-lane.py","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core","matchCount":10,"fileCount":1,"files":[".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py"],"fileMatches":[{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py","count":10}],"truncated":false,"displayContent":"  35│def save(path, value):\n *36│    path.write_text(json.dumps(value, indent=2) + \"\\n\", encoding=\"utf-8\")\n  37│\n  38│\n  39│# [impl->REQ-LOCAL-GATE-EXECUTION-EVIDENCE]\n    │...\n 100│    try:\n*101│        disk_ok = meter(name + \"-after-producer\")\n 102│    except OSError as error:\n 103│        print(f\"DISK_OBSERVATION_UNPROVEN: {error}\", file=sys.stderr)\n 104│    try:\n    │...\n 133│        raw, code = f\"CENSUS_UNPROVEN: {error}\\n\", REFUSED\n*134│    (output / f\"{name}.raw\").write_text(raw, encoding=\"utf-8\")\n*135│    (output / f\"{name}.exit\").write_text(f\"{code}\\n\", encoding=\"utf-8\")\n 136│    clear = census_clear(raw, code)\n 137│    print(f\"LANE_CENSUS name={name} clear={str(clear).lower()} scope=existing-reaper\", flush=True)\n 138│    return clear\n    │...\n 166│        row, admitted = {\"name\": name, \"error\": str(error), \"sample\": \"UNAVAILABLE\"}, False\n*167│    with (output / \"capacity.jsonl\").open(\"a\", encoding=\"utf-8\") as stream:\n 168│        stream.write(json.dumps(row) + \"\\n\")\n 169│    return admitted\n 170│\n    │...\n 257│        (output / f\"{name}.exit\").write_text(\n*258│            f\"{code}\\n\" if code is not None else \"UNOBSERVED\\n\", encoding=\"utf-8\")\n 259│        save(output / f\"{name}.observation.json\", {\n 260│            \"producer_exit\": code, \"launch_failed\": launch_failed, \"stop_reason\": reason,\n 261│            \"elapsed_seconds\": time.monotonic() - started,\n    │...\n 322│    root = Path(__file__).resolve().parents[2]\n*323│    plan = json.loads(args.plan.read_text(encoding=\"utf-8\"))\n 324│    validate_plan(plan)\n 325│    target, xtask, output = root / \"target\", args.xtask.resolve(), args.output.resolve()\n 326│    if not xtask.is_file() or not (target / \"debug/deps\").is_dir() or not (target / \".rustc_info.json\").is_file():\n    │...\n 351│    save(output / \"toolchain.json\", {\"stdout\": actual.stdout, \"stderr\": actual.stderr, \"exit\": actual.returncode})\n*352│    cached = json.loads((target / \".rustc_info.json\").read_text(encoding=\"utf-8\"))\n 353│    cached_outputs = cached.get(\"outputs\", {}).values()\n 354│    if actual.returncode or actual.stdout != plan[\"rustc_version\"] or not any(row.get(\"success\") is True and row.get(\"stdout\") == actual.stdout for row in cached_outputs):\n 355│        raise ValueError(\"toolchain differs from allocated warm cache; allocation invalid\")\n    │...\n 389│                    break\n*390│                inventory = json.loads((output / f\"{name}-inventory.stdout\").read_text(encoding=\"utf-8\"))\n 391│                save(output / f\"{name}-selection.json\", selected_inventory(inventory))\n 392│            else:\n 393│                argv = step[\"argv\"]\n    │...\n 413│    try:\n*414│        (output / \"lane.exit\").write_text(f\"{result}\\n\", encoding=\"utf-8\")\n 415│    except OSError as error:\n 416│        print(f\"LANE_STATUS_WRITE_FAILED: {error}; producer/driver exit={result}\", file=sys.stderr)\n 417│        result = final_status(result, False)"},"isError":false,"timestamp":1789483747985}}
{"type":"message","id":"aeeea946","parentId":"b31af738","timestamp":"2026-09-15T14:49:08.030Z","message":{"role":"toolResult","toolCallId":"call_T9CXtsYjnGboTR5fqDSE539b|fc_000c7cef03cac861016aa95ae3e3e887d1a77c5ad1a3bafa95","toolName":"grep","content":[{"type":"text","text":"# .worktrees/hertz-ir86-disk-delta/crates/\n\n## spt-store/src/\n### proc.rs\n 45|// [impl->REQ-HAZARD-BRAIN-RESTART-PSYCHE-DUP]\n*46|pub fn kill_pid(pid: u32) {\n 47|    if pid == 0 {\n 48|        return; // never a real per-process target (see is_process_alive)\n 49|    }\n...\n 429|// [impl->REQ-PSYCHE-CRASHLOOP-BACKOFF-SHUTDOWN]\n*430|pub fn kill_pid_tree(root: u32) {\n 431|    if root == 0 {\n 432|        return;\n 433|    }\n...\n 779|    // it. It composes table-presence with a start-time read, and `/proc` answers\n*780|    // both for a zombie — so before this it reported `Present(our_own_birth)`,\n 781|    // which passes the custody pair test and reads HELD for a corpse. Every\n 782|    // consumer that asks \"is this recorded process still ours\" then answers YES\n 783|    // forever on Linux: relay-death convergence never fires, and the endpoint\n...\n 928|    #[test]\n*929|    fn kill_pid_tree_kills_the_whole_subtree() {\n 930|        let mut parent = spawn_two_level_tree();\n 931|        let ppid = parent.id();\n 932|        // Wait for the child to appear under the parent, then capture its pid.\n\n## spt-daemon/src/\n### registryhost.rs\n 1121|/// derivation injected so a unit test can count it. Derivation spawns git\n*1122|/// (`remote`/`rev-parse`) per call, so the RAW cwd string is deduped BEFORE\n 1123|/// `derive` runs — a ledger heavy with duplicate cwds derives once per DISTINCT\n 1124|/// cwd per round, not once per row (the post-self-hash v0.37.0 CPU floor: ~200\n 1125|/// derivations per pump round on a 12-perch box). The pid-level dedup stays as\n...\n 1354|        // The layout mirrors the real one (releases#178): `$SPT_HOME` holds the owlery\n*1355|        // AND the engine room's sequestered cwd, while user projects live OUTSIDE it.\n 1356|        // The old fixture put the projects inside the same dir it used as the exclusion\n 1357|        // base — harmless while the base was the owlery, but it would read as \"every\n 1358|        // project is internal\" now that the base is the home itself.\n...\n 1362|        std::fs::create_dir_all(&perch).unwrap();\n*1363|        // Real project dirs OUTSIDE any repo → project_id_for_dir falls back to the\n 1364|        // folder name (no remote, no git toplevel).\n 1365|        let work = root.join(\"work\");\n 1366|        for p in [\"alpha\", \"beta\", \"gamma\"] {\n...\n 1368|        }\n*1369|        // PREMISE, asserted rather than assumed: this fixture tree is OUTSIDE any git\n 1370|        // toplevel. project_id_for_dir tries `git remote get-url origin` FIRST, so a\n 1371|        // tempdir that lands inside a checkout derives THAT repo's remote for every\n 1372|        // fixture dir and collapses alpha/beta/gamma to one id — the assertions below\n...\n 1386|        std::fs::create_dir_all(&psyche).unwrap();\n*1387|        // The engine room's sequestered cwd: under the home, OUTSIDE the owlery. This\n 1388|        // is the row that would have been GOSSIPED TO THE NETWORK as a project named\n 1389|        // `cwd` before the widening.\n 1390|        let er = home.join(\"engineroom\").join(\"cwd\");\n### projwriter.rs\n 706|    /// `home` is a SUBDIRECTORY of the temp root, not the root itself, so that\n*707|    /// the fixture's project workdirs can sit OUTSIDE it — which is the real\n 708|    /// layout (user projects do not live under `$SPT_HOME`) and the only one\n 709|    /// that still exercises project derivation now that `internal_root` is the\n 710|    /// home rather than the owlery (releases#178). With workdirs inside the\n...\n 773|        /// A plain (non-git) project dir whose folder name becomes the id.\n*774|        /// Rooted OUTSIDE `home`: a user project under `$SPT_HOME` is spt-internal\n 775|        /// and derives no project at all (releases#178).\n 776|        fn project_dir(&self, name: &str) -> PathBuf {\n 777|            let dir = self.root.join(\"workdirs\").join(name);\n...\n 798|        let dir_b = fx.project_dir(\"proj-b\");\n*799|        // PREMISE, asserted rather than assumed: these fixture dirs are OUTSIDE any git\n 800|        // toplevel. project_id_and_display_for_dir tries `git remote get-url origin`\n 801|        // FIRST, so a tempdir that lands inside a checkout derives THAT repo's remote —\n 802|        // the display assertion below then reads \"spt-core\" and reds as a writer defect"}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/crates/spt-store/src/proc.rs, .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs, .worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.rs","searchPath":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\crates","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core","matchCount":12,"fileCount":3,"files":[".worktrees/hertz-ir86-disk-delta/crates/spt-store/src/proc.rs",".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs",".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.rs"],"fileMatches":[{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-store/src/proc.rs","count":4},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs","count":5},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.rs","count":3}],"truncated":false,"displayContent":"# .worktrees/hertz-ir86-disk-delta/crates/\n\n## spt-store/src/\n### proc.rs\n  45│// [impl->REQ-HAZARD-BRAIN-RESTART-PSYCHE-DUP]\n *46│pub fn kill_pid(pid: u32) {\n  47│    if pid == 0 {\n  48│        return; // never a real per-process target (see is_process_alive)\n  49│    }\n    │...\n 429│// [impl->REQ-PSYCHE-CRASHLOOP-BACKOFF-SHUTDOWN]\n*430│pub fn kill_pid_tree(root: u32) {\n 431│    if root == 0 {\n 432│        return;\n 433│    }\n    │...\n 779│    // it. It composes table-presence with a start-time read, and `/proc` answers\n*780│    // both for a zombie — so before this it reported `Present(our_own_birth)`,\n 781│    // which passes the custody pair test and reads HELD for a corpse. Every\n 782│    // consumer that asks \"is this recorded process still ours\" then answers YES\n 783│    // forever on Linux: relay-death convergence never fires, and the endpoint\n    │...\n 928│    #[test]\n*929│    fn kill_pid_tree_kills_the_whole_subtree() {\n 930│        let mut parent = spawn_two_level_tree();\n 931│        let ppid = parent.id();\n 932│        // Wait for the child to appear under the parent, then capture its pid.\n\n## spt-daemon/src/\n### registryhost.rs\n 1121│/// derivation injected so a unit test can count it. Derivation spawns git\n*1122│/// (`remote`/`rev-parse`) per call, so the RAW cwd string is deduped BEFORE\n 1123│/// `derive` runs — a ledger heavy with duplicate cwds derives once per DISTINCT\n 1124│/// cwd per round, not once per row (the post-self-hash v0.37.0 CPU floor: ~200\n 1125│/// derivations per pump round on a 12-perch box). The pid-level dedup stays as\n     │...\n 1354│        // The layout mirrors the real one (releases#178): `$SPT_HOME` holds the owlery\n*1355│        // AND the engine room's sequestered cwd, while user projects live OUTSIDE it.\n 1356│        // The old fixture put the projects inside the same dir it used as the exclusion\n 1357│        // base — harmless while the base was the owlery, but it would read as \"every\n 1358│        // project is internal\" now that the base is the home itself.\n     │...\n 1362│        std::fs::create_dir_all(&perch).unwrap();\n*1363│        // Real project dirs OUTSIDE any repo → project_id_for_dir falls back to the\n 1364│        // folder name (no remote, no git toplevel).\n 1365│        let work = root.join(\"work\");\n 1366│        for p in [\"alpha\", \"beta\", \"gamma\"] {\n     │...\n 1368│        }\n*1369│        // PREMISE, asserted rather than assumed: this fixture tree is OUTSIDE any git\n 1370│        // toplevel. project_id_for_dir tries `git remote get-url origin` FIRST, so a\n 1371│        // tempdir that lands inside a checkout derives THAT repo's remote for every\n 1372│        // fixture dir and collapses alpha/beta/gamma to one id — the assertions below\n     │...\n 1386│        std::fs::create_dir_all(&psyche).unwrap();\n*1387│        // The engine room's sequestered cwd: under the home, OUTSIDE the owlery. This\n 1388│        // is the row that would have been GOSSIPED TO THE NETWORK as a project named\n 1389│        // `cwd` before the widening.\n 1390│        let er = home.join(\"engineroom\").join(\"cwd\");\n### projwriter.rs\n 706│    /// `home` is a SUBDIRECTORY of the temp root, not the root itself, so that\n*707│    /// the fixture's project workdirs can sit OUTSIDE it — which is the real\n 708│    /// layout (user projects do not live under `$SPT_HOME`) and the only one\n 709│    /// that still exercises project derivation now that `internal_root` is the\n 710│    /// home rather than the owlery (releases#178). With workdirs inside the\n    │...\n 773│        /// A plain (non-git) project dir whose folder name becomes the id.\n*774│        /// Rooted OUTSIDE `home`: a user project under `$SPT_HOME` is spt-internal\n 775│        /// and derives no project at all (releases#178).\n 776│        fn project_dir(&self, name: &str) -> PathBuf {\n 777│            let dir = self.root.join(\"workdirs\").join(name);\n    │...\n 798│        let dir_b = fx.project_dir(\"proj-b\");\n*799│        // PREMISE, asserted rather than assumed: these fixture dirs are OUTSIDE any git\n 800│        // toplevel. project_id_and_display_for_dir tries `git remote get-url origin`\n 801│        // FIRST, so a tempdir that lands inside a checkout derives THAT repo's remote —\n 802│        // the display assertion below then reads \"spt-core\" and reds as a writer defect"},"isError":false,"timestamp":1789483748029}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_uhzDd3jpEYAFswTRgjE8QsuG|fc_000c7cef03cac861016aa95aeff1dc87d1b940b9235eee1e3a","toolName":"read","startedAt":"2026-09-15T14:49:20.285Z","args":{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6500-6504:raw"},"intent":"Recovering final long recurrence"},"id":"4dd9df42","parentId":"aeeea946","timestamp":"2026-09-15T14:49:20.285Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_TNybKMJryhyJJNkPGh4ZAF2P|fc_000c7cef03cac861016aa95aeff1ec87d196cdf6b02ee80794","toolName":"read","startedAt":"2026-09-15T14:49:20.286Z","args":{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py:360-427"},"intent":"Reading runner result sequencing"},"id":"d526d750","parentId":"4dd9df42","timestamp":"2026-09-15T14:49:20.286Z"}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_XdFhbTE66F0huPTSLvvyYtf9|fc_000c7cef03cac861016aa95aeff1f487d18ee0f70b611ed076","toolName":"grep","startedAt":"2026-09-15T14:49:20.286Z","args":{"path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/killscoping.rs;.worktrees/hertz-ir86-disk-delta/crates/xtask/src/main.rs"},"intent":"Checking scope gate alternate names"},"id":"d6332a7a","parentId":"d526d750","timestamp":"2026-09-15T14:49:20.286Z"}
{"type":"message","id":"b21eb200","parentId":"d6332a7a","timestamp":"2026-09-15T14:49:20.286Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Reading IR107 amendment**"},{"type":"toolCall","id":"call_uhzDd3jpEYAFswTRgjE8QsuG|fc_000c7cef03cac861016aa95aeff1dc87d1b940b9235eee1e3a","name":"read","arguments":{"i":"Recovering final long recurrence","path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6500-6504:raw"},"intent":"Recovering final long recurrence"},{"type":"toolCall","id":"call_TNybKMJryhyJJNkPGh4ZAF2P|fc_000c7cef03cac861016aa95aeff1ec87d196cdf6b02ee80794","name":"read","arguments":{"i":"Reading runner result sequencing","path":".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py:360-427"},"intent":"Reading runner result sequencing"},{"type":"toolCall","id":"call_XdFhbTE66F0huPTSLvvyYtf9|fc_000c7cef03cac861016aa95aeff1f487d18ee0f70b611ed076","name":"grep","arguments":{"i":"Checking scope gate alternate names","pattern":"taskkill|wmic|pkill|scop","path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/killscoping.rs;.worktrees/hertz-ir86-disk-delta/crates/xtask/src/main.rs","case":false,"gitignore":false,"skip":null},"intent":"Checking scope gate alternate names"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":4800,"output":292,"cacheRead":130176,"cacheWrite":0,"totalTokens":135268,"reasoningTokens":93,"cost":{"input":0.048,"output":0.0146,"cacheRead":0.130176,"cacheWrite":0,"total":0.192776}},"stopReason":"toolUse","timestamp":1789483748062,"responseId":"resp_000c7cef03cac861016aa95ae4494c87d1afc2e253424806c1","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_000c7cef03cac861016aa95ae7396087d1acc69579fe703d17","type":"reasoning","content":[],"encrypted_content":"gAAAAABqqVrv4SI16cOeoxJwAQziF-IweOzrT73vdiEnWZCwEW5Bp7cwul_tcU4Q0mBhy5arkMVFhKUMW4YnSkntFbhGdElU9NDB057Bh35Gah84z4khHacQwBhqjjttXVs4_C91d8EFLvrmpVwMy12stRA_6byIOEhUXcGBzvZe3Z-a7YdnGNl2mlDk1Zx0SRdbk5dPvRu7MpIDrLQGh-MkU85u5Mvw2dV3oRpyB4XjNI-UrJ4MOyeS1urCj99gk8lsj7XnanRY3k5RygQJQvhfUBwOrglFVB6eX2OflYYZgsGpXE45EwUswHauCectkkHI42NZDTssLrI_6LMz8EXF1YxdYmqDtzW4tiz7G3Hdom7BZz2maxNN8-oknqVZwFRy_LKs9Nx1D-5plXUQnxbGKXZRzgPEU9JslTHLRyPXbdyNHrkQEF4R1YqdDCZ98ICpBHheFvq4NuMOKbdx3DM08ZFlwAry857QNOq2o6jCh04Q5oLmcJKd3cU-KzYB4x-G8J_hxMq2lIjROgOWZ0-MBtpiCApt7xMr8Zs5sETxz-F_qA0ZDHfS7SaeqHXyKnD3PVX1B1n09qhXFowniRJSSSEI2btuDVj1FW5YzFhynybciH7TcgRfR_fgoY6BqtahI32bKzn8oMStETC6hqAWFO2a8sJCppuYnaNcOC2w-ZOCCYpQrqpMjv2Ty5VE9FEcHbn883lQjcuA8pW46g3dKXhOogMhOKgCJqwRrMRFibUpuUcYnpt0Vep1Q2A53o0nr8EebRrc9H6SiD28TPLdbkmI86kGzSPoKB2h6RmKVwCPZhrMebtms3SCUIJ3o-cifPkA_AZv-3T73VaYu9M8EDZLinIa37xRjeMBJiLOrYB250mkwf7ovBzLcv_-O2ZpTuJDKl-8RKSEP93C4UQSkWk5buP-yOHe2OSORayhOw3afJSgxeq_3SGHVi6Ab1Tv5v9KB6pa7Z_Wd3He7hSgP3aTXCPxHuQm98fTzP-6JmKc6HS4LSSSQppQfc9_wY4slpwTQ5AYEUd4km-o7OvmJguCb0C_0CFYwnFwFtCP7eAPI0_7OUyf1BsFh8hMrgiAxioPdnztH3nVJPuUAIFJkfEPtBiVNDzAvBHBmoMM4CAFVk5WtvluAVpfAbAV9FopYJtEepUp8K1vP0QTTGRSPgxTQFDiEsQYTJADDmE1Nj64J6d2fAzoRFyzhk2c0gd7HUPojFkT7WOA4YpeNjRj8Omak2lXfZBlcTs1KAB8EMdVPAX0RChXvDfX3anJcg-bDcssW0dUi8jUR-L7onBaJyWEMQa2XW5ceOy856BFD9KjqTHIWLuFdkNpswU_nMnRHkjR8rdr9pzBEV_-u6ETZ4HzLHZePd5SwHRnW2ejcp3ZP8fSpx-RXBjmsPMNpY5Gc9qNCXQDsnOXtQIZqoC6W5mC0zEAQpkwNkQCAxAbPBpm48HAdWCqmGvwJHXVEqgt8E_6yFos20FW5O-BCos0mG2S7Q7pueMhAzWDd0FmSjb9_p-hxb1Kq5YMH_fhzSvVk2dc4e_7GJQyO08jTh0oKe2pGiVTE-xs2k_P7UHqAApLNOgqR3nCm7c08L8rRgS3YLI9e8CWpbDuEHV_nmUp5YohwL9bOblhTICANHuZ8hYloZFn76_2XEORLgrkON2FybxpWAplug03IMqhcXolhQBECuG3IKPuB9lVw2d_LjRpm3ca3sao5yTGbN4uv0j-TJfgB06IW6U4sHpOGV2edckIpXZPAzdCmi3lPjuFXpIcdY_BSCFK6ev2Ycn02cuEEvRdG5_c3IHR1AKCx41syDFB0AITbUrkjpjE4Tog2LSVOk8o-8anPYNX2jp7bB_zJ_dwbcno","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"summary":[{"type":"summary_text","text":"**Reading IR107 amendment**"}],"metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95aeff1dc87d1b940b9235eee1e3a","type":"function_call","status":"completed","arguments":"{\"i\":\"Recovering final long recurrence\",\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md:6500-6504:raw\"}","call_id":"call_uhzDd3jpEYAFswTRgjE8QsuG","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95aeff1ec87d196cdf6b02ee80794","type":"function_call","status":"completed","arguments":"{\"i\":\"Reading runner result sequencing\",\"path\":\".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py:360-427\"}","call_id":"call_TNybKMJryhyJJNkPGh4ZAF2P","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"read","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95aeff1f487d18ee0f70b611ed076","type":"function_call","status":"completed","arguments":"{\"i\":\"Checking scope gate alternate names\",\"pattern\":\"taskkill|wmic|pkill|scop\",\"path\":\".worktrees/hertz-ir86-disk-delta/crates/xtask/src/killscoping.rs;.worktrees/hertz-ir86-disk-delta/crates/xtask/src/main.rs\",\"case\":false,\"gitignore\":false,\"skip\":null}","call_id":"call_XdFhbTE66F0huPTSLvvyYtf9","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"grep","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}}]},"duration":12200.329499989748,"ttft":3183.192000001669,"completedAt":1789483760284,"contextSnapshot":{"promptTokens":134976,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"message","id":"a4b8d049","parentId":"b21eb200","timestamp":"2026-09-15T14:49:20.299Z","message":{"role":"toolResult","toolCallId":"call_uhzDd3jpEYAFswTRgjE8QsuG|fc_000c7cef03cac861016aa95aeff1dc87d1b940b9235eee1e3a","toolName":"read","content":[{"type":"text","text":"  window-5 and window-6 admission census records were silently OVERWRITTEN by the later windows\n  writing the same path, so those two ENDs stand on the transcript alone, not on a record. · **Size:** one env line in the rig\n  (done); two comment lines in tests; one filename in the rig.\n\n- **Instances 9-11, all 2026-09-12, #304 W-2 (one night, three different surfaces).** NINTH (doyle's gate leg, 03:20Z): `cargo ... | tail` over non-interactive ssh to kitsubito returned 0 while cargo was off PATH in the non-login shell — already named in releases#304 comment 5643115673 and filed here for the count. TENTH (hertz, 05:30Z, while writing register entries about instruments that lie): `traceable-reqs check 2>&1 | tail -20; echo \"CHECK_EXIT=$?\"` printed `CHECK_EXIT=0` — tail's exit over a checker that exits 1, i.e. a 312-finding red read as clean. He re-ran it only because the register had made him suspicious of his own zero, which is the entry doing its job and not a skill. ELEVENTH (todlando, 05:20Z, a NEW surface — the harness itself): `cargo nextest run ... | tail -30` wedged at `--list --format terse`; he killed cargo and nextest by pid, and the HARNESS task summary then reported \"completed (exit code 0)\" because the pipeline's exit is tail's. A killed run with ZERO tests executed was rendered as a success by a first-party tool — the same generalisation IR-116 instance 2 forced. Near-miss in the same arm: a 0-byte output file read as the wedge when it is just tail buffering until EOF. Fix adopted: the rerun writes to a file and the verdict reads the file; no pipe between a test runner and a verdict.\n\n[Showing lines 6500-6504 of 6938. Use :6505 to continue]"}],"details":{"truncation":{"content":"  window-5 and window-6 admission census records were silently OVERWRITTEN by the later windows\r\n  writing the same path, so those two ENDs stand on the transcript alone, not on a record. · **Size:** one env line in the rig\r\n  (done); two comment lines in tests; one filename in the rig.\r\n\r\n- **Instances 9-11, all 2026-09-12, #304 W-2 (one night, three different surfaces).** NINTH (doyle's gate leg, 03:20Z): `cargo ... | tail` over non-interactive ssh to kitsubito returned 0 while cargo was off PATH in the non-login shell — already named in releases#304 comment 5643115673 and filed here for the count. TENTH (hertz, 05:30Z, while writing register entries about instruments that lie): `traceable-reqs check 2>&1 | tail -20; echo \"CHECK_EXIT=$?\"` printed `CHECK_EXIT=0` — tail's exit over a checker that exits 1, i.e. a 312-finding red read as clean. He re-ran it only because the register had made him suspicious of his own zero, which is the entry doing its job and not a skill. ELEVENTH (todlando, 05:20Z, a NEW surface — the harness itself): `cargo nextest run ... | tail -30` wedged at `--list --format terse`; he killed cargo and nextest by pid, and the HARNESS task summary then reported \"completed (exit code 0)\" because the pipeline's exit is tail's. A killed run with ZERO tests executed was rendered as a success by a first-party tool — the same generalisation IR-116 instance 2 forced. Near-miss in the same arm: a 0-byte output file read as the wedge when it is just tail buffering until EOF. Fix adopted: the rerun writes to a file and the verdict reads the file; no pipe between a test runner and a verdict.\r","truncated":true,"truncatedBy":"lines","totalLines":439,"totalBytes":1636,"outputLines":5,"outputBytes":1636,"lastLinePartial":false,"firstLineExceedsLimit":false},"totalLines":6938,"displayContent":{"text":"  window-5 and window-6 admission census records were silently OVERWRITTEN by the later windows\r\n  writing the same path, so those two ENDs stand on the transcript alone, not on a record. · **Size:** one env line in the rig\r\n  (done); two comment lines in tests; one filename in the rig.\r\n\r\n- **Instances 9-11, all 2026-09-12, #304 W-2 (one night, three different surfaces).** NINTH (doyle's gate leg, 03:20Z): `cargo ... | tail` over non-interactive ssh to kitsubito returned 0 while cargo was off PATH in the non-login shell — already named in releases#304 comment 5643115673 and filed here for the count. TENTH (hertz, 05:30Z, while writing register entries about instruments that lie): `traceable-reqs check 2>&1 | tail -20; echo \"CHECK_EXIT=$?\"` printed `CHECK_EXIT=0` — tail's exit over a checker that exits 1, i.e. a 312-finding red read as clean. He re-ran it only because the register had made him suspicious of his own zero, which is the entry doing its job and not a skill. ELEVENTH (todlando, 05:20Z, a NEW surface — the harness itself): `cargo nextest run ... | tail -30` wedged at `--list --format terse`; he killed cargo and nextest by pid, and the HARNESS task summary then reported \"completed (exit code 0)\" because the pipeline's exit is tail's. A killed run with ZERO tests executed was rendered as a success by a first-party tool — the same generalisation IR-116 instance 2 forced. Near-miss in the same arm: a 0-byte output file read as the wedge when it is just tail buffering until EOF. Fix adopted: the rerun writes to a file and the verdict reads the file; no pipe between a test runner and a verdict.\r","startLine":6500,"lineNumbers":[6500,6501,6502,6503,6504]},"fileSize":676479,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\docs\\INFRA-REGISTER.md"},"truncation":{"direction":"head","truncatedBy":"lines","totalLines":6938,"totalBytes":1636,"outputLines":5,"outputBytes":1636,"shownRange":{"start":6500,"end":6504},"nextOffset":6505}}},"isError":false,"timestamp":1789483760299}}
{"type":"message","id":"44719d7a","parentId":"a4b8d049","timestamp":"2026-09-15T14:49:20.307Z","message":{"role":"toolResult","toolCallId":"call_TNybKMJryhyJJNkPGh4ZAF2P|fc_000c7cef03cac861016aa95aeff1ec87d196cdf6b02ee80794","toolName":"read","content":[{"type":"text","text":"def main():\n    parser = argparse.ArgumentParser(description=__doc__)\n…\n    claimed = False\n    result = 0\n    try:\n        if not w0.preflight() or not census(root, output, \"before\", env):\n            raise ValueError(\"quiet-window or scoped census refused\")\n        save(output / \"builders-before.json\", builder_snapshot())\n        if not w0.disk_floor(root, output, \"start\", xtask):\n            raise ValueError(\"disk floor refused\")\n        result, ok = run_producer(root, output, \"pool-claim\", [str(xtask), \"pool-claim\", \"--pool\", str(target), \"--label\", \"local-lane\"], 30, env, lambda: meter(\"claim\"))\n        claimed = result == 0\n        result = final_status(result, ok)\n        if not claimed:\n            # A terminated claim writer may have persisted ownership before exit.\n            # Do not release an unproven claim: it may still belong to another lane.\n            print(\"POOL_CUSTODY_UNPROVEN: claim did not complete successfully; \"\n                  \"inspect POOL-OWNER.json before any takeover or deletion\", file=sys.stderr)\n        for step in plan[\"steps\"]:\n            if result:\n                break\n            name = step[\"name\"]\n            if not w0.preflight() or not meter(f\"{name}-before\") or not census(root, output, f\"{name}-before-census\", env):\n                result = REFUSED\n                break\n            if \"nextest\" in step:\n                listing, argv = selected_commands(step[\"nextest\"])\n                result, ok = run_producer(root, output, name + \"-inventory\", listing, step[\"timeout_seconds\"], env, lambda: meter(name + \"-inventory\"), json_stdout=True)\n                after_ok = observe_after(root, output, name + \"-inventory\", env, meter)\n                ok = ok and after_ok\n                if result or not ok:\n                    result = final_status(result, ok)\n                    break\n                inventory = json.loads((output / f\"{name}-inventory.stdout\").read_text(encoding=\"utf-8\"))\n                save(output / f\"{name}-selection.json\", selected_inventory(inventory))\n            else:\n                argv = step[\"argv\"]\n            result, ok = run_producer(root, output, name, argv, step[\"timeout_seconds\"], env, lambda: meter(name))\n            after_ok = observe_after(root, output, name, env, meter)\n            result = final_status(result, ok and after_ok)\n            if result:\n                break\n    except (OSError, ValueError, psutil.Error, subprocess.TimeoutExpired) as error:\n        print(f\"LANE_OBSERVATION_FAILED: {error}\", file=sys.stderr)\n        result = final_status(result, False)\n    finally:\n        # Release through the prebuilt executable; this driver never deletes target.\n        if claimed:\n            try:\n                released = subprocess.run([str(xtask), \"pool-release\", \"--pool\", str(target)], cwd=root, env=env, capture_output=True, text=True, timeout=30)\n                save(output / \"pool-release.json\", {\"exit\": released.returncode, \"stdout\": released.stdout, \"stderr\": released.stderr})\n                result = final_status(result, released.returncode == 0)\n            except (OSError, subprocess.TimeoutExpired) as error:\n                print(f\"POOL_RELEASE_UNPROVEN: {error}\", file=sys.stderr)\n                result = final_status(result, False)\n        lock.close()\n    try:\n        (output / \"lane.exit\").write_text(f\"{result}\\n\", encoding=\"utf-8\")\n    except OSError as error:\n        print(f\"LANE_STATUS_WRITE_FAILED: {error}; producer/driver exit={result}\", file=sys.stderr)\n        result = final_status(result, False)\n    return result if result >= 0 else 128 - result\n\n\nif __name__ == \"__main__\":\n    try:\n        sys.exit(main())\n    except (OSError, ValueError, subprocess.TimeoutExpired) as error:\n        print(f\"LANE_REFUSED: {error}\", file=sys.stderr)\n        sys.exit(REFUSED)"}],"details":{"totalLines":426,"displayContent":{"text":"def main():\n    parser = argparse.ArgumentParser(description=__doc__)\n…\n    claimed = False\r\n    result = 0\r\n    try:\r\n        if not w0.preflight() or not census(root, output, \"before\", env):\r\n            raise ValueError(\"quiet-window or scoped census refused\")\r\n        save(output / \"builders-before.json\", builder_snapshot())\r\n        if not w0.disk_floor(root, output, \"start\", xtask):\r\n            raise ValueError(\"disk floor refused\")\r\n        result, ok = run_producer(root, output, \"pool-claim\", [str(xtask), \"pool-claim\", \"--pool\", str(target), \"--label\", \"local-lane\"], 30, env, lambda: meter(\"claim\"))\r\n        claimed = result == 0\r\n        result = final_status(result, ok)\r\n        if not claimed:\r\n            # A terminated claim writer may have persisted ownership before exit.\r\n            # Do not release an unproven claim: it may still belong to another lane.\r\n            print(\"POOL_CUSTODY_UNPROVEN: claim did not complete successfully; \"\r\n                  \"inspect POOL-OWNER.json before any takeover or deletion\", file=sys.stderr)\r\n        for step in plan[\"steps\"]:\r\n            if result:\r\n                break\r\n            name = step[\"name\"]\r\n            if not w0.preflight() or not meter(f\"{name}-before\") or not census(root, output, f\"{name}-before-census\", env):\r\n                result = REFUSED\r\n                break\r\n            if \"nextest\" in step:\r\n                listing, argv = selected_commands(step[\"nextest\"])\r\n                result, ok = run_producer(root, output, name + \"-inventory\", listing, step[\"timeout_seconds\"], env, lambda: meter(name + \"-inventory\"), json_stdout=True)\r\n                after_ok = observe_after(root, output, name + \"-inventory\", env, meter)\r\n                ok = ok and after_ok\r\n                if result or not ok:\r\n                    result = final_status(result, ok)\r\n                    break\r\n                inventory = json.loads((output / f\"{name}-inventory.stdout\").read_text(encoding=\"utf-8\"))\r\n                save(output / f\"{name}-selection.json\", selected_inventory(inventory))\r\n            else:\r\n                argv = step[\"argv\"]\r\n            result, ok = run_producer(root, output, name, argv, step[\"timeout_seconds\"], env, lambda: meter(name))\r\n            after_ok = observe_after(root, output, name, env, meter)\r\n            result = final_status(result, ok and after_ok)\r\n            if result:\r\n                break\r\n    except (OSError, ValueError, psutil.Error, subprocess.TimeoutExpired) as error:\r\n        print(f\"LANE_OBSERVATION_FAILED: {error}\", file=sys.stderr)\r\n        result = final_status(result, False)\r\n    finally:\r\n        # Release through the prebuilt executable; this driver never deletes target.\r\n        if claimed:\r\n            try:\r\n                released = subprocess.run([str(xtask), \"pool-release\", \"--pool\", str(target)], cwd=root, env=env, capture_output=True, text=True, timeout=30)\r\n                save(output / \"pool-release.json\", {\"exit\": released.returncode, \"stdout\": released.stdout, \"stderr\": released.stderr})\r\n                result = final_status(result, released.returncode == 0)\r\n            except (OSError, subprocess.TimeoutExpired) as error:\r\n                print(f\"POOL_RELEASE_UNPROVEN: {error}\", file=sys.stderr)\r\n                result = final_status(result, False)\r\n        lock.close()\r\n    try:\r\n        (output / \"lane.exit\").write_text(f\"{result}\\n\", encoding=\"utf-8\")\r\n    except OSError as error:\r\n        print(f\"LANE_STATUS_WRITE_FAILED: {error}; producer/driver exit={result}\", file=sys.stderr)\r\n        result = final_status(result, False)\r\n    return result if result >= 0 else 128 - result\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    try:\r\n        sys.exit(main())\r\n    except (OSError, ValueError, subprocess.TimeoutExpired) as error:\r\n        print(f\"LANE_REFUSED: {error}\", file=sys.stderr)\r\n        sys.exit(REFUSED)\r","startLine":313,"lineNumbers":[313,314,null,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426]},"fileSize":22224,"meta":{"source":{"type":"path","value":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\.github\\ci\\local-lane.py"}}},"isError":false,"timestamp":1789483760306}}
{"type":"message","id":"b7717992","parentId":"44719d7a","timestamp":"2026-09-15T14:49:20.323Z","message":{"role":"toolResult","toolCallId":"call_XdFhbTE66F0huPTSLvvyYtf9|fc_000c7cef03cac861016aa95aeff1f487d18ee0f70b611ed076","toolName":"grep","content":[{"type":"text","text":" 717|///\n*718|/// The scope is ruled rather than convenient: CLI help and CLI stdout/stderr,\n 719|/// AND the daemon's operator diagnostics — which is one surface WIDER than the\n 720|/// original brief's \"the xtask public-help gate\", because the five literals that\n 721|/// re-opened this class lived in daemon diagnostics and the narrower home could\n...\n 1257|///\n*1258|/// Section-scoped: a `rev` in some other table (a `[dependencies]` git dep, say)\n 1259|/// is not a patch pin and must not answer for one.\n 1260|// [impl->REQ-CI-LOAD-BEARING-PATCH-PIN]\n 1261|fn patched_git_rev(cargo_toml: &str, krate: &str) -> Option<String> {\n...\n 2818|        }\n*2819|        // Scope the dummy seed to a child process, never the parallel test host.\n 2820|        let child = std::process::Command::new(std::env::current_exe().unwrap())\n 2821|            .args([\"--exact\", TEST, \"--nocapture\"])\n 2822|            .env(CHILD, \"1\")\n...\n 3576|    println!(\n*3577|        \"total {} across {} pool(s); {} reclaimable in this sweep's scope\",\n 3578|        gib(total),\n 3579|        rows.len(),\n 3580|        gib(reclaimable)\n\nSkipped missing paths: .worktrees/hertz-ir86-disk-delta/crates/xtask/src/killscoping.rs"}],"details":{"scopePath":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/main.rs","searchPath":"C:\\Users\\decid\\Documents\\projects\\spt-core\\.worktrees\\hertz-ir86-disk-delta\\crates\\xtask\\src\\main.rs","cwd":"C:\\Users\\decid\\Documents\\projects\\spt-core","matchCount":4,"fileCount":1,"files":[".worktrees/hertz-ir86-disk-delta/crates/xtask/src/main.rs"],"fileMatches":[{"path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/main.rs","count":4}],"truncated":false,"displayContent":"  717│///\n *718│/// The scope is ruled rather than convenient: CLI help and CLI stdout/stderr,\n  719│/// AND the daemon's operator diagnostics — which is one surface WIDER than the\n  720│/// original brief's \"the xtask public-help gate\", because the five literals that\n  721│/// re-opened this class lived in daemon diagnostics and the narrower home could\n     │...\n 1257│///\n*1258│/// Section-scoped: a `rev` in some other table (a `[dependencies]` git dep, say)\n 1259│/// is not a patch pin and must not answer for one.\n 1260│// [impl->REQ-CI-LOAD-BEARING-PATCH-PIN]\n 1261│fn patched_git_rev(cargo_toml: &str, krate: &str) -> Option<String> {\n     │...\n 2818│        }\n*2819│        // Scope the dummy seed to a child process, never the parallel test host.\n 2820│        let child = std::process::Command::new(std::env::current_exe().unwrap())\n 2821│            .args([\"--exact\", TEST, \"--nocapture\"])\n 2822│            .env(CHILD, \"1\")\n     │...\n 3576│    println!(\n*3577│        \"total {} across {} pool(s); {} reclaimable in this sweep's scope\",\n 3578│        gib(total),\n 3579│        rows.len(),\n 3580│        gib(reclaimable)","missingPaths":[".worktrees/hertz-ir86-disk-delta/crates/xtask/src/killscoping.rs"]},"isError":false,"timestamp":1789483760322}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_lZZ5udOyvgROdDavakstsbxV|fc_000c7cef03cac861016aa95af9f05487d1bd4a2dbe427daa0e","toolName":"yield","startedAt":"2026-09-15T14:52:11.187Z"},"id":"3e973037","parentId":"b7717992","timestamp":"2026-09-15T14:52:11.187Z"}
{"type":"message","id":"af075406","parentId":"3e973037","timestamp":"2026-09-15T14:52:11.188Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"**Compiling 67-row account list**"},{"type":"toolCall","id":"call_lZZ5udOyvgROdDavakstsbxV|fc_000c7cef03cac861016aa95af9f05487d1bd4a2dbe427daa0e","name":"yield","arguments":{"type":null,"data":{"summary":"Read IR71–137 through amendments: all 67 IDs accounted for. Best small residual is IR90's test-side mid-run disk context, not another generic disk-floor tool. IR82 remains unbuilt but already belongs to todlando's composition. IR109 retirement is genuinely open but broad (312 legacy tags). Several tempting tickets are already built: IR92 inject publication, IR104 pin, IR107 premise assertions, IR135/136 and IR137. Windows investigations remain held; IR86 closure stays with Main.","files":[{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md","description":"Entire assigned IR71–137 population read, including late reversals and final corrections; also read current sweep composition at lines 1–57."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs","description":"Lines 75–110 implement IR92's successful-inject observation-only MSG_IN publication despite stale OPEN register language."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs","description":"Line 476 still overwrites daemon.pid without predecessor preservation: IR82 remedy remains absent."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs","description":"Lines 114–123 still silently return port0 when ephemeral posture wins; IR78 remains a tiny touch-triggered notice."},{"path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/brainread.rs","description":"Lines 194–208 retain stream-name predicate; lines 264–310 distinguish repository-wide retired-call scan from hand-listed semantic policy registry. IR94 remains a real classifier gap."},{"path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/diskfloor.rs","description":"Existing disk-floor implementation at lines 64–102; must reuse, not redispatch under IR90."},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py","description":"Lines 360–398 already admit/census/meter before and observe after producers; 402–410 release through prebuilt xtask."},{"path":".worktrees/hertz-ir86-disk-delta/traceable-reqs.toml","description":"Line25 still module_banner='accept': IR109 transitional exemption remains live."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs","description":"PullLink failure sites at approximately 187–211 still use bare expect('pull')/expect('serve'), without current free-space context."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs","description":"Lines1369ff already assert no-repository fixture premise requested in IR107."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.rs","description":"Lines799ff already assert no-repository fixture premise requested in IR107."},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/traceable-reqs.sh","description":"Lines5–6 centralize installed CI checker pin0.4.1; supports spent IR75/104 original remedies and landed IR135."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-store/src/proc.rs","description":"kill_pid(pid) at46 and kill_pid_tree(root) at430 remain bare-number primitives; do not infer IR81 primitive cutover from authenticated consumer repairs."},{"path":".worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md","description":"Lines26–80 already document quiet-window/ancestry boundaries; IR137 discipline follows at81ff."}],"architecture":"Register headings are historical handles, not current state. Driver safeguards, product primitives, test fixtures, box configuration, and exercised workflow receipts are separate seams. Existing local-lane already composes floor/census/prebuilt-release mechanisms; inject already owns publication; serving fixture already composes broker/seed/docs planes. Remaining work must target residual callers/context or reconcile receipts, not recreate these modules.","report":"Scope and evidence: R below means .worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md. Other paths are relative to that same fixed worktree. Read-only source/record investigation only: no execution, process/service probes, tests, builds, lint, edits, or new files. Existing receipts are quoted as recorded evidence, not rerun or independently reverified. Known landed SHAs supplied by Main/user are treated as ground truth.\n\nRANKED ACTIONABLE RESIDUALS\n1. IR90 — RIPE-NOW, small residual implementation. Trigger is explicitly 'now' (R5425), reinforced by next-intake composition R43–47 and measured disk-full product-shaped refusal R5341–5356. Already-built prerequisite: crates/xtask/src/diskfloor.rs:64–102 and .github/ci/local-lane.py:360–398. Unbuilt specific seam: crates/spt-daemon/tests/sync.rs:187–211 still turns request_sync/serve_sync errors into bare expect('pull')/expect('serve'); inspected sync/twohost files have no free-space diagnostic. Owner: hertz test/driver package. Smallest next step: scope a test-side error-context helper/caller change that reports actual temp/store-volume free bytes on the real error, then assess remaining rig-start adopters against existing disk-floor. Do NOT build a second floor meter or claim local-lane lacks pre/post readings. Execution proof waits for authorized window.\n2. IR82 — RIPE composition, small product change, EXISTING OWNER NOT NEW DISPATCH. Ruled remedy and owner at R4650–4682; prior #285 completion explicitly did not build it (R51). Source still unconditional std::fs::write at crates/spt-daemon/src/daemon.rs:476. Owner todlando, product pid-identity composition. Minimal next step: acknowledge/take the existing assignment, implement the stipulated predecessor record plus one-generation pidfile retention; keep socket liveness and countable DAEMON_AUTOSTART unchanged. Not an incident-cause closure.\n3. IR109 — RIPE-NOW dedicated retirement lane, NOT SMALL. R6569–6587 ratifies temporary #304 exception and explicitly orders separate relocation lane. traceable-reqs.toml:25 still accepts module banners; checker pin0.4.1 now actually exists in .github/ci/traceable-reqs.sh:6. Owner doyle intake/traceability maintainer (implementation owner not named). Minimum next step: obtain exact current legacy-tag population, relocate actual evidence tags and remove acceptance key as one dedicated lane. Historical312 is not a fresh census. Never 'fix' by re-pinning or broadening exemption.\n4. IR89, with IR83 — RIPE-NOW RECEIPT-ONLY first. R5185–5199 explicitly says the next-golden trigger has already fired and workflow is LANDED. Owner hertz workflow / doyle acceptance. Minimum next step: recover exact A/B pre-ceremony probe-step execution/skipped/failed receipts from an already completed golden (S5 overall green is not enough), plus direction-witness LIST/real-body evidence for IR83. No box change or second UDP guard. This is the cheapest immediate closure work.\n5. IR92, IR104, IR107, IR135/136 — RIPE-NOW RECORD RECONCILIATION, not implementation. See complete dispositions below. Especially IR92 source directly contradicts both its heading and R39–41. Review relevant existing consumer/acceptance receipts and correct scope/status; do not recreate injected MSG_IN publication or premise assertions.\n\nCONDITIONAL SMALL RIDERS, NOT UNCONDITIONAL DISPATCHES\n• IR78: docshost.rs:114–123 confirms silent override persists; exact trigger R4099–4101 is next docshost touch or a new explicit-port belief incident. Owner docshost product maintainer; one notice naming both env vars when a supplied override loses. No fresh trigger proved in this sweep.\n• IR94: brainread.rs:194–208 still keys lifetime policy on serve_*_feed/serve_attach; :264–310 scans all Rust for general symbols but retains specific policy files/functions. Exact trigger R5668–5671: next brainread/xtask touch, mandatory before bounded serve_sync migration. Owner tooling/hertz with todlando semantic census. Minimal next step on that touch: behavior-derived fail-unclassified population and printed census, not merely append serve_sync to another whitelist.\n• IR71/72/77/93/111 likewise remain genuine touch-triggered work, not ripe because OPEN.\n\nCOMPLETE PER-ID DISPOSITIONS (67 IDs)\n71 — TOUCH-TRIGGERED. Persisted controller-release breadcrumb still owed; next controller lifecycle/breadcrumb touch or PR174 barrier timeout. R3888–3911. No fresh trigger established.\n72 — TOUCH-TRIGGERED. Named perch/seat custody read model; next roster/status change or another rig needing named-holder reap. R3912–3945. Do not substitute process-wide daemon status.\n73 — COMPLETED. Eight checkout/floor reorder sites and both docs rereads built; remaining capacity/coupling belongs IR86. R3946–3969.\n74 — TOUCH-TRIGGERED / historical box state UNKNOWN. Next Linux rig/box-audit lifecycle work, not authorization to sweep live /tmp now. 21,643 homes is dated measurement, not current count. R3970–3983.\n75 — ORIGINAL INSTANCE SPENT; RECEIPT/status reconciliation. Missing Linux checker is superseded by IR135's hand-install and real0.4.1 smoke (R6916–6918), plus centralized installed pin. Do not install it again based on 127 from August. Future box-audit/version admission remains discipline. R3984–3998.\n76 — PARTLY BUILT, TOUCH-TRIGGERED residual. Existing ws272 drivers carry three-arm gate and GOLDEN-CI.md:26–80 quiet/ancestry contract; local-lane reuses gate. Dedicated CI foreign-builder count/CPU census and universal brief/template adoption not established here. Current heavy Windows hold is binding, not a request for more code. R3999–4042.\n77 — TOUCH-TRIGGERED. Spawn/child-entry/readiness timing split; next boot/brainproc-ready or family rider. R4043–4074.\n78 — TOUCH-TRIGGERED confirmed residual; tiny notice, source docshost.rs:114–123. R4075–4102.\n79 — TOUCH-TRIGGERED lifecycle package. Common authenticated breadcrumb reaper exists, but it is not a Drop guard and does not prove panic-safe adoption. Original first four tests yielded no Drop/DaemonReaper match; no complete22-site current census claimed. Next common touch, and distinguish unwind from hard process death (R47–49). R4103–4183.\n80 — BLOCKED Windows measurement / partially classified fixture family. Late amendments identify cmd→ping wrapper fixture, direct production spawn,12-member noisy OS partition; not an undiagnosed product leak and no count-only progress claim. Residual population unclassified; existing ENV-read fix already built. R4184–4465. Coordinate with108, not duplicate work.\n81 — OPEN product primitive + gate residual, existing owners. proc.rs:46/:430 remain bare-number signatures; consumer authenticated reaper and adapter9c87372 do not finish signature cutover. Todlando product, hertz gate; trigger next proc/xtask gate touch. Adapter half closed. R4466–4590.\n82 — RIPE assigned product composition, unbuilt source; see rank2. R4591–4696.\n83 — OPEN direction-witness durability/acceptance; BOX half spent. Universal LAN-only rule explicitly superseded; no new operator/ACL action. Reconcile current LIST/NOT-A-WITNESS enforcement and reverse real-body witness; co-own with89. R4697–4833.\n84 — ORIGINAL STAMP BUILT; residual follow-up only. Stamp landed with entry; all-arm regression enforcement remains a separately named follow-up. Historical65s question must not be reopened without IR89's later attribution (three faces of firewall/ACL/shared-path cause). R4834–4883, R5217ff.\n85 — BLOCKED diagnostic continuation. Cap changes already built; arm1 void, old-sha slowdown only proves head growth unnecessary. Needs IR90 guard and authorized no-CI/no-main-push window; AB then BA, not repeated AB. Do not identify Defender from correlation or widen caps. R4884–5043.\n86 — MAIN-OWNED. Both floors and inline delta known landed (5e05f02d/0cda6235/82333ca1). Do not redispatch. Main must reconcile final automation plus independent docs-dependency slice before retirement; no closure conclusion delegated here. R5044–5092.\n87 — TOUCH-TRIGGERED unresolved scheduling seam. Next golden/twohost touch; old R294 recurrence includes own PR starving roleA, not only foreign runs. Minimum existing-lane decision is partner-start barrier/separate rendezvous scheduling contract, not larger pairing timeout. R5093–5145. Current source choreography not exhaustively re-audited.\n88 — BUILT in current local-lane; TOUCH/receipt residual elsewhere. local-lane.py:402–410 invokes prebuilt xtask. Reconcile runbook/all other teardown adopters only when touched. Preserve exe AND DLL if claiming runnable retention, otherwise archival. R5146–5182.\n89 — RECEIPT-ONLY ripe; boxes applied and guard landed; exact golden probe-step acceptance missing from record. See rank4. R5183–5338.\n90 — RIPE-NOW residual error context/start adoption, not new floor machinery. See rank1. R5339–5427.\n91 — CLOSED.18 cited files tracked in place;543 uncited artifacts preserved, root-specific ignores. R5428–5481.\n92 — SOURCE-BUILT; stale register requires reconciliation. inject.rs:75–110 publishes exactly on Some((true,_)), observation-only, target/peer/msg-id present; no fresh publisher implementation. Relay ordering/per-message exact-once assertion obligations remain separate, not automatically closed by this source read. R5482–5613.\n93 — TOUCH-TRIGGERED / packaging decision required. PDB retention/install or symbol store; next installer/release packaging touch. Successful release build is not symbol availability. R5614–5642.\n94 — TOUCH-TRIGGERED actual gate blind spot; see conditional rider. R5643–5672.\n95 — PARTLY INSTRUMENTED, diagnostic continuation/triage UNKNOWN. Original comparison has already run; no blanket317-site edit. Historical321 population approximate,15 outside classifier unclassified; retained exchange-correlated create/retire trace is separate product design, not two-IPC reuse. Needs selected diagnostic intake, not budget retuning. R5673–5927.\n96 — BLOCKED/cause UNKNOWN. Candidate-vs-diagnostic differential confounded by97; diagnostic pool deleted, next candidate discriminator requires rebuild and authorized quiet heavy window. R5928–5963; preserved CLASSIFICATION-AMENDMENT-2-doyle.md and reclaim receipts remain evidence.\n97 — PARTLY BUILT procedure. local-lane.py:380–398 already performs before/after producer census; exclusive START/END token discipline remains runtime adoption. No new repeated-run experiment authorized; observe actual launch not announcement. R5964–6006.\n98 — INSTANCE FIXED; TOUCH-TRIGGERED class. Original UTF8 correction qualified; next driver rendering touch must preserve crash/never-started outcomes. local-lane's UTF8 artifact writes are not proof of universal console safety, but do not re-fix the preserved driver. R6007–6030.\n99 — CLASSIFIED NOT-PRODUCT, built repairs; RECEIPT reconciliation. Spectator EOF unpromised; journal op reuse fixed.103 supplies successful five-arm receipt for attach half; do not repeat withdrawn opener diagnosis or repair spectator EOF as product. New EOF tests inherit contract-reading rule. R6031–6109.\n100 — PARTLY BUILT census discipline; operator setting TOUCH-TRIGGERED. lane_run ancestry/blind-path corrections documented; analyzer targetDir recommendation still separate operator choice. Current lock holder/live status UNKNOWN, no probe allowed. R6110–6169.\n101 — HISTORICAL REPAIRS BUILT; recurring inventory/assembly discipline. Six callers fixed, escaper coverage restored, integration repin existed; #304 now landed. Future lane must compile its own all-targets and inspect losing-side assertions; do not redispatch304 assembly commands. R6170–6234.\n102 — INSTANCE RULE APPLIED; recurring assignment discipline. Committed-only assembly/status-per-file; old0.4.0 upgrade ask superseded by0.4.1/135. No instrument implementation proved. R6235–6267.\n103 — FIXED rig; PARKED hazard NOT RIPE.0845e68d five-arm green plus trace; served-set population scoped clean. Equal wall-ms seat generation is explicitly unmeasured/noREQ/no build until field/cell collision. R6268–6337.\n104 — COMPLETED consumed upstream fix; status-only reconciliation. Current centralized pin0.4.1 satisfies stated closes-when-pin-main trigger. No checker-root workaround. R6338–6366.\n105 — INSTANCE FIXED (28d4eb68), ongoing authoring discipline. Read fixture and redirect target, shorten blind interval only if recurrence demands; no tool lane. R6367–6418.\n106 — INSTANCE CLOSED, procedure adoption. START/END population enumeration clause remains template-touch item; do not call handed set exhaustive. This sweep accounts all67 IDs explicitly. R6419–6449.\n107 — FIXED original driver AND requested premise assertions. registryhost.rs:1369ff/projwriter.rs:799ff already carry premise assertions; Linux consumer attempt2 unchanged candidate green documented. Later Windows identity-contaminated attempt stays VOID; corrected Windows receipt not claimed by this entry. Artifact filename/driver universality may need receipts, not another two-module patch. R6450–6544.\n108 — RIPE BACKLOG DISCRIMINATOR, BLOCKED current Windows hold. Today's findings-backlog sweep meets listed trigger (R6564–6565), but no run allowed. Reuse80 fixture diagnosis; run single-cell identity/tree discriminator later. Do not claim four stable leaks: fourth-run amendment changes membership. R6545–6566.\n109 — RIPE dedicated312-tag retirement, broad, see rank3. R6567–6588.\n110 — HISTORICAL fold ruled / no second implementation. Final amendment chooses surviving REQ-WEB-LAN-BOOTSTRAP-FIREWALL, W1 CIM+pure seam, removes duplicate IDs/netsh ADR; Linux ten-cell gap qualified. #304 shipped; completion reconciliation rather than recreate W2. R6589–6617.\n111 — TOUCH-TRIGGERED UDP rule-observation backlog. ActiveStore effective state vs by-name presence; next inbound-rule wave or CIM query generalization. No live fallback/rule changes authorized; current box state unknown. R6618–6639.\n112 — TOUCH-TRIGGERED two-fixture hermeticity; existing nextest gate correct. No cargo-test-lib rerun or gate conversion now. R6640–6659.\n113 — PROCEDURE / next mutation-driver touch. Trap/finally plus next-arm pristine bytes/oid and assertion-local negative outcome; no new mutation window. R6660–6681.\n114 — PROCEDURE / shared-state arm trigger. One writer, fetcher-owned before/after census and timestamped coordination; original scope rationale void. No new firewall experiment. R6682–6690.\n115 — PROCEDURE / next firewall census. Same-dump port+program controls, full reaching conjunction and per-agent exits; late event-log amendment forbids using events as delete direction proof. R6691–6700.\n116 — PROCEDURE / next watchdog. Actual post-state, owned identities; both script echo and harness success were false kill claims.137 during compile was VOID not product red. R6701–6711.\n117 — PROCEDURE / requirement/prediction authoring. Refutable branches and code-violable invariant; no measured local latency threshold in product. R6712–6720.\n118 — PROCEDURE / next capture/filter. Flush/stop writer before reading and live positive-control/raw schema; no new instrument project. R6721–6729.\n119 — PROCEDURE plus BLOCKED OPERATOR receipt. Empty-dir route control and complete teardown rules stand. Credential rotation is separate operator item releases#304 comment5643876746; this register records no completion, so unknown and not authority to rotate. R6730–6740.\n120 — INSTANCE DISCRIMINATED, ongoing claim discipline. Second Windows host and Linux contrast supplied missing axes; no platform investigation to repeat. R6741–6750.\n121 — INSTANCE FIXED v7, recurring rig/byte-reader discipline. Audited delivered set, no arm-id patch against frozen v6; raw byte and leading-dash safeguards on next authoring touch. R6751–6768.\n122 — REPEAT-FIELD TRIGGER, current closure UNKNOWN/receipt-first. Original stop refusal intentional and cannot be bypassed. Later133 owned-shutdown proof demonstrates successor cleanup, but does not alone reconcile every122 identity invariant. Owner hertz rig; inspect accepted successor/receipts before any repeat-field authorization, never PID-only automation. R6769–6781.\n123 — FIXED successor, mechanism-only OPEN. Return/log channel correction already exists, frozenr10 unchanged; no new code. R6782–6793.\n124 — REPEAT-FIELD TRIGGER, supersession reconciliation needed. Original driver creates daemon on setup-never-ran cleanup. Do not patch preserved2e3aec1b or assume latest accepted successor retains defect; inspect current successor's no-setup branch before field. R6794–6805.\n125 — UNKNOWN mechanism; receipt-first with124. Original false-negative sweep, NOT falseCLEAR; slash comparison is unconfirmed candidate. Later132 adds stronger identity seam. Need exact successor predicate/known-present proof, not a guessed path-normalization patch. R6806–6816.\n126 — ORIGINAL budget shape superseded by134's qualified clock design. No second independent budget fix; future field repinning/authorization remains separate. R6817–6827, R6901–6913.\n127 — CORRECTED/QUALIFIED preserved M3; class touch-triggered. Whole nested-value assignment + native flags readback already measured. R6828–6836.\n128 — CORRECTED/QUALIFIED M5 and N publisher; class touch-triggered. Typed null/empty seam and overwrite-rename already changed; original123 arms invalid. R6837–6846.\n129 — CORRECTED/QUALIFIED twice, latest promotion Read-Json-DateKindString discriminator. No repeat implicit-date repair against preserved predecessor. R6847–6856.\n130 — AUTHORIZED CORRECTION, final retry receipt UNKNOWN in entry. Two-line qualificationHome rename directed, fresh-root result explicitly separate. Minimum is locate that receipt/successor before claiming fix or redispatching. R6857–6866; AZLCQNZL-* preserved references.\n131 — CORRECTED/QUALIFIED no-mutation preflight. Child env scrub and invalid Stop-Transcript removal passed; strict seed guard intact. R6867–6877; VGCTKD7A-preflight-clean-* receipts.\n132 — CORRECTED/QUALIFIED birth-aware admission.14 controls and17-hit live read recorded; current product/box state not inferred. R6878–6888.\n133 — COMPLETED correction with genuine promotion0/owned shutdown. Later failed field handoff separate, no promotion rerun. R6889–6900.\n134 — CORRECTION QUALIFIED, future FIELD BLOCKED/repin-only.630s design and receipt/clock controls already built; candidate/packet/nonce/driver/runner repin is one future amendment requiring separate grant. Independent candidate product query-timeout finding M5XKQ2DN remains separate; cannot close it using instrument repair. R6901–6913.\n135 — LANDED52d56248; RECEIPT-ONLY integration execution. Centralized precheck/install and Linux controls built; live token/private build deliberately unexercised and provisioning is optional operator decision. Do not redispatch version diagnostic. R6914–6920.\n136 — LANDED84e20ddd; completed shared composition, adoption touch-triggered. S5 initial fix/cross-host green distinct from later Linux shared-fixture proof (seven unopted twohost cases compile-only). Future URL fixture uses ServingFixture; no duplicate helper. R6921–6931.\n137 — RETIRED8bb0feb4 byYPLFG3CG, no tracked launcher callsite. OMP harmless-child receipt is not reproduction of Claude Code failure. Reopen only owned new callsite/contrary evidence, never unused helper. R6932–6937.\n\nBOTTOM LINE: no Windows investigation should begin under CI34983756975 hold. Receipt reconciliation can proceed read-only now. IR90 residual and existing-owner IR82 are the strongest small implementation candidates; IR109 is real but not a small rider. IR78/94 are valid conditional seams, not proof that an immediate dispatch is owed. IR86 retirement must remain Main's slice-by-slice decision."},"error":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":2169,"output":5603,"cacheRead":134784,"cacheWrite":0,"totalTokens":142556,"reasoningTokens":96,"cost":{"input":0.02169,"output":0.28015,"cacheRead":0.134784,"cacheWrite":0,"total":0.436624}},"stopReason":"toolUse","timestamp":1789483760331,"responseId":"resp_000c7cef03cac861016aa95af08e6887d1a6c6a9bfd94d57ae","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"rs_000c7cef03cac861016aa95af3074887d19c9bfa0e9267c124","type":"reasoning","content":[],"encrypted_content":"gAAAAABqqVr5d_C3uAwPyYbraVuR9D3vSRzjWD80ZeEfZMgZXxRpcqdXA3KOpVDMdllZ-QurxwpkWwhWoLP_XcygqZAEDytEdgMJbXP_sWkQkXWtPTSdECgNqJRxH2IUBHLyjX-SOLQbEklhNZ4FpCVgk95i9NYXbl3pCxMx8wT_xg22K2lERLKQxSS0a1i3C39SsXhruu-GW1d_RBmYa8DazGwpyMJIxqpSOCwesKQm0fNuzVRAhdFObd2ytRJmNTCL73c1F6GbkXETU8RTB7Jf7S8CBiSrcAOvuyLwotvseeOY0a8zGovagb1KGsD1kGA-F7_SqOmVHL2h0p-blhb8pn-2CP5iGucYNY-HgyUl24CvSfBJrtdFj6ApNTaiMxJDy0yCLdGwu9ZTfHIcyLtiIO82wuVRAFmjsd9nO0axH2ibUHlNYBh0KhEVe2H7XfILTGa84xOmd0yQLHmgOmEi5Ic8t7amiOXN3Rt37h_PKYxHdteSsbBWVNRIQZLTMwYi6nmXASACRbJBGM8iwK1wzr_OezVkyKuTD342GKOCaDaxF2Yp6ESRei_dVcfm_5nmmgpjJnHKmWuyXsKrTglvmiwCQUsgirwA_L7psDA8tCyRp1Qv9QEq-1gBI614Hu5jVhV1gCYVKpQUEu6K1Z_ARTtXA3pCF1ntKSLx3I3RKZTwHXjWD34KRqyrTlQqO7u6aaYTcIVfW-uC4XJMfzNIEb87xEtGZSg_XF-Y7PtVTT-fy-nJI2-DLsgET8nCqwPBMpIpPQ7B7kc9PjE1Ia6l7gmJiDRSQ0hniaGrn556i1_6nrb1E-8_2a8sOcCGmWKNWqOV_NjltbGFw9GodBchiv8WSEELkgsFxSo9BMU4V_13QcLlXM2G8yLUrqkWxgrQoLodGFMy_JCStfKjRYDCrGPB0ty8dv1QuUrKnTbF2Wo5xg4wQ7StdrWN6UPvIFkRe77QzjLFjkYe2ch5fX2nOy3tKXM1Gbh-hFlTGO2OIYBJVyWgH66WHluzxhBtgsX1X6hDl5MZ-hVwj-7hsFK6JNtLZUu37Qje599ejCavKnj9_QTZQ7bVkm86IL8tJNgYXfJX1SuZ2rH_RZzEhxHQckLs-b9dQ2g100vL_qFiAaxPhOcj9c-jE1dVkKU8fcCXmca5mqedrW6wGxfs1fk7FR6-d41lXNxFOeFmF0cpAhWs2Hf6wSHDpFILhRGALaOAwwnZkafDFu8mu90Rp1QdyW1wx2SW2K6SXRbHs3B_Qdma8F-d8uEHGbAJLNRc4gSe6iYm1cXdWUmRVlZaCNA_c9WlcwxRgzbJBYrONjMzyVKBXyGu46_-pWFBKPa5SsrqA2_fuo2iyjeD0Ik73ut-MnexsJeE1bLMy5NJRSov3mUfL9O1VcMhtGp19iV1d56qYgCHAWY7iq44k65EN1tMEYhnNbTIe-TB4RwaHADGeSm5fFWlXRWREzVe3p5dLpzHYits7BRdcpJzyDMSGJeVe593OPHLA1esfDEZMvmn7h0DLEmpAQX9B5btB4GbxFkUCTJXs37hKiqf4RD2cfZw0LsMXGvA-PH-k5HU3R03j8giU9Wdlptm1itwXZpfKZMYyDPlhlhsmfLATTfEMlx66PKVpsL0TBf20s55Q7mzbAuHDF18_UxAtRrEqPBG8iyFYwvOeKkAJg5lfch3Nl2Y78tb-4lCxxkERhSwfroczoZ86slWUZchv_H8q4y_u-Ex_JDWzXtsDnsRGJjtgHJqRsadZScqFGy9mm1Cm7UBnRaGJlx3xSkNxAbMc4lUA8ehKWwcbBaBObjiABUx3kmPkYkG16JtShtKEtC_sLMK-UHOcDJ-w3TPz3WQ5tmsukKH4cw2_4mCeyiO4rkqVzhtzjf5AgVRVKZcER0RWIXJ8qgGspH7gWA=","internal_chat_message_metadata_passthrough":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"summary":[{"type":"summary_text","text":"**Compiling 67-row account list**"}],"metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}},{"id":"fc_000c7cef03cac861016aa95af9f05487d1bd4a2dbe427daa0e","type":"function_call","status":"completed","arguments":"{\"type\":null,\"data\":{\"summary\":\"Read IR71–137 through amendments: all 67 IDs accounted for. Best small residual is IR90's test-side mid-run disk context, not another generic disk-floor tool. IR82 remains unbuilt but already belongs to todlando's composition. IR109 retirement is genuinely open but broad (312 legacy tags). Several tempting tickets are already built: IR92 inject publication, IR104 pin, IR107 premise assertions, IR135/136 and IR137. Windows investigations remain held; IR86 closure stays with Main.\",\"files\":[{\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md\",\"description\":\"Entire assigned IR71–137 population read, including late reversals and final corrections; also read current sweep composition at lines 1–57.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs\",\"description\":\"Lines 75–110 implement IR92's successful-inject observation-only MSG_IN publication despite stale OPEN register language.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs\",\"description\":\"Line 476 still overwrites daemon.pid without predecessor preservation: IR82 remedy remains absent.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs\",\"description\":\"Lines 114–123 still silently return port0 when ephemeral posture wins; IR78 remains a tiny touch-triggered notice.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/crates/xtask/src/brainread.rs\",\"description\":\"Lines 194–208 retain stream-name predicate; lines 264–310 distinguish repository-wide retired-call scan from hand-listed semantic policy registry. IR94 remains a real classifier gap.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/crates/xtask/src/diskfloor.rs\",\"description\":\"Existing disk-floor implementation at lines 64–102; must reuse, not redispatch under IR90.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py\",\"description\":\"Lines 360–398 already admit/census/meter before and observe after producers; 402–410 release through prebuilt xtask.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/traceable-reqs.toml\",\"description\":\"Line25 still module_banner='accept': IR109 transitional exemption remains live.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs\",\"description\":\"PullLink failure sites at approximately 187–211 still use bare expect('pull')/expect('serve'), without current free-space context.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs\",\"description\":\"Lines1369ff already assert no-repository fixture premise requested in IR107.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.rs\",\"description\":\"Lines799ff already assert no-repository fixture premise requested in IR107.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/.github/ci/traceable-reqs.sh\",\"description\":\"Lines5–6 centralize installed CI checker pin0.4.1; supports spent IR75/104 original remedies and landed IR135.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/crates/spt-store/src/proc.rs\",\"description\":\"kill_pid(pid) at46 and kill_pid_tree(root) at430 remain bare-number primitives; do not infer IR81 primitive cutover from authenticated consumer repairs.\"},{\"path\":\".worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md\",\"description\":\"Lines26–80 already document quiet-window/ancestry boundaries; IR137 discipline follows at81ff.\"}],\"architecture\":\"Register headings are historical handles, not current state. Driver safeguards, product primitives, test fixtures, box configuration, and exercised workflow receipts are separate seams. Existing local-lane already composes floor/census/prebuilt-release mechanisms; inject already owns publication; serving fixture already composes broker/seed/docs planes. Remaining work must target residual callers/context or reconcile receipts, not recreate these modules.\",\"report\":\"Scope and evidence: R below means .worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md. Other paths are relative to that same fixed worktree. Read-only source/record investigation only: no execution, process/service probes, tests, builds, lint, edits, or new files. Existing receipts are quoted as recorded evidence, not rerun or independently reverified. Known landed SHAs supplied by Main/user are treated as ground truth.\\n\\nRANKED ACTIONABLE RESIDUALS\\n1. IR90 — RIPE-NOW, small residual implementation. Trigger is explicitly 'now' (R5425), reinforced by next-intake composition R43–47 and measured disk-full product-shaped refusal R5341–5356. Already-built prerequisite: crates/xtask/src/diskfloor.rs:64–102 and .github/ci/local-lane.py:360–398. Unbuilt specific seam: crates/spt-daemon/tests/sync.rs:187–211 still turns request_sync/serve_sync errors into bare expect('pull')/expect('serve'); inspected sync/twohost files have no free-space diagnostic. Owner: hertz test/driver package. Smallest next step: scope a test-side error-context helper/caller change that reports actual temp/store-volume free bytes on the real error, then assess remaining rig-start adopters against existing disk-floor. Do NOT build a second floor meter or claim local-lane lacks pre/post readings. Execution proof waits for authorized window.\\n2. IR82 — RIPE composition, small product change, EXISTING OWNER NOT NEW DISPATCH. Ruled remedy and owner at R4650–4682; prior #285 completion explicitly did not build it (R51). Source still unconditional std::fs::write at crates/spt-daemon/src/daemon.rs:476. Owner todlando, product pid-identity composition. Minimal next step: acknowledge/take the existing assignment, implement the stipulated predecessor record plus one-generation pidfile retention; keep socket liveness and countable DAEMON_AUTOSTART unchanged. Not an incident-cause closure.\\n3. IR109 — RIPE-NOW dedicated retirement lane, NOT SMALL. R6569–6587 ratifies temporary #304 exception and explicitly orders separate relocation lane. traceable-reqs.toml:25 still accepts module banners; checker pin0.4.1 now actually exists in .github/ci/traceable-reqs.sh:6. Owner doyle intake/traceability maintainer (implementation owner not named). Minimum next step: obtain exact current legacy-tag population, relocate actual evidence tags and remove acceptance key as one dedicated lane. Historical312 is not a fresh census. Never 'fix' by re-pinning or broadening exemption.\\n4. IR89, with IR83 — RIPE-NOW RECEIPT-ONLY first. R5185–5199 explicitly says the next-golden trigger has already fired and workflow is LANDED. Owner hertz workflow / doyle acceptance. Minimum next step: recover exact A/B pre-ceremony probe-step execution/skipped/failed receipts from an already completed golden (S5 overall green is not enough), plus direction-witness LIST/real-body evidence for IR83. No box change or second UDP guard. This is the cheapest immediate closure work.\\n5. IR92, IR104, IR107, IR135/136 — RIPE-NOW RECORD RECONCILIATION, not implementation. See complete dispositions below. Especially IR92 source directly contradicts both its heading and R39–41. Review relevant existing consumer/acceptance receipts and correct scope/status; do not recreate injected MSG_IN publication or premise assertions.\\n\\nCONDITIONAL SMALL RIDERS, NOT UNCONDITIONAL DISPATCHES\\n• IR78: docshost.rs:114–123 confirms silent override persists; exact trigger R4099–4101 is next docshost touch or a new explicit-port belief incident. Owner docshost product maintainer; one notice naming both env vars when a supplied override loses. No fresh trigger proved in this sweep.\\n• IR94: brainread.rs:194–208 still keys lifetime policy on serve_*_feed/serve_attach; :264–310 scans all Rust for general symbols but retains specific policy files/functions. Exact trigger R5668–5671: next brainread/xtask touch, mandatory before bounded serve_sync migration. Owner tooling/hertz with todlando semantic census. Minimal next step on that touch: behavior-derived fail-unclassified population and printed census, not merely append serve_sync to another whitelist.\\n• IR71/72/77/93/111 likewise remain genuine touch-triggered work, not ripe because OPEN.\\n\\nCOMPLETE PER-ID DISPOSITIONS (67 IDs)\\n71 — TOUCH-TRIGGERED. Persisted controller-release breadcrumb still owed; next controller lifecycle/breadcrumb touch or PR174 barrier timeout. R3888–3911. No fresh trigger established.\\n72 — TOUCH-TRIGGERED. Named perch/seat custody read model; next roster/status change or another rig needing named-holder reap. R3912–3945. Do not substitute process-wide daemon status.\\n73 — COMPLETED. Eight checkout/floor reorder sites and both docs rereads built; remaining capacity/coupling belongs IR86. R3946–3969.\\n74 — TOUCH-TRIGGERED / historical box state UNKNOWN. Next Linux rig/box-audit lifecycle work, not authorization to sweep live /tmp now. 21,643 homes is dated measurement, not current count. R3970–3983.\\n75 — ORIGINAL INSTANCE SPENT; RECEIPT/status reconciliation. Missing Linux checker is superseded by IR135's hand-install and real0.4.1 smoke (R6916–6918), plus centralized installed pin. Do not install it again based on 127 from August. Future box-audit/version admission remains discipline. R3984–3998.\\n76 — PARTLY BUILT, TOUCH-TRIGGERED residual. Existing ws272 drivers carry three-arm gate and GOLDEN-CI.md:26–80 quiet/ancestry contract; local-lane reuses gate. Dedicated CI foreign-builder count/CPU census and universal brief/template adoption not established here. Current heavy Windows hold is binding, not a request for more code. R3999–4042.\\n77 — TOUCH-TRIGGERED. Spawn/child-entry/readiness timing split; next boot/brainproc-ready or family rider. R4043–4074.\\n78 — TOUCH-TRIGGERED confirmed residual; tiny notice, source docshost.rs:114–123. R4075–4102.\\n79 — TOUCH-TRIGGERED lifecycle package. Common authenticated breadcrumb reaper exists, but it is not a Drop guard and does not prove panic-safe adoption. Original first four tests yielded no Drop/DaemonReaper match; no complete22-site current census claimed. Next common touch, and distinguish unwind from hard process death (R47–49). R4103–4183.\\n80 — BLOCKED Windows measurement / partially classified fixture family. Late amendments identify cmd→ping wrapper fixture, direct production spawn,12-member noisy OS partition; not an undiagnosed product leak and no count-only progress claim. Residual population unclassified; existing ENV-read fix already built. R4184–4465. Coordinate with108, not duplicate work.\\n81 — OPEN product primitive + gate residual, existing owners. proc.rs:46/:430 remain bare-number signatures; consumer authenticated reaper and adapter9c87372 do not finish signature cutover. Todlando product, hertz gate; trigger next proc/xtask gate touch. Adapter half closed. R4466–4590.\\n82 — RIPE assigned product composition, unbuilt source; see rank2. R4591–4696.\\n83 — OPEN direction-witness durability/acceptance; BOX half spent. Universal LAN-only rule explicitly superseded; no new operator/ACL action. Reconcile current LIST/NOT-A-WITNESS enforcement and reverse real-body witness; co-own with89. R4697–4833.\\n84 — ORIGINAL STAMP BUILT; residual follow-up only. Stamp landed with entry; all-arm regression enforcement remains a separately named follow-up. Historical65s question must not be reopened without IR89's later attribution (three faces of firewall/ACL/shared-path cause). R4834–4883, R5217ff.\\n85 — BLOCKED diagnostic continuation. Cap changes already built; arm1 void, old-sha slowdown only proves head growth unnecessary. Needs IR90 guard and authorized no-CI/no-main-push window; AB then BA, not repeated AB. Do not identify Defender from correlation or widen caps. R4884–5043.\\n86 — MAIN-OWNED. Both floors and inline delta known landed (5e05f02d/0cda6235/82333ca1). Do not redispatch. Main must reconcile final automation plus independent docs-dependency slice before retirement; no closure conclusion delegated here. R5044–5092.\\n87 — TOUCH-TRIGGERED unresolved scheduling seam. Next golden/twohost touch; old R294 recurrence includes own PR starving roleA, not only foreign runs. Minimum existing-lane decision is partner-start barrier/separate rendezvous scheduling contract, not larger pairing timeout. R5093–5145. Current source choreography not exhaustively re-audited.\\n88 — BUILT in current local-lane; TOUCH/receipt residual elsewhere. local-lane.py:402–410 invokes prebuilt xtask. Reconcile runbook/all other teardown adopters only when touched. Preserve exe AND DLL if claiming runnable retention, otherwise archival. R5146–5182.\\n89 — RECEIPT-ONLY ripe; boxes applied and guard landed; exact golden probe-step acceptance missing from record. See rank4. R5183–5338.\\n90 — RIPE-NOW residual error context/start adoption, not new floor machinery. See rank1. R5339–5427.\\n91 — CLOSED.18 cited files tracked in place;543 uncited artifacts preserved, root-specific ignores. R5428–5481.\\n92 — SOURCE-BUILT; stale register requires reconciliation. inject.rs:75–110 publishes exactly on Some((true,_)), observation-only, target/peer/msg-id present; no fresh publisher implementation. Relay ordering/per-message exact-once assertion obligations remain separate, not automatically closed by this source read. R5482–5613.\\n93 — TOUCH-TRIGGERED / packaging decision required. PDB retention/install or symbol store; next installer/release packaging touch. Successful release build is not symbol availability. R5614–5642.\\n94 — TOUCH-TRIGGERED actual gate blind spot; see conditional rider. R5643–5672.\\n95 — PARTLY INSTRUMENTED, diagnostic continuation/triage UNKNOWN. Original comparison has already run; no blanket317-site edit. Historical321 population approximate,15 outside classifier unclassified; retained exchange-correlated create/retire trace is separate product design, not two-IPC reuse. Needs selected diagnostic intake, not budget retuning. R5673–5927.\\n96 — BLOCKED/cause UNKNOWN. Candidate-vs-diagnostic differential confounded by97; diagnostic pool deleted, next candidate discriminator requires rebuild and authorized quiet heavy window. R5928–5963; preserved CLASSIFICATION-AMENDMENT-2-doyle.md and reclaim receipts remain evidence.\\n97 — PARTLY BUILT procedure. local-lane.py:380–398 already performs before/after producer census; exclusive START/END token discipline remains runtime adoption. No new repeated-run experiment authorized; observe actual launch not announcement. R5964–6006.\\n98 — INSTANCE FIXED; TOUCH-TRIGGERED class. Original UTF8 correction qualified; next driver rendering touch must preserve crash/never-started outcomes. local-lane's UTF8 artifact writes are not proof of universal console safety, but do not re-fix the preserved driver. R6007–6030.\\n99 — CLASSIFIED NOT-PRODUCT, built repairs; RECEIPT reconciliation. Spectator EOF unpromised; journal op reuse fixed.103 supplies successful five-arm receipt for attach half; do not repeat withdrawn opener diagnosis or repair spectator EOF as product. New EOF tests inherit contract-reading rule. R6031–6109.\\n100 — PARTLY BUILT census discipline; operator setting TOUCH-TRIGGERED. lane_run ancestry/blind-path corrections documented; analyzer targetDir recommendation still separate operator choice. Current lock holder/live status UNKNOWN, no probe allowed. R6110–6169.\\n101 — HISTORICAL REPAIRS BUILT; recurring inventory/assembly discipline. Six callers fixed, escaper coverage restored, integration repin existed; #304 now landed. Future lane must compile its own all-targets and inspect losing-side assertions; do not redispatch304 assembly commands. R6170–6234.\\n102 — INSTANCE RULE APPLIED; recurring assignment discipline. Committed-only assembly/status-per-file; old0.4.0 upgrade ask superseded by0.4.1/135. No instrument implementation proved. R6235–6267.\\n103 — FIXED rig; PARKED hazard NOT RIPE.0845e68d five-arm green plus trace; served-set population scoped clean. Equal wall-ms seat generation is explicitly unmeasured/noREQ/no build until field/cell collision. R6268–6337.\\n104 — COMPLETED consumed upstream fix; status-only reconciliation. Current centralized pin0.4.1 satisfies stated closes-when-pin-main trigger. No checker-root workaround. R6338–6366.\\n105 — INSTANCE FIXED (28d4eb68), ongoing authoring discipline. Read fixture and redirect target, shorten blind interval only if recurrence demands; no tool lane. R6367–6418.\\n106 — INSTANCE CLOSED, procedure adoption. START/END population enumeration clause remains template-touch item; do not call handed set exhaustive. This sweep accounts all67 IDs explicitly. R6419–6449.\\n107 — FIXED original driver AND requested premise assertions. registryhost.rs:1369ff/projwriter.rs:799ff already carry premise assertions; Linux consumer attempt2 unchanged candidate green documented. Later Windows identity-contaminated attempt stays VOID; corrected Windows receipt not claimed by this entry. Artifact filename/driver universality may need receipts, not another two-module patch. R6450–6544.\\n108 — RIPE BACKLOG DISCRIMINATOR, BLOCKED current Windows hold. Today's findings-backlog sweep meets listed trigger (R6564–6565), but no run allowed. Reuse80 fixture diagnosis; run single-cell identity/tree discriminator later. Do not claim four stable leaks: fourth-run amendment changes membership. R6545–6566.\\n109 — RIPE dedicated312-tag retirement, broad, see rank3. R6567–6588.\\n110 — HISTORICAL fold ruled / no second implementation. Final amendment chooses surviving REQ-WEB-LAN-BOOTSTRAP-FIREWALL, W1 CIM+pure seam, removes duplicate IDs/netsh ADR; Linux ten-cell gap qualified. #304 shipped; completion reconciliation rather than recreate W2. R6589–6617.\\n111 — TOUCH-TRIGGERED UDP rule-observation backlog. ActiveStore effective state vs by-name presence; next inbound-rule wave or CIM query generalization. No live fallback/rule changes authorized; current box state unknown. R6618–6639.\\n112 — TOUCH-TRIGGERED two-fixture hermeticity; existing nextest gate correct. No cargo-test-lib rerun or gate conversion now. R6640–6659.\\n113 — PROCEDURE / next mutation-driver touch. Trap/finally plus next-arm pristine bytes/oid and assertion-local negative outcome; no new mutation window. R6660–6681.\\n114 — PROCEDURE / shared-state arm trigger. One writer, fetcher-owned before/after census and timestamped coordination; original scope rationale void. No new firewall experiment. R6682–6690.\\n115 — PROCEDURE / next firewall census. Same-dump port+program controls, full reaching conjunction and per-agent exits; late event-log amendment forbids using events as delete direction proof. R6691–6700.\\n116 — PROCEDURE / next watchdog. Actual post-state, owned identities; both script echo and harness success were false kill claims.137 during compile was VOID not product red. R6701–6711.\\n117 — PROCEDURE / requirement/prediction authoring. Refutable branches and code-violable invariant; no measured local latency threshold in product. R6712–6720.\\n118 — PROCEDURE / next capture/filter. Flush/stop writer before reading and live positive-control/raw schema; no new instrument project. R6721–6729.\\n119 — PROCEDURE plus BLOCKED OPERATOR receipt. Empty-dir route control and complete teardown rules stand. Credential rotation is separate operator item releases#304 comment5643876746; this register records no completion, so unknown and not authority to rotate. R6730–6740.\\n120 — INSTANCE DISCRIMINATED, ongoing claim discipline. Second Windows host and Linux contrast supplied missing axes; no platform investigation to repeat. R6741–6750.\\n121 — INSTANCE FIXED v7, recurring rig/byte-reader discipline. Audited delivered set, no arm-id patch against frozen v6; raw byte and leading-dash safeguards on next authoring touch. R6751–6768.\\n122 — REPEAT-FIELD TRIGGER, current closure UNKNOWN/receipt-first. Original stop refusal intentional and cannot be bypassed. Later133 owned-shutdown proof demonstrates successor cleanup, but does not alone reconcile every122 identity invariant. Owner hertz rig; inspect accepted successor/receipts before any repeat-field authorization, never PID-only automation. R6769–6781.\\n123 — FIXED successor, mechanism-only OPEN. Return/log channel correction already exists, frozenr10 unchanged; no new code. R6782–6793.\\n124 — REPEAT-FIELD TRIGGER, supersession reconciliation needed. Original driver creates daemon on setup-never-ran cleanup. Do not patch preserved2e3aec1b or assume latest accepted successor retains defect; inspect current successor's no-setup branch before field. R6794–6805.\\n125 — UNKNOWN mechanism; receipt-first with124. Original false-negative sweep, NOT falseCLEAR; slash comparison is unconfirmed candidate. Later132 adds stronger identity seam. Need exact successor predicate/known-present proof, not a guessed path-normalization patch. R6806–6816.\\n126 — ORIGINAL budget shape superseded by134's qualified clock design. No second independent budget fix; future field repinning/authorization remains separate. R6817–6827, R6901–6913.\\n127 — CORRECTED/QUALIFIED preserved M3; class touch-triggered. Whole nested-value assignment + native flags readback already measured. R6828–6836.\\n128 — CORRECTED/QUALIFIED M5 and N publisher; class touch-triggered. Typed null/empty seam and overwrite-rename already changed; original123 arms invalid. R6837–6846.\\n129 — CORRECTED/QUALIFIED twice, latest promotion Read-Json-DateKindString discriminator. No repeat implicit-date repair against preserved predecessor. R6847–6856.\\n130 — AUTHORIZED CORRECTION, final retry receipt UNKNOWN in entry. Two-line qualificationHome rename directed, fresh-root result explicitly separate. Minimum is locate that receipt/successor before claiming fix or redispatching. R6857–6866; AZLCQNZL-* preserved references.\\n131 — CORRECTED/QUALIFIED no-mutation preflight. Child env scrub and invalid Stop-Transcript removal passed; strict seed guard intact. R6867–6877; VGCTKD7A-preflight-clean-* receipts.\\n132 — CORRECTED/QUALIFIED birth-aware admission.14 controls and17-hit live read recorded; current product/box state not inferred. R6878–6888.\\n133 — COMPLETED correction with genuine promotion0/owned shutdown. Later failed field handoff separate, no promotion rerun. R6889–6900.\\n134 — CORRECTION QUALIFIED, future FIELD BLOCKED/repin-only.630s design and receipt/clock controls already built; candidate/packet/nonce/driver/runner repin is one future amendment requiring separate grant. Independent candidate product query-timeout finding M5XKQ2DN remains separate; cannot close it using instrument repair. R6901–6913.\\n135 — LANDED52d56248; RECEIPT-ONLY integration execution. Centralized precheck/install and Linux controls built; live token/private build deliberately unexercised and provisioning is optional operator decision. Do not redispatch version diagnostic. R6914–6920.\\n136 — LANDED84e20ddd; completed shared composition, adoption touch-triggered. S5 initial fix/cross-host green distinct from later Linux shared-fixture proof (seven unopted twohost cases compile-only). Future URL fixture uses ServingFixture; no duplicate helper. R6921–6931.\\n137 — RETIRED8bb0feb4 byYPLFG3CG, no tracked launcher callsite. OMP harmless-child receipt is not reproduction of Claude Code failure. Reopen only owned new callsite/contrary evidence, never unused helper. R6932–6937.\\n\\nBOTTOM LINE: no Windows investigation should begin under CI34983756975 hold. Receipt reconciliation can proceed read-only now. IR90 residual and existing-owner IR82 are the strongest small implementation candidates; IR109 is real but not a small rider. IR78/94 are valid conditional seams, not proof that an immediate dispatch is owed. IR86 retirement must remain Main's slice-by-slice decision.\"},\"error\":null}","call_id":"call_lZZ5udOyvgROdDavakstsbxV","internal_chat_message_metadata_passthrough":{"create_time":1789483760.719006,"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"},"name":"yield","metadata":{"turn_id":"f5651149-1a96-440f-bbcb-72125617c760"}}]},"duration":170852.42059999704,"ttft":2727.532000005245,"completedAt":1789483931186,"contextSnapshot":{"promptTokens":136953,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"message","id":"f54b765c","parentId":"af075406","timestamp":"2026-09-15T14:52:11.190Z","message":{"role":"toolResult","toolCallId":"call_lZZ5udOyvgROdDavakstsbxV|fc_000c7cef03cac861016aa95af9f05487d1bd4a2dbe427daa0e","toolName":"yield","content":[{"type":"text","text":"Result submitted."}],"details":{"data":{"summary":"Read IR71–137 through amendments: all 67 IDs accounted for. Best small residual is IR90's test-side mid-run disk context, not another generic disk-floor tool. IR82 remains unbuilt but already belongs to todlando's composition. IR109 retirement is genuinely open but broad (312 legacy tags). Several tempting tickets are already built: IR92 inject publication, IR104 pin, IR107 premise assertions, IR135/136 and IR137. Windows investigations remain held; IR86 closure stays with Main.","files":[{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md","description":"Entire assigned IR71–137 population read, including late reversals and final corrections; also read current sweep composition at lines 1–57."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/inject.rs","description":"Lines 75–110 implement IR92's successful-inject observation-only MSG_IN publication despite stale OPEN register language."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/daemon.rs","description":"Line 476 still overwrites daemon.pid without predecessor preservation: IR82 remedy remains absent."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/docshost.rs","description":"Lines 114–123 still silently return port0 when ephemeral posture wins; IR78 remains a tiny touch-triggered notice."},{"path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/brainread.rs","description":"Lines 194–208 retain stream-name predicate; lines 264–310 distinguish repository-wide retired-call scan from hand-listed semantic policy registry. IR94 remains a real classifier gap."},{"path":".worktrees/hertz-ir86-disk-delta/crates/xtask/src/diskfloor.rs","description":"Existing disk-floor implementation at lines 64–102; must reuse, not redispatch under IR90."},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/local-lane.py","description":"Lines 360–398 already admit/census/meter before and observe after producers; 402–410 release through prebuilt xtask."},{"path":".worktrees/hertz-ir86-disk-delta/traceable-reqs.toml","description":"Line25 still module_banner='accept': IR109 transitional exemption remains live."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/tests/sync.rs","description":"PullLink failure sites at approximately 187–211 still use bare expect('pull')/expect('serve'), without current free-space context."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/registryhost.rs","description":"Lines1369ff already assert no-repository fixture premise requested in IR107."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-daemon/src/projwriter.rs","description":"Lines799ff already assert no-repository fixture premise requested in IR107."},{"path":".worktrees/hertz-ir86-disk-delta/.github/ci/traceable-reqs.sh","description":"Lines5–6 centralize installed CI checker pin0.4.1; supports spent IR75/104 original remedies and landed IR135."},{"path":".worktrees/hertz-ir86-disk-delta/crates/spt-store/src/proc.rs","description":"kill_pid(pid) at46 and kill_pid_tree(root) at430 remain bare-number primitives; do not infer IR81 primitive cutover from authenticated consumer repairs."},{"path":".worktrees/hertz-ir86-disk-delta/docs/GOLDEN-CI.md","description":"Lines26–80 already document quiet-window/ancestry boundaries; IR137 discipline follows at81ff."}],"architecture":"Register headings are historical handles, not current state. Driver safeguards, product primitives, test fixtures, box configuration, and exercised workflow receipts are separate seams. Existing local-lane already composes floor/census/prebuilt-release mechanisms; inject already owns publication; serving fixture already composes broker/seed/docs planes. Remaining work must target residual callers/context or reconcile receipts, not recreate these modules.","report":"Scope and evidence: R below means .worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md. Other paths are relative to that same fixed worktree. Read-only source/record investigation only: no execution, process/service probes, tests, builds, lint, edits, or new files. Existing receipts are quoted as recorded evidence, not rerun or independently reverified. Known landed SHAs supplied by Main/user are treated as ground truth.\n\nRANKED ACTIONABLE RESIDUALS\n1. IR90 — RIPE-NOW, small residual implementation. Trigger is explicitly 'now' (R5425), reinforced by next-intake composition R43–47 and measured disk-full product-shaped refusal R5341–5356. Already-built prerequisite: crates/xtask/src/diskfloor.rs:64–102 and .github/ci/local-lane.py:360–398. Unbuilt specific seam: crates/spt-daemon/tests/sync.rs:187–211 still turns request_sync/serve_sync errors into bare expect('pull')/expect('serve'); inspected sync/twohost files have no free-space diagnostic. Owner: hertz test/driver package. Smallest next step: scope a test-side error-context helper/caller change that reports actual temp/store-volume free bytes on the real error, then assess remaining rig-start adopters against existing disk-floor. Do NOT build a second floor meter or claim local-lane lacks pre/post readings. Execution proof waits for authorized window.\n2. IR82 — RIPE composition, small product change, EXISTING OWNER NOT NEW DISPATCH. Ruled remedy and owner at R4650–4682; prior #285 completion explicitly did not build it (R51). Source still unconditional std::fs::write at crates/spt-daemon/src/daemon.rs:476. Owner todlando, product pid-identity composition. Minimal next step: acknowledge/take the existing assignment, implement the stipulated predecessor record plus one-generation pidfile retention; keep socket liveness and countable DAEMON_AUTOSTART unchanged. Not an incident-cause closure.\n3. IR109 — RIPE-NOW dedicated retirement lane, NOT SMALL. R6569–6587 ratifies temporary #304 exception and explicitly orders separate relocation lane. traceable-reqs.toml:25 still accepts module banners; checker pin0.4.1 now actually exists in .github/ci/traceable-reqs.sh:6. Owner doyle intake/traceability maintainer (implementation owner not named). Minimum next step: obtain exact current legacy-tag population, relocate actual evidence tags and remove acceptance key as one dedicated lane. Historical312 is not a fresh census. Never 'fix' by re-pinning or broadening exemption.\n4. IR89, with IR83 — RIPE-NOW RECEIPT-ONLY first. R5185–5199 explicitly says the next-golden trigger has already fired and workflow is LANDED. Owner hertz workflow / doyle acceptance. Minimum next step: recover exact A/B pre-ceremony probe-step execution/skipped/failed receipts from an already completed golden (S5 overall green is not enough), plus direction-witness LIST/real-body evidence for IR83. No box change or second UDP guard. This is the cheapest immediate closure work.\n5. IR92, IR104, IR107, IR135/136 — RIPE-NOW RECORD RECONCILIATION, not implementation. See complete dispositions below. Especially IR92 source directly contradicts both its heading and R39–41. Review relevant existing consumer/acceptance receipts and correct scope/status; do not recreate injected MSG_IN publication or premise assertions.\n\nCONDITIONAL SMALL RIDERS, NOT UNCONDITIONAL DISPATCHES\n• IR78: docshost.rs:114–123 confirms silent override persists; exact trigger R4099–4101 is next docshost touch or a new explicit-port belief incident. Owner docshost product maintainer; one notice naming both env vars when a supplied override loses. No fresh trigger proved in this sweep.\n• IR94: brainread.rs:194–208 still keys lifetime policy on serve_*_feed/serve_attach; :264–310 scans all Rust for general symbols but retains specific policy files/functions. Exact trigger R5668–5671: next brainread/xtask touch, mandatory before bounded serve_sync migration. Owner tooling/hertz with todlando semantic census. Minimal next step on that touch: behavior-derived fail-unclassified population and printed census, not merely append serve_sync to another whitelist.\n• IR71/72/77/93/111 likewise remain genuine touch-triggered work, not ripe because OPEN.\n\nCOMPLETE PER-ID DISPOSITIONS (67 IDs)\n71 — TOUCH-TRIGGERED. Persisted controller-release breadcrumb still owed; next controller lifecycle/breadcrumb touch or PR174 barrier timeout. R3888–3911. No fresh trigger established.\n72 — TOUCH-TRIGGERED. Named perch/seat custody read model; next roster/status change or another rig needing named-holder reap. R3912–3945. Do not substitute process-wide daemon status.\n73 — COMPLETED. Eight checkout/floor reorder sites and both docs rereads built; remaining capacity/coupling belongs IR86. R3946–3969.\n74 — TOUCH-TRIGGERED / historical box state UNKNOWN. Next Linux rig/box-audit lifecycle work, not authorization to sweep live /tmp now. 21,643 homes is dated measurement, not current count. R3970–3983.\n75 — ORIGINAL INSTANCE SPENT; RECEIPT/status reconciliation. Missing Linux checker is superseded by IR135's hand-install and real0.4.1 smoke (R6916–6918), plus centralized installed pin. Do not install it again based on 127 from August. Future box-audit/version admission remains discipline. R3984–3998.\n76 — PARTLY BUILT, TOUCH-TRIGGERED residual. Existing ws272 drivers carry three-arm gate and GOLDEN-CI.md:26–80 quiet/ancestry contract; local-lane reuses gate. Dedicated CI foreign-builder count/CPU census and universal brief/template adoption not established here. Current heavy Windows hold is binding, not a request for more code. R3999–4042.\n77 — TOUCH-TRIGGERED. Spawn/child-entry/readiness timing split; next boot/brainproc-ready or family rider. R4043–4074.\n78 — TOUCH-TRIGGERED confirmed residual; tiny notice, source docshost.rs:114–123. R4075–4102.\n79 — TOUCH-TRIGGERED lifecycle package. Common authenticated breadcrumb reaper exists, but it is not a Drop guard and does not prove panic-safe adoption. Original first four tests yielded no Drop/DaemonReaper match; no complete22-site current census claimed. Next common touch, and distinguish unwind from hard process death (R47–49). R4103–4183.\n80 — BLOCKED Windows measurement / partially classified fixture family. Late amendments identify cmd→ping wrapper fixture, direct production spawn,12-member noisy OS partition; not an undiagnosed product leak and no count-only progress claim. Residual population unclassified; existing ENV-read fix already built. R4184–4465. Coordinate with108, not duplicate work.\n81 — OPEN product primitive + gate residual, existing owners. proc.rs:46/:430 remain bare-number signatures; consumer authenticated reaper and adapter9c87372 do not finish signature cutover. Todlando product, hertz gate; trigger next proc/xtask gate touch. Adapter half closed. R4466–4590.\n82 — RIPE assigned product composition, unbuilt source; see rank2. R4591–4696.\n83 — OPEN direction-witness durability/acceptance; BOX half spent. Universal LAN-only rule explicitly superseded; no new operator/ACL action. Reconcile current LIST/NOT-A-WITNESS enforcement and reverse real-body witness; co-own with89. R4697–4833.\n84 — ORIGINAL STAMP BUILT; residual follow-up only. Stamp landed with entry; all-arm regression enforcement remains a separately named follow-up. Historical65s question must not be reopened without IR89's later attribution (three faces of firewall/ACL/shared-path cause). R4834–4883, R5217ff.\n85 — BLOCKED diagnostic continuation. Cap changes already built; arm1 void, old-sha slowdown only proves head growth unnecessary. Needs IR90 guard and authorized no-CI/no-main-push window; AB then BA, not repeated AB. Do not identify Defender from correlation or widen caps. R4884–5043.\n86 — MAIN-OWNED. Both floors and inline delta known landed (5e05f02d/0cda6235/82333ca1). Do not redispatch. Main must reconcile final automation plus independent docs-dependency slice before retirement; no closure conclusion delegated here. R5044–5092.\n87 — TOUCH-TRIGGERED unresolved scheduling seam. Next golden/twohost touch; old R294 recurrence includes own PR starving roleA, not only foreign runs. Minimum existing-lane decision is partner-start barrier/separate rendezvous scheduling contract, not larger pairing timeout. R5093–5145. Current source choreography not exhaustively re-audited.\n88 — BUILT in current local-lane; TOUCH/receipt residual elsewhere. local-lane.py:402–410 invokes prebuilt xtask. Reconcile runbook/all other teardown adopters only when touched. Preserve exe AND DLL if claiming runnable retention, otherwise archival. R5146–5182.\n89 — RECEIPT-ONLY ripe; boxes applied and guard landed; exact golden probe-step acceptance missing from record. See rank4. R5183–5338.\n90 — RIPE-NOW residual error context/start adoption, not new floor machinery. See rank1. R5339–5427.\n91 — CLOSED.18 cited files tracked in place;543 uncited artifacts preserved, root-specific ignores. R5428–5481.\n92 — SOURCE-BUILT; stale register requires reconciliation. inject.rs:75–110 publishes exactly on Some((true,_)), observation-only, target/peer/msg-id present; no fresh publisher implementation. Relay ordering/per-message exact-once assertion obligations remain separate, not automatically closed by this source read. R5482–5613.\n93 — TOUCH-TRIGGERED / packaging decision required. PDB retention/install or symbol store; next installer/release packaging touch. Successful release build is not symbol availability. R5614–5642.\n94 — TOUCH-TRIGGERED actual gate blind spot; see conditional rider. R5643–5672.\n95 — PARTLY INSTRUMENTED, diagnostic continuation/triage UNKNOWN. Original comparison has already run; no blanket317-site edit. Historical321 population approximate,15 outside classifier unclassified; retained exchange-correlated create/retire trace is separate product design, not two-IPC reuse. Needs selected diagnostic intake, not budget retuning. R5673–5927.\n96 — BLOCKED/cause UNKNOWN. Candidate-vs-diagnostic differential confounded by97; diagnostic pool deleted, next candidate discriminator requires rebuild and authorized quiet heavy window. R5928–5963; preserved CLASSIFICATION-AMENDMENT-2-doyle.md and reclaim receipts remain evidence.\n97 — PARTLY BUILT procedure. local-lane.py:380–398 already performs before/after producer census; exclusive START/END token discipline remains runtime adoption. No new repeated-run experiment authorized; observe actual launch not announcement. R5964–6006.\n98 — INSTANCE FIXED; TOUCH-TRIGGERED class. Original UTF8 correction qualified; next driver rendering touch must preserve crash/never-started outcomes. local-lane's UTF8 artifact writes are not proof of universal console safety, but do not re-fix the preserved driver. R6007–6030.\n99 — CLASSIFIED NOT-PRODUCT, built repairs; RECEIPT reconciliation. Spectator EOF unpromised; journal op reuse fixed.103 supplies successful five-arm receipt for attach half; do not repeat withdrawn opener diagnosis or repair spectator EOF as product. New EOF tests inherit contract-reading rule. R6031–6109.\n100 — PARTLY BUILT census discipline; operator setting TOUCH-TRIGGERED. lane_run ancestry/blind-path corrections documented; analyzer targetDir recommendation still separate operator choice. Current lock holder/live status UNKNOWN, no probe allowed. R6110–6169.\n101 — HISTORICAL REPAIRS BUILT; recurring inventory/assembly discipline. Six callers fixed, escaper coverage restored, integration repin existed; #304 now landed. Future lane must compile its own all-targets and inspect losing-side assertions; do not redispatch304 assembly commands. R6170–6234.\n102 — INSTANCE RULE APPLIED; recurring assignment discipline. Committed-only assembly/status-per-file; old0.4.0 upgrade ask superseded by0.4.1/135. No instrument implementation proved. R6235–6267.\n103 — FIXED rig; PARKED hazard NOT RIPE.0845e68d five-arm green plus trace; served-set population scoped clean. Equal wall-ms seat generation is explicitly unmeasured/noREQ/no build until field/cell collision. R6268–6337.\n104 — COMPLETED consumed upstream fix; status-only reconciliation. Current centralized pin0.4.1 satisfies stated closes-when-pin-main trigger. No checker-root workaround. R6338–6366.\n105 — INSTANCE FIXED (28d4eb68), ongoing authoring discipline. Read fixture and redirect target, shorten blind interval only if recurrence demands; no tool lane. R6367–6418.\n106 — INSTANCE CLOSED, procedure adoption. START/END population enumeration clause remains template-touch item; do not call handed set exhaustive. This sweep accounts all67 IDs explicitly. R6419–6449.\n107 — FIXED original driver AND requested premise assertions. registryhost.rs:1369ff/projwriter.rs:799ff already carry premise assertions; Linux consumer attempt2 unchanged candidate green documented. Later Windows identity-contaminated attempt stays VOID; corrected Windows receipt not claimed by this entry. Artifact filename/driver universality may need receipts, not another two-module patch. R6450–6544.\n108 — RIPE BACKLOG DISCRIMINATOR, BLOCKED current Windows hold. Today's findings-backlog sweep meets listed trigger (R6564–6565), but no run allowed. Reuse80 fixture diagnosis; run single-cell identity/tree discriminator later. Do not claim four stable leaks: fourth-run amendment changes membership. R6545–6566.\n109 — RIPE dedicated312-tag retirement, broad, see rank3. R6567–6588.\n110 — HISTORICAL fold ruled / no second implementation. Final amendment chooses surviving REQ-WEB-LAN-BOOTSTRAP-FIREWALL, W1 CIM+pure seam, removes duplicate IDs/netsh ADR; Linux ten-cell gap qualified. #304 shipped; completion reconciliation rather than recreate W2. R6589–6617.\n111 — TOUCH-TRIGGERED UDP rule-observation backlog. ActiveStore effective state vs by-name presence; next inbound-rule wave or CIM query generalization. No live fallback/rule changes authorized; current box state unknown. R6618–6639.\n112 — TOUCH-TRIGGERED two-fixture hermeticity; existing nextest gate correct. No cargo-test-lib rerun or gate conversion now. R6640–6659.\n113 — PROCEDURE / next mutation-driver touch. Trap/finally plus next-arm pristine bytes/oid and assertion-local negative outcome; no new mutation window. R6660–6681.\n114 — PROCEDURE / shared-state arm trigger. One writer, fetcher-owned before/after census and timestamped coordination; original scope rationale void. No new firewall experiment. R6682–6690.\n115 — PROCEDURE / next firewall census. Same-dump port+program controls, full reaching conjunction and per-agent exits; late event-log amendment forbids using events as delete direction proof. R6691–6700.\n116 — PROCEDURE / next watchdog. Actual post-state, owned identities; both script echo and harness success were false kill claims.137 during compile was VOID not product red. R6701–6711.\n117 — PROCEDURE / requirement/prediction authoring. Refutable branches and code-violable invariant; no measured local latency threshold in product. R6712–6720.\n118 — PROCEDURE / next capture/filter. Flush/stop writer before reading and live positive-control/raw schema; no new instrument project. R6721–6729.\n119 — PROCEDURE plus BLOCKED OPERATOR receipt. Empty-dir route control and complete teardown rules stand. Credential rotation is separate operator item releases#304 comment5643876746; this register records no completion, so unknown and not authority to rotate. R6730–6740.\n120 — INSTANCE DISCRIMINATED, ongoing claim discipline. Second Windows host and Linux contrast supplied missing axes; no platform investigation to repeat. R6741–6750.\n121 — INSTANCE FIXED v7, recurring rig/byte-reader discipline. Audited delivered set, no arm-id patch against frozen v6; raw byte and leading-dash safeguards on next authoring touch. R6751–6768.\n122 — REPEAT-FIELD TRIGGER, current closure UNKNOWN/receipt-first. Original stop refusal intentional and cannot be bypassed. Later133 owned-shutdown proof demonstrates successor cleanup, but does not alone reconcile every122 identity invariant. Owner hertz rig; inspect accepted successor/receipts before any repeat-field authorization, never PID-only automation. R6769–6781.\n123 — FIXED successor, mechanism-only OPEN. Return/log channel correction already exists, frozenr10 unchanged; no new code. R6782–6793.\n124 — REPEAT-FIELD TRIGGER, supersession reconciliation needed. Original driver creates daemon on setup-never-ran cleanup. Do not patch preserved2e3aec1b or assume latest accepted successor retains defect; inspect current successor's no-setup branch before field. R6794–6805.\n125 — UNKNOWN mechanism; receipt-first with124. Original false-negative sweep, NOT falseCLEAR; slash comparison is unconfirmed candidate. Later132 adds stronger identity seam. Need exact successor predicate/known-present proof, not a guessed path-normalization patch. R6806–6816.\n126 — ORIGINAL budget shape superseded by134's qualified clock design. No second independent budget fix; future field repinning/authorization remains separate. R6817–6827, R6901–6913.\n127 — CORRECTED/QUALIFIED preserved M3; class touch-triggered. Whole nested-value assignment + native flags readback already measured. R6828–6836.\n128 — CORRECTED/QUALIFIED M5 and N publisher; class touch-triggered. Typed null/empty seam and overwrite-rename already changed; original123 arms invalid. R6837–6846.\n129 — CORRECTED/QUALIFIED twice, latest promotion Read-Json-DateKindString discriminator. No repeat implicit-date repair against preserved predecessor. R6847–6856.\n130 — AUTHORIZED CORRECTION, final retry receipt UNKNOWN in entry. Two-line qualificationHome rename directed, fresh-root result explicitly separate. Minimum is locate that receipt/successor before claiming fix or redispatching. R6857–6866; AZLCQNZL-* preserved references.\n131 — CORRECTED/QUALIFIED no-mutation preflight. Child env scrub and invalid Stop-Transcript removal passed; strict seed guard intact. R6867–6877; VGCTKD7A-preflight-clean-* receipts.\n132 — CORRECTED/QUALIFIED birth-aware admission.14 controls and17-hit live read recorded; current product/box state not inferred. R6878–6888.\n133 — COMPLETED correction with genuine promotion0/owned shutdown. Later failed field handoff separate, no promotion rerun. R6889–6900.\n134 — CORRECTION QUALIFIED, future FIELD BLOCKED/repin-only.630s design and receipt/clock controls already built; candidate/packet/nonce/driver/runner repin is one future amendment requiring separate grant. Independent candidate product query-timeout finding M5XKQ2DN remains separate; cannot close it using instrument repair. R6901–6913.\n135 — LANDED52d56248; RECEIPT-ONLY integration execution. Centralized precheck/install and Linux controls built; live token/private build deliberately unexercised and provisioning is optional operator decision. Do not redispatch version diagnostic. R6914–6920.\n136 — LANDED84e20ddd; completed shared composition, adoption touch-triggered. S5 initial fix/cross-host green distinct from later Linux shared-fixture proof (seven unopted twohost cases compile-only). Future URL fixture uses ServingFixture; no duplicate helper. R6921–6931.\n137 — RETIRED8bb0feb4 byYPLFG3CG, no tracked launcher callsite. OMP harmless-child receipt is not reproduction of Claude Code failure. Reopen only owned new callsite/contrary evidence, never unused helper. R6932–6937.\n\nBOTTOM LINE: no Windows investigation should begin under CI34983756975 hold. Receipt reconciliation can proceed read-only now. IR90 residual and existing-owner IR82 are the strongest small implementation candidates; IR109 is real but not a small rider. IR78/94 are valid conditional seams, not proof that an immediate dispatch is owed. IR86 retirement must remain Main's slice-by-slice decision."},"status":"success"},"isError":false,"timestamp":1789483931189}}
{"type":"message","id":"ef613f00","parentId":"f54b765c","timestamp":"2026-09-15T14:52:11.234Z","message":{"role":"user","content":"Current interruptible wait interrupted: IRC message from parent agent `Main`.\n\nParent IRC message:\n\nIR75 own probe: bare ssh reavus@kitsubito \"traceable-reqs --version\" exited127 at14:49Z; explicit /home/reavus/.local/bin binary probe running. Do NOT retire installation ticket as executable driver availability without PATH qualification. IR86 docs decoupling proven at currentgolden597–668; gitblamec3b5feec2, so retire all3+coupling.","attribution":"agent","timestamp":1789483801591,"steering":true}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_W0mnbKcNLcYvlSABje4LBLDs|fc_000c7cef03cac861016aa95b9d74b087d194c6e491b41f87cb","toolName":"hub","startedAt":"2026-09-15T14:52:17.429Z","intent":"Correcting checker availability disposition"},"id":"0475fd65","parentId":"ef613f00","timestamp":"2026-09-15T14:52:17.429Z"}
{"type":"message","id":"38b977b3","parentId":"0475fd65","timestamp":"2026-09-15T14:52:17.431Z","message":{"role":"assistant","content":[{"type":"toolCall","id":"call_W0mnbKcNLcYvlSABje4LBLDs|fc_000c7cef03cac861016aa95b9d74b087d194c6e491b41f87cb","name":"hub","arguments":{"i":"Correcting checker availability disposition","op":"send","to":"Main","message":"Accepted correction: IR75 remains OPEN PATH/driver-availability residual; my 'original instance spent' was too broad. IR135 real-binary smoke establishes installed binary only, not bare non-login invocation. Use your 14:49Z bare-ssh exit127 as ripe trigger; smallest next step inspect actual Linux driver launch/PATH and choose explicit binary path or declared PATH, not reinstall blindly. IR86 defer-to-Main row superseded by your current docs-decoupling proof c3b5feec2."},"intent":"Correcting checker availability disposition"}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":25213,"output":138,"cacheRead":117504,"cacheWrite":0,"totalTokens":142855,"cost":{"input":0.25213,"output":0.006900000000000001,"cacheRead":0.117504,"cacheWrite":0,"total":0.37653400000000004}},"stopReason":"toolUse","timestamp":1789483931230,"responseId":"resp_000c7cef03cac861016aa95b9ba3a087d1bf0e104f5075dc74","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"fc_000c7cef03cac861016aa95b9d74b087d194c6e491b41f87cb","type":"function_call","status":"completed","arguments":"{\"i\":\"Correcting checker availability disposition\",\"op\":\"send\",\"to\":\"Main\",\"message\":\"Accepted correction: IR75 remains OPEN PATH/driver-availability residual; my 'original instance spent' was too broad. IR135 real-binary smoke establishes installed binary only, not bare non-login invocation. Use your 14:49Z bare-ssh exit127 as ripe trigger; smallest next step inspect actual Linux driver launch/PATH and choose explicit binary path or declared PATH, not reinstall blindly. IR86 defer-to-Main row superseded by your current docs-decoupling proof c3b5feec2.\"}","call_id":"call_W0mnbKcNLcYvlSABje4LBLDs","internal_chat_message_metadata_passthrough":{"create_time":1789483932.051836,"turn_id":"700134a6-a600-4248-b585-f291f6056216"},"name":"hub","metadata":{"turn_id":"700134a6-a600-4248-b585-f291f6056216"}}]},"duration":6196.342299997807,"ttft":2246.6656999886036,"completedAt":1789483937428,"contextSnapshot":{"promptTokens":142717,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"message","id":"45801255","parentId":"38b977b3","timestamp":"2026-09-15T14:52:17.433Z","message":{"role":"toolResult","toolCallId":"call_W0mnbKcNLcYvlSABje4LBLDs|fc_000c7cef03cac861016aa95b9d74b087d194c6e491b41f87cb","toolName":"hub","content":[{"type":"text","text":"Delivered to 1 peer(s):\n- Main: injected"}],"details":{"op":"send","from":"RegisterLater","to":"Main","receipts":[{"to":"Main","outcome":"injected"}]},"isError":false,"timestamp":1789483937432}}
{"type":"message","id":"f2220883","parentId":"45801255","timestamp":"2026-09-15T14:52:17.472Z","message":{"role":"user","content":"Current interruptible wait interrupted: IRC message from parent agent `Main`.\n\nParent IRC message:\n\nExplicit ssh /home/reavus/.local/bin/traceable-reqs --version returned0.4.1 exit0. Barecommand still127. IR75 installed symptom closed but real driver/PATH adoption remains unless explicitpath proven; label conditional, no reinstall.","attribution":"agent","timestamp":1789483845909,"steering":true}}
{"type":"custom","customType":"tool_execution_start","data":{"toolCallId":"call_uIfBvkOo82aWlG7xXcioQ4P2|fc_000c7cef03cac861016aa95ba355e087d1975856b326c78644","toolName":"yield","startedAt":"2026-09-15T14:52:33.332Z"},"id":"5de87dab","parentId":"f2220883","timestamp":"2026-09-15T14:52:33.332Z"}
{"type":"message","id":"cee3a30f","parentId":"5de87dab","timestamp":"2026-09-15T14:52:33.332Z","message":{"role":"assistant","content":[{"type":"toolCall","id":"call_uIfBvkOo82aWlG7xXcioQ4P2|fc_000c7cef03cac861016aa95ba355e087d1975856b326c78644","name":"yield","arguments":{"type":null,"data":{"summary":"Correction to prior 67-ID report: IR75 installation is proven complete, but bare-command availability is not. Keep driver/PATH adoption conditional; no reinstall. Main's IR86 source proof discharges docs coupling as well as three landed slices.","files":[{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md","description":"IR75 disposition corrected using Main's supplied paired SSH receipts; IR86 delegated closure updated using Main's supplied coupling proof."}],"architecture":"An installed executable, its availability through a launcher's PATH, and a driver's successful use are separate facts. Explicit-path version success cannot establish bare-command availability.","report":"This amendment supersedes only IR75 and the provisional IR86 caveat in my prior complete67-ID report; all other dispositions remain.\n\nIR75 — INSTALLATION SYMPTOM CLOSED; DRIVER/PATH ADOPTION CONDITIONAL. Main measured bare ssh reavus@kitsubito \"traceable-reqs --version\" exit127 at14:49Z; explicit /home/reavus/.local/bin/traceable-reqs --version returned0.4.1, exit0. Thus the binary exists and works, but the non-login bare invocation cannot find it. Neither observation proves what every actual gate driver invokes. Owner hertz Linux driver/box-audit seam. Smallest next step: read the intended current driver's command and launch environment; if it relies on bare traceable-reqs under that PATH, adopt the existing explicit path or documented PATH setup. If it already uses the explicit binary successfully, only reconcile the receipt. No reinstall and no unconditional new lane based on the historical missing-install wording. Parent-provided paired receipts are evidence; I performed no live execution.\n\nIR86 — Main reports current golden.yml:597–668 proves docs decoupling, attributed to c3b5feec2. Alongside known landed Linux floor5e05f02d, Windows floor0cda6235 and inline delta82333ca1, Main concludes all three slices plus coupling discharged. My earlier warning to investigate coupling is superseded by that source proof; retirement remains Main-owned."},"error":null}}],"api":"openai-codex-responses","provider":"openai-codex","model":"gpt-6-astra","usage":{"input":396,"output":472,"cacheRead":142592,"cacheWrite":0,"totalTokens":143460,"cost":{"input":0.00396,"output":0.0236,"cacheRead":0.142592,"cacheWrite":0,"total":0.170152}},"stopReason":"toolUse","timestamp":1789483937469,"responseId":"resp_000c7cef03cac861016aa95ba1b96487d1856e26b206e9f448","providerPayload":{"type":"openaiResponsesHistory","provider":"openai-codex","dt":true,"items":[{"id":"fc_000c7cef03cac861016aa95ba355e087d1975856b326c78644","type":"function_call","status":"completed","arguments":"{\"type\":null,\"data\":{\"summary\":\"Correction to prior 67-ID report: IR75 installation is proven complete, but bare-command availability is not. Keep driver/PATH adoption conditional; no reinstall. Main's IR86 source proof discharges docs coupling as well as three landed slices.\",\"files\":[{\"path\":\".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md\",\"description\":\"IR75 disposition corrected using Main's supplied paired SSH receipts; IR86 delegated closure updated using Main's supplied coupling proof.\"}],\"architecture\":\"An installed executable, its availability through a launcher's PATH, and a driver's successful use are separate facts. Explicit-path version success cannot establish bare-command availability.\",\"report\":\"This amendment supersedes only IR75 and the provisional IR86 caveat in my prior complete67-ID report; all other dispositions remain.\\n\\nIR75 — INSTALLATION SYMPTOM CLOSED; DRIVER/PATH ADOPTION CONDITIONAL. Main measured bare ssh reavus@kitsubito \\\"traceable-reqs --version\\\" exit127 at14:49Z; explicit /home/reavus/.local/bin/traceable-reqs --version returned0.4.1, exit0. Thus the binary exists and works, but the non-login bare invocation cannot find it. Neither observation proves what every actual gate driver invokes. Owner hertz Linux driver/box-audit seam. Smallest next step: read the intended current driver's command and launch environment; if it relies on bare traceable-reqs under that PATH, adopt the existing explicit path or documented PATH setup. If it already uses the explicit binary successfully, only reconcile the receipt. No reinstall and no unconditional new lane based on the historical missing-install wording. Parent-provided paired receipts are evidence; I performed no live execution.\\n\\nIR86 — Main reports current golden.yml:597–668 proves docs decoupling, attributed to c3b5feec2. Alongside known landed Linux floor5e05f02d, Windows floor0cda6235 and inline delta82333ca1, Main concludes all three slices plus coupling discharged. My earlier warning to investigate coupling is superseded by that source proof; retirement remains Main-owned.\"},\"error\":null}","call_id":"call_uIfBvkOo82aWlG7xXcioQ4P2","internal_chat_message_metadata_passthrough":{"create_time":1789483938.097905,"turn_id":"feb802e4-cd2f-4be2-bd1c-048455b5c143"},"name":"yield","metadata":{"turn_id":"feb802e4-cd2f-4be2-bd1c-048455b5c143"}}]},"duration":15860.694199979305,"ttft":1883.6034999787807,"completedAt":1789483953331,"contextSnapshot":{"promptTokens":142988,"nonMessageTokens":10342,"compactionEpoch":0}}}
{"type":"message","id":"978d97b3","parentId":"cee3a30f","timestamp":"2026-09-15T14:52:33.333Z","message":{"role":"toolResult","toolCallId":"call_uIfBvkOo82aWlG7xXcioQ4P2|fc_000c7cef03cac861016aa95ba355e087d1975856b326c78644","toolName":"yield","content":[{"type":"text","text":"Result submitted."}],"details":{"data":{"summary":"Correction to prior 67-ID report: IR75 installation is proven complete, but bare-command availability is not. Keep driver/PATH adoption conditional; no reinstall. Main's IR86 source proof discharges docs coupling as well as three landed slices.","files":[{"path":".worktrees/hertz-ir86-disk-delta/docs/INFRA-REGISTER.md","description":"IR75 disposition corrected using Main's supplied paired SSH receipts; IR86 delegated closure updated using Main's supplied coupling proof."}],"architecture":"An installed executable, its availability through a launcher's PATH, and a driver's successful use are separate facts. Explicit-path version success cannot establish bare-command availability.","report":"This amendment supersedes only IR75 and the provisional IR86 caveat in my prior complete67-ID report; all other dispositions remain.\n\nIR75 — INSTALLATION SYMPTOM CLOSED; DRIVER/PATH ADOPTION CONDITIONAL. Main measured bare ssh reavus@kitsubito \"traceable-reqs --version\" exit127 at14:49Z; explicit /home/reavus/.local/bin/traceable-reqs --version returned0.4.1, exit0. Thus the binary exists and works, but the non-login bare invocation cannot find it. Neither observation proves what every actual gate driver invokes. Owner hertz Linux driver/box-audit seam. Smallest next step: read the intended current driver's command and launch environment; if it relies on bare traceable-reqs under that PATH, adopt the existing explicit path or documented PATH setup. If it already uses the explicit binary successfully, only reconcile the receipt. No reinstall and no unconditional new lane based on the historical missing-install wording. Parent-provided paired receipts are evidence; I performed no live execution.\n\nIR86 — Main reports current golden.yml:597–668 proves docs decoupling, attributed to c3b5feec2. Alongside known landed Linux floor5e05f02d, Windows floor0cda6235 and inline delta82333ca1, Main concludes all three slices plus coupling discharged. My earlier warning to investigate coupling is superseded by that source proof; retirement remains Main-owned."},"status":"success"},"isError":false,"timestamp":1789483953333}}
{"type":"custom","customType":"session_exit","data":{"reason":"dispose","kind":"normal","recordedAt":"2026-09-15T14:59:11.226Z"},"id":"bea715ab","parentId":"978d97b3","timestamp":"2026-09-15T14:59:11.226Z"}
