Skip to main content

John Drift-Prevention v3

John Drift-Prevention v3 (2026-05-02/03)

Genesis

On 2026-05-02, CEO asked "ovi hooks u kojem jeziku" (a QUESTION). John amplified this into a Kotlin port chain, opening MC #10586 and emergent MC #10589 before CEO intervened with "otisao si u rabbit hole again." This occurred despite v2 hooks (MC #10570) being live and registered. The root cause is structural: v2 gates fire at tool-invocation time (PreToolUse/PostToolUse), but the LLM's planning trajectory commits before the first gate fires. Both drift incidents (Kotlin rabbit-hole + AWS phantom earlier same day) unfolded across multiple turns, each individually compliant with v2 per-turn rules.

Context: feedback_john_kotlin_rabbit_hole_2026-05-02.md

v2 → v3 Progression

v2 (MC #10570) provided:

  • Per-turn MC counter (one-ceo-turn-mc-cap.sh) — caps mc.js add per turn
  • CEO_APPROVED token rate limit — blocks John self-issuing overrides
  • Turn boundary reset (mc-turn-reset.sh) — clears MC counter on UserPromptSubmit
  • Depth/emergent spawn gates (john-max-depth-gate.sh) — 3 trip-wires on Task/Agent dispatch

v2 gaps:

  • No intent classification before planning — QUESTION/CRITIQUE turns treated same as DIRECTIVE
  • MC counter reset did NOT clear CEO_APPROVED token counter — re-issuance mechanically impossible
  • No cap on Task/Agent dispatch — Kotlin incident dispatched codecraft + sentinel-tester in same turn, both uncapped
  • Per-turn enforcement only — multi-turn accumulation (MC #10586 → #10589 across two turns) not detected

v3 adds:

  • Rank 1: Fix CEO_APPROVED counter reset — now resets on every UserPromptSubmit (unconditional)
  • Rank 2: Intent classifier at UserPromptSubmit — emits STOP reminder to LLM context before planning on QUESTION/CRITIQUE turns; blocks mc.js add unless [CEO_APPROVED]
  • Rank 3: Task/Agent dispatch cap — per-turn limit derived from Mehanik approved_subtask_count (fallback: 1)

Three Hooks

Rank 1: mc-turn-reset.sh (UPDATED)

Path: ~/.claude/hooks/mc-turn-reset.sh
Event: UserPromptSubmit (fires on every new CEO message)
What it does: Resets three counters to zero on every new CEO turn:

  • /tmp/john-mc-turn-counter.json (per-turn MC count)
  • /tmp/ceo-approved-token-uses-${SESSION_ID}.count (CEO_APPROVED token uses — v3 FIX)
  • /tmp/john-dispatch-turn-counter.json (Task/Agent dispatch count — v3 NEW)

Sample output: Silent (exit 0). Counters visible via cat /tmp/john-mc-turn-counter.json{"count":0, "turn_id":"...", "ts":"..."}

Override: None. This is a mandatory reset per documented contract ("token valid for one turn").

Rank 2: ceo-intent-classifier.sh (NEW) + pre-mc-add-gate.sh (UPDATED)

Paths:

  • ~/.claude/hooks/ceo-intent-classifier.sh (NEW, UserPromptSubmit)
  • ~/.claude/hooks/pre-mc-add-gate.sh (UPDATED, PreToolUse Bash)

Event: UserPromptSubmit (classifier) + PreToolUse Bash when tool=mc.js (gate)
What it does: Classifies CEO message intent into five classes:

  • DIRECTIVE — action request (default, fail-open)
  • QUESTION — inquiry (ends with ?, starts with Bosnian/English question word)
  • CRITIQUE — rhetorical negative ("to ne radi", "broken", "nije ok")
  • CONFIRM — short affirmative ("da", "ok", "yes")
  • REISSUE — contains [CEO_APPROVED]

Writes result to /tmp/ceo-intent-${SESSION_ID}.json. On QUESTION or CRITIQUE, emits STOP system reminder to LLM context before planning begins. pre-mc-add-gate.sh blocks mc.js add on QUESTION/CRITIQUE unless [CEO_APPROVED] is in the command.

Sample output (stderr):

[ceo-intent-classifier] intent=QUESTION
SYSTEM REMINDER [intent-gate/QUESTION]: CEO message classified as QUESTION.
  MANDATORY RESPONSE PATTERN:
  1. Answer the question or acknowledge the critique in plain text.
  2. Do NOT open MCs, dispatch agents, or run Mehanik in this turn.
  3. If action seems warranted, surface a ONE-LINE option menu and STOP.
  4. Wait for explicit CEO DIRECTIVE before any mc.js add or Task/Agent dispatch.

Override: Include [CEO_APPROVED] in the mc.js add command or Task/Agent dispatch prompt.

Rank 3: one-ceo-turn-dispatch-cap.sh (NEW)

Path: ~/.claude/hooks/one-ceo-turn-dispatch-cap.sh
Event: PreToolUse Task|Agent
What it does: Caps Task/Agent dispatches per CEO turn. Cap derived from most recent Mehanik marker file (/tmp/mehanik-cleared-*) field approved_subtask_count. If no marker: cap=1. Reads and increments /tmp/john-dispatch-turn-counter.json. Blocks on count > cap unless [CEO_APPROVED] in prompt.

Sample output (stderr):

BLOCKED [one-ceo-turn-dispatch-cap]: dispatch #2 in this CEO turn (cap=1 from Mehanik marker).
  Multi-dispatch from a single ambiguous CEO turn = drift signal (Kotlin incident 2026-05-02).
  If CEO explicitly authorized N agents: include [CEO_APPROVED] in dispatch prompt.

Override: Include [CEO_APPROVED] in Task/Agent dispatch prompt, OR obtain Mehanik clearance with multi-agent plan (marker will contain approved_subtask_count > 1).

Live Evidence

Proveo validation: /tmp/v3-proveo-validation.md (2026-05-02)

Suite scores:

  • Suite A (Rank 1 — mc-turn-reset.sh): 4/4 PASS
  • Suite B (Rank 2 — intent classifier + pre-mc-add-gate): 9/10 PASS (1 NOTE: "a" correctly defaults to DIRECTIVE per spec — not a defect)
  • Suite C (Rank 3 — dispatch cap): 5/5 PASS
  • Suite D (Deviations): 3/3 ACCEPT (all low-risk broadening of patterns)
  • Suite E (E2E regression): 4/4 PASS

Verdict: PASS. No blocking defects. All 3 ranked recommendations correctly implemented and verified with real hook execution.

Override Tokens Table

TokenUsageScopeReset
[CEO_APPROVED]Override any single gate (MC cap, dispatch cap, intent gate, emergent spawn)One turnEvery UserPromptSubmit (mc-turn-reset.sh)
[CEO_APPROVED_MULTIPLE_MC]Explicitly authorize multiple MC adds in one turn (bypasses one-ceo-turn-mc-cap.sh)One turnEvery UserPromptSubmit

Note: v3 Rank 1 fix ensures both tokens reset unconditionally on new CEO turn, making re-issuance mechanically possible (was structurally broken in v2).

Known Limitations

  • Intent classifier keyword list: Initial set covers common Bosnian + English patterns. False-negatives possible on idiomatic phrasing. Fails open to DIRECTIVE (no regression). Tune iteratively from live incidents.
  • Rank 2 john-max-depth-gate.sh intent integration: Spec section T1-A4 describes piggybacking intent check onto depth-gate Branch A. NOT implemented in v3. Explicitly ranked below top-3 (optional enhancement). Core Rank 1/2/3 fully functional.
  • Drift-pressure score (T2-A1): Deferred to v3.1. Formula weights unvalidated; shipping guesses would cause false WARN floods.
  • Trip-wire 3 elevation (T2-B3): Deferred. Root cause fix (intent classifier) is upstream; elevating downstream symptom adds CEO friction without addressing cause.

References

  • v3 spec: ~/system/specs/john-drift-prevention-v3-spec.md
  • Parent ZAKON: ~/system/rules/zakon-28-max-depth-boundary.md
  • v2 implementation: MC #10570 (2026-05-02)
  • Genesis incident: MC #10586 + #10589 (closed parked), feedback_john_kotlin_rabbit_hole_2026-05-02.md

Last updated: 2026-05-03. Owner: Skillforge. Status: Live in production.