fix(coding-agent): base plan-default freshness on built branch context

A blocklist of `message`/`mode_change` entries missed context-bearing entries
that carry no literal message — a compacted branch, a branch summary, or a
custom-role message — which buildSessionContext still feeds the model. Such a
resumed session was misclassified as fresh and auto-entered plan mode, overriding
its restored mode.

Gate on buildSessionContext().messages (the resolved branch context — messages,
custom messages, branch summaries, and compaction summaries) plus a `mode_change`
entry check. SDK startup metadata and extension `custom` state entries stay
excluded. Added a regression test for a compacted session with no trailing
message.
This commit is contained in:
ephraimduncan
2026-06-05 12:36:09 +00:00
parent c426f2517a
commit 442648be56
2 changed files with 27 additions and 21 deletions
@@ -159,6 +159,20 @@ describe("InteractiveMode plan.defaultOnStartup", () => {
expect(session?.getPlanModeState()).toMatchObject({ enabled: true });
});
it("does not enter plan mode for a compacted session with no trailing message", async () => {
// A compacted branch carries summary context (buildSessionContext emits the
// compaction summary as a message), so it is not fresh even without a literal
// `message` entry; the startup default must not override its restored mode.
const created = createHarness(Settings.isolated({ "plan.defaultOnStartup": true, "compaction.enabled": false }));
created.sessionManager.appendModelChange("anthropic/claude-sonnet-4-5");
created.sessionManager.appendCompaction("prior conversation summary", undefined, "first-kept", 1000);
await created.init({ suppressWelcomeIntro: true });
expect(created.planModeEnabled).toBe(false);
expect(session?.getPlanModeState()).toBeUndefined();
});
it("does not re-enter plan mode when a restored mode_change turned it off (no message yet)", async () => {
// User enabled plan, toggled it off (mode_change "none"), then quit before
// sending a turn. On --continue the reconciler restores that off state; the