Skip to content

Observe Claude permission exits that leave blocked state standing #507

Description

@schickling-assistant

Motivation

A Claude PermissionRequest records blockedOn: human. Current main clears that state on several later lifecycle edges and correctly handles StopFailure, but it neither registers nor reduces two documented permission-exit events:

  • PostToolUseFailure: the approved tool started and then failed;
  • PermissionDenied: auto mode rejected the identified tool call before execution.

Ignoring either event can leave the seat falsely blocked until an unrelated later event arrives.

Current-main boundary

StopFailure is already correct and is the positive control for this change:

  • settings run both the dedicated notifier and claude-observe.sh StopFailure;
  • the reducer records idle, clears blockedOn, and distinguishes provider-auth from other API errors;
  • claude-stop-failure.sh reads the official .error field.

Do not reopen or duplicate that work.

Manual permission denial is also not covered by PermissionDenied. Claude's current hook contract explicitly excludes manual dialog denial, PreToolUse hook rejection, and deny-rule matches. The existing pinned manual-denial experiment observed no later event. That eventless path must remain held until a later authoritative lifecycle edge; this issue must not synthesize an outcome.

Scenarios

Approved tool fails

PermissionRequest → PostToolUseFailure
blocked/human      → active/none

The tool was admitted for execution. Its failure ends the pending permission question even though the turn can continue.

Auto mode denies

PermissionRequest → PermissionDenied
blocked/human      → active/none

The identified call was rejected before execution. The model can continue or retry, so this is not a terminal seat state.

Manual dialog denies

PermissionRequest → no hook event
blocked/human      → remains blocked/human

No exact exit observation exists. A later UserPromptSubmit, SessionStart, Stop, or StopFailure can reset the stale state according to its own lifecycle meaning.

Evidence

The Claude Code 2.1.259 hook reference states:

  • PostToolUseFailure fires only after a tool started and failed; permission rejection does not emit it.
  • PermissionDenied fires for auto-mode classifier denial and carries tool_use_id; it does not fire for manual denial.
  • StopFailure fires instead of Stop when an API error ends the turn.

The existing PreToolUse clear rule is backed by a real 2.1.237 serialization experiment, not a documented 2.1.259 correlation guarantee. Re-measure that ordering in the same focused provider probe instead of broadening the reducer by assumption.

This is an st2 settings/reducer defect with deterministic local fixtures. /sk-repro is not applicable because there is no external project bug to isolate.

Acceptance

  • Generated Claude settings register claude-observe.sh for PostToolUseFailure and PermissionDenied.
  • PermissionRequest followed by an official PostToolUseFailure envelope produces active, blockedOn: none, and no synthetic terminal condition.
  • PermissionRequest followed by an official auto-mode PermissionDenied envelope produces active, blockedOn: none, and no claim that the tool executed.
  • Existing StopFailure settings, reducer, notifier, and .error fixtures remain green as positive controls.
  • A manual-denial trace with no later event remains blocked; the implementation does not fabricate PermissionDenied or Stop.
  • Subagent envelopes continue to leave top-level state unchanged.
  • A disposable Claude Code 2.1.259 PTY probe records PermissionRequest, PostToolUseFailure, PermissionDenied, PreToolUse, PostToolUse, Stop, and StopFailure without mutating the operator credential store.
  • The probe confirms the approved-failing-tool edge and rechecks the existing serialization premise. Any divergence updates the mapping before merge.
  • No condition/disposition schema and no harness-state v3 work is introduced.
Posted on behalf of @schickling
field value
agent_identity dev3.direct.omp.9exwnk6h
session dev3.9exwnk6h
agent_persona generalist
agent_supervisor unavailable
agent_tool OMP
agent_tool_version 18.1.7
agent_runtime OMP 18.1.7
tooling_profile dotfiles@931583a

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

    area:driverHarness drivers: launch, MCP, app-server, native delivery · Set: manualarea:presencePresence, status records, and heartbeats · Set: manualharness:claudeClaude Code-specific behavior · Set: manualorigin:agentFiled or primarily produced by an AI agent · Set: manualtype:bugSomething broken or a regression · Set: manual

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions