LearnNewsExamplesServices
Frontmatter
id17200
titleThe theme guard covers agentos only, and its parity rule flags correct aliases
stateClosed
labels
enhancementaitestingbuild
assigneesneo-opus-grace
createdAtAug 15, 2026, 7:26 PM
updatedAtAug 16, 2026, 2:51 AM
githubUrlhttps://github.com/neomjs/neo/issues/17200
authorneo-opus-grace
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 16, 2026, 2:51 AM

The theme guard covers agentos only, and its parity rule flags correct aliases

Closed Backlog/active-chunk-16 enhancementaitestingbuild
neo-opus-grace
neo-opus-grace commented on Aug 15, 2026, 7:26 PM

Refs #14618

Split out of #14618 after its AC-2 was amended with measurement. That ticket owns a visual-baseline harness; this owns the static guard that should have been answering its colour question all along. Independent value: the parity refinement below improves the agentos coverage that already exists, whether or not the workstation is ever added.

Problem

buildScripts/util/check-agentos-theme.mjs is the right instrument for "did a colour escape the token layer, and does the light skin actually differ from the dark one" — static SCSS analysis, no baselines, no threshold, no platform drift. It has two gaps.

1. It scans agentos only.

darkPath : resources/scss/theme-neo-dark/apps/agentos/Viewport.scss
lightPath: resources/scss/theme-neo-light/apps/agentos/Viewport.scss
viewDir  : resources/scss/src/apps/agentos

The workstation has all three equivalent surfaces and is unscanned — including the --agent-dock-preview-* family, which is exactly what #14618's preview-language-pair-* baselines capture and what the pixel suite provably cannot see.

2. Its parity rule flags correct code as a violation.

The rule is "every contracted colour token must carry a genuinely different value in dark vs light", exempting only the two mode-invariant font tokens. Measured on the workstation skins:

24 tokens per skin · 0 missing in either skin · 8 byte-identical across skins

All 8 are identical by correct design:

token why
--workstation-font-mono, --workstation-font-sans mode-invariant, same contract agentos already exempts
--agent-dock-preview-accept, --agent-dock-preview-signal alias → var(--workstation-signal)
--agent-dock-proxy-border, -ground, -shadow, -text alias → var(--workstation-…) / color-mix(…)

A naive port reports 6 false positives on correct code. The rule compares the written expression when what it means is the resolved value: an alias is byte-identical across skins precisely because its referent differs per skin, which is the token layer working.

Running the guard against workstation paths with the current default contract returns 56 violations, every one an --fm-* contract complaint — the workstation uses a different token family, so it needs its own contract rather than a copied one.

The Architectural Reality

  • collectAgentosThemeFailures({darkPath, lightPath, viewDir, contractedTokens}) is already fully path-parameterised. Extending it is a second invocation and a contract, not a refactor.
  • The parity refinement is not workstation-specific. Agentos can grow an alias token the day someone writes one, and the guard would then reject it — so this strengthens existing coverage rather than only widening it.
  • The guard's name and CI job say "agentos"; covering two app surfaces makes both a misnomer.
  • The workstation's view SCSS carries no bare colour literals today, so adopting token-only consumption there starts from a clean surface rather than a wall of pre-existing violations.

The Fix

  1. Generalise from one hardcoded surface to a list of app surfaces, each with its own paths and token contract; register the workstation alongside agentos.
  2. Make parity alias-aware: a token whose value is a var() / color-mix() expression referring to another token satisfies parity when its referent differs per skin. Byte-identical expression, different resolved value.
  3. Rename the guard, its npm script and its workflow to describe what it now covers.

Out of Scope

  • The visual baseline suite's threshold. Its permissive default is correct for the geometry it owns; #14618 carries the amended AC and the measurement.
  • Adding tokens to either skin, or changing any colour value. This makes the existing surfaces enforced, not different.
  • The --fm-* contract itself.

Acceptance Criteria

  • The guard evaluates both agentos and the workstation, each with its own token contract, and a single run reports violations from both.
  • Parity is alias-aware: a var() / color-mix() token that resolves through a per-skin-differing referent passes, and the six workstation aliases are proven to pass by spec rather than by exemption list.
  • A token that is byte-identical and resolves identically in both skins still fails — the alias rule must not become a blanket escape for "starts with var(".
  • The workstation surface passes clean at adoption, with the run output recorded in the PR body so the starting state is a measurement rather than a claim.
  • Seeded proof, which is #14618's AC-2 answered at the right layer: a bare colour literal in a workstation view SCSS fails the guard; reverting it passes. Both arms spec'd, because a guard that rejects everything passes a one-sided corpus too.
  • Guard name, npm script and workflow describe the covered surfaces; the CI job runs on changes to either app's skins or views.

Evidence class

Measured on dev 2026-08-15. Guard scope read at source (DEFAULT_PATHS, collectAgentosThemeFailures signature). The 56-violation and 24-token/8-identical figures come from running collectAgentosThemeFailures against workstation paths and diffing the two skins' parsed token maps in one process. The alias classification is by reading each of the 8 identical values, not inferred from the count.

Live latest-open sweep at 2026-08-15T17:25:44Z: #14618 is the parent context; nothing equivalent open. A2A sweep: no competing claim.

Decision Record impact

none — no ADR governs the theme-guard surface.

🖖 Authored by Grace (Claude Opus 5, Claude Code). Session b17338dd-b474-494f-b08c-683044de2ddb. Split after @tobiu redirected #14618's AC-2 from pixel diffing to (S)CSS analysis across light and dark.

tobiu referenced in commit 3e2a6d8 - "feat(build): the theme guard covers the workstation, and the off-token proof lands without pixels (#17205) on Aug 16, 2026, 2:51 AM
tobiu closed this issue on Aug 16, 2026, 2:51 AM