87. Panel auto-open master switch¶
- Status: accepted
- Date: 2026-10-27
Context¶
Content-driven panel auto-open (ADR-0044, amended by ADR-0059/0078/0079) has
been unconditional since it shipped: when a task is created, a background job
spawns, a workflow starts, or percepts arrive, the matching panel opens
itself (with a toast explaining the open), and the memory panel follows the
same rule at startup via applyMemoryContentDefault. The only escape hatch
was the per-panel manual override — which the user has to re-assert per
panel, and which with remember_panel_state on becomes a per-folder
preference to manage.
Some users do not want panels moving at all: a layout in motion is exactly the kind of surprise the toast layer (ADR-0044/issue #162) was built to explain, but explaining a surprise is not the same as not wanting it. There was no way to say "panels open when I open them".
Decision¶
Add one master switch for the whole behaviour, default on (existing users keep exactly the behaviour they have today; bothered users opt out once):
- Config:
"panel_auto_open": bool(internal/config, unset = on), sitting besideremember_panel_state. Unlike panel state (which is per-folder, ADR-0078), this is a user-level disposition and therefore a plain global config key. - Command:
/panel autoopen [on|off]— the skip-permissions grammar (on|offsets, bare query answers in the transcript, anything else is a usage line), persisted like/tips on|offviasaveLocalOrGlobal, with state changes as notification toasts (issue #162) and the bare query in the transcript.autoopenis a/panelsubword but not a panel region: it is intercepted inhandlePanelCmdbefore the region lookup, so it never collides with a panel name and is offered by thepanelcompletion namespace. - Gate:
autoOpenPanelreturns immediately when the switch is off — no open, no toast, no tab activation — andapplyMemoryContentDefaultskips its startup open too. Nothing else changes: manual/panel <name>and F1-F6 toggles, the per-panel manual override, the finalization reset (ADR-0059), per-folder panel state (ADR-0078), and the tabbed-theme slot gate (ADR-0079) all behave exactly as before, layering on top when the switch is on.
Companion change: saved panel state is startup layout (amends ADR-0078)¶
Shipping the master switch exposed a contradiction: with the switch on
(the default), a restored panel-state file could still silently veto every
auto-open. loadPanelState seeded panelManualOverride for every stored
entry, and with remember_panel_state on (default) the ADR-0059 expiry
never ran — so any panel the user had ever toggled was locked out of its
next content forever, per folder. Real user state accumulated into exactly
that: all six panels overridden, auto-open visibly "gone" with nothing
wrong in config.
ADR-0078's promise ("content-driven auto-open never fights what the user
last chose") is retired; the master switch now covers that case properly
(panel_autoopen off = layout content never touches). The durable half of
a toggle moves to a new panelPrefs map:
- A manual toggle records both a
panelPrefsentry (durable, persisted) — and an in-sessionpanelManualOverrideveto. loadPanelStaterestores open/closed state pluspanelPrefs— startup layout only. It never seeds the veto.savePanelStatepersistspanelPrefs∪ current overrides, so choices accumulate across sessions without ever becoming a veto.resetManualOverrideIfFinalizedalways applies (theremember_panelStateearly-return is gone): an in-session veto covers exactly the live content the user dismissed and expires when it finalizes (ADR-0059, in full, for both persistence modes).
Consequences¶
/panel autoopen offgives a fully static panel layout: panels change only on explicit request.on(the default) restores today's behaviour; the choice survives restarts.- The switch is global while the manual override is per-folder — with the switch on nothing changes about the override semantics; with it off the override is moot (nothing auto-opens to override).
- Panels re-open on new content even across sessions (the amended
ADR-0078 contract). Users who want a settled layout now have the
explicit tool for it:
/panel autoopen off. - Model tests that build
model{}literals directly (rather than throughnewModel) must setpanelAutoOpen: trueto exercise auto-open — the zero value means "off", while production always seeds from config (default on).