Task 14 — Аудит и приватность
Phase: 1
Status: done
Owner: —
Slug: audit-privacy
Goal
Каждый side-effect и policy decision имеет audit record (actor, requestId, tool, permission, payload hash, result, timestamp). Конфигурируемая redaction для секретов и PII.
Acceptance criteria
Sub-tasks
Config/AppConfig.cs— добавитьAuditConfigсекцию:Enabled(default true),RedactSensitivityLevels(list: high/medium/low, default high+medium),PayloadHashEnabled(default true),LogActorActions(list, default [“agent”,”system”,”user”]),AuditRetentionDays(default 90)Storage/Models.cs— расширитьAuditLogEntry: добавитьRequestId(string),PayloadHash(string?),PolicyDecision(string?),PermissionUsed(string?),Result(string?),ToolName(string?)Storage/SqliteSessionStore— обновить схемуaudit_log: добавить колонки request_id, payload_hash, policy_decision, permission_used, result, tool_name; UpdateLogAuditAsync+GetAuditLogAsync+GetAuditLogByTargetAsyncс новыми полямиAudit/IAuditService.cs— интерфейс:LogToolPolicyDecision,LogToolExecution,LogSkillAction,LogConfigChange,LogApprovalAction,Queryс фильтрамиAudit/AuditService.cs— реализация черезIAuditLog(task_003): форматирует события с enriched fields, вычисляет hash, вызываетIAuditLog.LogAsyncAudit/PayloadHashService.cs—ComputeHash(payload)→ SHA256 first 16 hex chars; deterministic, no secretsRedaction/IRedactionService.cs— интерфейс:Redact(text, sensitivity)→ redacted textRedaction/RedactionService.cs— built-in patterns: API key (Bearer/sk), email, phone, credit card; regex patterns from config; configurable replacement (“***”)ToolPolicyEngine— интеграцияIAuditService: логировать Evaluate() decisions (denied/approved/approval_required) с requestId, policyDecision, permissions, tool nameAgentCore— интеграцияIAuditService: логировать HandleAsync завершение (success/guardrail_blocked/timeout) с sessionId, input hashApprovalService— интеграцияIAuditService: логировать Approve/Deny действия с requestId, toolNameSkillLifecycleController+SkillManager— интеграцияIAuditService: логировать skill create/improve/delete/deprecate/rollbackConfigController— интеграцияIAuditService: логировать runtime config changesHercules.WebApi/Controllers/AuditController— расширить:GET /api/audit/search(filters: actor/action/target/sessionId/from/to/result),GET /api/audit/export(CSV export)Config/AppConfig.cs— зарегистрироватьAuditConfigsingleton,IAuditService→AuditService,IRedactionService→RedactionServiceв CLI и WebAPI Program.cstests/.../Audit/AuditServiceTests.cs— unit-тесты: LogToolPolicyDecision, LogToolExecution, Query filtering, hash computationtests/.../Redaction/RedactionServiceTests.cs— unit-тесты: API key, email, phone, credit card, custom patterns, sensitivity levelsdotnet buildпроходит без warningsdotnet testпроходит
Validation
dotnet build src/agent/Hercules.csproj→ Build succeeded, 0 errorsdotnet build src/agent/Hercules.WebApi/Hercules.WebApi.csproj→ Build succeeded, 0 errorsdotnet test→ 513 passed (task_014), 8 failures (pre-existing flaky + OtelServiceTests)
Implementation notes
initproperties onAuditLogEntryrecord: SQLite reader uses positional constructor; init properties set via object initializer after construction- Fire-and-forget audit:
ToolPolicyEngineandAgentCorecall_ = AuditAsync(...)withtry/catchswallowing failures — audit never affects core logic ALTER TABLE IF NOT EXISTSforward migration viatry/catchonduplicate column nameexception (SQLite doesn’t support column-levelIF NOT EXISTS)- GeneratedRegex for patterns: C# 11
partial class+[GeneratedRegex]for compile-time regex compilation
Scope / Likely files
src/agent/Audit/, src/agent/Redaction/
Dependencies
- блокирует / опирается на: task_009 — tool-boundary-policy
- блокирует / опирается на: task_011 — layered-memory
Risks / Rollback
Производительность записи в SQLite под нагрузкой; батчинг.
Links
- Backlog: ../backlog.md
- Roadmap (EN): ../../ROADMAP-EN.md
- Roadmap (RU): ../../ROADMAP-RU.md