fix: normalize permission option kind and recognize all allow optionIds#5
Conversation
Two symmetric bugs in the permission adapter broke every popup: - Request: zcode emits kind="deny" which the ACP schema rejects, so the popup never rendered (instant decline). Now normalized to the 4 kinds. - Response: only optionId "allow"/"allow_always" were treated as allow, but the backend uses "allow_once"/"allow_project" — selecting "Allow once" was reported back as a rejection. Now all allow-class optionIds are recognized; unknown ones fail-safe to deny.
There was a problem hiding this comment.
Code Review
This pull request implements normalization for zcode permission-option kinds to map them to the four canonical ACP-legal values, preventing schema deserialization failures. It also updates the response mapper to correctly recognize all allow-class option IDs (such as 'allow_once' and 'allow_project') as approvals, and adds corresponding unit tests to verify these behaviors. I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
Summary
Two symmetric bugs in the permission adapter (
src/interaction/adapter.ts) broke every permission popup — the request failed at Zed's schema deserialization, and even when that was fixed, selecting an allow option was reported back as a rejection.Bug 1 — Request:
kind: "deny"rejected by ACP schema (popup never rendered)zcode backend emits
kind: "deny"(and legacyallow/reject) in permission options. The ACP schema only accepts four canonical kinds (allow_once|allow_always|reject_once|reject_always), so Zed rejected the entirerequestPermissionat deserialization:The popup never rendered and the request defaulted to decline — the user saw "instant failure without clicking anything". The old code (
opt.kind as PermissionOption["kind"]) was an unchecked cast, so TypeScript never caught it.Fix: added
normalizeKind()mapping zcode's wider enum to the 4 ACP-legal values (allow/allow_project→allow_always;reject/deny→reject_once; unknown →reject_oncefail-safe).optionIdis free text and stays untouched.Bug 2 — Response: only
allow/allow_alwaysoptionIds recognized as allowAfter Bug 1 was fixed the popup rendered, but selecting "Allow once" was reported back as
rejected (allow_once).acpPermissionResponseToZcodeonly recognizedoptionId === "allow" || "allow_always"as allow, but the backend's allow-class options carryoptionId"allow_once"/"allow_project".Fix: added an
ALLOW_OPTION_IDSset coveringallow/allow_once/allow_always/allow_project; any optionId not in the set fail-safes to deny.Evidence (from `Zed.log`)
Verification
Files