feat(FN-3791): add agent provisioning approval guards and policy enforcemen

Implements approval guards for agent provisioning (FN-3791), adding policy-gated create/delete flows with dedupe logic, CLI tool alignment, engine run-audit coverage, and corresponding test suites, plus documentation updates and a regression fix for verification/tool docs sync.

Fusion-Task-Id: FN-3791
This commit is contained in:
Fusion
2026-05-10 22:44:50 -07:00
committed by gsxdsm
parent 9dc0e38245
commit 3ec12f10e7
10 changed files with 316 additions and 19 deletions

View File

@@ -107,9 +107,24 @@ Agent provisioning approvals (`agent_provisioning` category):
- `fn_agent_create` / `fn_agent_delete` can return `pending_approval` under `projectSettings.agentProvisioning` policy (`approvalMode`, trusted roles/IDs, `alwaysApproveDelete`).
- Approval request is persisted with provisioning context (`tool` + `params`) and visible in mailbox/API approval queues.
- Dashboard/API decision route `POST /api/approvals/:id/decision` executes deferred provisioning on `approve` via engine dispatcher (`executeApprovedAgentProvisioning`) and never executes on `deny`.
- Decision handling emits run-audit mutations: `agent:create:approved`, `agent:create:denied`, `agent:delete:approved`, `agent:delete:denied` using original request task/run/requester linkage.
- Decision handling emits run-audit mutations: `agent:create:{requested,approved,denied}` and `agent:delete:{requested,approved,denied}` using original request task/run/requester linkage.
- Malformed provisioning context or failed execution returns 500 from the decision route (no silent approval).
Resolver decision table (`resolveAgentProvisioningPolicy`):
| matchedRule | decision | Notes |
| --- | --- | --- |
| `missing-caller` | `deny` | Caller context missing. |
| `privileged-caller` | `allow` | Bypasses trust checks and `alwaysApproveDelete`. |
| `approval-mode-never` | `allow` | Global short-circuit, including deletes. |
| `delete-always-approve` | `require-approval` | Default delete behavior when not short-circuited. |
| `trusted-agent-id` | `allow` | Exact caller ID allowlist match. |
| `trusted-role` | `allow` | Case-insensitive role allowlist match. |
| `approval-mode-trusted-only` | `require-approval` | Untrusted fallback in default mode. |
| `approval-mode-always` | `require-approval` | Approval always required unless privileged/never mode. |
Out of scope in FN-3791: `spawn_agent` (ephemeral child worktree lifecycle). Follow-up task: "Evaluate approval guards for `spawn_agent` (ephemeral worktree children)".
Default and legacy fallback behavior:
- New **non-ephemeral/permanent** agents persist a normalized `permissionPolicy` using preset `unrestricted` when not explicitly provided.