Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions internal/acp/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,22 @@ func NewACPApprovalFunc(transport *Transport) policy.ApprovalFunc {
Status: ToolCallStatusPending,
},
Options: []PermissionOption{
{OptionID: "once", Kind: "allow_once", Name: "Allow once"},
{OptionID: "always", Kind: "allow_always", Name: "Always allow"},
{OptionID: "reject", Kind: "reject_once", Name: "Reject"},
{OptionID: "once", Kind: KindAllowOnce, Name: "Allow once"},
{OptionID: "always", Kind: KindAllowAlways, Name: "Always allow"},
{OptionID: "reject", Kind: KindRejectOnce, Name: "Reject"},
},
}

// Refuse to send an unserializable request: the ACP client's strict
// serde enum rejects unknown PermissionOptionKind values at
// deserialization, which surfaces as a silent approval denial. Deny
// loudly here instead, so a newly added invalid kind can never reach
// the wire.
if bad, ok := invalidPermissionOptionKind(permReq.Options); ok {
Logger.Printf("refusing to send request_permission: invalid option kind %q — denying", bad)
return policy.ApprovalDeny
}

resp, err := transport.CallClientMethod(req.SessionID, MethodSessionRequestPerm, permReq)
if err != nil {
Logger.Printf("request_permission failed: %v — denying", err)
Expand Down Expand Up @@ -418,3 +428,16 @@ func NewACPApprovalFunc(transport *Transport) policy.ApprovalFunc {
}
}
}

// invalidPermissionOptionKind returns the first option whose kind is not one
// of the four schema-defined PermissionOptionKind values, and whether any such
// option exists. Kept as a standalone helper so the send-path guard in
// NewACPApprovalFunc is directly testable.
func invalidPermissionOptionKind(opts []PermissionOption) (PermissionOptionKind, bool) {
for _, opt := range opts {
if !opt.Kind.Valid() {
return opt.Kind, true
}
}
return "", false
}
Loading
Loading