---
name: precheck-admission-discipline
description: "2026-09-12 #300 precheck — D1/D2 ran and closed; the durable lessons are about instruments that cannot fire, claims that outrun measurement, and what a shared-host admission actually demands."
metadata: 
  node_type: memory
  type: project
  originSessionId: 19d48c98-d787-4436-90c2-da3f52339ae1
  modified: 2026-09-12T22:29:16.855Z
---

2026-09-12. doyle granted ONE Claude launch for the D1/D2 precheck; it ran and the window closed.
Receipt (full paths + SHA-256 for 18 artifacts): `.claude/reports/2026-09-12-precheck-d1-d2/RECEIPT.md`,
commit `8cfeb83`. Plan pin `6cec8a5c`. See [[cc-acceptance-surface-provenance]].

**RESULT, narrowly:** D1 = YES for ONE print-mode submission — `UserPromptSubmit` fired, evidenced by
its OWN attributed transcript (new since a pre-launch inventory AND carrying a nonce), with
`SessionStart` artifacts establishing the hook config loaded independently of D1 itself. NOT a
universal guarantee. D2 = YES for TRANSCRIPT PERSISTENCE AFTER TERMINATION only; window
UNESTABLISHED, so neither mid-turn termination nor resumability was shown.

⭐⭐ **A CONTROL THAT CANNOT FIRE IS WORSE THAN NO CONTROL** — it converts every run into a void. A peer
proposed requiring a `SessionStart` trace line as the instrument-presence witness; measuring first
showed all 23 `SessionStart` mentions across both trace generations are CONDITIONAL branches. Same for
`PreToolUse` (16/16 exceptional) and `Stop`. **This trace routinely records `UserPromptSubmit` and
NOTHING ELSE**, so no trace-side witness of instrument presence exists for any hook — which made the
first D1 design CIRCULAR (the only possible witness was the thing being measured).

⭐⭐ **THE TRANSCRIPT IS A SECOND, INDEPENDENT INSTRUMENT, and it is the one that worked.** Carried as
"best-effort, unmeasured" precisely because it could only widen the answer space; it turned
{YES, evidence-unavailable} into a real YES. Meanwhile the trace slice carried NO entry attributable
to the spawn at all (only `id=perri` lines) — recorded as UNEXPLAINED, no cause invented.

⭐⭐ **I ASSERTED A FAILURE MODE I NEVER MEASURED**: that PowerShell 5.1 would "silently restore" argv
shredding. That claims a FALLBACK PATH. Absence of a member implies unavailability, not silent
degradation. Withdrawn in text rather than deleted.

⭐⭐ **`Start-Process -ArgumentList` SHREDS a multiword argument** — MEASURED: a 4-element vector
arrived as 16 arguments. Use `ProcessStartInfo.ArgumentList` (per-element escaping; modern .NET only,
absent on 5.1) and prove EXACT vector equality, never a substring. My original "argv proof" used the
broken construction to test itself.

⭐ **Fault injection beats declaring a branch untestable.** I said QUERY-FAILURE/EXIT-UNCERTAIN needed
a host fault; making the process-query a PARAMETER put the fault in the test instead. Both branches
then passed with residual identity preserved and no false CONFIRMED-EXIT.

⭐ **Void must not vanish from the report**: scheduled / attempted / evaluable / unavailable side by
side, so 10/10/2/8 can never read as "2 of 2". Excluding from a denominator is not the same as
excluding from the record.

⭐ **A zero from an instrument aimed at the wrong population is not a zero.** I read the CI queue on
two legacy repos and got clean results that meant nothing; and a `CPU=0.00` on the runner was an
ACCESS ARTIFACT (property empty for service processes, rendered as 0.00) that I nearly reported as
idleness — caught by a positive control on my own process. Sharpens [[list-vs-predicate-assertions]].

⭐ **A trust key OUTLIVES its directory.** `trust-probe31`'s `.claude.json` entry survived the
directory's deletion, so recreating that exact path inherits trust with ZERO config writes — better
than the write-then-clean variant I had offered.
