| 1 | package event |
| 2 | |
| 3 | import "encoding/json" |
| 4 | |
| 5 | // Approval identifies a pending tool-call approval for an ApprovalRequest |
| 6 | // event. ID correlates the request with the controller's Approve(ID, …) reply. |
| 7 | type Approval struct { |
| 8 | ID string |
| 9 | Tool string |
| 10 | Subject string |
| 11 | Reason string // optional annotation explaining why approval is needed |
| 12 | // RawInput is the exact structured tool input. ACP permission clients use it |
| 13 | // together with locations/reason instead of parsing a human title. |
| 14 | RawInput json.RawMessage |
| 15 | Fresh bool // current human decision required; do not offer remembered grants |
| 16 | // Kind classifies the approval surface: "tool" (default), "plan", "recovery", |
| 17 | // or "write_access". Empty means ordinary permission for backward compat. |
| 18 | Kind string |
| 19 | Recovery *RecoveryApproval |
| 20 | WriteAccess *WriteAccessApproval |
| 21 | TurnID string |
| 22 | // Generation and PermissionRevision bind a decision to the exact runtime |
| 23 | // permission snapshot that emitted it. New clients echo both values when |
| 24 | // resolving; older clients remain fenced by turn/runtime identity. |
| 25 | Generation uint64 |
| 26 | PermissionRevision uint64 |
| 27 | } |
| 28 | |
| 29 | // ApprovalKindWriteAccess is the Approval.Kind value for directory expansion. |
| 30 | const ApprovalKindWriteAccess = "write_access" |
| 31 | |
| 32 | // WriteAccessApproval is the backward-compatible structured payload for |
| 33 | // extending writable roots. Slices are never nil on the wire. |
| 34 | type WriteAccessApproval struct { |
| 35 | Directories []string `json:"directories"` |
| 36 | DisplayDirectories []string `json:"display_directories"` |
| 37 | Justification string `json:"justification,omitempty"` |
| 38 | BroadHomeAccess bool `json:"broad_home_access,omitempty"` |
| 39 | OrdinaryPermissionNeeded bool `json:"ordinary_permission_needed,omitempty"` |
| 40 | PersistAllowed bool `json:"persist_allowed,omitempty"` |
| 41 | } |
| 42 | |
| 43 | // NormalizeWriteAccessApproval makes list fields non-nil for desktop/JSON. |
| 44 | func NormalizeWriteAccessApproval(w *WriteAccessApproval) *WriteAccessApproval { |
| 45 | if w == nil { |
| 46 | return nil |
| 47 | } |
| 48 | if w.Directories == nil { |
| 49 | w.Directories = []string{} |
| 50 | } |
| 51 | if w.DisplayDirectories == nil { |
| 52 | w.DisplayDirectories = []string{} |
| 53 | } |
| 54 | return w |
| 55 | } |
| 56 | |
| 57 | // RecoveryApproval is the backward-compatible structured payload for Auto |
| 58 | // Guard decisions. Old clients can ignore this nested object safely. |
| 59 | type RecoveryApproval struct { |
| 60 | SourceAgent string // agent that proposed the next mutation |
| 61 | FailedTool string // tool that failed; empty for pre-action boundaries |
| 62 | FailedSummary string // short failure/error summary; optional |
| 63 | Diagnosis string // agent/host diagnosis when failure recovery is active |
| 64 | NextTool string // tool about to run |
| 65 | NextAction string // concrete next command/file change/MCP action |
| 66 | ChangeKind string // same_strategy | strategy | scope | risk | uncertain |
| 67 | ChangeRationale string // what changed vs the original approach |
| 68 | ReviewRationale string // why the host/reviewer needs confirmation |
| 69 | PlanBefore string // active structured plan before a material transition |
| 70 | PlanAfter string // proposed structured plan after a material transition |
| 71 | CanGrantTask bool // offer a semantic grant scoped to the current task |
| 72 | TaskGrantScope string // concise host-classified operation + exact target |
| 73 | } |
| 74 |