LearnNewsExamplesServices
Frontmatter
id18450
titleMake the dock WorkspaceSet adapter overridable through Neo
stateClosed
labels
enhancementairefactoringcoredashboard
assigneesneo-gpt-emmy
createdAtSep 8, 2026, 7:30 AM
updatedAtSep 8, 2026, 8:19 AM
githubUrlhttps://github.com/neomjs/neo/issues/18450
authorneo-gpt-emmy
commentsCount0
parentIssue18304
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtSep 8, 2026, 8:19 AM

Make the dock WorkspaceSet adapter overridable through Neo

Closed v13.2.0/archive-v13-2-0-chunk-19 enhancementairefactoringcoredashboard
neo-gpt-emmy
neo-gpt-emmy commented on Sep 8, 2026, 7:30 AM

Context

The remaining extension question on #18304 names WorkspaceSet as a bounded candidate. Its parent record already rejects a registered wrapper that copies factory descriptors after class setup: registration succeeds while the copied method shadows the configured override.

The Problem

At dev@5c75b2d666, src/dashboard/dock/window/WorkspaceSet.mjs still exports createDockWorkspaceSet, returning an object whose methods close over manager and Group resolvers. A direct probe against the identical source blob 47880b2eb98ae24eaeaefc63ce44ed1c917041a9 produced:

factory namespace: null; configured has override: not reached
registered Base control namespace: present; configured has override: reached

Workstation and Demo-B each construct this adapter. Popups borrow the root's adapter. A class conversion introduces a real instance lifetime: neither creating consumer currently destroys this plain object.

The Architectural Reality

Neo.setupClass applies overwrites to the prototype; core.Base.destroy unregisters the instance and clears its own fields. window/VesselPark.mjs is the neighbouring registered-owner precedent. Group participant membership belongs to manager.Transaction, not to this adapter. Registration callbacks may outlive the adapter that created them.

The Fix

Convert the existing module to Neo.dashboard.dock.window.WorkspaceSet extends Neo.core.Base, default-exported through Neo.setupClass. Put the actual operations on the prototype. Replace the factory imports and calls in both production constructors and existing tests. The creating consumers destroy their adapter; borrowed popup references do not.

Keep Group participant callbacks bound to their registration context so clearing adapter fields cannot break retained capture, preparation, adoption, compensation or projection. Preserve current membership, validation, queue-head reduction and write receipts.

Contract Ledger Matrix

Target surface Source of authority Proposed behavior Fallback Docs Evidence
Module construction WorkspaceSet.mjs#createDockWorkspaceSet; Neo.setupClass Default registered class, created through Neo with manager/getGroupId/documentModel No compatibility factory Class/config JSDoc Namespace plus effective overwrite/subclass dispatch
Existing methods and size Current WorkspaceSet implementation Same arguments/results; real prototype dispatch Existing unbound/refusal behavior Method JSDoc Existing membership, compensation and transaction suites
Adapter destruction core.Base.destroy; creator teardown in Workstation/Demo-B Release adapter instance only; creator owns teardown No implicit participant retirement Lifetime JSDoc Instance released; retained participants remain usable
Registered participant callbacks WorkspaceSet.register; Group participant lifetime Retain their registration dependencies independently of adapter fields Existing validation/refusal behavior Registration JSDoc Queued and later writes after adapter destruction, including projection

Decision Record impact

Aligned with ADR 0029 §2.1: windows remain render targets, membership remains worker-owned. No schema, Group or transaction protocol amendment. This is a leaf of the already-graduated ownership direction on #18304.

Acceptance Criteria

  • The default export registers the WorkspaceSet class, and an actual method override changes dispatch; no copied post-setup descriptor can shadow it.
  • Both production constructors use the registered class; the named factory export and its executable consumers are removed.
  • Workstation and Demo-B release the adapter they create; borrowed popup teardown does not destroy it.
  • Destroying an adapter does not unregister Group participants or break their already-registered capture/prepare/adopt/compensate/project callbacks, including queued work.
  • Existing membership, synchronous compensation, queued transaction, placement, participation and consumer tests remain green.
  • Modified APIs retain JSDoc summaries and the generated class hierarchy includes the new class.

Out of Scope

TearOut conversion, additional consumer decomposition, #18448's multi-step pin repair, changed transaction semantics, new persisted state, and guide authoring.

Avoided Traps

  • A namespace-only wrapper is a false green; the prototype must own the executed methods.
  • Destroying the adapter must not retire the Group or borrowed participants.
  • Do not bind retained callbacks to fields that Base destruction clears.
  • Do not preserve an unused factory for compatibility or introduce another manager.

Related

Parent: #18304. Registered-owner precedent: #18399. Adjacent active repair: #18448.

Live latest-open and all-state A2A sweeps ran immediately before creation; no equivalent or overlapping current claim. Own-assignment bodies #16498 and #17540 cover film acceptance and deferred guides, not this adapter. The final MC sweep recovered memory fdabb0ab-56ea-468c-94c4-66d037c4d94c: the same factory/overwrite counterexample, the descriptor-copy false green and the new Base lifetime obligation were already recorded on the parent. Earlier broader queries returned irrelevant initialization records. KB returned older docking vocabulary and was not treated as current implementation authority. Structure-map command is unavailable in this Engine checkout (silent exit 1); placement stays in the existing module.

Origin Session ID: 153d2e0a-ebae-4087-bcd5-3c92d213132c

Retrieval Hint: WorkspaceSet prototype override dispatch retained Group participant callbacks adapter destruction