Skip to content

fix(server): Grok's "Always allow this session" no longer saves a project-wide grant - #13796

Merged
juliusmarminge merged 1 commit into
t3code/codex-turn-mappingfrom
t3code/grok-session-allow-not-persistent
Sep 26, 2026
Merged

juliusmarminge merged 1 commit into
t3code/codex-turn-mappingfrom
t3code/grok-session-allow-not-persistent

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Sep 26, 2026 •

Copy link
Copy Markdown
Member

Choosing Always allow this session on a Grok command approval gives Grok a permanent, project-wide allow for that command. A brand-new Supervised Grok thread in the same project then runs it without asking.

Reproduced live with Grok 1.0.41 (grok-4.7-build-fast) in a disposable repo:

  1. Supervised thread A: "run rm marker1.txt". The approval card appears, and I pick Always allow this session.
  2. Grok writes ~/.grok/sessions/<repo>/permission_grok-code-extension.toml containing allowed_bash_commands = ["rm marker1.txt"].
  3. New Supervised thread B in the same repo (a separate grok --permission-mode default agent stdio process): "run rm marker1.txt". It runs with no prompt, and the DB has 0 runtime requests for thread B.

Why

The ACP adapter maps acceptForSession to whichever option has kind allow_always. With T3's clientType: "extension" (#13732), Grok's bash and monitor prompts offer always-allow ("Yes, and don't ask again for bash commands"). Grok records that as a persistent grant for the project (crates/codegen/xai-grok-workspace/src/permission/grants.rs record_prompt_outcome, persisted by manager/mod.rs persist_state, at f0e3be1), not for the session. The only session-scoped allow_always Grok sends is allow-edits-session on edit prompts (prompter.rs ALLOW_EDITS_SESSION_OPTION_ID, "Session-only and never persisted"). The recorded fixtures show exactly these option sets:

prompt Grok options
bash (grok_auto_blocked_command) always-allow, allow-once, reject-once, reject-always
monitor (grok_monitor) same as bash
edit (tool_call_read_only_on_request) allow-edits-session, allow-once, reject-once
subagent (grok_background_subagent) allow-once, reject-once

What changed

The Grok flavor now sets approvalOptions (the hook Antigravity already uses), so clients render only choices the request can honor. Edit prompts offer Allow all edits this session, because Grok scopes it to the session. Bash, monitor, MCP and subagent prompts offer Approve, Decline and Cancel. Web and mobile already render options when present. This is Grok-only; the generic ACP adapter is unchanged. The user docs sentence that promised a remembered command is updated.

Out of scope, noted for follow-up: when T3's own policy auto-approves a Grok prompt (Full access with an explicit override), selectAutoApprovedPermissionOption in the generic ACP adapter still prefers allow_always. The grok_monitor fixture shows T3 answering always-allow there.

Cleanup note

My live repro left a real grant file for the disposable repo: ~/.grok/sessions/%2Fhome%2F<user>%2Ftmp%2Fbughunt-grok%2Frepo3/permission_grok-code-extension.toml (plus an earlier one for .../repo1/). I did not delete anything outside the scratch directory.

Verification

  • Replay fixtures (recorded transcripts, current clientType: "extension" initialize _meta):
    • grok_auto_blocked_command now asserts that the bash approval card offers cancel, decline, accept, and still that Approve answers Grok's allow-once.
    • tool_call_read_only_on_request/grok now asserts that the edit card offers cancel, decline, acceptForSession, accept.
    • Without the fix, both fail (expected undefined to deeply equal [...]). With the fix, both pass.
  • vp test run src/orchestration-v2/testkit/OrchestratorReplayFixtures.integration.test.ts -t grok: 13 passed.
  • vp test run src/provider/acp/GrokAcpSupport.test.ts src/orchestration-v2/Adapters/GrokAdapterV2.test.ts src/orchestration-v2/Adapters/AcpAdapterV2.test.ts src/orchestration-v2/testkit/OrchestratorReplayFixtures.contract.test.ts: 152 passed.
  • vp exec tsc --noEmit -p . in apps/server: no errors. knip --workspace apps/server --exports: clean. vp lint on touched files: only pre-existing warnings on untouched lines.
  • Not run: repo-wide checks, or a live click-through of the new card labels.

Model: Claude Opus 5.5 (Claude Code)

🤖 Generated with Claude Code


Devin Review

…ject-wide grant

The approval card offered "Always allow this session" on every Grok prompt
and answered it with Grok's `allow_always` option. On bash, monitor and MCP
prompts that option is Grok's persistent always-allow, which it writes to
`~/.grok/sessions/<cwd>/permission_*.toml` for the whole project. A new
Supervised Grok thread in the same project then ran the command with no
prompt.

The Grok flavor now advertises per-request approval options. File-change
prompts keep a session choice, relabelled "Allow all edits this session",
because Grok's `allow-edits-session` answer lasts only the session. Other
prompts offer Approve, Decline and Cancel.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Sep 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire — 4.9 KiB — 6.8 KiB ✅
Codex Thread snapshot wire — 3.7 KiB — 4.9 KiB ✅
Codex Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Codex Live turn WebSocket decoded — 20.4 KiB — 29.3 KiB ✅
Codex Live turn messages — 2 — 8 ✅
Claude Total thread wire — 4.9 KiB — 6.8 KiB ✅
Claude Thread snapshot wire — 3.7 KiB — 4.9 KiB ✅
Claude Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Claude Live turn WebSocket decoded — 20.8 KiB — 29.3 KiB ✅
Claude Live turn messages — 2 — 8 ✅

Baseline: unavailable · PR result: f73d4db · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 106.1 KiB
  • Claude decoded thread snapshot: 106.4 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

macroscopeapp Bot commented Sep 26, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This focused fix changes Grok’s production permission behavior by preventing a misleading session choice from creating project-wide command grants while preserving the genuine session-only edit option. Because it affects authorization and persistence of tool permissions, human review is warranted.

You can add or adjust custom eligibility rules. Learn more.

@juliusmarminge
juliusmarminge merged commit 954dbd7 into t3code/codex-turn-mapping Sep 26, 2026
23 of 24 checks passed
@juliusmarminge
juliusmarminge deleted the t3code/grok-session-allow-not-persistent branch September 26, 2026 18:14
juliusmarminge added a commit that referenced this pull request Sep 26, 2026
Brings in the V2 bug-hunt fixes merged since this branch was cut
(#13541, #13775, #13786, #13793, #13796, #13802). No conflicts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant