Task 10 — Гейты подтверждения
Phase: 1
Status: done
Owner: —
Slug: approval-gates
Goal
Read-only операции идут автоматически; write/delete/network/shell/financial/hardware требуют policy-based подтверждения с показом proposed action оператору.
Acceptance criteria
Sub-tasks
ApprovalRequestrecord вStorage/Models.cs— Id, SessionId, ToolName, ArgumentsJson, PolicyDecision, Reason, RequestedAt, RequestedBy, Status (Pending/Approved/Denied/Expired), ApprovedAt, DeniedAtIApprovalService/ApprovalServiceвTools/Approval/— RequestAsync, Approve, Deny, GetPending, GetBySession, ExpireOld (configurable TTL, default 30 min)ApprovalService— in-memory ConcurrentDictionary + SQLite persistence (tableapproval_requests)SqliteSessionStore— Add tablesapproval_requests+ methods SaveApprovalRequestAsync, GetPendingApprovalsAsync, UpdateApprovalStatusAsync, ExpireOldApprovalsAsyncToolPolicyEngine— integrateIApprovalService: при RequiresApproval → вызывает_approvalService.RequestAsync(...)и возвращает NeedsApproval с request IDAgentCore.RunWithToolsAsync— перед tool execution: проверяетIApprovalService.IsApproved(toolName, sessionId); если approved — выполняет; если pending — возвращает “waiting for approval” сообщениеApprovalController.cs— WebAPI endpoints: GET /api/approvals/pending, GET /api/approvals/{id}, POST /api/approvals/{id}/approve, POST /api/approvals/{id}/deny-
[x] ConsoleUI— интерактивный поток: команда /approvals listapprove {id} deny {id} Program.cs(CLI + WebAPI) — зарегистрироватьIApprovalServiceв DIAppConfig— добавитьApprovalConfig(Enabled, DefaultTtlMinutes=30, MaxPending=50)- Unit-тесты:
ApprovalServiceTests.cs— 14 тестов: request, approve, deny, get pending, TTL expiry, session filtering, idempotency dotnet buildпроходит без warningsdotnet testпроходит (406/406)
Scope / Likely files
src/agent/Tools/Approval/, src/agent/Hercules.WebApi/Controllers/ApprovalController.cs
Dependencies
- блокирует / опирается на: task_009 — tool-boundary-policy
Risks / Rollback
UX-фрикция в CLI/Web при частых подтверждениях; батчинг и доверенные scopes.
Implementation notes
2026-08-12
Добавлено:
Storage/Models.cs — ApprovalRequest record:
- Id, SessionId, ToolName, ArgumentsJson, PolicyDecision, Reason, RequestedAt, RequestedBy, Status, ApprovedAt, DeniedAt
Config/AppConfig.cs — ApprovalConfig + AppConfig.Approval:
- Enabled (default true), DefaultTtlMinutes=30, MaxPending=50
Storage/SqliteSessionStore.cs — новая таблица + методы:
approval_requeststable (id TEXT PK, session_id, tool_name, arguments_json, policy_decision, reason, requested_at, requested_by, status, approved_at, denied_at)SaveApprovalRequestAsync,GetPendingApprovalsAsync,GetApprovalRequestsAsync,UpdateApprovalStatusAsync,ExpireOldApprovalsAsync- Indexes: ix_approval_session, ix_approval_status
Tools/Approval/ApprovalService.cs — IApprovalService + ApprovalService:
- In-memory
ConcurrentDictionary<string, ApprovalResult>(O(1) lookup для IsApproved) - Session-level index:
ConcurrentDictionary<string, ConcurrentDictionary<string, bool>> - Auto-approve when
ApprovalConfig.Enabled = false ApproveAsync/DenyAsync— idempotent, returns false if already processedIsApproved(toolName, sessionId)— O(1) check для hot path в AgentCoreExpireOldApprovalsAsync— fire-and-forget TTL cleanup
Tools/Policy/ToolPolicyEngine.cs — интеграция:
- Конструктор принимает
IApprovalService?(nullable, backward-compatible) - При RequiresApproval: вызывает
_approvalService.RequestAsync(...)и возвращает NeedsApproval с request ID - При Critical tools: также регистрирует approval request
Agent/AgentCore.cs — интеграция:
- Конструктор принимает
IApprovalService?(nullable, backward-compatible) - В
RunWithToolsAsync: послеpolicyResult.RequiresApprovalпроверяет_approvals?.IsApproved(toolName, SessionId)— если approved, выполняет tool; иначе возвращает waiting message
Hercules.WebApi/Controllers/ApprovalController.cs — 5 endpoints:
GET /api/approvals/pending— pending approvals (опционально: ?sessionId=xxx)GET /api/approvals/{id}— конкретный запросPOST /api/approvals/{id}/approve— одобритьPOST /api/approvals/{id}/deny— отклонитьGET /api/approvals— все (last 100)
CLI/ConsoleUI.cs — /approvals command:
/approvals list— таблица pending-запросов/approvals approve {id}— одобрить/approvals deny {id}— отклонить
Program.cs (CLI + WebAPI) — DI:
ApprovalConfigsingletonIApprovalService→ApprovalServiceToolPolicyEngineполучаетIApprovalServiceв конструктор
Tests — tests/.../Tools/ApprovalServiceTests.cs — 14 тестов:
- request, approve, deny, get pending, TTL expiry, session filtering, idempotency, disabled mode
Validation:
dotnet buildHercules.csproj — 0 errors, 0 warningsdotnet buildHercules.WebApi.csproj — 0 errors, 0 warningsdotnet test— 406/406 passed
Links
- Backlog: ../backlog.md
- Roadmap (EN): ../../ROADMAP-EN.md
- Roadmap (RU): ../../ROADMAP-RU.md