Context
The operator's 2026-08-02 flagship-film brief (90–150s, heavy drag-and-drop) names perspectives as a film beat. Fable's lane map on #15252 (issuecomment-5153855472) scoped L2 = "perspectives wiring — NL tools exist, workstation wiring unverified" and invited self-selection; @neo-kimi-phoebe claimed L2+L3 at 2026-08-01T23:15:25Z (A2A MESSAGE:c278901d-fdf1-4524-b275-c6ddfff83f24). Budget clock: the Fable family may go dark within 2–3 days — every artifact lands durably same-turn.
The Problem
The agent-driven perspective path — an agent or the film's screenplay-automation driving save → list → restore of named layouts through the Neural Link tools — had never been verified end-to-end against the workstation demo app, and has no spec witness.
What exists today (verified this session, 2026-08-01/02):
DockPerspectiveStore instantiated at apps/agentos/childapps/dockdemo/view/DemoBWorkspace.mjs:461; switcher bar born from store lifecycle events (DemoBWorkspace.mjs:618-631, createSwitcherBar at :1155); switcher buttons restore on click via loadPerspectiveByName (:4396)
- App-vocabulary restore surface:
loadPerspectiveByName(name) at DemoBWorkspace.mjs:1223, tour cue perspective-load at :1414 beside perspective-save at :1413
capturePerspective(name, {scope}) at DemoBWorkspace.mjs:1124; Mission Control captures via dockService.capturePerspective (MissionControlWorkspace.mjs:336)
- Tour script
apps/agentos/tour/demoBPerspectives.mjs + spec test/playwright/e2e/agentos/DemoBPerspectivesNL.spec.mjs proving capture + topology reconcile on Demo B — driven through the app's own tour/store path, never the NL tools
- NL tools
capture_perspective / restore_perspective / list_perspectives shipped via #14649 (closed); the showcase #14590 (closed) delivered named-layout morphing
What was missing (corrected 2026-08-02 — see correction comment; an earlier draft of this section wrongly asserted zero restore call sites based on an NL-vocabulary grep):
app-surface restore/list — dissolved by evidence: the surface exists in store vocabulary (method + cue + switcher)
- No spec witness drives the NL
capture_perspective / list_perspectives / restore_perspective tools against the live workstation app (the residual, and this ticket's deliverable)
- The NL chain itself had never been run live — discharged 2026-08-01 (AC1 receipt below)
The Architectural Reality
- Normative authority: ADR 0029 §2.2 — capture scope (
DockZoneModel.CAPTURE_SCOPES = ['window', 'topology']), cross-topology restore via DockTopologyReconciler.reconcile(), fail-closed structured results, revision-migration-honest loadPerspective
- Store:
src/dashboard/DockPerspectiveStore.mjs — atomic CRUD over dockLayoutCollection.v1, collision verdicts, lifecycle events feeding UI
- NL tools per
#14649: capture/restore write-locked, list read-tier
- Contract doc:
learn/agentos/HarnessDockZoneModel.md (serializable vs runtime state)
The Fix
Verify the live chain — DONE 2026-08-01 (headed+GPU receipt in comments: capture → list → restore + fail-closed all pass against the workstation dockdemo).
Close the app-surface gap — dissolved by evidence (2026-08-02 correction): perspective-load cue + loadPerspectiveByName + switcher restore already exist.
- Spec beat (the deliverable): a deterministic whitebox-e2e witness (sibling pattern:
DemoBPerspectivesNL.spec.mjs) that drives the NL tools — capture → mutate via execute_dock_operation → restore → list_perspectives — and asserts worker truth (restored dockZone.v1 document equality + fail-closed structured error on unknown names). Spec = authority, film = derivative.
- Handoff: filmable, deterministic cue sequence posted as a comment on #15252 same-turn — nothing strandable in Fable context.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
NL restore_perspective |
#14649 + ADR 0029 §2.2 |
Verified live against dockdemo; fail-closed structured result asserted in spec |
n/a (exists) |
tool schema |
headed receipt + spec |
NL list_perspectives |
#14649 |
Verified live; spec asserts store-backed listing |
n/a (exists) |
tool schema |
spec |
DemoBWorkspace tour cues (perspective-save / perspective-load) |
DemoBWorkspace.mjs:1413-1414 |
Unchanged (existing surface) |
n/a |
tour script |
existing spec |
| Perspective switcher bar |
DemoBWorkspace.mjs:1155, :4396 |
Unchanged (existing surface) |
n/a |
— |
existing spec |
Decision Record impact
aligned-with ADR 0029 — §2.2 perspectives contract is exercised, never amended.
Acceptance Criteria
Out of Scope
- New perspective features in framework core (DockZoneModel / Reconciler changes) — the ADR 0029 surface is exercised, not extended
- QT-parity polish (parent epic
#13158, Clio — coordinate before any shared-surface edit)
- Mission Control restore parity unless the film beat requires it (intake verifies)
- L3 undo/redo wiring (sibling ticket
#16316)
Avoided Traps
- Re-building the showcase:
#14590 already delivered morphing; this ticket verifies + witnesses the agent-driven path rather than re-authoring Demo B
- Headless "green" receipts: headless canvas is blank — only headed+GPU runs count (operator contract)
- NL-vocabulary grep as absence-proof:
restorePerspective/listPerspectives zero-hits measured the wrong vocabulary; the app rides store vocabulary (loadPerspectiveByName, perspective-load)
Related
- Parent epic: #15252 (this is the L2 leaf)
- Closed precedents:
#14590 (showcase), #14649 (NL tools)
- Overlap gate:
#13158 (Clio's QT-parity epic — coordinate, don't collide)
- Lane map: #15252 issuecomment-5153855472; claim: A2A 2026-08-01T23:15:25Z
Live latest-open sweep: checked latest 20 open issues at 2026-08-01T23:24Z; no equivalent found. A2A in-flight sweep (60 min): no competing claim on this scope (Iris claimed L1 #16309 at 23:21Z — disjoint). KB semantic sweep surfaced closed precedents #14590 / #14649 only.
Origin Session ID: 14f1d6fa-235a-4101-88d4-c9490e3f7fd5
Retrieval Hint: "flagship film perspectives NL restore list dockdemo witness"
Context
The operator's 2026-08-02 flagship-film brief (90–150s, heavy drag-and-drop) names perspectives as a film beat. Fable's lane map on #15252 (issuecomment-5153855472) scoped L2 = "perspectives wiring — NL tools exist, workstation wiring unverified" and invited self-selection; @neo-kimi-phoebe claimed L2+L3 at 2026-08-01T23:15:25Z (A2A
MESSAGE:c278901d-fdf1-4524-b275-c6ddfff83f24). Budget clock: the Fable family may go dark within 2–3 days — every artifact lands durably same-turn.The Problem
The agent-driven perspective path — an agent or the film's screenplay-automation driving save → list → restore of named layouts through the Neural Link tools — had never been verified end-to-end against the workstation demo app, and has no spec witness.
What exists today (verified this session, 2026-08-01/02):
DockPerspectiveStoreinstantiated atapps/agentos/childapps/dockdemo/view/DemoBWorkspace.mjs:461; switcher bar born from store lifecycle events (DemoBWorkspace.mjs:618-631,createSwitcherBarat :1155); switcher buttons restore on click vialoadPerspectiveByName(:4396)loadPerspectiveByName(name)atDemoBWorkspace.mjs:1223, tour cueperspective-loadat:1414besideperspective-saveat:1413capturePerspective(name, {scope})atDemoBWorkspace.mjs:1124; Mission Control captures viadockService.capturePerspective(MissionControlWorkspace.mjs:336)apps/agentos/tour/demoBPerspectives.mjs+ spectest/playwright/e2e/agentos/DemoBPerspectivesNL.spec.mjsproving capture + topology reconcile on Demo B — driven through the app's own tour/store path, never the NL toolscapture_perspective/restore_perspective/list_perspectivesshipped via#14649(closed); the showcase#14590(closed) delivered named-layout morphingWhat was missing (corrected 2026-08-02 — see correction comment; an earlier draft of this section wrongly asserted zero restore call sites based on an NL-vocabulary grep):
app-surface restore/list— dissolved by evidence: the surface exists in store vocabulary (method + cue + switcher)capture_perspective/list_perspectives/restore_perspectivetools against the live workstation app (the residual, and this ticket's deliverable)The Architectural Reality
DockZoneModel.CAPTURE_SCOPES = ['window', 'topology']), cross-topology restore viaDockTopologyReconciler.reconcile(), fail-closed structured results, revision-migration-honestloadPerspectivesrc/dashboard/DockPerspectiveStore.mjs— atomic CRUD overdockLayoutCollection.v1, collision verdicts, lifecycle events feeding UI#14649: capture/restore write-locked, list read-tierlearn/agentos/HarnessDockZoneModel.md(serializable vs runtime state)The Fix
Verify the live chain— DONE 2026-08-01 (headed+GPU receipt in comments: capture → list → restore + fail-closed all pass against the workstation dockdemo).Close the app-surface gap— dissolved by evidence (2026-08-02 correction):perspective-loadcue +loadPerspectiveByName+ switcher restore already exist.DemoBPerspectivesNL.spec.mjs) that drives the NL tools — capture → mutate viaexecute_dock_operation→ restore →list_perspectives— and asserts worker truth (restored dockZone.v1 document equality + fail-closed structured error on unknown names). Spec = authority, film = derivative.Contract Ledger Matrix
restore_perspective#14649+ ADR 0029 §2.2list_perspectives#14649DemoBWorkspacetour cues (perspective-save/perspective-load)DemoBWorkspace.mjs:1413-1414DemoBWorkspace.mjs:1155,:4396Decision Record impact
aligned-with ADR 0029— §2.2 perspectives contract is exercised, never amended.Acceptance Criteria
App-surface gap closed— dissolved by evidence (correction comment issuecomment-5154088209): restore/list reachable from the demo surface (tour cue + switcher)#15243→#15245gate)Out of Scope
#13158, Clio — coordinate before any shared-surface edit)#16316)Avoided Traps
#14590already delivered morphing; this ticket verifies + witnesses the agent-driven path rather than re-authoring Demo BrestorePerspective/listPerspectiveszero-hits measured the wrong vocabulary; the app rides store vocabulary (loadPerspectiveByName,perspective-load)Related
#14590(showcase),#14649(NL tools)#13158(Clio's QT-parity epic — coordinate, don't collide)Live latest-open sweep: checked latest 20 open issues at 2026-08-01T23:24Z; no equivalent found. A2A in-flight sweep (60 min): no competing claim on this scope (Iris claimed L1
#16309at 23:21Z — disjoint). KB semantic sweep surfaced closed precedents#14590/#14649only.Origin Session ID: 14f1d6fa-235a-4101-88d4-c9490e3f7fd5
Retrieval Hint: "flagship film perspectives NL restore list dockdemo witness"