Task 9 — Граница инструментов и policy engine
Phase: 1
Status: done
Owner: —
Slug: tool-boundary-policy
Goal
Локальные инструменты объявляют input/output схемы, side-effect level, required permission, timeout, retry, idempotency. ToolPolicy применяет allow/deny перед вызовом.
Acceptance criteria
Sub-tasks
ToolPolicy.cs—SideEffectLevelenum (None/Read/Local/External/Critical),ToolPermissionflags enum,ToolDescriptorrecord (Name, InputSchema, OutputSchema, SideEffectLevel, RequiredPermissions, TimeoutSeconds, MaxRetries, Idempotent),PolicyContextrecord,ToolPolicyResultrecord withAllowed/Denied/RequiresApproval/UnknownTooldecisionsToolPermissionSet.cs—Has/HasAll/Missingchecks,ToHumanReadable(),ParseFromString()extension methods,Default/ReadOnlystatic factoriesToolPolicyEngine.cs—Register(ToolDescriptor),Register(ITool),Evaluate(PolicyContext); deny-list (glob patterns), side-effect approval threshold, permission check, dry-run mode, unknown-tool policyITool— добавленIToolDescriptorProviderinterface сGetPolicyDescriptor();ToolRegistry.Registerвызывает_policy?.Register(tool)AgentCore.RunWithToolsAsync— вызывает_policy.Evaluate()передtool.ExecuteAsync(); denied/approval-required tools возвращают user-friendly сообщение без выполненияAppConfig— добавленаToolPolicyConfigсекция (DryRun, AllowUnknownTools, MinSideEffectLevelForApproval, DeniedTools, AgentPermissions, DefaultTimeoutSeconds)- DI registration в
Program.cs(CLI + WebAPI):ToolPermissionSet,ToolPolicyEngine,ToolPolicyConfig - Unit tests:
ToolPolicyEngineTests.cs— 18 тестов (registration, deny-list, unknown tools, dry-run, permissions, approval threshold) dotnet buildпроходит без warningsdotnet testпроходит (389/389)
Scope / Likely files
src/agent/Tools/, src/agent/Tools/Policy/
Dependencies
- блокирует / опирается на: task_001 — core-agent-loop
- блокирует / опирается на: task_007 — typed-contracts
Risks / Rollback
Сложные правила сложно отлаживать; нужен policy dry-run режим.
Implementation notes
2026-08-12
Добавлено:
Tools/Policy/ToolPolicy.cs — типы для tool policy engine:
SideEffectLevelenum: None(0), Read(1), Local(2), External(3), Critical(4)ToolPermission[Flags] enum: None, Read, Write, Delete, Network, Shell, Financial, Hardware, MemoryToolDescriptorrecord: Name, InputSchema, OutputSchema, SideEffectLevel, RequiredPermissions, TimeoutSeconds, MaxRetries, IdempotentPolicyContext: ToolName, ArgumentsJson, SessionId, ApprovedToolsThisSessionPolicyDecisionenum: Allowed, Denied, RequiresApproval, UnknownToolToolPolicyResult: IsAllowed, IsDenied, RequiresApproval, DryRun, static factories
Tools/Policy/ToolPermissionSet.cs — permission management:
ToolPermissionSet: granted permissions set,Has/HasAll/MissingchecksToolPermissionExtensions:ToHumanReadable(),ParseFromString("Read|Write|Network")
Tools/Policy/ToolPolicyEngine.cs — policy evaluation:
Register(ToolDescriptor)— direct descriptor registrationRegister(ITool)— usesIToolDescriptorProvider.GetPolicyDescriptor()if available, otherwise infers from tool nameEvaluate(PolicyContext)— deny-list → unknown-tool → side-effect threshold → permission check → critical checkIToolDescriptorProvider— interface for tools that want to declare their own descriptorDryRunmode: only logs, never blocksIConfigReloadimplementation for runtime config updates
Config/AppConfig.cs — ToolPolicyConfig section:
- DryRun, AllowUnknownTools, MinSideEffectLevelForApproval, DeniedTools, AgentPermissions, DefaultTimeoutSeconds
Tools/ITool.cs — added IToolDescriptorProvider interface
Tools/ToolRegistry.cs — _policy?.Register(tool) after each tool registration
Agent/AgentCore.cs — policy check in RunWithToolsAsync:
- Before
tool.ExecuteAsync(): evaluatesPolicyContext - Denied → returns user-friendly message, continues to next iteration
- RequiresApproval → returns message prompting user to confirm
Program.cs (CLI + WebAPI) — DI:
ToolPolicyConfigsingletonToolPermissionSet(from AgentPermissions string)ToolPolicyEnginesingletonToolRegistryreceives policy engine in constructor
Tests — ToolPolicyEngineTests.cs: 18 tests covering all policy scenarios
Validation:
dotnet buildHercules.csproj — 0 errors, 0 warningsdotnet buildHercules.WebApi.csproj — 0 errors, 0 warningsdotnet test— 389/389 passed
Links
- Backlog: ../backlog.md
- Roadmap (EN): ../../ROADMAP-EN.md
- Roadmap (RU): ../../ROADMAP-RU.md