Pre-Approve System
Reduces operator approval bottleneck in autonomous modes by auto-approving predictable operations via glob-based pattern matching.
Phases
Section titled “Phases”| Phase | Scope | Status |
|---|---|---|
| Phase 1 | Core pattern matching + isDangerous integration + --pre-approve CLI flag | Done |
| Phase 2 | Haiku planning pass + tabbed approval UI | Done |
| Phase 3 | Audit trail (SQLite) + DAG integration | Done |
Phase 1 — Core Pattern Matching (Done)
Section titled “Phase 1 — Core Pattern Matching (Done)”interface PreApprovalPattern { tool: string; // 'bash', 'write_file', 'read_file', etc. pattern: string; // Glob: "npm run *", "dist/**" label: string; // Human-readable description risk: 'low' | 'medium' | 'high';}
interface PreApprovalSet { id: string; approvedAt: string; approvedBy: 'operator'; taskSummary: string; patterns: PreApprovalPattern[]; maxUses: number; // 0 = unlimited ttlMs: number; // 0 = session-scoped usageCounts: number[]; // Per-pattern counter}Modules
Section titled “Modules”src/core/pre-approve.ts—globToRegex(),extractMatchString(),matchesPreApproval(),buildApprovalSet()src/tools/permission-guard.ts—isDangerous()4th parampreApproval?, inline matching (avoids circular dep)src/core/agent.ts—preApprovalfield, passed toisDangerous()src/index.ts—--pre-approve <glob>(repeatable)
Security
Section titled “Security”- Critical patterns (CRITICAL_BASH) silently filtered by
buildApprovalSet() - Session-scoped by default (ttlMs=0)
- maxUses=10 default
- Glob-only, no backtracking
autoApprovePatternsNOT inPROJECT_SAFE_KEYS
nodyn --pre-approve "npm run *" \ --pre-approve "rm dist/**"Phase 2 — Haiku Planning Pass + Approval UI (Done)
Section titled “Phase 2 — Haiku Planning Pass + Approval UI (Done)”Overview
Section titled “Overview”Before executing a task in autonomous modes, a fast Haiku planning pass analyzes the goal and proposes pre-approval patterns. The operator reviews them in a tabbed dialog before execution begins.
User: --approve "bash:npm run *" --approve "write_file:dist/**" │ ▼ ┌─── CLI Patterns ────────────┐ │ Build PreApprovalSet from │ │ --approve patterns │ └───────────┬─────────────────┘ ▼ Agent runs with approved setSupporting Files
Section titled “Supporting Files”src/cli/approval-dialog.ts
Section titled “src/cli/approval-dialog.ts”interface ApprovalDialogResult { approved: boolean; patterns: PreApprovalPattern[]; // operator-selected subset maxUses: number; ttlMs: number;}
async function showApprovalDialog( proposed: PlanningResult, goal: string, promptTabs: (questions: TabQuestion[]) => Promise<string[]>,): Promise<ApprovalDialogResult>- Tab 1: Goal + Haiku reasoning (read-only)
- Tab 2: Pattern checkboxes with risk badges (low/medium default checked, high unchecked)
- Tab 3: Limits — maxUses (5/10/25/unlimited), TTL (session/30min/1h/4h)
Modified Files
Section titled “Modified Files”src/index.ts—--auto-approve-allauto-approves low + medium risk patternssrc/core/session.ts— PassapiKey/apiBaseURLto mode controller for plannersrc/index.ts—--no-pre-approve(skip planning),--auto-approve-all(approve low+medium without dialog)
Security
Section titled “Security”- Haiku receives only goal text + tool names (no secrets)
- All proposed patterns filtered through
isCriticalTool()(inpermission-guard.ts) - Operator has final approval via dialog
--auto-approve-allonly auto-approves low + medium risk- Planning failure is never fatal
Phase 3 — Audit Trail + DAG Integration (Done)
Section titled “Phase 3 — Audit Trail + DAG Integration (Done)”Overview
Section titled “Overview”All pre-approval decisions and usage are persisted to SQLite for compliance tracking. The DAG engine supports per-step pre-approval patterns.
Implementation
Section titled “Implementation”— (deleted) Audit trail functionality consolidated intosrc/core/pre-approve-audit.tspermission-guard.ts- SQLite tables (migration v4):
pre_approval_sets— set metadata (id, run_id, patterns JSON, approved_by, task_summary, etc.)pre_approval_events— individual check decisions (set_id, tool, pattern, decision, timestamp)
src/tools/permission-guard.ts— 5thauditparam onisDangerous(): records approval/exhausted/expired decisions viaPreApproveAuditLikesrc/core/agent.ts—auditfield in AgentConfig, passed toisDangerous()- DAG per-step pre-approval — manifest steps can declare
pre_approvepatterns, built into per-stepPreApprovalSet /approvalsslash command — list sets, show details, audit history, export- Observability channels:
nodyn:preapproval:match,nodyn:preapproval:exhausted,nodyn:preapproval:expired - RunHistory —
insertPreApprovalSet(),insertPreApprovalEvent(),getPreApprovalSets(),getPreApprovalEvents(),getPreApprovalSummary()
— (deleted) Tests consolidated intopre-approve-audit.test.tspermission-guard.test.ts