LearnNewsExamplesServices
Frontmatter
id17230
titleA theme surface whose token pattern matches nothing reads as clean
stateClosed
labels
bugaitestingbuild
assignees[]
createdAtAug 16, 2026, 2:42 AM
updatedAtAug 16, 2026, 11:01 AM
githubUrlhttps://github.com/neomjs/neo/issues/17230
authorneo-opus-grace
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 16, 2026, 11:01 AM

A theme surface whose token pattern matches nothing reads as clean

Closed Backlog/active-chunk-16 bugaitestingbuild
neo-opus-grace
neo-opus-grace commented on Aug 16, 2026, 2:42 AM

Context

Raised by @neo-kimi-iris as a non-blocking finding while reviewing PR #17205, and filed rather than folded in so her verification of that head stayed intact. Hers is the finding; the ticket is mine because the registry it applies to is code I shipped.

The Problem

check-theme-surfaces.mjs reads each registered surface through a per-surface tokenPattern. If an entry's pattern does not match that surface's actual token namespace, extractFmTokens returns an empty map — and every downstream check then passes, because there is nothing to compare, nothing to find missing, and nothing to flag. The surface reports clean while being entirely unexamined.

This is the same vacuous-green class PR #17205 was written to kill, one level up: the PR pins it for the two registered surfaces with a spec that drives one fixture under two namespaces and asserts opposite verdicts. What it does not do is make the collector itself refuse a zero-extraction surface, so the protection covers today's registry rather than the mechanism.

The failure mode is specific and quiet: register a third surface, get the namespace prefix slightly wrong, and CI goes green on a surface nobody is checking. Nothing in the output distinguishes "clean" from "read nothing".

I have first-hand evidence the class is live rather than theoretical: while building #17205 I ran the workstation surface under the agentos --fm-* pattern, extracted zero tokens, and got a pass. It looked exactly like success. Iris's point is that a spec caught my instance because the pair was registered — the next one will not have a spec written for it in advance.

The Architectural Reality

  • buildScripts/util/check-theme-surfaces.mjsextractFmTokens(file, tokenPattern) returns a Map; an unmatched pattern yields an empty one.
  • collectThemeSurfaceFailures — the parity, completeness and contracted-vocabulary checks all iterate the extracted maps, so an empty map produces zero failures by construction rather than by verdict.
  • SURFACES (the registry added in #17200) — each entry supplies its own tokenPattern, which is precisely the field that can be wrong for a newly registered surface.

The registry is the right shape; the gap is that it trusts an entry to be self-consistent, and a wrong tokenPattern is silent by design rather than loud.

The Fix

A zero-extraction failure in the collector: when a surface's dark and light maps are both empty, that is a registry defect, not a clean surface — fail with the surface name and the pattern that matched nothing.

Both-empty is the right condition rather than either-empty. A skin file legitimately defining no tokens on one side is already caught by the completeness check, whereas both sides empty can only mean the pattern never matched.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
collectThemeSurfaceFailures #17200's registry design Both token maps empty ⇒ a named failure identifying the surface and its unmatched pattern Surfaces that extract tokens behave exactly as today guard JSDoc Iris's review of PR #17205; my own measured zero-extraction pass during #17200

Acceptance Criteria

  • A registered surface whose tokenPattern matches no declaration in either skin fails with a message naming the surface and the pattern, rather than passing silently.
  • A surface that extracts tokens normally is unaffected — proven by the existing #17200 specs staying green without modification.
  • A surface where exactly one skin is empty keeps its current disposition (the completeness check owns that case) — pinned so the new guard does not swallow it.
  • The real tree still passes: both registered surfaces extract non-empty maps.

Out of Scope

  • Validating that a tokenPattern is correct for its surface beyond the both-empty signal — that needs a namespace declaration the registry does not currently carry.
  • Any change to parity, token-only, completeness or text-safe-ink semantics.

Avoided Traps

  • Fail on either map empty. Rejected: the completeness check already owns the one-sided case with a better message, and this would double-report it.
  • Assert a minimum token count. Rejected: a threshold is a number to argue about; zero-versus-nonzero is the actual signal, and a surface with genuinely one token is legitimate.
  • Leave it to the spec. Rejected explicitly — that is the current state. A spec proves the classes someone thought to write; the collector protects the ones nobody did, which is the whole reason the registry exists.

Decision Record impact

none.

Related

  • Found in review of PR #17205 (#17200 — the registry this applies to)
  • Class origin: #14618 AC-2, the amended pixel-suite instrument question

Live latest-open sweep: checked latest 20 open issues at 2026-08-16T00:20Z; no equivalent found.

Origin Session ID: b17338dd-b474-494f-b08c-683044de2ddb

Retrieval Hint: check-theme-surfaces zero extraction vacuous green tokenPattern registry surface reads clean unexamined

tobiu referenced in commit 0e32ee6 - "fix(build): a surface that extracted nothing stops reading as clean (#17230) (#17235) on Aug 16, 2026, 11:01 AM
tobiu closed this issue on Aug 16, 2026, 11:01 AM