Ticket Guard
repo: ~/Projects/ticket-guard · 3 commits · 0 in last 24h, 0 in last 7d ·
Creative ideas + design notes
Commits with substantial prose (≥120 chars) — the rationale behind each move.
1d2b313 · 2026-09-13 · harden ticket-guard after second-model review: pid+start identity, no-tty guard, throttle (TK-11621)
Codex was spend-capped (TK-11571 condition); review came from Kimi k3. Its sharpest
point matched my own adversarial pass: pid ALONE is not a process identity because
macOS recycles pids, so a dead writer's pid can be re-issued and re-validate a stale
record. Now requires pid AND start time (ps -o lstart= is byte-identical to the
record's owner.started, verified on ttys003).
Also from that review: a session with no controlling tty (headless claude -p) would
have probed a degenerate state path and let ttyless sessions inherit each other's
binding -> now an explicit fail-loud guard.
Added a 15-min per-identity throttle: without it a genuinely ticketless session gets
the reminder on every prompt forever, burning context to repeat itself. Stamp is keyed
to pid+start so a NEW session is never silenced by a dead one's stamp.
Perf: start time resolved LAZILY, only on the path that needs it — the 45 of 77
launcher-bound sessions exit at step 2 and never pay for it. 0.48s -> 0.03s.
Negative test 8 -> 14 cases, all pass, incl. pid-reuse, no-tty, missing start time,
and all three throttle behaviours.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkVx1x2ppxm6tdEXngBj2P
ffe9706 · 2026-09-13 · install.sh: gated, idempotent, self-verifying settings.json wiring (TK-11621)
Refuses to wire if the negative test fails. Backs up settings.json. Rehearsed on a
copy: additive only (UserPromptSubmit 5->6), idempotent, other hook events untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkVx1x2ppxm6tdEXngBj2P
153f410 · 2026-09-13 · ticket-guard: UserPromptSubmit hook that catches ticketless sessions at first action (TK-11621)
Enforces CLAUDE.md's every-action-rides-a-ticket rule mechanically instead of
relying on model memory. Fires on UserPromptSubmit (not SessionStart) so an idle
restored session is never made to invent a ticket for work it is not doing.
Fail-loud: an unmeasured binding is never treated as bound (TK-11431 amd 1).
Identity-checks the tty status record against the live pid to defeat the
reusable-tty-slot false green. 60-70ms vs the 18-27s full scan.
Ships with a negative test (8 cases, all injected faults go red).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkVx1x2ppxm6tdEXngBj2P
File tree
4 files tracked. Click any to browse the source at HEAD.
rendered in 1ms