# claude-spt UserPromptSubmit Timeout Bundle

**Date:** 2026-07-10  
**Triage owner:** perri  
**Disposition:** v0.21.0 accepted and building immediately

## Reports

1. [`01-user-prompt-submit-timeout-rca.md`](01-user-prompt-submit-timeout-rca.md)  
   Pins the hook timeout to `self_id -> spt whoami --json -> full endpoint-list project projection -> synchronous Git fanout`. Explains why `whoami` was historically chosen, why deployah/Doyle selectivity is threshold behavior, and why PROJECT-INDEX is related but not sufficient defense for a correctness-critical hook.

2. [`02-imminent-fix-and-publish-plan.md`](02-imminent-fix-and-publish-plan.md)  
   Proposes an immediate claude-spt patch: repair session-carrier write custody, use `SPT_ENDPOINT_ID` only with payload-SID proof, bypass `whoami` on ordinary spt-hosted prompts, add stage timings, avoid double listing on live invocation, and retain the safe fallback until spt-core ships a narrow identity-only API.

## Agreed Perri disposition

Perri read both reports and source-verified the load-bearing claims.

1. Carrier custody is a prerequisite commit in the same release and a standalone correctness fix.
2. Verified identity requires `SPT_ENDPOINT_ID` plus carrier SID equal to the payload SID, with the carrier written only after successful strict registration/boundary.
3. Publish now with documented `whoami` fallback for harness-hosted/mismatch cases; do not wait for PROJECT-INDEX or the core API.
4. Apply the verified resolver at the shared `self_id` seam across every hook handler, not only UserPromptSubmit. This prevents the same Git fanout from delaying PreToolUse, Stop, Notification, SessionEnd, SubagentStart, and SessionStart paths.
5. Publish as **v0.21.0** because behavior changes across all handlers and new trace fields are added.
6. Binary-only release: no skeleton/plugin reload; endpoint bounce activates it.
7. Perri implemented from `UPS-IDENTITY-PLAN.md`; carrier custody and the fast path landed atomically because they are safety-coupled, with independently pinned requirements/tests.

## Landed transactional park custody

The operator-visible failure was message-body loss: the old hook deleted parked bodies before the slow identity call, then Claude Code killed the hook before context emission. v0.21.0 includes structural custody rather than only trigger removal:

1. Deadline-dominating identity and optional live-roster work run before any park drain.
2. Drain renames `.park` to `.park.pending`, reads it, and does not delete it.
3. A pre-existing pending row is loudly redelivered.
4. Context emits before the hook's final commit.
5. Final commit deletes pending rows and clears the deferred wake park.

Claude Code exposes no emission acknowledgement because stdout is consumed after hook exit. Therefore exactly-once delivery is impossible at this seam; the remaining emit→commit crash window can duplicate a body, never silently lose it. This matches the established “duplicates beat silent loss” policy.

`REQ-HAZARD-PARK-DRAIN-DEADLINE` pins operation order, identity-before-drain, and uncommitted redelivery. Live acceptance kills a test hook during identity and asserts later redelivery.

## Build and publish status

- Carrier custody, shared verified resolver, stage timing, and transactional park custody landed on main (`b20c12b` plus follow-ups).
- Post-version-bump full gate passed.
- 309-test suite green, including transactional-custody operation-sequence assertions.
- **claude-spt v0.21.0 published and tagged:** https://github.com/SaberMage/claude-spt/releases/tag/v0.21.0
- Windows and supported Linux artifacts published together.
- Release notes disclose the harness-hosted/mismatch fallback limitation without claiming full closure.
- Remaining acceptance: kill a test-perch hook mid-identity and assert pending-body redelivery after nodes update.

## Cross-repository dependency

Request spt-core add a stable identity-only adapter API:

`session ID -> endpoint ID or null`

It must perform no endpoint listing, project enrichment, Git, registry fanout, or network activity. Existing `endpoint-info` is not suitable because it also computes latest-project metadata.

The spt-core persistent materialized project index remains canonical for enriched list/picker/reporting performance. The identity-only API removes an unnecessary correctness dependency even after that index ships.

The identity-only API request is filed in spt-core as **F-037** in `docs/SPT-CORE-FINDINGS.md` and has been pushed to main.

## Agreed trace stages

`skill`, `wake`, `park-drain`, `live-roster`, `identity(path=verified-env|core-fallback)`, `busy`, `poll`, `nudge`, `emit`, and `total`; monotonic timings only, never prompt or message bodies.

## Safety observed during RCA

- No real UserPromptSubmit hook was executed.
- No endpoint was marked busy.
- No inbox was polled or drained.
- No daemon or endpoint was stopped, restarted, or killed.
