[FEATURE] Native monotonic per-session turn/prompt index in hook payloads

Status Open
Maintainer reply None cached
Activity 0 comments · opened Aug 25, 2026

Problem

We run a custom Stop/UserPromptSubmit hook pair to track a per-session "turn number" so we can label each model response (Turn N). The mechanism: increment a counter file on UserPromptSubmit, then have the Stop hook validate that the model's self-chosen prefix matches the counter.

This breaks because several events reach the model as a genuine "turn" — eliciting a real model response — without firing UserPromptSubmit:

  • Task-notifications for background/monitor activity
  • Teammate cross-session messages (Agent Teams SendMessage)
  • Other injected system-reminders / notifications not tied to a real user-initiated tool call (related to the "fake/injected notification" reports in #83338, #80818, #84539)

Each of these causes a model response, but none of them increments our counter, so it drifts out of sync with the actual sequence of model responses the Stop hook is validating against. There's no reliable way for a hook to distinguish "this is turn N" without hand-rolling detection for every event type that can elicit a response — and that list isn't stable or fully enumerable from hook payloads today.

Workaround and its limitation

Counter file in session state, incremented on UserPromptSubmit, checked on Stop. Works only for genuine user-typed prompts. Any injected/background-originated turn silently skips the increment, so the counter undercounts and the Stop hook rejects an otherwise-correct turn label.

Proposed feature

Expose a native, monotonically increasing per-session turn index (or "prompt index") as a field in all hook payloads — UserPromptSubmit, PreToolUse, PostToolUse, Stop, and any injected-notification/system-reminder-triggering event.

  • Increments exactly once per distinct event that elicits a model response, including injected/background notifications — not just literal user-typed prompts.
  • Read-only, provided by the harness, so hook authors don't need to hand-roll a counter that can't see every real "turn."
  • Would let hook-based tooling (turn labeling, rate limiting, audit logs, per-turn diagnostics) key off a reliable source of truth instead of reconstructing session structure from partial signals.

Happy to provide our current hook implementation as a reference for the workaround if useful.

View original on GitHub ↗