Skip to content

fix: scope one-time edit approvals to a single edit - #50

Open
ChanTso wants to merge 1 commit into
LiuMengxuan04:mainfrom
ChanTso:fix/permission-once
Open

ChanTso wants to merge 1 commit into
LiuMengxuan04:mainfrom
ChanTso:fix/permission-once

Conversation

@ChanTso

@ChanTso ChanTso commented Sep 3, 2026

Copy link
Copy Markdown

Problem

The edit approval menu distinguishes one-time, turn-scoped, and persistent
choices, but allow_once and deny_once were recorded in session-scoped
caches.

A one-time decision therefore applied to every later edit of the same file for
the rest of the session, even when the proposed diff had changed: apply once
kept approving them with no prompt, and reject once kept rejecting them with
no prompt and no way to re-approve. This also made apply once broader than
allow this file in this turn.

The session-scoped edit caches predate the turn-scoped choices. Once
allow this file in this turn and allow all edits in this turn existed, the
one-time branches were still writing to those caches, so the one-time entries
never behaved as one-time.

Reproduction

  1. Run npm run dev.
  2. Ask the model to propose two different edits to the same file.
  3. Choose 1 (apply once) for the first edit.

Before: the second edit is applied without another prompt or diff review.

After: the second edit prompts again and displays its own diff.

Repeat with 5 (reject once), which is also what Escape maps to:

Before: later edits to the same file fail with Edit denied without
another prompt.

After: the next edit prompts again and can be approved.

Changes

  • keep allow_once local to the current ensureEdit() request
  • keep deny_once local to the current ensureEdit() request
  • remove the now-unused sessionAllowedEdits cache

Turn-scoped and persistent edit choices are unchanged. sessionDeniedEdits is
retained because reject-with-guidance still uses it.

Path and command approvals keep their session-scoped allow once: those menus
have no turn-scoped option, so the session cache is still the only way to stop
being asked there. The edit menu already offers 2-4 for that, which is why
only edits change here.

Choosing apply once repeatedly now prompts once per edit. Options 2-4
remain available for approving the file for the turn, all edits for the turn,
or the file permanently. Adding an explicit session-scoped choice to the edit
menu would be a product decision rather than a fix, so it is left out of this
PR.

The production change is a five-line deletion in src/permissions.ts. It
introduces no new abstraction, dependency, persistence-format change, or TUI
change. This preserves MiniCode's explicit Claude Code-style approval
hierarchy: broader permissions remain separate choices instead of being
inferred from a one-time response.

No user-facing documentation described the previous session-scoped behavior,
so no documentation change is included.

Regression tests

Added test/permissions.test.ts covering:

  • a revised diff prompts again after allow_once
  • a revised diff prompts again after deny_once and can then be approved
  • allow_turn still covers repeated edits to the same file only within the
    current turn

The first two tests fail on the previous implementation. The allow_turn
test is a regression guard and passes before and after the fix.

Verification

node --import tsx --test test/permissions.test.ts   # 3 passed
npm run check
npm test                                            # 231 passed
npm run lint

@LiuMengxuan04

Copy link
Copy Markdown
Owner

感谢你的PR,我们正在进行版本升级,请等我们近期升级完成之后集中处理PR请求

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.

2 participants