Skip to content

fix: normalize permission option kind and recognize all allow optionIds#5

Merged
william0wang merged 1 commit into
mainfrom
fix/permission-kind-normalization
Jul 5, 2026
Merged

fix: normalize permission option kind and recognize all allow optionIds#5
william0wang merged 1 commit into
mainfrom
fix/permission-kind-normalization

Conversation

@william0wang

Copy link
Copy Markdown
Owner

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 legacy allow/reject) in permission options. The ACP schema only accepts four canonical kinds (allow_once | allow_always | reject_once | reject_always), so Zed rejected the entire requestPermission at deserialization:

unknown variant `deny`, expected one of `allow_once`, `allow_always`, `reject_once`, `reject_always`

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_projectallow_always; reject/denyreject_once; unknown → reject_once fail-safe). optionId is free text and stays untouched.

Bug 2 — Response: only allow/allow_always optionIds recognized as allow

After Bug 1 was fixed the popup rendered, but selecting "Allow once" was reported back as rejected (allow_once). acpPermissionResponseToZcode only recognized optionId === "allow" || "allow_always" as allow, but the backend's allow-class options carry optionId "allow_once" / "allow_project".

Fix: added an ALLOW_OPTION_IDS set covering allow/allow_once/allow_always/allow_project; any optionId not in the set fail-safes to deny.

Evidence (from `Zed.log`)

  • Before: `unknown variant `deny`` → request failed at deserialization, no popup
  • After Bug 1 fix: popup rendered with 3 options ✓, but selecting "Allow once" → `rejected (allow_once)`
  • After Bug 2 fix: selecting "Allow once" → file write executed ✓

Verification

  • TDD: wrote failing regression tests first, watched them red, then fixed
  • `pnpm test` — 90/90 passing (4 new regression tests: 2 for request normalization, 2 for response recognition)
  • `pnpm build` — clean
  • `prettier` applied to the 2 changed files
  • Manually verified end-to-end: permission popup renders, Allow-once selection correctly authorizes the tool call

Files

  • `src/interaction/adapter.ts` — `normalizeKind()` + `ALLOW_OPTION_IDS` (the two fixes are symmetric: request direction + response direction)
  • `tests/interaction.test.ts` — 4 regression tests using the real backend payload observed in `Zed.log`

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.
@william0wang william0wang merged commit 5f178a6 into main Jul 5, 2026
1 check passed
@william0wang william0wang deleted the fix/permission-kind-normalization branch July 5, 2026 13:07

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant