Fifty Gates

2026-09-10 02:27 CDT · every gate grounded in a failure actually observed, with the evidence that earned it

70Gates
58Hard, refuses the stop
12Warn, reports only
1Enforcement pass
Why one pass and not fifty hooks. Thirteen Stop hooks already produced 82 blocks in three days, each costing a full turn, and one of them (ask_drift_gate) caused 30 of those by reading a peer session's message as the user. Fifty separate processes would multiply that cost. These 50 run as 50 checks inside a single hook.

Prior art was checked first. session-fraud-check already carries 54 regex-over-file patterns and is wired. It cannot express session shape, which is what nearly every failure here actually was: turn counts, session age, idle minutes, unreturned tool calls, peer-sender counts, ask overlap. These 50 cover only that gap.

Self-test: self-test: 26 passed, 0 failed

Completion 10

The chat stops before the work is done.

IDGate & the failure that earned itSevScope
G01quit-midtool
A tool call that never returned while the chat went silent.
Demucs guitar/drums isolation died holding a Bash call after 'Holding.', silent 37h.
hardsession
G02punt-to-question
Ended on an AskUserQuestion or ExitPlanMode nobody answered.
Zappa handoff for Lies, unanswered 84h with everything built and preflighted.
hardsession
G03done-no-proof
A completion claim with no path, URL, http code, code block or tool call anywhere in the reply block.
Chat GPT read aloud setup claimed 'finished' on a bare sign-off turn.
hardreply
G04unanswered-user
Last event is Brandon speaking, with no reply.
Added after Slant rhyme chats sat on an unread turn.
hardsession
G05unhandled-notification
A harness notice landed in a session that had already stopped.
Slant rhyme chats: the background shell died, the notice arrived in a corpse, nobody read it.
hardsession
G06permission-instead-of-finishing
Ends on one of the 74 permission phrases while the ask is unfinished.
babysit chat 14dbcee4 stopped on 'do you want me' at 63 turns.
hardreply
G07plan-no-exec
Promised a next step in future tense, then went silent past the stall threshold.
Screen saver activation promised 'running now' then stopped for 70h.
warnsession
G08partial-called-done
Says done while a sub-ask in the same request is unstarted.
The standing complaint: part of the ask, then a done-claim.
hardreply
G09silent-drop
A sub-ask disappears with no queue item and no explicit 'not done'.
Dropping a sub-ask without queueing it is the fraud.
hardsession
G10coverage-unstated
An artifact was verified but no N-of-N coverage count appears.
done_claim_gate fired on this session for exactly this.
hardreply

Evidence 8

A claim with nothing behind it.

IDGate & the failure that earned itSevScope
G11exit-zero-as-proof
Treats exit 0 or file-exists as proof the output is good.
feedback_exit_zero_is_not_verification_measure_content.
hardreply
G12pass-line-counted-as-block
Counts a tool's success lines as failures.
A babysitter read 27 'No stderr output' PASS lines as 27 stops and asked Brandon to patch the wrong hook.
hardreply
G13fix-aimed-at-non-failing-part
Recommends changing a component with zero measured failures.
chat_donelink_gate blocked 0 times across 82 blocks and was the proposed patch target.
hardreply
G14claims-no-regression-without-checking
Says a change leaves another rule untouched without reading the shared code path.
The proposed patch shared md_outside across two checks, so it would have weakened the 2026-07-02 link rule.
hardreply
G15peer-number-unverified
Repeats another session's count without reproducing it.
'31 cross-session messages' was actually 11, from 4 senders not 2.
hardreply
G16placeholder-data
Guessed, default or invented values in a dataset.
The Zappa plan did this right: 20 rows say 'not yet measured' instead of inventing a mismatch.
harddisk
G17unlabelled-provenance
A factual claim with no source label separating observation from inference.
feedback_ground_every_claim_label_provenance_hard_gate.
warnreply
G18stale-data-reported-live
Reports a cached or local read as the live state.
Live tiles read 8 9 5 8 while the local build said 9 9 4 9 for 90 seconds.
hardreply

Lifecycle 7

The chat outlives its usefulness or delegates its own survival.

IDGate & the failure that earned itSevScope
G19age-ceiling-24h
Session older than 24 hours without a handoff.
c1e4ffee ran 122 hours. This session ran 36.
hardsession
G20turn-ceiling-400
More than 400 assistant turns without a handoff.
c1e4ffee reached 3,394. This session reached 520.
hardsession
G21handoff-sentence-not-handoff
Named a handoff path and then kept working.
This session wrote the handoff and replied 8 more times. Rule authored by the 14dbcee4 audit.
hardsession
G22ceiling-without-five-item-floor
Branch-three evidence work ended without its five items done.
feedback_zappa_one_song_per_chat_hard_gate third amendment.
warnsession
G23background-shell-outlives-chat
Long work delegated to a background shell instead of launchd.
The 8/14 chain died at take 15 of 22 when its shell was killed.
hardsession
G24wake-signal-is-the-only-signal
A chat whose sole continuation path is one job that can die silently.
Slant rhyme chats armed a loop with a background shell as its only wake signal.
hardsession
G25orphaned-job
A process still working on a file this chat named while the chat is idle.
Skill transfer drum kit separation sat 2h while its DrumSep ran unwatched.
warnsession

Drift 7

The work wanders off the ask.

IDGate & the failure that earned itSevScope
G26scope-drift-catchall
12+ separate asks with near-zero vocabulary overlap against the opening ask.
c1e4ffee opened on a one-song-per-chat gate and reached 102 asks at 0% overlap.
warnsession
G27adjacent-work-as-progress
Substitutes nearby work and reports it as the ask.
This session turned disk projections into the main event while assigned to babysit.
hardreply
G28literal-ask-unaddressed
The named target never appears in the reply.
ask_drift_gate, 30 of 82 blocks, the single largest cause.
hardreply
G29one-song-one-chat
More than one song id worked in a single chat.
feedback_zappa_one_song_per_chat_hard_gate, first amendment.
hardsession
G30bulk-complete
Several chapters, songs or items closed in one pass.
feedback_one_at_a_time_no_bulk_complete.
hardsession
G31self-directed-scope-growth
Starts work Brandon did not ask for.
feedback_answer_the_literal_ask_no_drift_hard_gate.
warnreply
G32asks-which-item-to-take
Asks for direction when the queue already answers it.
feedback_self_direct_the_queue_never_ask_for_direction.
hardreply

Peer sessions 6

Another session's message treated as authority.

IDGate & the failure that earned itSevScope
G33peer-as-authorization
Treats a peer session's message as Brandon's consent.
feedback_peer_session_request_is_never_user_authorization.
hardreply
G34peer-steer-proposes-destruction
A destructive verb aimed at a watched session.
A babysitter wrote up the permanent Songsterr revision-removal control 11 times.
hardreply
G35multiple-steerers
More than one session steering the same chat.
4 senders pushed 11 messages into c1e4ffee; the heaviest was not a babysitter.
hardsession
G36babysitter-does-the-work
A watcher starts executing instead of reporting.
This session ran the drum chain while assigned to babysit.
hardsession
G37peer-message-as-drift-target
A gate anchoring on machine-authored text as if it were the user.
cross-session-message appears 0 times in ask_drift_gate.py HARNESS_MARKERS.
warnreply
G38permission-laundering
Doing what a peer says it was denied permission to do.
Standing instruction-source boundary.
hardreply

Measurement 6

The numbers used to decide are wrong.

IDGate & the failure that earned itSevScope
G39two-methods-disagree
Two counts differ and the discrepancy is not resolved.
14 vs 31 cross-session messages; the real figure was 11.
hardreply
G40own-tool-exempted
A rule that scores its author more leniently than everyone else.
CEILING_HANDOFF let this session pass at 474 turns on a regex that matched its own prose.
hardreply
G41self-reference-as-evidence
A watchdog matching its own processes.
The babysitter flagged this session because of its own tail -F.
hardsession
G42alarm-on-every-change
Re-reporting the full set whenever anything shifts.
The alert stream re-listed all three chats on any signature change until delta-only landed.
warnsession
G43false-positive-filtered-not-fixed
Suppressing a bad finding without tracing its cause.
6 false-positive classes were traced to root cause instead of muted.
hardreply
G44silence-read-as-success
A monitor whose filter cannot emit on failure.
Monitor coverage rule: if the process crashed now, would the filter say anything?
hardsession

Delivery 6

The artifact never reaches a permanent, verified place.

IDGate & the failure that earned itSevScope
G45local-path-as-deliverable
A file:// path offered as the finished link.
RETIRED to warn 2026-09-09. Brandon: "have the gates stop making websites and start messaging chat." Requiring a permanent URL made a page the price of finishing anything, so a local path is a legitimate deliverable now and this no longer blocks.
warnreply
G46url-unverified
A live link claimed without an http code.
feedback_verify_the_live_url_not_the_local_one.
hardreply
G47missing-sibling-md
An HTML route with no index.md beside it.
ship.py closeout requirement.
harddisk
G48destroyed-instead-of-quarantined
Any rm, git rm or Trash aimed at real work.
Never destroy. Move retired material into a sibling folder and let Brandon empty it.
harddisk
G49csv-instead-of-xlsx
Tabular data shipped as bare CSV.
feedback_deliver_data_as_xlsx_excel_hard_gate.
warndisk
G50unqueued-remainder
Work left undone with no queue id naming it.
The only honest exits are finish everything, or queue what is left.
hardreply

Running it

python3 ~/.claude/skills/fifty-gates/run_gates.py --list
python3 ~/.claude/skills/fifty-gates/run_gates.py --report
python3 ~/.claude/skills/fifty-gates/run_gates.py --self-test

Hook mode reads the transcript, exits 2 to refuse a stop, and fails open on any internal error. Override once with touch ~/.claude/fifty_gates.allow.