Context
Sub of #19126 (the visual-first opening; the operator's steer of 2026-09-23 13:5xZ: rails, pin/unpin and the drop-zone motion are part of the attraction, and they need scene-owned interactions, not narration). The film's cue vocabulary has no rail cue; the dense control already proves the interaction with a human's clicks (WorkstationNL.spec.mjs › the unpin action, the rail tab, the reveal overlay, its Pin).
The Problem
The Workstation film cannot show its rails. Nothing in apps/workstation/tour/ drives the header's unpin action, a rail tab or the reveal's pin, so the take could only narrate a rail — an edit trick the steer rules out.
The Architectural Reality
src/dashboard/dock/interaction/Rail.mjs renders a rail tab per auto-hidden item as a real button whose handler is onTabClick (:427, :777), which hands the item to RevealStateMachine#tabClick (:785); the reveal's pin is RevealOverlay's toolbar action (neo-dashboard-dock-reveal-pin, aria-label Pin, :189–195) routed through revealPinRequested → the rail's onRevealPinRequested (Rail.mjs:350).
- The pane's header projects the engine's
pin action (enableDockPinAction, default on; aria-label unpin while the item is pinned), focus-gated like the other five, through tab.Container#headerActions (src/tab/Container.mjs:327); the dock Workspace routes the intent and commits setItemAutoHidden. A focus-gated action is mounted only while its subject holds real focus (toolbar.Base follows the subject's containsFocus, kept by manager.Focus) — a synthetic mouse event moves no focus.
apps/workstation/tour/GestureDriver.mjs owns in-window scripted input: runGesture (dispatched input settles before cleanup releases it), simulateEvent (real synthetic mouse events through InteractionService), the film cursor dot, waitFor/trap. executeCrossZoneShowcaseStep is the sibling to mirror; TourController#executeCue dispatches cues (apps/workstation/view/TourController.mjs:287), and the unit spec pins the vocabulary list exactly.
The Fix
A rail cue and GestureDriver#executeRailStep({itemId, sourceNodeId}, options): click the pane's tab and take real focus by name, walk the cursor to the header's unpin action and click it, wait for the committed document (items[itemId].autoHidden === true) and the rail tab, walk to the rail tab and click, wait for the reveal overlay to be visible with the item, walk to the reveal's pin and click, wait for autoHidden === false and the pane back in its home node. Receipts {collapsed, revealed, restored, edge} plus documentBefore/documentAfter with documentsUnchanged reported. Cancellation and destruction release input through the existing runGesture cleanup; a missing action, rail tab or overlay fails with a named error and no residue. The film gains a film-rails scene at the position #19126 names, with filmPace options and the cursor dot; the unit vocabulary arm and the budget pin move in the same change.
Acceptance Criteria
Out of Scope
- The
native-return cue (#19126's other executor, @neo-gpt-emmy's seam); the opening's reorder and re-pace (#19126); the take (#15252).
Related
#19126 · #15252 · #18028 / PR #18038 (the reveal's containment) · #18118 / #18120 (the reveal's motion) · #17952 (collapse to the rail from the header)
Sweeps: live latest-20 open at 2026-09-23T14:05:46Z — none equivalent (#19126 is the parent); A2A — no claim on the rail cue; own open assignments (#19126, #19101, #15252) — parents only.
Origin Session ID: 522f6841-f568-4800-bff8-7ee8e1f99dd3
Retrieval Hint: query_raw_memories("film rail cue executeRailStep unpin rail tab reveal pin back real pointer input")
🪢 Mnemosyne (Claude Fable 5.1 · Claude Code) · session 522f6841-f568-4800-bff8-7ee8e1f99dd3
Context
Sub of #19126 (the visual-first opening; the operator's steer of 2026-09-23 13:5xZ: rails, pin/unpin and the drop-zone motion are part of the attraction, and they need scene-owned interactions, not narration). The film's cue vocabulary has no rail cue; the dense control already proves the interaction with a human's clicks (
WorkstationNL.spec.mjs› the unpin action, the rail tab, the reveal overlay, itsPin).The Problem
The Workstation film cannot show its rails. Nothing in
apps/workstation/tour/drives the header'sunpinaction, a rail tab or the reveal's pin, so the take could only narrate a rail — an edit trick the steer rules out.The Architectural Reality
src/dashboard/dock/interaction/Rail.mjsrenders a rail tab per auto-hidden item as a real button whosehandlerisonTabClick(:427,:777), which hands the item toRevealStateMachine#tabClick(:785); the reveal's pin isRevealOverlay's toolbar action (neo-dashboard-dock-reveal-pin,aria-labelPin,:189–195) routed throughrevealPinRequested→ the rail'sonRevealPinRequested(Rail.mjs:350).pinaction (enableDockPinAction, default on;aria-labelunpinwhile the item is pinned), focus-gated like the other five, throughtab.Container#headerActions(src/tab/Container.mjs:327); the dock Workspace routes the intent and commitssetItemAutoHidden. A focus-gated action is mounted only while its subject holds real focus (toolbar.Basefollows the subject'scontainsFocus, kept bymanager.Focus) — a synthetic mouse event moves no focus.apps/workstation/tour/GestureDriver.mjsowns in-window scripted input:runGesture(dispatched input settles before cleanup releases it),simulateEvent(real synthetic mouse events throughInteractionService), the film cursor dot,waitFor/trap.executeCrossZoneShowcaseStepis the sibling to mirror;TourController#executeCuedispatches cues (apps/workstation/view/TourController.mjs:287), and the unit spec pins the vocabulary list exactly.The Fix
A
railcue andGestureDriver#executeRailStep({itemId, sourceNodeId}, options): click the pane's tab and take real focus by name, walk the cursor to the header'sunpinaction and click it, wait for the committed document (items[itemId].autoHidden === true) and the rail tab, walk to the rail tab and click, wait for the reveal overlay to be visible with the item, walk to the reveal's pin and click, wait forautoHidden === falseand the pane back in its home node. Receipts{collapsed, revealed, restored, edge}plusdocumentBefore/documentAfterwithdocumentsUnchangedreported. Cancellation and destruction release input through the existingrunGesturecleanup; a missing action, rail tab or overlay fails with a named error and no residue. The film gains afilm-railsscene at the position #19126 names, withfilmPaceoptions and the cursor dot; the unit vocabulary arm and the budget pin move in the same change.Acceptance Criteria
railis a handled cue;executeRailStepperforms unpin → reveal → pin back through real pointer input and returns the three phase receipts with the pane home in its own node afterwards. Restated 2026-09-23 from "the document round-tripped byte-identical": byte-identity is reported in the receipt (documentsUnchanged), not required — the pin back may leavepinnedor the active item different from the moment before the fold.film-railsscene (budget ≤ 8 s, pauses only to read the reveal), and the headless replay (WorkstationFilmTourNL.spec.mjs -g 'under autoGates') asserts the rail receipts at the PR head on the seat's own bridge.Out of Scope
native-returncue (#19126's other executor, @neo-gpt-emmy's seam); the opening's reorder and re-pace (#19126); the take (#15252).Related
#19126 · #15252 · #18028 / PR #18038 (the reveal's containment) · #18118 / #18120 (the reveal's motion) · #17952 (collapse to the rail from the header)
Sweeps: live latest-20 open at 2026-09-23T14:05:46Z — none equivalent (#19126 is the parent); A2A — no claim on the rail cue; own open assignments (#19126, #19101, #15252) — parents only.
Origin Session ID: 522f6841-f568-4800-bff8-7ee8e1f99dd3 Retrieval Hint:
query_raw_memories("film rail cue executeRailStep unpin rail tab reveal pin back real pointer input")🪢 Mnemosyne (Claude Fable 5.1 · Claude Code) · session 522f6841-f568-4800-bff8-7ee8e1f99dd3