Skip to content

fix(native-chat): chats from before permission modes keep the mode they were running with - #28099

Merged
brennanb2025 merged 6 commits into
mainfrom
brennanb2025/chat-permission-old-chats-use-default
Oct 13, 2026
Merged

brennanb2025 merged 6 commits into
mainfrom
brennanb2025/chat-permission-old-chats-use-default

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 8 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​370 $\color{#cf222e}{\Huge{\mathbf{−}}}$​1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​369
Prod 6 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​62 $\color{#cf222e}{\Huge{\mathbf{−}}}$​2 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​60

ELI5

#26116 (merged, not in a release yet) gave each Claude and Codex chat its own permission setting, saved on the chat: Ask for approval before running commands, or Full access to just run them. A button next to "+" in the chat shows it and changes it.

The chats people already have when they update were made before that setting existed, so nothing is saved on them, and #26116 treats "nothing saved" as Ask for approval. Before #26116, a chat simply did what Settings → Agents → Agent Permissions said, and that is Yolo (no prompts) by default. So on the day #26116 ships, most chat users would find every chat they already have asking before each command. A user has already reported exactly this ("every single command needs manual confirmation", STA-10345).

With this PR, the first time Orca starts after the update, it saves a permission mode onto every Claude and Codex chat that doesn't have one: the mode the chat was already running with, taken from that chat's own agent's Agent Permissions setting. Users on Yolo keep Full access and users on Manual keep Ask. The new-chat default only affects new chats. From then on those chats are ordinary chats with their own saved mode, and the button shows the right mode straight away.

What Changed

Terms used below

What you see

Chat Today on main With this PR
A chat you already had, Agent Permissions on Yolo Ask for approval: starts prompting Full access, saved on the chat at the first launch after the update
A chat you already had, Agent Permissions on Manual Ask for approval Ask for approval, saved the same way
Claude on Yolo and Codex on Manual (or the reverse) Ask for approval for both Each old chat keeps its own agent's setting: Claude chats Full access, Codex chats Ask
A chat where you've already picked a mode that mode that mode (never overwritten)
A new chat the new-chat default unchanged
Changing the new-chat default later affects new chats affects new chats only; chats you already had keep their saved mode

Mechanism: one step when the host's chat service starts (on the desktop that's at app start, when saved chats are restored; on a remote server it's the first chat request). After the chat record store is open, and before any chat can be read or started, the host runs one pass over its saved chats in a single store transaction. Each Claude or Codex chat whose saved options have no permission mode gets the mode it was already running with: Full access if that agent's own launch arguments skip permissions (the same check Orca used for these chats before #26116), otherwise Ask. Nothing else in the saved options changes.

  • Runs only once in effect. After that first run no chat is missing a mode, so later startups find nothing to do. There is no "already ran" flag to store or clean up.
  • Never overwrites. A chat that already has a saved value is left alone, even an unrecognised one, which main already treats as Ask.
  • Never blocks anything. If the pass fails, the failure is logged and Orca starts normally. Those chats behave as they do on main (Ask) for that session, and the pass tries again on the next start.
  • New chats always get a mode at creation. Every create path already saved one, except a chat created by attaching to a location the client supplies (used by older clients and agentSession.ensure). That path now gets the same new-chat seed. Without it, such a chat would run Ask and then switch to Full access after the next restart's pass. An existing chat is never reseeded: the store applies options only when it creates the record.
  • Skipped on a read-only store. If a newer Orca wrote the chat database, this build doesn't write to it at all, and the pass doesn't run.

The code that launches a chat, decides whether it must restart after a mode change, and draws the button is unchanged from main. It reads the chat's saved mode as before; the difference is that, after the pass, every Claude and Codex chat has one.

Why

Without this, the release that ships #26116 turns existing chats for most chat users from "no prompts" into "prompt for everything". The new button can fix that only one chat at a time, and only after the user works out what changed.

When a required per-item setting is added, the common pattern is to fill in every existing item once with the behaviour it already had, so that afterwards nothing ever has to handle the setting being missing. This PR does that.

Alternatives considered (both built and reviewed on this branch before):

  • Old chats keep following the new-chat default until changed. This was the first version. Keeping those chats in sync with the setting took a settings-change listener, a button refresh and an extra field sent between client and host (+539 lines). It also contradicted the setting's own description, "applies to new chats only".

  • Save the mode on an old chat the first time it starts. This was the second version. An independent review reproduced two timing bugs:

    • Launched one mode, saved another. The setting was read twice, at launch and later when saving. Changing it while a chat was starting meant the chat launched with one mode and saved the other, then restarted itself.
    • Mode never saved. On slow-starting agents, picking a model during startup made the host throw the save away along with the outdated start report.

    It also left the button possibly wrong before the first start.

    The startup pass removes all three, because no chat ever starts without a saved mode. It is also smaller: no change to the launch path at all.

  • Keep Ask for those chats. That's the regression this PR fixes.

Cost: one write per old Claude or Codex chat, once, on the first launch after the update.

Linked Issue

STA-10345 (user feedback), following #26116.

Visual Proof

Upgrade path on macOS, hidden dev builds: a profile with real Claude and Codex chats created on a build from just before #26116, with Agent Permissions on Yolo for both. A copy of that same profile was opened by main and by this PR (fe9903b0fdf).

Before (main): the old Claude chat's button shows Ask for approval…

Before: old chat shows Ask for approval

…and asking it to write a file stops at Allow Bash?, though this user never chose Ask.

Before: Allow Bash prompt

After: the same old Claude chat shows Full access, and the same kind of request runs with no prompt (the new file is in the file list).

After: old Claude chat shows Full access and the write ran

The old Codex chat on the same profile, also Full access with no prompt:

After: old Codex chat shows Full access and the write ran

Control: a copy of the same profile with Agent Permissions on Manual. The old chats get Ask for approval, and a write shows a real approval card.

Control: Manual old chat asks before running

Testing

  • Automated (pnpm test on the 8 permission, backfill, create, runtime and record-store test files): 122/122 pass. New tests cover:

    • old Claude and Codex chats with no mode getting Full access or Ask from their own agent's arguments, including mixed arguments (Claude Yolo with Codex Manual, and the reverse);
    • saved valid and unrecognised modes, other agents' chats, and every other saved option left alone;
    • a second pass writing nothing, and a read-only store being skipped;
    • a failed pass not blocking startup;
    • changing the new-chat default not moving an old chat;
    • a client-supplied attach creating a new chat with the seed, and an existing chat never being reseeded.
  • Fail-before controls: the new tests fail on the previous head of this branch (the mixed-arguments cases fail with "expected 'ask' to be 'full-access'") and pass now. The store test fails if the store takes request options on an existing chat.

  • Checks: pnpm tc:node passes. orca-ci-checks --no-typecheck passes except two checks that fail the same way on the branch's earlier head: five mobile import-cycle warnings, and a local Bun tooling error.

  • CI: green on 3a7a4b98fcc. The wider runs also cover every test file under src/main/runtime and src/main/native-chat locally (1,736 tests). They caught three test stubs missing the launch-seed method that the attach path now reads, which are fixed.

  • Live upgrade QA, macOS (M4Air, hidden dev builds, CDP-driven): on fe9903b0fdf, fresh copies of the real pre-feat(native-chat): each Claude/Codex chat gets its own permission mode #26116 profile. Later commits only inline a small cache and fix test stubs, so behaviour is unchanged.

    • Yolo: both old chats were saved as Full access about 2 s after startup, before any agent process started. Both buttons showed Full access, and both wrote a file with no prompt. Claude was launched with the skip-permissions flag; Codex ran with approval "never".
    • Manual: both old chats were saved as Ask. Both buttons showed Ask, and real approval cards appeared (Claude "Allow Bash?", Codex "Run a command?").
  • Live QA on the previous head dbdf865 (same pass, filled from the shared default; not re-run on the final head):

    • With Settings → "Permissions for new chats" switched to Ask before the old Claude chat's first start, it still showed Full access and ran with no prompt.
    • After quit and relaunch, both chats kept Full access with their saved options byte-identical, and the second pass changed nothing.
  • Not tested live: SSH and remote servers (code path only: each host runs the pass with its own settings), Linux, Windows, mobile. Picking a Codex model or effort is a separate bug, fixed in fix(native-chat): store a chat's permission mode on its own, so a model pick can't reset it #28268.

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

Notes

  • SSH and remote hosts: each execution host (this Mac, an SSH host, a paired Orca server) runs the pass on its own chats with its own settings when it first starts on the new version. Nothing new is sent between client and host. Desktop Settings can't yet show or edit a remote host's new-chat default; that's an existing limitation for new remote chats too, and a separate follow-up.
  • Mixed versions: the saved mode is an ordinary chat option that already exists on main. Older clients read it through the existing options read.
  • Other agents (Grok, OpenCode, Pi, OMP) have no per-chat modes and are unchanged.
  • If the pass fails on the first launch and the user then changes Agent Permissions, the retry on the next start uses the changed arguments. That is rare and harmless: the user's own choice.
  • Known separate bug, not fixed here: on main, picking a Codex or Claude model or effort erases a chat's saved mode, so it falls back to Ask. That affects new chats too and is fixed in fix(native-chat): store a chat's permission mode on its own, so a model pick can't reset it #28268.
  • Earlier versions of this branch are kept at brennanb2025/chat-permission-old-chats-use-default-live-backup (first version), and in the branch history at 509e5125558 (second version).

@brennanb2025

brennanb2025 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

Problem. Claude and Codex chats made before #26116 have no saved permission mode, and main reads that as Ask for approval. Before #26116 those chats did whatever Settings → Agents → Agent Permissions said, which is Yolo (no prompts) by default. So on upgrade, most chat users would find every existing chat asking before each command (reported in STA-10345).

What changes for the user. The first time the host's chat service starts on the new version, each old Claude or Codex chat gets the mode it was already running with: Full access if that agent's own arguments skip permissions, otherwise Ask. The button shows the right mode immediately. From then on these chats behave like any other chat: the "Permissions for new chats" default affects new chats only.

How. One store transaction over the saved chats, before any chat can be read or started. It fills only a missing mode, never overwrites a saved one, and leaves every other option alone. It skips a read-only store. A failure is logged, doesn't block startup, and is retried on the next start. A chat created by attaching to a client-supplied location now gets the same new-chat seed every other create path already uses, so no new chat is ever missing a mode. This replaces the earlier designs: live inheritance of the default, then saving the mode at first start, which had two reproduced timing bugs. The launch path is unchanged from main.

Review (final head 3a7a4b98fcc):

  • Round 5 was a full review by three independent reviewers covering correctness and every creation path, architecture, and performance plus readiness. All three found one real issue: old chats were filled from the shared new-chat default, which is Full only if both agents skip prompts. That would have saved Ask on old Claude chats for a user with Claude on Yolo and Codex on Manual. Fixed: each old chat now uses its own agent's arguments, the same check Orca used before feat(native-chat): each Claude/Codex chat gets its own permission mode #26116.
  • Also fixed: a redundant existing-record check in the attach seed (the store already applies options only when it creates a chat), an unrelated test-fixture edit, and doc wording.
  • Round 6 (narrow) confirmed the fixes. New tests fail on the previous head and pass now.
  • Since then: a small per-agent cache whose test proved nothing was removed (the backfill now reads each chat's agent arguments directly), and CI caught three test stubs missing the launch-seed method the attach path now reads. Both are fixed.
  • Deferred P3: the first-run write costs about 0.1 s per 5,000 old chats on the desktop restore path, then about 2 ms with no writes on later starts.
  • Still open, accepted as a separate follow-up: desktop Settings can't view or edit a remote host's new-chat default.

Verified.

  • Focused tests 122/122, pnpm tc:node, and local static checks (only the two known local failures: mobile import cycles and a Bun tooling error).
  • Hidden M4Air upgrade QA with real Claude and Codex, on fe9903b0fdf (later commits don't change behaviour):
    • Yolo profile: both old chats saved as Full before any agent started, and both wrote with no prompt.
    • Manual profile: both saved as Ask, with real approval cards.
  • On the previous head, with the same pass: switching the default to Ask before the old chat's first start left it at Full, and quit/relaunch kept everything with nothing rewritten. These two cases weren't re-run on the final head, whose change only affects the startup value.

Not verified. SSH and remote servers live (code path only), Linux, Windows, mobile.

CI. Green on 3a7a4b98fcc.

Separate, related: on main, picking a model or effort erases a chat's saved mode, so it falls back to Ask. Fixed in #28268 (draft).

Draft. Not merged.

@brennanb2025
brennanb2025 marked this pull request as ready for review October 13, 2026 06:47
…t default

A Claude or Codex chat created before chats had their own permission mode has
none saved, and it ran Ask, so every existing chat of a Yolo user started asking
for approval after the update. A chat with no saved mode now runs Settings ->
Chat -> Permissions, read from the host's settings on each launch, read and
restart check.
@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 70840b34-1d32-4266-a087-3b90b3b4bf7b
📥 Commits

Reviewing files that changed from the base of the PR and between fe9903b and b24b80a.

📒 Files selected for processing (2)
  • src/main/runtime/agent-session-permission-backfill.test.ts
  • src/main/runtime/agent-session-permission-backfill.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.

📝 Walkthrough

The runtime now backfills missing permission modes for saved Claude and Codex chats using each provider’s full-access setting. The backfill skips read-only stores, preserves existing modes and record data, and logs failures without stopping installation. The attach handler also adds a truthy launch-seed permission mode to attach options. Tests cover backfill behavior, startup persistence, and create and ensure attach requests.

Priority: ➖ Normal

Merge Risk: 🟡 Moderate · up to b24b8

This change fills in missing chat permission modes. Some older chats could be saved with the wrong mode, notably chats pinned to a different host, and the saved mode would not be corrected later. The new test may also fail on Windows during cleanup. Resolve or explicitly accept these before merging.

Pre-merge checks · Passed 4 · Failed 1

Failed Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 45.83% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 24 functions across 37 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly identifies the main change: preserving permission modes for chats created before per-chat permission modes existed.
Description check Passed The description is comprehensive and covers the user impact, implementation, rationale, linked issue context, visual proof, testing, limitations, and compatibility notes. Some template sections and ch…
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…rt ran with

A chat saved before chats had permission modes ran the new-chat default on every
start, so it kept following that setting. Its first start now writes the mode it
ran into the chat's saved options, through the same write that already carries the
chat's other options over a start; from then on it is a chat with its own mode.
@brennanb2025
brennanb2025 force-pushed the brennanb2025/chat-permission-old-chats-use-default branch from 514dea1 to 509e512 Compare October 13, 2026 07:05

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: cc376ad9-1d29-4907-817f-201adcef069d
📥 Commits

Reviewing files that changed from the base of the PR and between 514dea1 and 509e512.

📒 Files selected for processing (9)
  • src/main/native-chat/agent-session-wire/structured-agent-session-acquisition-options.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-acquisition.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-attach-flow.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-attach-orchestration.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-launch-permission.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-launch-permission.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-provider-started.ts
  • src/main/runtime/orca-runtime-get-worktree-ps.ts
  • src/main/runtime/structured-agent-session-runtime.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.

Comment thread src/main/native-chat/agent-session-wire/structured-agent-session-acquisition.ts Outdated
@brennanb2025 brennanb2025 changed the title fix(native-chat): chats from before permission modes use the new-chat default, not Ask fix(native-chat): chats from before permission modes keep the mode they were running with Oct 13, 2026
Replace the save-at-first-start path with one startup pass: before the chat
host is exposed, every Claude and Codex record with no saved permissionMode
gets the host's new-chat default, in one store transaction. Saved values,
including invalid ones, and every other option are left alone; a read-only
store is skipped and a failure is logged and retried next start.

The runtime fallback in launch, acquisition, provider-started and attach is
restored to main's behaviour. A client-supplied attach that creates a new
record now gets the same new-chat seed as every other create path.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 016f4a9e-1f8b-4e8c-9369-1cf1c81e49a6
📥 Commits

Reviewing files that changed from the base of the PR and between 509e512 and dbdf865.

📒 Files selected for processing (12)
  • config/scripts/vitest-sqlite-runtime-files.mjs
  • src/main/native-chat/agent-session-wire/structured-agent-session-startup-attempt-host.test.ts
  • src/main/runtime/agent-session-permission-backfill.test.ts
  • src/main/runtime/agent-session-permission-backfill.ts
  • src/main/runtime/agent-session-record-store.ts
  • src/main/runtime/orca-runtime-get-worktree-ps.ts
  • src/main/runtime/orca-runtime-structured-launch-settings-wiring.test.ts
  • src/main/runtime/rpc/methods/structured-agent-session-create-handler.ts
  • src/main/runtime/rpc/methods/structured-agent-session-permission-create.test.ts
  • src/main/runtime/rpc/methods/structured-agent-session-rpc.test-fixture.ts
  • src/main/runtime/structured-agent-session-runtime.test.ts
  • src/main/runtime/structured-agent-session-runtime.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

root = await mkdtemp(join(tmpdir(), 'orca-permission-backfill-'))
})
afterEach(async () => {
await rm(root, { recursive: true, force: true })

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Close the test database before removing root.

The test database registry keeps its SQLite connection open after each test. On Windows, the open database can block rm(root), so the cleanup fails. Call closeTestJournalHostDatabases() before rm, as the adjacent store-transaction tests do. (raw.githubusercontent.com)

logger
})
try {
await recordStore.store.backfillChatPermissionModes(deps.initialChatPermissionMode)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not backfill when initialChatPermissionMode is absent.

initialChatPermissionMode is optional, but this call runs with undefined when a caller omits it. newChatPermissionMode then selects Ask for Claude and Codex. The transaction saves Ask permanently, so a later start with a Full access default cannot correct those chats. Require the dependency or skip the backfill when it is absent. (raw.githubusercontent.com)

An older Claude or Codex chat ran with that agent's own Arguments before
permission modes existed, so the startup pass now saves full access or ask
per agent instead of the combined new-chat default. A user with Claude on
bypass and Codex on Manual keeps Claude chats on full access.

The attach create path always passes its permission seed; the reservation
already applies options only when it creates the record.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

🟡 Minor · Preserve attach options when adding the… · structured-agent-session-create-handler.ts:42-44

src/main/runtime/rpc/methods/structured-agent-session-create-handler.ts:42-44
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Preserve attach options when adding the permission seed.

When an attach request creates a new record, the handler replaces all existing params.options with the permission seed. This drops other valid initial options. Merge the seed into the existing options.

Proposed change
-      ? { options: { [AGENT_CHAT_PERMISSION_MODE_OPTION_ID]: permissionMode } }
+      ? { options: { ...params.options, [AGENT_CHAT_PERMISSION_MODE_OPTION_ID]: permissionMode } }

ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6da23a99-c6d8-42bb-9abd-e6551200abc3
📥 Commits

Reviewing files that changed from the base of the PR and between dbdf865 and fe9903b.

📒 Files selected for processing (10)
  • src/main/native-chat/agent-session-wire/structured-agent-session-startup-attempt-host.test.ts
  • src/main/runtime/agent-session-permission-backfill.test.ts
  • src/main/runtime/agent-session-permission-backfill.ts
  • src/main/runtime/agent-session-record-store.test.ts
  • src/main/runtime/agent-session-record-store.ts
  • src/main/runtime/orca-runtime-structured-launch-settings-wiring.test.ts
  • src/main/runtime/rpc/methods/structured-agent-session-create-handler.ts
  • src/main/runtime/rpc/methods/structured-agent-session-permission-create.test.ts
  • src/main/runtime/structured-agent-session-runtime.test.ts
  • src/main/runtime/structured-agent-session-runtime.ts
💤 Files with no reviewable changes (1)
  • src/main/runtime/rpc/methods/structured-agent-session-permission-create.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.

if (record.options?.[AGENT_CHAT_PERMISSION_MODE_OPTION_ID] !== undefined) {
continue
}
const permissionMode = modeFor(record.provider)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🔎 Supported by static analysis

🏁 Script executed:

set -o pipefail
printf '%s\n' '--- changed file ---'
nl -ba src/main/runtime/agent-session-permission-backfill.ts
printf '%s\n' '--- references ---'
rg -n -F --glob '*.{ts,tsx}' -e 'backfillAgentSessionPermissionModes' -e 'executionHostId' -e 'interface AgentSession' -e 'type AgentSession' src/main src | head -240
printf '%s\n' '--- relevant files ---'
rg --files src/main | rg 'agent-session|permission|runtime|store' | head -160

Repository: stablyai/orca

Length of output: 41652


🏁 Script executed:

set -o pipefail
nl -ba src/main/runtime/agent-session-permission-backfill.ts
printf '%s\n' '--- direct references ---'
rg -n -F --glob '*.{ts,tsx}' -e 'backfillAgentSessionPermissionModes' -e 'executionHostId' src/main src

Repository: stablyai/orca

Length of output: 45657


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- exact backfill references ---'
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'backfillAgentSessionPermissionModes' . || test "$?" -eq 1
printf '%s\n' '--- exact ranWithFullAccess references ---'
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'ranWithFullAccess' . || test "$?" -eq 1
printf '%s\n' '--- store transaction declaration and references ---'
rg -n -F --glob '*.ts' --glob '*.tsx' -e 'export interface AgentSessionStoreTransactions' -e 'export type AgentSessionStoreTransactions' -e 'AgentSessionStoreTransactions' src/main/native-chat src/main/runtime || test "$?" -eq 1
printf '%s\n' '--- agent session record declarations ---'
rg -n -F --glob '*.ts' --glob '*.tsx' -e 'AgentSessionRecord' -e 'type AgentSessionRecord' -e 'interface AgentSessionRecord' -e 'location: {' src/main/native-chat src/main/runtime | head -240

Repository: stablyai/orca

Length of output: 38991


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- agent-session-record-store ---'
nl -ba src/main/runtime/agent-session-record-store.ts | sed -n '70,135p'
printf '%s\n' '--- agent-session-store-transactions ---'
nl -ba src/main/runtime/agent-session-store-transactions.ts | sed -n '1,220p'
printf '%s\n' '--- shared record and fixture ---'
nl -ba src/shared/agent-session-record.ts | sed -n '1,180p'
nl -ba src/main/native-chat/agent-session-record-test-fixture.ts | sed -n '1,90p'
printf '%s\n' '--- journal schema and backfill tests ---'
nl -ba src/main/native-chat/agent-session-journal/journal-database-schema.ts | sed -n '1,130p'
nl -ba src/main/runtime/agent-session-permission-backfill.test.ts | sed -n '1,190p'

Repository: stablyai/orca

Length of output: 36842


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- backfill method callers ---'
rg -n -F --glob '*.ts' --glob '*.tsx' -- 'backfillChatPermissionModes' . || test "$?" -eq 1
printf '%s\n' '--- launch/default resolution candidates ---'
rg -n -F --glob '*.ts' --glob '*.tsx' -e 'ranWithFullAccess' -e 'permissionMode' -e 'bypassPermissions' -e 'dangerouslySkipPermissions' src/main src/shared | head -320

Repository: stablyai/orca

Length of output: 30457


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- runtime call and dependency declaration ---'
nl -ba src/main/runtime/structured-agent-session-runtime.ts | sed -n '220,285p'
rg -n -F --glob '*.ts' --glob '*.tsx' -e 'resolveAgentFullAccess' -e 'resolveAgentPermissionMode' src/main src/shared

Repository: stablyai/orca

Length of output: 5129


🏁 Script executed:

set -o pipefail
printf '%s\n' '--- runtime dependency type ---'
nl -ba src/main/runtime/structured-agent-session-runtime.ts | sed -n '95,135p'
printf '%s\n' '--- resolver wiring ---'
nl -ba src/main/runtime/orca-runtime-get-worktree-ps.ts | sed -n '205,240p'
nl -ba src/main/runtime/orca-runtime-structured-launch-settings-wiring.test.ts | sed -n '1,60p'

Repository: stablyai/orca

Length of output: 8811


Resolve permission defaults for the chat’s execution host.

When record.location.executionHostId differs from the current runtime host, resolveAgentFullAccess uses this host’s configured arguments. The backfill then saves that mode, and the existing-mode guard prevents a later correction. Resolve the default for record.location.executionHostId, or skip records whose host-specific default is unavailable.

@brennanb2025
brennanb2025 merged commit c5d7628 into main Oct 13, 2026
32 checks passed
@brennanb2025
brennanb2025 deleted the brennanb2025/chat-permission-old-chats-use-default branch October 14, 2026 05:54
registered2nd pushed a commit to registered2nd/orca that referenced this pull request Oct 14, 2026
…ey were running with (stablyai#28099)

* fix(native-chat): chats saved before permission modes run the new-chat default

A Claude or Codex chat created before chats had their own permission mode has
none saved, and it ran Ask, so every existing chat of a Yolo user started asking
for approval after the update. A chat with no saved mode now runs Settings ->
Chat -> Permissions, read from the host's settings on each launch, read and
restart check.

* fix(native-chat): an older chat keeps the new-chat mode its first start ran with

A chat saved before chats had permission modes ran the new-chat default on every
start, so it kept following that setting. Its first start now writes the mode it
ran into the chat's saved options, through the same write that already carries the
chat's other options over a start; from then on it is a chat with its own mode.

* fix(native-chat): save older chats' permission mode once at host startup

Replace the save-at-first-start path with one startup pass: before the chat
host is exposed, every Claude and Codex record with no saved permissionMode
gets the host's new-chat default, in one store transaction. Saved values,
including invalid ones, and every other option are left alone; a read-only
store is skipped and a failure is logged and retried next start.

The runtime fallback in launch, acquisition, provider-started and attach is
restored to main's behaviour. A client-supplied attach that creates a new
record now gets the same new-chat seed as every other create path.

* fix(native-chat): fill each older chat from its own agent's arguments

An older Claude or Codex chat ran with that agent's own Arguments before
permission modes existed, so the startup pass now saves full access or ask
per agent instead of the combined new-chat default. A user with Claude on
bypass and Codex on Manual keeps Claude chats on full access.

The attach create path always passes its permission seed; the reservation
already applies options only when it creates the record.

* refactor(native-chat): read each chat's agent arguments directly in the permission backfill

* test(native-chat): give stub runtimes the launch seed the attach path reads

(cherry picked from commit c5d7628)
brennanb2025 added a commit that referenced this pull request Oct 15, 2026
…ey were running with (#28099)

* fix(native-chat): chats saved before permission modes run the new-chat default

A Claude or Codex chat created before chats had their own permission mode has
none saved, and it ran Ask, so every existing chat of a Yolo user started asking
for approval after the update. A chat with no saved mode now runs Settings ->
Chat -> Permissions, read from the host's settings on each launch, read and
restart check.

* fix(native-chat): an older chat keeps the new-chat mode its first start ran with

A chat saved before chats had permission modes ran the new-chat default on every
start, so it kept following that setting. Its first start now writes the mode it
ran into the chat's saved options, through the same write that already carries the
chat's other options over a start; from then on it is a chat with its own mode.

* fix(native-chat): save older chats' permission mode once at host startup

Replace the save-at-first-start path with one startup pass: before the chat
host is exposed, every Claude and Codex record with no saved permissionMode
gets the host's new-chat default, in one store transaction. Saved values,
including invalid ones, and every other option are left alone; a read-only
store is skipped and a failure is logged and retried next start.

The runtime fallback in launch, acquisition, provider-started and attach is
restored to main's behaviour. A client-supplied attach that creates a new
record now gets the same new-chat seed as every other create path.

* fix(native-chat): fill each older chat from its own agent's arguments

An older Claude or Codex chat ran with that agent's own Arguments before
permission modes existed, so the startup pass now saves full access or ask
per agent instead of the combined new-chat default. A user with Claude on
bypass and Codex on Manual keeps Claude chats on full access.

The attach create path always passes its permission seed; the reservation
already applies options only when it creates the record.

* refactor(native-chat): read each chat's agent arguments directly in the permission backfill

* test(native-chat): give stub runtimes the launch seed the attach path reads

(cherry picked from commit c5d7628)
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