You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
Motivation
A Claude
PermissionRequestrecordsblockedOn: human. Current main clears that state on several later lifecycle edges and correctly handlesStopFailure, 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
StopFailureis already correct and is the positive control for this change:claude-observe.sh StopFailure;idle, clearsblockedOn, and distinguishes provider-auth from other API errors;claude-stop-failure.shreads the official.errorfield.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,PreToolUsehook 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
The tool was admitted for execution. Its failure ends the pending permission question even though the turn can continue.
Auto mode denies
The identified call was rejected before execution. The model can continue or retry, so this is not a terminal seat state.
Manual dialog denies
No exact exit observation exists. A later
UserPromptSubmit,SessionStart,Stop, orStopFailurecan reset the stale state according to its own lifecycle meaning.Evidence
The Claude Code 2.1.259 hook reference states:
PostToolUseFailurefires only after a tool started and failed; permission rejection does not emit it.PermissionDeniedfires for auto-mode classifier denial and carriestool_use_id; it does not fire for manual denial.StopFailurefires instead ofStopwhen an API error ends the turn.The existing
PreToolUseclear 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-reprois not applicable because there is no external project bug to isolate.Acceptance
claude-observe.shforPostToolUseFailureandPermissionDenied.PermissionRequestfollowed by an officialPostToolUseFailureenvelope producesactive,blockedOn: none, and no synthetic terminal condition.PermissionRequestfollowed by an official auto-modePermissionDeniedenvelope producesactive,blockedOn: none, and no claim that the tool executed.StopFailuresettings, reducer, notifier, and.errorfixtures remain green as positive controls.PermissionDeniedorStop.PermissionRequest,PostToolUseFailure,PermissionDenied,PreToolUse,PostToolUse,Stop, andStopFailurewithout mutating the operator credential store.Posted on behalf of @schickling
agent_identitysessionagent_personaagent_supervisoragent_toolagent_tool_versionagent_runtimetooling_profile