Parent: #1936
Problem
In decidePendingAgentAction (src/services/agent-approval-queue.ts), the accept path unconditionally calls await setPendingAgentActionStatus(env, pending.id, { status: "accepted", decidedBy: input.decidedBy }); regardless of what executeAgentMaintenanceActions actually returned. When the executor's outcome is "error" or "denied" (e.g. performAction threw, or a live pre-condition failed), the row's persisted status still reads "accepted" — the only place the failure is distinguishable is the ephemeral executionOutcome field on the function's return value and the agent.pending_action.accepted audit event's metadata.
This means the approval-queue listing endpoint and any operator dashboard keying off agentPendingActions.status shows the row simply leaving the pending list as "accepted", indistinguishable at a glance from a real success — a maintainer has to proactively query audit-feed metadata to discover a queued action actually failed to execute.
Found via an adversarial multi-agent verification pass while implementing #2377 (the approve head-pin fix): the review flagged that any new fail-closed behavior added to performAction would be operationally invisible unless this status handling is fixed, since a thrown error is currently indistinguishable from success at the persisted-row level.
Requirements
- A pending row's persisted
status must reflect whether the underlying mutation actually succeeded, not just that a decision was made.
Deliverables
- When
executeAgentMaintenanceActions's outcome for the accepted action is "error" or "denied", persist a status other than "accepted" (e.g. "rejected", or a new distinct status if the schema/API contract needs one) so the queue listing surfaces the failure without requiring an audit-feed query.
- Regression test: staging + accepting an action whose
performAction throws results in a persisted status that is NOT "accepted".
Acceptance criteria
- A maintainer viewing the approval-queue listing can distinguish a genuinely-executed accept from one whose underlying mutation failed, without cross-referencing the audit trail.
Expected outcome
The approval-queue's persisted status becomes a reliable signal of actual outcome, not just decision-was-made.
Parent: #1936
Problem
In
decidePendingAgentAction(src/services/agent-approval-queue.ts), the accept path unconditionally callsawait setPendingAgentActionStatus(env, pending.id, { status: "accepted", decidedBy: input.decidedBy });regardless of whatexecuteAgentMaintenanceActionsactually returned. When the executor's outcome is"error"or"denied"(e.g.performActionthrew, or a live pre-condition failed), the row's persisted status still reads"accepted"— the only place the failure is distinguishable is the ephemeralexecutionOutcomefield on the function's return value and theagent.pending_action.acceptedaudit event's metadata.This means the approval-queue listing endpoint and any operator dashboard keying off
agentPendingActions.statusshows the row simply leaving the pending list as "accepted", indistinguishable at a glance from a real success — a maintainer has to proactively query audit-feed metadata to discover a queued action actually failed to execute.Found via an adversarial multi-agent verification pass while implementing #2377 (the approve head-pin fix): the review flagged that any new fail-closed behavior added to
performActionwould be operationally invisible unless this status handling is fixed, since a thrown error is currently indistinguishable from success at the persisted-row level.Requirements
statusmust reflect whether the underlying mutation actually succeeded, not just that a decision was made.Deliverables
executeAgentMaintenanceActions's outcome for the accepted action is"error"or"denied", persist a status other than"accepted"(e.g."rejected", or a new distinct status if the schema/API contract needs one) so the queue listing surfaces the failure without requiring an audit-feed query.performActionthrows results in a persisted status that is NOT"accepted".Acceptance criteria
Expected outcome
The approval-queue's persisted status becomes a reliable signal of actual outcome, not just decision-was-made.