BODY CORRECTED 2026-09-04 by me, the author. The mechanism this ticket asserted is falsified, the fix it prescribed is not demonstrated to address the reported symptom, and one identifier in it was wrong. The measured symptom stands. Sections below are rewritten rather than appended to, because the old Acceptance Criteria were written against the falsified mechanism and a reader following them builds the wrong arm — which is exactly what I did in PR #18267 (closed unmerged). What changed and how it was measured is in Measured vs Asserted.
Context
Measured by @neo-opus-vega on a downstream consumer (2026-09-03) while chasing the operator's report that pop-out is broken there. He is on the client app per operator direction; this is the engine half.
Live latest-open sweep: checked the latest 10 open issues at 2026-09-03T06:45Z; no equivalent. #18153 covers pop-out opening nothing (the inert vessel) — a different defect on the same action. #18039 is the same class for reload and is closed.
The Problem
The reported symptom, measured on a real consumer, same app, same session:
boot-projected node, focused:
tabs=["Dokumente","Systematik"] acts=["More tabs","lock","pop out","maximize","close"] ← present
after ONE addTab + ONE close commit, focused:
tabs=["Systematik"] acts=["lock","maximize","close"] ← GONE
This is the whole of what is established. The transition is visible → gone on a downstream consumer. Nothing below this line should be read as explaining it.
Measured vs Asserted
This ticket originally asserted a mechanism: pop-out's hidden is computed once at projection and lives on a retained instance that no sweep repairs, so it goes stale. syncDockPopOutAction was prescribed and shipped in #18160.
That mechanism does not reproduce in the unit tier. Measured 2026-09-04 with a workspace built the way a shipping writer builds one — tearOutHandlers installed in construct()beforeprojectDockModel(), so pop-out projects visible:
sync PRESENT: boot hidden=false → after addTab+closeItem: same instance, hidden=false
sync REMOVED: boot hidden=false → after addTab+closeItem: same instance, hidden=false
Deleting syncDockPopOutAction from the sweep entirely changes nothing. The retained instance keeps hidden=false; nothing drives it to true. So in this shape the sync is not what stands between the user and the symptom, and the asserted staleness never occurs.
Falsified by @neo-gpt-emmy on PR #18267 and re-derived independently before conceding. #18160's sync is correct and well-formed code for a mechanism that has not been shown to be the operative one. It is not a defect and is not being reverted; it simply is not evidence that this ticket is resolved.
Also corrected: the original body prescribed getActionItem('popOut'). The registered action name is 'pop-out' (LayoutAdapter:1183); popOut is the tooltip key (:1186). #18160 used the correct one. Had anyone implemented the spelling this ticket specified, the lookup returns undefined and action && (…) swallows it silently — a guard that never fires.
The Architectural Reality
Workspace#syncDockHeaderActions() sweeps retained chrome and now re-evaluates five actions including pop-out (Workspace.mjs:2124, shipped in #18160).
syncDockPopOutAction (:1773) computes hidden = !itemId || !this.dockPopOutActionActive and assigns it. The assignment is change-guarded by construction: Neo.mjs:463 gates afterSet behind config.set(value), so an unchanged reactive-config write fires nothing. This is #18245's idiom.
What is NOT known: which of those inputs changed on the live consumer, or whether the disappearance happened on the retained instance at all rather than on a re-projected node. The consumer's topology (a Workstation host, a rail, a focused node) is richer than any unit fixture built so far, and the symptom has never been reproduced outside it.
The Fix
Unknown — and that is the current state of this ticket, not a placeholder.
The next step is a reproduction, not an implementation. Until the visible → gone sequence reproduces somewhere a test can watch it, any arm written here certifies a mechanism nobody has witnessed. PR #18267 is the worked example of that failure: it went red under three mutations and still tested the wrong direction.
Whoever picks this up should first answer: on the consumer where it was measured, does it still reproduce? If it does not, closing this as not-reproducible is the honest end state.
Acceptance Criteria
AC-1 — the reported sequence is reproduced somewhere observable: an action that is visible, a commit, and the same action gone. Consumer, e2e or unit — the tier is free, the direction is not. Without this, nothing below is actionable.
AC-2 — the input that changed is named: itemId, enableDockPopOutAction, tearOutHandlers, enableDockTearOutLifecycle, canOpenTearOutVessel, or a re-projection that replaced the instance. One of them, identified from the reproduction rather than inferred.
AC-3 — only then, a fix and an arm that is red before it and green after, against the reproduction from AC-1.
AC-4 — if AC-1 cannot be reproduced on the consumer where it was originally measured, this ticket closes as not-reproducible with that measurement recorded, and #18160 stays as shipped.
Retired ACs, and why — the original AC-1 through AC-6 asked for an arm proving pop-out survives a commit, plus a change-guard count and an opt-in check. AC-3 (writes only on change) and AC-4 (opt-in guard) are satisfied on dev today and are recorded above so nobody rebuilds them. The rest were written against the falsified mechanism.
Out of Scope
#18153's vessel gap — pop-out opening nothing is a different defect on the same action, already owned.
Reverting #18160. Its sync is correct code and harmless; it is simply not evidence for this ticket.
Making pop-out available where it is genuinely unavailable.
Avoided Traps
Writing the arm before the reproduction. Directly demonstrated by PR #18267: an arm can be red under three independent mutations and still witness the opposite of the reported transition, because the mutations only probe the scenario the arm itself constructed.
Asserting the config rather than the rendered action — still true, still a trap.
Treating #18160's merge as this ticket's resolution. The code shipped; the symptom was never tied to it.
Retrieval Hint: pop-out action disappears from the dock header after a commit — symptom measured on a consumer, mechanism NOT identified, sweep-staleness hypothesis falsified in the unit tier
Context
Measured by @neo-opus-vega on a downstream consumer (2026-09-03) while chasing the operator's report that pop-out is broken there. He is on the client app per operator direction; this is the engine half.
Live latest-open sweep: checked the latest 10 open issues at 2026-09-03T06:45Z; no equivalent. #18153 covers pop-out opening nothing (the inert vessel) — a different defect on the same action. #18039 is the same class for
reloadand is closed.The Problem
The reported symptom, measured on a real consumer, same app, same session:
This is the whole of what is established. The transition is
visible → goneon a downstream consumer. Nothing below this line should be read as explaining it.Measured vs Asserted
This ticket originally asserted a mechanism: pop-out's
hiddenis computed once at projection and lives on a retained instance that no sweep repairs, so it goes stale.syncDockPopOutActionwas prescribed and shipped in #18160.That mechanism does not reproduce in the unit tier. Measured 2026-09-04 with a workspace built the way a shipping writer builds one —
tearOutHandlersinstalled inconstruct()beforeprojectDockModel(), so pop-out projects visible:Deleting
syncDockPopOutActionfrom the sweep entirely changes nothing. The retained instance keepshidden=false; nothing drives it totrue. So in this shape the sync is not what stands between the user and the symptom, and the asserted staleness never occurs.Falsified by @neo-gpt-emmy on PR #18267 and re-derived independently before conceding. #18160's sync is correct and well-formed code for a mechanism that has not been shown to be the operative one. It is not a defect and is not being reverted; it simply is not evidence that this ticket is resolved.
Also corrected: the original body prescribed
getActionItem('popOut'). The registered action name is'pop-out'(LayoutAdapter:1183);popOutis the tooltip key (:1186). #18160 used the correct one. Had anyone implemented the spelling this ticket specified, the lookup returnsundefinedandaction && (…)swallows it silently — a guard that never fires.The Architectural Reality
Workspace#syncDockHeaderActions()sweeps retained chrome and now re-evaluates five actions including pop-out (Workspace.mjs:2124, shipped in #18160).syncDockPopOutAction(:1773) computeshidden = !itemId || !this.dockPopOutActionActiveand assigns it. The assignment is change-guarded by construction:Neo.mjs:463gatesafterSetbehindconfig.set(value), so an unchanged reactive-config write fires nothing. This is #18245's idiom.dockPopOutActionActive(:1687) =enableDockPopOutAction === true && !!tearOutHandlers && (!enableDockTearOutLifecycle || canOpenTearOutVessel).What is NOT known: which of those inputs changed on the live consumer, or whether the disappearance happened on the retained instance at all rather than on a re-projected node. The consumer's topology (a Workstation host, a rail, a focused node) is richer than any unit fixture built so far, and the symptom has never been reproduced outside it.
The Fix
Unknown — and that is the current state of this ticket, not a placeholder.
The next step is a reproduction, not an implementation. Until the
visible → gonesequence reproduces somewhere a test can watch it, any arm written here certifies a mechanism nobody has witnessed. PR #18267 is the worked example of that failure: it went red under three mutations and still tested the wrong direction.Whoever picks this up should first answer: on the consumer where it was measured, does it still reproduce? If it does not, closing this as not-reproducible is the honest end state.
Acceptance Criteria
itemId,enableDockPopOutAction,tearOutHandlers,enableDockTearOutLifecycle,canOpenTearOutVessel, or a re-projection that replaced the instance. One of them, identified from the reproduction rather than inferred.Retired ACs, and why — the original AC-1 through AC-6 asked for an arm proving pop-out survives a commit, plus a change-guard count and an opt-in check. AC-3 (writes only on change) and AC-4 (opt-in guard) are satisfied on
devtoday and are recorded above so nobody rebuilds them. The rest were written against the falsified mechanism.Out of Scope
Avoided Traps
Related
reload, closed.syncDockPopOutAction; correct code, unproven relevance here.Origin Session ID: 7596538d-5324-419a-b043-95c585d833ea
Retrieval Hint:
pop-out action disappears from the dock header after a commit — symptom measured on a consumer, mechanism NOT identified, sweep-staleness hypothesis falsified in the unit tier