LearnNewsExamplesServices
Frontmatter
id17573
titleRelocated dock examples render only via the Fleet Manager's palette
stateClosed
labels
bugairefactoring
assigneesneo-gpt
createdAtAug 22, 2026, 10:02 PM
updatedAtAug 23, 2026, 2:31 AM
githubUrlhttps://github.com/neomjs/neo/issues/17573
authorneo-opus-grace
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 23, 2026, 2:31 AM

Relocated dock examples render only via the Fleet Manager's palette

Closed Backlog/active-chunk-18 bugairefactoring
neo-opus-grace
neo-opus-grace commented on Aug 22, 2026, 10:02 PM

Context

Surfaced by @neo-gpt-emmy's RA-4 on PR #17562 (#16322, the dockdemo relocation). That PR moved the two dock demos out of the Fleet Manager app into examples/dashboard/, and dissolved every examples/ → product ESM import. It did not dissolve the theme-layer dependency, because that one is load-bearing and removing it is a design decision rather than a cleanup.

Live latest-open sweep: latest 20 open issues checked 2026-08-22T20:0xZ; nothing covers example-to-product theme coupling. #17241 was proposed as the owner during review and is the wrong home — that ticket promotes --dock-* tokens from apps into the engine; this is an example app consuming a product app's palette, a different layer with a different fix.

The Problem

examples/dashboard/choreography/DemoAWorkspace.mjs and examples/dashboard/crossWindow/DemoBWorkspace.mjs both declare:

additionalThemeFiles: ['AgentOS.view.Viewport', 'Neo.dashboard.Container']

AgentOS.view.Viewport resolves to resources/scss/theme-neo-{dark,light}/apps/agentos/Viewport.scss — the Fleet Manager's harness shell, which declares 33 --fm-* tokens. The relocated example stylesheets consume 10 of them:

--fm-font-mono · --fm-font-sans · --fm-ground · --fm-ink · --fm-ink-dim · --fm-line · --fm-line-soft · --fm-panel · --fm-panel-2 · --fm-signal

So two examples/ apps render correctly only because a product app's theme file is pulled into their document. An example is meant to be the thing a consumer copies; this one silently requires the flagship's palette to look right.

Why it is not simply a leftover. It is invisible to an import census — additionalThemeFiles is a string array resolved by the theme loader, not an ESM edge — which is exactly why the relocation's "the examples reach nothing outside src/" check did not see it. That claim was true of the import graph and false of the theme graph.

The Architectural Reality

  • ai/../src/worker/App.mjs:497-503insertThemeFiles resolves each additionalThemeFiles entry from the string's own root, so AgentOS.view.Viewport loads the FM sheet regardless of which app declares it. The mechanism works; the layering is what is wrong.
  • resources/scss/theme-neo-{dark,light}/apps/agentos/Viewport.scss — the 33-token FM shell.
  • resources/scss/src/examples/dashboard/{choreography,crossWindow}/*.scss — the consumers, restored to these paths by PR #17562.

The Fix

Give the examples a palette they own. Two candidate shapes, and the choice is the ticket's real content:

  1. Example-owned token layer — declare the 10 consumed tokens under resources/scss/theme-neo-{dark,light}/examples/dashboard/, and drop AgentOS.view.Viewport from both additionalThemeFiles. The examples stop tracking FM's palette; they also stop drifting with it, which is the trade to decide deliberately.
  2. Promote the shared subset — if these ten are genuinely generic surface tokens (ground/ink/line/panel/signal is a complete neutral set), promote them to a theme-level vocabulary both FM and the examples consume, and leave FM owning only what is actually FM-specific.

Shape 2 is the better architecture if the subset really is generic; shape 1 is the honest fallback if it is not. Deciding that requires reading the token semantics, not just counting them.

Acceptance Criteria

  • Neither relocated example declares AgentOS.view.Viewport in additionalThemeFiles.
  • Both examples render with their intended styling with the FM app's theme files absent from the document — asserted on computed styles in a browser, not on SCSS source, since the whole defect class is invisible to source inspection.
  • A control proves the assertion can fail: removing the new example-owned token layer reddens it.
  • The decision between an example-owned layer and a promoted shared vocabulary is recorded with its reasoning, not just implemented.
  • No --fm-* token is referenced from anywhere under resources/scss/src/examples/**.

Out of Scope

  • Neo.dashboard.Container in the same additionalThemeFiles arrays — that is an engine sheet and is exactly the dependency an example should have.
  • The --dock-* promotion (#17241 and its leaves). Different layer, already owned.
  • Restyling the demos. This is about where their tokens come from, not what they look like.

Avoided Traps

  • Deleting the dependency without replacing the tokens. The demos would render unstyled; PR #17562 already learned this the expensive way by deleting a stylesheet that a grep said nothing imported.
  • Filing this under #17241. That ticket moves --dock-* from apps into the engine. Folding a product-palette dependency into it would blur two different layering problems and give neither a clean close.
  • Asserting the fix on SCSS source. The coupling is a runtime theme-loader edge; only a rendered document can show it is gone.

Related

#16322 / PR #17562 (the relocation that surfaced it) · #17241 (adjacent, different layer) · #17514 (the Body-side architecture guide stating the token-ownership discipline)

Retrieval Hint: additionalThemeFiles AgentOS.view.Viewport examples fm token coupling theme graph vs import graph

Origin Session ID: cb3eb9c7-875a-4eac-a716-02878fa535c5

tobiu referenced in commit 6c88215 - "fix(dashboard): give relocated demos an owned palette (#17573) (#17588)" on Aug 23, 2026, 2:31 AM
tobiu closed this issue on Aug 23, 2026, 2:31 AM