LearnNewsExamplesServices
Frontmatter
id16786
titleFleetManager StateOptions: instance declaration, class-static write
stateClosed
labels
enhancementaiarchitectureagent-os
assigneesneo-kimi-phoebe
createdAtAug 9, 2026, 3:19 PM
updatedAtAug 9, 2026, 7:58 PM
githubUrlhttps://github.com/neomjs/neo/issues/16786
authorneo-kimi-phoebe
commentsCount2
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 9, 2026, 7:58 PM

FleetManager StateOptions: instance declaration, class-static write

Closed Backlog/active-chunk-14 enhancementaiarchitectureagent-os
neo-kimi-phoebe
neo-kimi-phoebe commented on Aug 9, 2026, 3:19 PM

Context

Filed from my PR #16781 review (pullrequestreview-4891455561) — publicly committed there as reviewer-seeded follow-up. The FleetManager telltale seams (wake / throttle / presence) are the SANCTIONED plain-field injection seams designed in #15271 / #15272 / #15273: devFleetServer assigns the options on the class (FleetManager.wakeStateOptions = …), and FleetControlBridge.getManager() falls back to the class-as-singleton. Every live path works today. This ticket is NOT an attack on the seam — it is a declaration/write semantics mismatch inside the sanctioned pattern.

The Problem

FleetManager.mjs declares the three options as INSTANCE fields — wakeStateOptions = null (:84), throttleStateOptions = null (:99), presenceStateOptions = null (:108), each with @member JSDoc — while the production writer assigns the CLASS property (devFleetServer.mjs:144 / :170 / :186). The declaration says instance; the write says static. They agree only because the class is never instantiated on any live path.

The trap: a future Neo.create(FleetManager) — a second consumer, a real-class test double — runs the field initializers, gets this.presenceStateOptions = null, and SHADOWS the class-static injection the writer placed. Presence/wake/throttle then silently degrade to honest-unknown with green-looking wiring. The failure is silent precisely because the adapters' honesty contract works: a degraded capability reads as "no producer wired", never as "shadowed injection" — the exact silent-permission failure shape reviewer-instrument-audit.md Shape 1 warns about.

Verified by source trace at 2e69b04240 / 170a635f57 during the #16781 review (observation, not a live failure — the trap is latent).

The Architectural Reality

  • ai/services/fleet/FleetManager.mjs:84 / :99 / :108 — instance-field declarations with @member JSDoc
  • ai/services/fleet/devFleetServer.mjs:144 / :170 / :186 — class-static assignments (the sanctioned injection writes)
  • ai/services/fleet/FleetControlBridge.mjs:203getManager() returns this.manager || FleetManager: prototype methods run with this = the class, so this.presenceStateOptions reads the class property; instance-field initializers never execute on this path
  • Sibling adapters (fleetWakeStateAdapter / fleetThrottleStateAdapter / fleetPresenceStateAdapter) consume ...(this.<axis>StateOptions || {}) — falsy-safe either way

The Fix

One file, behavior-preserving: declare the three options as static class fields on FleetManager, with JSDoc updated to name the class-as-singleton injection contract (writer: the composing entrypoint assigns the class property; readers: prototype methods called on the class OR injected stubs).

  • Class reads (this.x with this = class) resolve identically to today.
  • The class-static writes from devFleetServer land on DECLARED statics instead of undeclared expansions.
  • An instance read resolves undefined (statics are not on the prototype chain) → falsy → the same honest-degraded path as null today — and can never shadow the class-static injection with a stale instance null.

Acceptance Criteria

  • All three *StateOptions declared static on FleetManager; JSDoc names the class-as-singleton injection contract
  • A witness assertion (FleetManager or FleetControlBridge spec): pre-injection, Object.hasOwn(FleetManager, 'presenceStateOptions') is true with value null — the declaration now exists where the write lands
  • Sibling spec suite green unchanged (FleetManager, FleetControlBridge, fleetWakeRoutesSource, fleetPresenceStateAdapter, fleetCockpitStatus specs) — no behavior change
  • devFleetServer.mjs wiring untouched (the sanctioned writes stay byte-identical)

Out of Scope

  • Redesigning the plain-field injection seam (#15271#15273 — sanctioned, documented)
  • Converting FleetManager to instantiated usage across consumers — churn for zero behavioral gain
  • The adapters, the DTO, the cockpit renderers

Avoided Traps

  • Attacking the seam pattern itself. The Knowledge Base documents these as intentional plain-field injection seams; the defect is only the declaration/write semantics mismatch inside them.
  • "Make it a proper singleton instance." Instantiating FleetManager everywhere would touch every consumer and the bridge fallback for zero behavioral gain, and would fight the established devFleetServer wiring.

Decision Record impact

none — internal field-declaration semantics; no config surface, no ADR-governed contract changes.

Related

PR #16781 (origin of the finding) · #16737 / #16736 / #16738 (the axis family the seams feed) · #15271 / #15272 / #15273 (the sanctioned seam design) · .agents/skills/pr-review/references/reviewer-instrument-audit.md (Shape 1)

Live latest-open sweep: checked latest 20 open issues at 2026-08-09T13:2xZ; no equivalent found. A2A in-flight sweep: no claim on FleetManager field/static scope. KB semantic sweep: only the sanctioned-seam design tickets surfaced — no defect ticket.

Origin Session ID: 3167a938-5173-471d-b8ee-2c5f603f5c92

Retrieval Hint: "FleetManager StateOptions instance field class static shadow injection seam"