LearnNewsExamplesServices
Frontmatter
title>-
authorneo-opus-ada
stateMerged
createdAtAug 4, 2026, 1:33 AM
updatedAtAug 4, 2026, 1:48 AM
closedAtAug 4, 2026, 1:48 AM
mergedAtAug 4, 2026, 1:48 AM
branchesdevada/16474-narrow-label-import
urlhttps://github.com/neomjs/neo/pull/16475
contentTrust
projected
quarantined0
signals[]
Merged
neo-opus-ada
neo-opus-ada commented on Aug 4, 2026, 1:33 AM

Resolves #16474

The Data Sync Pipeline has failed every run since its last green at 2026-08-02T20:13:14Z, on the content indexes and SEO stage:

Cannot find package 'chromadb'
  imported from ai/services/knowledge-base/ChromaManager.mjs

A docs job required a vector-database client, and it did so to read GitHub labels. --include-labels dynamically imports docs/index/labels.mjs, which reached GH_LabelService through ai/services.mjs — a barrel with 66 eager top-level imports spanning every MCP server. Importing one export constructs all of them.

The coupling is old and was always free. The two-path install tier (#16389, merged after that last green run) moved chromadb into the Brain tier, and the Body-tier CI running this script stopped paying for an import it never needed. Nothing about the split is wrong — it made a latent dependency load-bearing.

Evidence: L3 (the failure and the fix both reproduced locally under a Body-tier-equivalent install, with a positive control) → L4 required (the pipeline itself green on dev). Residual: post-merge pipeline recovery [#16474].

Deltas from ticket

makeSafe is not lost, and that was checked rather than assumed. The barrel wraps services in makeSafe(service, spec), which Zod-validates and marshals input arguments. list_labels (ai/mcp/server/github-workflow/openapi.yaml:135) declares no parameters and no requestBody; the raw method is async listLabels(); the call site passes nothing. So the wrapper resolves to parse({})paramNames: []method.call(service) — identical to the direct call.

That equivalence is local, not general, and the call site says so: a method with parameters would also lose object→positional marshalling, so this is not a licence to narrow other barrel imports without checking.

The Neo bootstrap is not optional. A bare direct import throws:

ReferenceError: Neo is not defined
  at src/core/Compare.mjs:166

LabelService is a Neo.setupClass class and the barrel had been performing the namespace bootstrap too. Measured: Neo + core/_export is sufficient — InstanceManager is not needed here. Both imports look unused, so both carry a comment saying they are not.

Three pre-existing alignment fixes in getContrastColor. Unrelated to this change and present on dev (verified against origin/dev's own copy), but the staged-file hook rejects the commit while they are in a file I touch.

Test Evidence

The failure reproduces locally, because this machine's main checkout is a Body-tier install. To test the fix in the branch that has it, the worktree's chromadb was temporarily hidden to make it Body-tier-equivalent:

FIXED (this branch):
  Fetching labels from GitHub...
  Found 38 labels. Writing to apps/portal/resources/data/labels.json...
  Successfully generated labels.json

POSITIVE CONTROL (dev's version, same hidden-chromadb environment):
  Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'chromadb'
    imported from …/ai/services/knowledge-base/ChromaManager.mjs

git status on the generated index: no diff. The output is byte-identical to what is committed — the AC that matters is that the label index is unchanged, not merely that the script runs.

Static import walk over the entry point, run against both versions with the same instrument:

version modules walked reaches chromadb
dev 107 yes — via ai/services.mjsDreamServiceGoldenPathSynthesizer → memory-core HealthServiceStorageRouterCollectionProxyChromaManager
this branch 27 no

The control matters: the walker demonstrably finds chromadb when it is reachable, so the negative result is a measurement rather than a broken probe. (CI's error names the knowledge-base ChromaManager while the walk finds the memory-core one first — two arms of the same barrel, same conclusion.)

Surfaces touched: buildScripts/docs/index/labels.mjs → exercised end-to-end above; no dedicated spec covers this build script (None found), and its output is asserted by diff against the committed index.

Post-Merge Validation

  • The Data Sync Pipeline reaches content indexes and SEO without ERR_MODULE_NOT_FOUND.
  • The pipeline goes green on dev and the standing alarm #16428 self-closes on recovery. If it does not, the chromadb import was one cause and not the only one — the streak began after 2026-08-02T20:13:14Z and this fixes what run 30861274995 shows, which is not proof it is the sole failure.
  • apps/portal/resources/data/labels.json is unchanged by the first post-merge pipeline run.

Out of Scope

Making ai/services.mjs lazy. That would fix this class everywhere and is the better long-term answer, but it changes a surface every MCP server imports. This narrows one consumer; a census of other Body-tier barrel consumers is worth filing if the pattern recurs.

Commits

  • 652d99b292 — import LabelService directly, with the bootstrap it needs

Authored by Ada (Claude Opus 5, Claude Code). Session eeacb603-97f1-4241-9b2f-3a542cab6d2c.

tobiu
tobiu APPROVED reviewed on Aug 4, 2026, 1:38 AM

No review body provided.