Skip to content

guard: long sessions run dozens of tool calls with no memory contact — the per-turn gate keys off continuation prompts #296

Description

@CryptoJones

Symptom

In long sessions the agent stops consulting OMI. Measured on hermes over every Claude Code transcript since the hooks went live (2026-08-24):

Preflight outcome at prompt submit Turns Tool calls in those turns Agent consults
Memory injected 407 2975 165
Gate auto-cleared, nothing injected 362 2037 97

Longest single turn: 152 tool calls. 91 auto-clears on 2026-09-03 alone. Compaction is not the cause — SessionStart(source=compact) re-primes correctly (verified in transcripts).

Mechanisms

  1. The relevance signal is the prompt text only. guard.preflight_turn ranks notes against the user prompt; a match sharing fewer than two terms auto-clears the gate (release: 8.7.0 — stop injecting weak preflight matches #257). In a long session the prompts are continuations — retry (Claude Code's own API auto-retry), Yes please, go ahead, Delete it, <task-notification> wakeups — so roughly 40% of turns start with the gate open and no memory injected.
  2. The gate has no budget inside a turn. Once the sentinel exists, decide allows everything until the next turn-start reset. One autonomous turn can run for hours and hundreds of actions while the work drifts far from whatever was consulted at its start.

Fix (harness-agnostic — lives in guard.py, so every adapter inherits it)

  • Continuation-aware preflight. A short/continuation-shaped prompt is retrieved against a composite of the prompt, the previous turn's task, and the agent's recent activity; the gate auto-clears only when the composite also misses. An identical prompt re-sent within seconds is an auto-retry and carries the previous turn's gate state instead of resetting it.
  • Action budget in the decision core. Every allowed non-consult action counts against a per-turn budget in the sentinel. At the budget the core retrieves against the turn's task plus its action trail; if a relevant note that this session has not yet seen exists, the gate re-arms and demands that specific note (one recall-note call clears it). No candidate → the budget resets and the auto-clear is logged. Harnesses with a post-tool hook that can inject context (Claude Code PostToolUse) get the note injected proactively instead of blocked.
  • Doctor visibility. Auto-clear rate and mid-turn re-arms become a doctor check so this regresses loudly next time.

Related: #290 (mid-turn user messages invisible to the classifier) — same root: the guard only sees the turn's opening message.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions