Skip to content

fix(app-bundle): fire the plan→executing un-gag reminder for every primary agent - #1153

Merged
jeonghun-jj-lee merged 4 commits into
mainfrom
fix/plan-mode-reminder-develop
Sep 14, 2026
Merged

jeonghun-jj-lee merged 4 commits into
mainfrom
fix/plan-mode-reminder-develop

Conversation

@jeonghun-jj-lee

@jeonghun-jj-lee jeonghun-jj-lee commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Problem

An agent switched into develop (or research) mode keeps behaving as if it's still in plan mode — read-only, refusing to edit.

Root cause is in the engine's per-turn reminder logic (session/reminders.ts, inherited from upstream). With experimentalPlanMode off (the Amicode default), two reminders are injected off the user message's stored agent:

  • plan.txt — the "READ-ONLY phase" reminder — fires when agent.name === "plan".
  • build-switch.txt — the "you are no longer in read-only mode" un-gag — fired only when agent.name === "build".

Amicode ships develop/research as primary agents (renamed from autodev/autoresearch), but upstream's build-only allowlist never learned about them. So a plan → develop switch stops the plan reminder (good) yet never delivers the un-gag (bad) — the model stays anchored to the plan-mode framing it accumulated.

Fix

Broaden the un-gag condition from an agent-name allowlist to the structural complement:

- if (wasPlan && input.agent.name === "build") {
+ if (wasPlan && input.agent.name !== "plan") {

plan is the only read-only primary agent, so !== "plan" is exactly "any executing agent." This:

  • covers build, develop, research, and any future primary agent — no mode-name enumeration, no coupling to the mode-rename registry;
  • matches upstream's own experimental-branch guard (input.agent.name !== "plan") — it's a back-port of their corrected semantics, not an invention.

Mechanics

  • Forks upstream session/reminders.ts into the overlay: one-line condition change + a provenance comment, otherwise byte-identical to the pinned base (7fe9938).
  • manifest.json updated surgically: files hash + classification: "M" + counts.overlay_total 807→808 + per_package["packages/opencode"].M 73→74. exceptions untouched. (refresh_manifest.mjs was deliberately not used — it's exceptions-unaware and would duplicate the 23 exception files into files, failing the gate.)
  • Drift gate passes: 831 files, overlay↔manifest bijection holds, all hashes verify.

Verification

Confirmed empirically against real session data: in a live session, a plan → develop transition with no intervening build turn received no un-gag reminder, while the build transitions in the same session did. Also confirmed the mode switch correctly propagates agent: "develop" onto user messages (292 user / 2164 assistant develop-tagged messages), so the reminder gap — not a propagation bug — is the cause.

Out of scope (pre-existing, flagged)

The drift gate's step 1 fails on pristine main too: the manifest carries upstream_base_sha but not upstream_base_archive_sha256, so with a materialize cache present it errors. CI passes because it runs the gate without a cache (SKIP path). This PR neither causes nor touches that gap — worth a separate fix.

Summary by CodeRabbit

  • New Features
    • Added contextual reminders during sessions when switching between planning and execution modes.
    • Planning-mode reminders now help guide users to create or continue a plan.
    • Execution-mode reminders can reference an existing plan when transitioning from planning.
    • Reminders are omitted when no applicable user message or mode transition is detected.

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Warning

Review limit reached

Next included review available in 11 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 12f6ffdb-08c4-4c88-9c15-ccd14428b437

📥 Commits

Reviewing files that changed from the base of the PR and between 22f6c60 and b838a18.

📒 Files selected for processing (4)
  • packages/extension/src/chat_bridge.ts
  • packages/extension/src/rebuild/atomic_adoption.ts
  • packages/extension/test/chat_bridge.test.ts
  • scripts/rebuild_amicode.sh

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: a55293ac-7618-4eac-98ae-649306e41983

📥 Commits

Reviewing files that changed from the base of the PR and between 382cecc and 22f6c60.

📒 Files selected for processing (2)
  • packages/app-bundle/manifest.json
  • packages/app-bundle/overlay/packages/opencode/src/session/reminders.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The change adds SessionReminders.apply, which appends plan-related reminder parts based on agent and plan-mode state. The bundle manifest now tracks the new overlay file and updated counts.

Changes

Session reminders

Layer / File(s) Summary
Reminder effect
packages/app-bundle/overlay/packages/opencode/src/session/reminders.ts
Adds SessionReminders.apply. It appends PROMPT_PLAN, BUILD_SWITCH, or PLAN_MODE reminders when their conditions match. It can create the plan directory and returns messages unchanged when no condition applies.
Bundle manifest registration
packages/app-bundle/manifest.json
Adds the new file hash and modified classification. Updates the package modified count from 73 to 74 and the overlay total from 807 to 808.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: aarontrowbridge

Merge Risk: ⚪ Minimal · up to 22f6c

This change makes the session reminder that keeps agents from behaving as read-only fire for any non-plan agent (develop, research, build, and future ones), not just build, which should fix the reported issue where switching from plan to develop or research left the model stuck in a read-only mindset. The manifest bookkeeping for the new file is internally consistent, and no material defect was found in the new reminder logic that would block merging.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: extending the plan-to-executing reminder to every primary agent.
Description check ✅ Passed The description explains the problem, root cause, fix, mechanics, verification, and out-of-scope issue. It does not include the required Related Issue entry, explicit Type of Change selection, or temp…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/plan-mode-reminder-develop

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.

…imary agent

The "you are no longer in read-only mode" switch reminder (build-switch.txt)
only fired for the built-in `build` agent (`input.agent.name === "build"`), so
a plan→develop or plan→research switch left the model still under the plan-mode
reminder — it kept behaving read-only inside an edit-capable director mode.
Amicode ships `develop`/`research` as primary agents (autodev→develop,
autoresearch→research); upstream's `build`-only allowlist never learned about
them.

Broaden the condition to the structural complement `!== "plan"` (plan is the
only read-only primary), which also matches upstream's OWN experimental-branch
guard. No mode-name enumeration, so future primary agents are covered with no
further change.

Mechanics: forks upstream session/reminders.ts into the overlay — one-line
condition change plus a provenance comment, otherwise byte-identical to the
pinned base (7fe9938). manifest.json updated surgically (files hash +
classification M + counts 807→808 + per_package packages/opencode.M 73→74);
exceptions untouched (refresh_manifest.mjs is exceptions-unaware and was NOT
used). Drift gate passes: 831 files, overlay↔manifest bijection holds.

Verified empirically against real session data: a plan→develop transition with
no intervening build turn received no un-gag reminder, while build transitions
did.
@jeonghun-jj-lee
jeonghun-jj-lee force-pushed the fix/plan-mode-reminder-develop branch from ae929d7 to 22f6c60 Compare September 14, 2026 18:23
… build:app

The in-app "Rebuild Locally" button (dev-tools-rebuild handler) ran
`pnpm --filter amicode run build:app` plain, with no --direct-worktree and no
AMICODE_DEPLOY_OVERRIDE. build_app_bundle.mjs's #992 deploy guard refuses
(exit 1) whenever HEAD ≠ origin/main or the tree is dirty — exactly the state
the LOCAL button builds by design (a feature branch / working tree as-is) — so
the app-bundle step failed with "app bundle build failed".

The shell fallback scripts/rebuild_amicode.sh already does this correctly:
local mode passes `build:app -- --direct-worktree` with
AMICODE_DEPLOY_OVERRIDE="local rebuild: <branch> working tree", while main mode
(freshly synced to a clean origin/main) builds plain. This brings the button to
parity with the script.

Extracts rebuildAppBundleStep(mode, branch) — a pure helper mirroring the
existing rebuildGitCommand pattern — so the local-vs-main divergence is
unit-tested (4 new tests). build:binary is untouched: it has no deploy guard,
and the script runs it without --direct-worktree too.
…ing out

The clipboard-image-read handler spawns up to three sequential osascript
calls (file-url → PNG → TIFF), each with a 3 s timeout. With no image on
the clipboard all three error out, easily exceeding vitest's 5 s default —
so the test was a consistent failure on CI and most dev machines.

Mock node:child_process's execFile (the only API the clipboard path uses)
to call back with an error immediately. The test still exercises the
handler's wiring: message dispatch, visibility gate, reply shape, and the
nonce+tab echo — just without depending on a real macOS clipboard or a
live osascript process.

exec (used by the rebuild handler) is left untouched via the spread.
…estart (#1152)

After a rebuild, worktree directories (used by subagent task_spawn sessions)
may be deleted while the DB still references them. On server restart the
engine bootstraps instances for ALL session directories — hitting ENOENT for
stale ones, which cascades into MCP server failures and blocks the chat panel.

Instead of deleting sessions (which loses history), repoint each stale
session to its parent project's main directory (project.worktree). Both
rebuild paths (shell script + in-app Developer Tools button) now run
rehome_stale_worktree_sessions / rehomeStaleWorktreeSessions after DB
restore and before reload.

Also adds bin/ and packs/ to the content-dir deploy lists in both the shell
script and atomic_adoption.ts — the MCP server script (bin/dist/mcp-amico.mjs)
and pack manifests were never being copied to the installed extension during
rebuilds.
@jeonghun-jj-lee
jeonghun-jj-lee merged commit 103444c into main Sep 14, 2026
11 checks passed
@jeonghun-jj-lee
jeonghun-jj-lee deleted the fix/plan-mode-reminder-develop branch September 14, 2026 19:22
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