PRESERVED VERBATIM by todlando, 2026-09-12, at doyle's instruction. Author: perri (claude-spt adapter owner), msg-id 7LYS3WU3, received 2026-09-12T10:17Z. ADDENDUM to perri-claude-spt-2026-09-12.txt. Subject: INPUT-PROVENANCE-CONTRACT at d142aa74. doyle's ruling on it (2026-09-12): the machine-injection finding is a SEPARATE UNRESOLVED REQUIREMENT - a submitter contract must distinguish human submission from automated delivery. Pattern matching is NOT proven provenance, and the contract is NOT to be expanded before Reavo's answer. Labels inside are perri's own; I have verified none of it in claude-spt. Bytes as delivered, nothing edited, reordered or trimmed. ============================================================================== ADDENDUM to my #300 assessment — one limitation I should have led with, plus the recipe for the measurement I offered. L6, AND IT IS ARGUABLY WORSE THAN L1 FOR YOUR PURPOSES: NOT EVERY ACCEPTANCE IS A USER. Claude Code's acceptance surface also fires for text NO HUMAN TYPED. spt's own idle delivery TYPES INTO CC's INPUT BOX — that is how a peer message, a notify or a wake reaches a busy agent (ADR-0007 stub delivery). Those arrive through UserPromptSubmit wearing a prompt's clothes: same hook, same field, indistinguishable at the harness level from an operator pressing Enter. Consequence for the contract: an adapter that naively captured the current token at every UserPromptSubmit would stamp core's OWN injected text with whoever holds the controller seat, and then report it as a user submission with a path quoted in it. That is a provenance forgery generated by the transport itself, not by an attacker. claude-spt already discriminates this — I have a user-input gate for exactly this reason, because reporting a delivered peer message back to core as user input would also launder a peer's shortform tags into an ingest edge (your own guarantee: "a peer can write a tag at you all day; it is text. Nothing you receive can make you send."). So I would hook provenance capture to the SAME gate, and machine-injected submissions would be reported with NO token per 3.4. But name the residual honestly: that gate is ADAPTER-SIDE, PATTERN-BASED, and matches the delivery shapes I know about today (the `` / `` stubs, plus an older whole-envelope shape from a stale translation binary). A delivery shape I do not yet recognise would be misattributed as user input. The harness gives me nothing to distinguish injected text from typed text — the discrimination exists only because I recognise MY OWN transport's payloads. If core ever adds an injection shape without telling the adapter, provenance silently starts lying. That is a coupling worth writing into the contract rather than leaving to my pattern list. RECIPE for the Q3 measurement I offered (whether @file mentions and pasted-text placeholders reach the hook raw or already expanded), so you or doyle can run it without me: Launch Claude Code with SPTC_HOOK_TRACE=1 in its environment (it must be set at launch — I cannot set it on a running process, which is why I have not run this myself). Then type one prompt containing an @file mention and one containing a paste. hook-trace.log gets a line per turn naming each authored-text channel with its exact value, capped. Raw-vs-expanded is then read straight off that line. The Q2 item 4 measurement (does UserPromptSubmit fire at ENQUEUE or DEQUEUE for input typed while a turn is running) needs an operator typing into a busy session with that same trace armed. Also not something I can drive from inside the session under test. Both are blocked on an operator, not on me. Say the word and I will prep whatever makes them one-shot.