LearnNewsExamplesServices
Frontmatter
id18388
titleKeep vessel conversion policy overridable through Neo
stateClosed
labels
bugaitestingarchitecturedashboard
assigneesneo-gpt
createdAtSep 6, 2026, 8:24 PM
updatedAtSep 6, 2026, 9:06 PM
githubUrlhttps://github.com/neomjs/neo/issues/18388
authorneo-gpt
commentsCount0
parentIssue18304
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtSep 6, 2026, 9:06 PM

Keep vessel conversion policy overridable through Neo

Closed v13.2.0/archive-v13-2-0-chunk-19 bugaitestingarchitecturedashboard
neo-gpt
neo-gpt commented on Sep 6, 2026, 8:24 PM

Context

The dashboard extensibility audit found that window/VesselConversion.mjs exports a closure factory without a Neo namespace identity. Explicit factory thresholds work, but Neo.overwrites does not reach it. At dev@3a0773c9, the only production consumer is interaction/TabSortZone.mjs.

The Problem

Applications can change the exposed thresholds and composition callback, but cannot specialize the sensor's geometry or transition decisions through ordinary Neo methods without replacing/wrapping its closure. This is an unfinished extensibility outcome of #18304. The existing conversion grammar and strict asynchronous admission are valuable and must be retained.

The Architectural Reality

Neo.setupClass and Base.applyOverwrites provide registered identity, method/default overrides and lifecycle. IdGenerator shows that lightweight exceptions still register through gatekeep; transient state does not imply exemption from namespace ownership. The peer assessment requires specializing a decision without copying its lifecycle.

The Fix

Replace the factory in its existing file with a registered Neo.core.Base sensor class. Keep thresholds and required admission callbacks configurable, move policy helpers to overridable methods, and retain per-instance conversion/transition state. TabSortZone creates and destroys its sensor through the existing class lifecycle. Remove the retired factory export and migrate its existing unit suite.

Target surface Source of authority Proposed behavior Fallback Docs Evidence
conversion policy Base method/overwrite contract one registered class; internal dispatch reaches overrides default grammar unchanged class/config/method JSDoc overwrite and subclass controls
transition state current sensor generation fence reset and destroy invalidate late admission explicit false retains current state reset/destroy contract held-promise controls
source ownership TabSortZone sensor lifetime creator destroys its sensor no leaked registration consumer method docs owner teardown control

Decision Record impact

Aligned with ADR 0029: conversion remains transient policy over the existing outcome machine. No new outcome state, wire schema or persistence behavior.

Decision Record

No new ADR. This implements the existing decomposition/extension outcome.

Discussion Criteria Mapping

D#18150's ownership questions 2–3: a stateful extracted owner has a bounded lifecycle and a replaceable decision surface. D#17818's selected namespace mirrors the module path.

Acceptance Criteria

  • The sensor is registered at Neo.dashboard.dock.window.VesselConversion; Neo method/default overwrites and subclass specialization affect the executed sensor policy.
  • Existing threshold, geometry, pointer-exit, hysteresis and strict synchronous/asynchronous admission controls pass unchanged in meaning.
  • Reset and destroy invalidate pending transitions; late completion cannot restore conversion or mutate a destroyed sensor.
  • TabSortZone owns construction and teardown; the retired factory has no production or test callers, and invalid construction does not leak a registered instance.
  • The focused source/sensor suites and appropriate repository checks pass; JSDoc describes the extension points.

Out of Scope

PreviewContract (Emmy's independent lane), Workspace decomposition, native popup adoption, dropped indicators, new lint rules, and conversion metric/threshold tuning. This is one bounded PR; no changes to merged #18383.

Avoided Traps

Registering a wrapper around closed lexical helpers would retain the defect. Converting all eight census candidates would mix unrelated concerns. Preserving the factory alias would retain a competing extension surface.

Related

Part of #18304. Prior context: #18064 and PR #18061; this ticket does not implement their guideline/lint work.

Creation freshness: latest 20 open issues and recent all-state A2A checked immediately before creation; no matching sensor implementation leaf. Own-assignment sweep found no overlapping leaf. MC query VesselConversion sensor policy cannot be overwritten returned three unrelated results; current source and the published audit carry the rationale.

Origin Session ID: 01a07609-5e09-70f0-bf2c-a27d77d1b7f2 Retrieval Hint: VesselConversion Neo.overwrites sensor lifecycle policy 18304