-
Notifications
You must be signed in to change notification settings - Fork 0
Implement approval timeout policies with pluggable TimeoutPolicy protocol (DESIGN_SPEC §12.4) #126
Description
Context
Implement the approval timeout policy system defined in DESIGN_SPEC §12.4. When an action requires human approval (per autonomy level in §12.2), the agent must wait. The framework provides configurable timeout policies that determine what happens when a human doesn't respond.
All policies implement a TimeoutPolicy protocol. The policy is configurable per autonomy level and per action risk tier.
Task park/resume: During any wait, the agent parks the blocked task (saving its full serialized AgentContext state) and picks up other available tasks. When approval arrives, the agent resumes the original context exactly where it left off.
Policies (§12.4)
Policy 1: Wait Forever (Default for Critical Actions)
Action stays in human queue indefinitely. Agent works on other tasks while waiting.
Policy 2: Deny on Timeout
All unapproved actions auto-deny after configurable timeout. Agent receives denial reason and can retry with a different approach.
Policy 3: Tiered Timeout
Different timeout behavior based on action risk level:
- Low-risk (file edits, tests): auto-approve after short wait
- Medium-risk (git push, architecture): auto-deny after longer wait
- High-risk (deployment, database admin): wait forever
Policy 4: Escalation Chain
On timeout, approval request escalates to next human in configured chain (direct manager → department head → CEO). If entire chain times out, action denied.
Acceptance Criteria
Protocol Interface
-
TimeoutPolicyprotocol defined with standard operations (check_timeout, apply_policy, get_risk_tier) - Policy selection configurable via YAML (
approval_timeout.policy: "wait" | "deny" | "tiered" | "escalation") - Policy configurable per autonomy level and per action risk tier
- New policies addable without modifying existing ones
Implementations
- Wait policy — indefinite queue, no timeout
- Deny policy — configurable timeout, auto-deny with reason
- Tiered policy — risk-based timeout/action matrix (approve/deny/wait per tier)
- Escalation policy — configurable escalation chain, chain-exhausted fallback
Task Park/Resume Mechanism
-
AgentContextserialization for task parking (full state: conversation, progress, cost, turn count) - Distinct from
AgentContextSnapshot(compact telemetry model) - Task resume from serialized context on approval arrival
- Agent picks up other tasks while original is parked
- Parked task tracking (queue of parked tasks per agent)
Common Requirements
- Integration with human approval queue (Implement human approval queue API (Litestar controller + guards) #37)
- Integration with autonomy levels (Implement autonomy levels and configurable approval workflows (DESIGN_SPEC §12.2) #42) — policy applies based on autonomy config
- Timeout tracking and notification system
- Audit trail for all timeout decisions (approved, denied, escalated)
- Unit tests for each policy (>80% coverage)
Dependencies
- Human approval queue (Implement human approval queue API (Litestar controller + guards) #37) — approval routing
- Autonomy levels (Implement autonomy levels and configurable approval workflows (DESIGN_SPEC §12.2) #42) — determines which policy applies
- Agent engine (Implement agent engine core with ExecutionLoop protocol integration (DESIGN_SPEC §3.1, §6.1, §6.5) #11) — for context serialization/resumption
Design Spec Reference
- §12.4 — Approval Timeout Policy (4 policies behind TimeoutPolicy protocol, task park/resume)
- §12.2 — Autonomy levels (determines when approval is needed)
Design Decisions Finalized
- D1 — Action Types:
category:actionhierarchy used by risk tier classification for timeout policies. - D19 — Risk Tier Classification: Pluggable
RiskTierClassifierprotocol. Initial: configurable YAML mapping (RiskTierMappingwithdict[str, ApprovalRiskLevel]). Sensible defaults. Unknown action types → HIGH (fail-safe). - D20 — Context Serialization: Pydantic JSON via persistence backend.
ParkedContextmodel with metadata columns (execution_id, agent_id, task_id, parked_at) +context_jsonblob.ParkedContextRepositoryprotocol. Conversation stored verbatim. - D21 — Resume Injection: Tool result injection. Approval request modeled as tool call; approval decision returned as
ToolResult. Fallback: system message for engine-initiated parking.
Common pattern: All strategies use pluggable protocol interfaces with one initial implementation. Alternative strategies are documented in DESIGN_SPEC.md for future.