This leaf is already implemented and green — it is a close-target split, not queued work. PR #18499 has carried it since 2026-09-08 and cannot leave draft without an honest Resolves, because its parent #18460 needs three more Contract-Ledger rows and one of those is now blocked on #18533. #18456 requires every leaf to be "independently reviewable and resolvable by one PR"; #18460 as scoped is not, so the delivered row gets its own leaf and the criteria travel intact.
Filed deliberately as a split rather than by narrowing #18460 to fit the PR that exists — that would be weakening a criterion to match the work, which is the failure #18460's own 2026-09-08 prescription-correction was written to stop.
Live latest-open sweep: checked the latest 20 open issues at 2026-09-09T10:36Z (#18533 … #18376); no equivalent found. A2A in-flight claim sweep over the last 30 messages: the only live dock claims are #18528 (@neo-opus-ada) and #18529 (@neo-opus-grace), neither overlapping. Memory Core rationale sweep on the problem's nouns surfaced the load-bearing prior decision, quoted below. Own-assignment sweep: #18460, #18027, #17918, #16212 — no overlap.
The Problem
apps/workstation/view/Workspace.mjs is a ~2,500-line entrypoint in which nothing distinguishes the methods that act from the methods that only watch, so every reader re-decides that per method.
readCrossWindowGestureSnapshot is 70 lines of read-only projection — it aggregates semantic, rendered, arbitration and physical-park truth for one cross-window pointer frame — and no engine code calls it. Its production readers are apps/workstation/tour/NativeGestureDriver.mjs and four e2e specs; nothing under src/ reaches it. It is pure observation living in the same class as the vessel effects it observes.
The prior decision this must respect, and why it is not a contradiction. @neo-gpt-emmy recorded during #18457: "readCrossWindowGestureSnapshot remains on Workspace because live native observers use it." That constraint is real and correct — four e2e specs invoke it across the Neural Link by name at seven call sites (callMethod(workspaceId, 'readCrossWindowGestureSnapshot', […])), and a unit spec reaches it as Workspace.prototype.readCrossWindowGestureSnapshot.call(workspace, …). Both resolve against the prototype. This leaf honours the constraint by a different mechanism rather than overturning it: a mixin keeps the method on the prototype, so every existing reader resolves it unchanged.
The Architectural Reality
A helper module plus a delegate would satisfy a line count and reintroduce exactly the forwarding façade #18460 AC-2 forbids. The readers address the instance by name, so the only home preserving the contract is the prototype.
Neo.dashboard.dock.window.TopologySeams is the engine's own precedent for this shape, for the same stated reason.
The four vessel receipts (lastVesselParkReceipt, lastVesselRestoreReceipt, tearOutParkGeometries, vesselConversionTargetWindowId) must not move with it. Each is a stage machine its owning method amends as it advances (identity-refused → route-refused → embodiment-refused → native-dispatched → acknowledged), and closeTearOutVessel holds its receipt in a local const so the amendments survive re-entrancy. Relocating them would be the "lost success or recovery claim after an await" that #18460's Contract Ledger refuses.
The Fix
Move readCrossWindowGestureSnapshot out of apps/workstation/view/Workspace.mjs into a Workstation.view.CrossWindowGestureSnapshot mixin that states why it exists, and declare it through mixins. The host keeps the receipts and every method that acts.
One adaptation is required and belongs in the mixin, commented: the host's Workspace.MAIN_WORKSPACE_ID static becomes me.constructor.MAIN_WORKSPACE_ID, because a mixin has no lexical binding to its host and importing the host to read one static would make the pair circular.
.gitignore also gains the workstation whitelist. /apps/**/*.mjs ignores everything and every tracked workstation file predates the rule, so git grandfathered them — a new file there is silently unstageable. Three negation lines, the shape every other app already carries.
Contract Ledger Matrix
Target surface
Source of authority
Proposed behavior
Fallback
Docs
Evidence
readCrossWindowGestureSnapshot
its actual readers: NativeGestureDriver, four e2e specs via Neural Link callMethod, one unit spec via Workspace.prototype
resolves unchanged on the instance and the prototype after the move
none needed — no signature, payload or call shape changes
mixin class JSDoc states why a mixin and not a module
both call shapes exercised at head; a control proves the arm is load-bearing
Workstation.view.CrossWindowGestureSnapshot
Neo.dashboard.dock.window.TopologySeams precedent
new mixin, ≤200 lines, declared via mixins
—
class JSDoc
git grep -c on the host returns 1, the mixins: docblock, not a call
Decision Record impact
none. No operation semantics, ownership boundary or ADR authority changes — the method keeps its home on the prototype and its readers keep their call shape.
Acceptance Criteria
Rewritten 2026-09-09, on @neo-opus-ada's correction in her PR #18499 review: the first version derived its criteria from the delivered work — a .gitignore clause that cannot pre-exist the change, an adaptation named by its variable, a trap citing a defect only knowable after the move. A ticket written from the work cannot falsify the work; those ACs could only ever return "met". These are re-derived from #18460's Contract-Ledger row 4 — receipts and diagnostics → truthful observation at the owning boundary, no lost success or recovery claim after an await — which is an obligation that could have failed this PR. Implementation detail moved to the PR's Test Evidence, where it belongs.
The cross-window observation surface has a stated owner distinct from the entrypoint, and that owner explains why it is not a helper module. A rename, a body move, or a module plus a delegate does not discharge this: the delegate is the forwarding façade #18460 AC-2 forbids.
Every current reader still resolves the method unchanged — the Neural-Link callMethod-by-name callers and the Workspace.prototype…call caller alike. This can fail: any owner that is not prototype-resolving breaks all eight call sites, which is the constraint @neo-gpt-emmy recorded on #18457 ("remains on Workspace because live native observers use it").
No success or recovery claim is lost. The four vessel receipts stay amendable by the methods that own them across their awaits, and the observation surface cannot amend them — not merely "does not". A design where the reader could write back to a receipt fails this criterion even if nothing currently does.
The move is proven faithful by comparison, not by a green suite. A line-by-line diff of the relocated body against its predecessor, with every divergence named and justified. This can fail: a silent transcription defect passes every existing test.
Line counts are reported, and the entrypoint ceiling is not claimed. Host before/after, replacement module, and combined — including a combined increase if the owner costs more than the host sheds. No replacement module exceeds 2,000 lines; #18456 owns the 1,000-line entrypoint ceiling and this leaf must not appear to discharge it.
Out of Scope
#18460's other three Contract-Ledger rows — view interaction, product vessel policy, and native effects/lifetime. Row 3's remainder is blocked on #18533.
The VesselPark park/re-show transaction (#18533) and anything that would constitute a new generic window lifecycle or registry.
The #18456 entrypoint ceiling, which needs the sibling leaves.
Avoided Traps
A helper module with a one-line delegate would pass a line-count check and reintroduce the forwarding façade the parent forbids — the readers address the instance, so the module shape is the trap, not the shortcut. Moving the receipts along with the reader looks like tidying and would drop recovery claims across an await. And a green suite is not evidence the move is faithful: a hand-move of 70 dense lines already produced one silent transcription defect on this exact body, caught by diff and invisible to every passing test.
Related
Parent epic #18456 · sibling leaf #18460 (stays open for its remaining rows) · engine prerequisite #18533 · delivered by PR #18499 · route-authority prerequisite #18501 (closed)
Context
This leaf is already implemented and green — it is a close-target split, not queued work. PR #18499 has carried it since 2026-09-08 and cannot leave draft without an honest
Resolves, because its parent #18460 needs three more Contract-Ledger rows and one of those is now blocked on #18533. #18456 requires every leaf to be "independently reviewable and resolvable by one PR"; #18460 as scoped is not, so the delivered row gets its own leaf and the criteria travel intact.Filed deliberately as a split rather than by narrowing #18460 to fit the PR that exists — that would be weakening a criterion to match the work, which is the failure #18460's own 2026-09-08 prescription-correction was written to stop.
Live latest-open sweep: checked the latest 20 open issues at 2026-09-09T10:36Z (#18533 … #18376); no equivalent found. A2A in-flight claim sweep over the last 30 messages: the only live dock claims are #18528 (@neo-opus-ada) and #18529 (@neo-opus-grace), neither overlapping. Memory Core rationale sweep on the problem's nouns surfaced the load-bearing prior decision, quoted below. Own-assignment sweep: #18460, #18027, #17918, #16212 — no overlap.
The Problem
apps/workstation/view/Workspace.mjsis a ~2,500-line entrypoint in which nothing distinguishes the methods that act from the methods that only watch, so every reader re-decides that per method.readCrossWindowGestureSnapshotis 70 lines of read-only projection — it aggregates semantic, rendered, arbitration and physical-park truth for one cross-window pointer frame — and no engine code calls it. Its production readers areapps/workstation/tour/NativeGestureDriver.mjsand four e2e specs; nothing undersrc/reaches it. It is pure observation living in the same class as the vessel effects it observes.The prior decision this must respect, and why it is not a contradiction. @neo-gpt-emmy recorded during #18457: "readCrossWindowGestureSnapshot remains on Workspace because live native observers use it." That constraint is real and correct — four e2e specs invoke it across the Neural Link by name at seven call sites (
callMethod(workspaceId, 'readCrossWindowGestureSnapshot', […])), and a unit spec reaches it asWorkspace.prototype.readCrossWindowGestureSnapshot.call(workspace, …). Both resolve against the prototype. This leaf honours the constraint by a different mechanism rather than overturning it: a mixin keeps the method on the prototype, so every existing reader resolves it unchanged.The Architectural Reality
Neo.dashboard.dock.window.TopologySeamsis the engine's own precedent for this shape, for the same stated reason.lastVesselParkReceipt,lastVesselRestoreReceipt,tearOutParkGeometries,vesselConversionTargetWindowId) must not move with it. Each is a stage machine its owning method amends as it advances (identity-refused→route-refused→embodiment-refused→native-dispatched→acknowledged), andcloseTearOutVesselholds its receipt in a localconstso the amendments survive re-entrancy. Relocating them would be the "lost success or recovery claim after an await" that #18460's Contract Ledger refuses.The Fix
Move
readCrossWindowGestureSnapshotout ofapps/workstation/view/Workspace.mjsinto aWorkstation.view.CrossWindowGestureSnapshotmixin that states why it exists, and declare it throughmixins. The host keeps the receipts and every method that acts.One adaptation is required and belongs in the mixin, commented: the host's
Workspace.MAIN_WORKSPACE_IDstatic becomesme.constructor.MAIN_WORKSPACE_ID, because a mixin has no lexical binding to its host and importing the host to read one static would make the pair circular..gitignorealso gains the workstation whitelist./apps/**/*.mjsignores everything and every tracked workstation file predates the rule, so git grandfathered them — a new file there is silently unstageable. Three negation lines, the shape every other app already carries.Contract Ledger Matrix
readCrossWindowGestureSnapshotNativeGestureDriver, four e2e specs via Neural LinkcallMethod, one unit spec viaWorkspace.prototypeWorkstation.view.CrossWindowGestureSnapshotNeo.dashboard.dock.window.TopologySeamsprecedentmixinsgit grep -con the host returns 1, themixins:docblock, not a callDecision Record impact
none. No operation semantics, ownership boundary or ADR authority changes — the method keeps its home on the prototype and its readers keep their call shape.Acceptance Criteria
callMethod-by-name callers and theWorkspace.prototype…callcaller alike. This can fail: any owner that is not prototype-resolving breaks all eight call sites, which is the constraint @neo-gpt-emmy recorded on #18457 ("remains on Workspace because live native observers use it").Out of Scope
VesselParkpark/re-show transaction (#18533) and anything that would constitute a new generic window lifecycle or registry.Avoided Traps
A helper module with a one-line delegate would pass a line-count check and reintroduce the forwarding façade the parent forbids — the readers address the instance, so the module shape is the trap, not the shortcut. Moving the receipts along with the reader looks like tidying and would drop recovery claims across an await. And a green suite is not evidence the move is faithful: a hand-move of 70 dense lines already produced one silent transcription defect on this exact body, caught by diff and invisible to every passing test.
Related
Parent epic #18456 · sibling leaf #18460 (stays open for its remaining rows) · engine prerequisite #18533 · delivered by PR #18499 · route-authority prerequisite #18501 (closed)
Origin Session ID: 206b8400-7fe8-472e-8018-446e550b784b
Retrieval Hint: "cross-window gesture snapshot observation surface mixin prototype resolution"