LearnNewsExamplesServices
Frontmatter
id17256
titleThe engine→Brain boundary needs an enforceable guard before the nine crossings move
stateClosed
labels
enhancementaitestingarchitecturebuild
assigneesneo-opus-ada
createdAtAug 16, 2026, 10:39 PM
updatedAtAug 17, 2026, 10:35 AM
githubUrlhttps://github.com/neomjs/neo/issues/17256
authorneo-opus-ada
commentsCount0
parentIssue17239
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 17, 2026, 10:35 AM

The engine→Brain boundary needs an enforceable guard before the nine crossings move

Closed Backlog/active-chunk-16 enhancementaitestingarchitecturebuild
neo-opus-ada
neo-opus-ada commented on Aug 16, 2026, 10:39 PM

Context

The guard half of #17239, split per its reviewer's fork answer (option 1: guard first, burndown after). Filed as a leaf so the guard has an honest close target while #17239 stays open on the relocation it actually asks for.

Two independent reasons the guard leads rather than trails, both from the parent's own thread:

  1. The count was wrong three times. #17239 named three crossings. Running its own AC-1 grep found six. Rewriting the detector to read the AST found ten — but one of those ten was my own detector defect, not a real crossing. The true census is nine crossings across seven files, all under buildScripts/. Every sweep before the last was from-anchored, and a dynamic import has no from keyword. A baseline turns the count into an artifact that fails when it drifts, instead of a number in a title that outlives the sweep that produced it.
  2. publish.mjs is the atomic devmain release path. It is the one relocation where a mid-move regression is expensive and hard to notice, and it should not move without a net.

The Problem

neomjs/neo is the engine; ai/ is the Brain. The direction is one-way by design — the Brain may consume the engine, never the reverse. Nothing enforces it, so ten crossings accumulated without any of them failing anything.

src/** is clean, and stays clean. An earlier revision of this ticket claimed otherwise, on the strength of src/worker/App.mjs:779 doing import('../ai/Client.mjs'). That resolves to src/ai/Client.mjs, not the top-level ai/ — and src/ai/** is the engine's own AI layer, the one sanctioned seam by which the Body connects to the Brain. Engine code, by design.

The claim came from a predicate matching specifier text rather than resolving it against the importing file: identical text, opposite meanings by directory. Retracted in full; the guard now resolves before deciding, and the spec asserts both verdicts of that pair.

What the earlier hand-greps genuinely missed is buildScripts/devCockpit.mjs — three crossings, all dynamic imports, which have no from keyword and so were invisible to every from-anchored sweep.

The Architectural Reality

Ten crossings, three classes. A and B are the parent ticket's split; C is one neither census had.

Class What it is Fix shape Sites
A engine tooling reaching a Brain service moves a concern labels.mjs, rebuildContentIndexesAndSeo.mjs, publish.mjs
B agent-serving script misfiled in an engine directory moves a file agentCoAuthorEmails.mjs, deriveFleetRoster.mjs, agent-preflight.mjs, devCockpit.mjs (×3)

The A/B split is #17239's and it is complete. A "Class C" proposed in an earlier revision of this ticket was an artifact of the predicate defect above and has been withdrawn.

The Fix

buildScripts/util/check-engine-brain-boundary.mjs — reads ImportDeclaration / ImportExpression nodes from the AST, not text — plus a burndown baseline, a lint-staged entry, and its required CI mirror.

Three properties that are the whole point:

  • Asserts the property, not the list. The baseline exempts known debt; it is not the assertion. A crossing in a file the baseline does not cover fails, so a new one cannot pass by leaving the listed nine intact.
  • The ratchet fails both ways. A baselined crossing that no longer violates must also leave the baseline, or the recorded count drifts above the real one and becomes a list of things that used to be true.
  • Rows carry count. devCockpit.mjs imports localBearer.mjs at two lines; a key of file+specifier alone holds one member for both, so removing one occurrence would leave the key present and the diff silent — the measured shape from a sibling baseline where 83 rows collapsed to 9 keys and deleting 63 of 64 still reported green.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
check-engine-brain-boundary.mjs new fails on an unbaselined crossing, or on baseline drift in either direction unparseable source → skipped (check-parse owns that) module JSDoc red-proofs below
check-engine-brain-boundary-baseline.json this ticket ten rows, each with class + count + why it is tolerated absent file → hard failure inline note per row git ls-files census
lint-staged {buildScripts,src}/**/*.mjs package.json runs the guard pre-commit --no-verify bypass covered by the CI mirror lint-guard-ci-parity OK
engine-brain-boundary-lint.yml lint-guard-ci-parity CI mirror; resolved by parsed run: full path in a *-lint.yml n/a header comment lint green

Decision Record impact

none — restores a boundary no ADR presently defines. Whether the engine↔Brain direction deserves a formal ADR is #17239's stated follow-up, not this leaf's.

Acceptance Criteria

  • The guard reports zero drift against the shipped baseline on dev, and the baseline contains all nine crossings with per-row class and count.
  • src/ai/** consumers are NOT convicted — the specifier is resolved against the importing file rather than pattern-matched. Asserted at three import depths, plus the same specifier yielding opposite verdicts from buildScripts/ and from src/worker/.
  • A crossing in a file absent from the baseline fails — red-proofed, so the check cannot degrade into a snapshot comparison.
  • Both ratchet directions fail — a new crossing, and a baselined crossing that disappeared without a baseline edit.
  • A partial burndown of a multi-occurrence crossing fails (2 → 1 on devCockpit.mjs), red-proofed.
  • A dynamic import('../ai/…') is detected — the shape every prior sweep missed.
  • The guard does not convict comments, prose strings, apps/ai/** lookalikes, or its own JSDoc, which quotes specifiers as examples.
  • lint-guard-ci-parity passes: the lint-staged guard has a CI mirror that invokes it by full path.

Out of Scope

  • Relocating any of the ten. That is #17239, deliberately. This leaf lands the net; the parent does the moving.
  • The Class C decision. The guard makes it visible and baselines it; whether src/worker/App.mjs keeps its lazy Brain import is a call for #17239 or its own ticket.
  • Making the workflow a required status context — #17171 covers that class for all nineteen existing lint workflows.

Avoided Traps

  • Regex over source text. The first draft did this and convicted its own JSDoc — invisible until the file became tracked and the guard could scan itself. Masking comments would have fixed that one instance; reading the parse tree removes the class and catches the dynamic imports, which is what took the count from six to ten.
  • Baseline-as-assertion. Flagged by the parent's reviewer before it could ship: a snapshot used as the assertion lets a seventh import in a new file pass while the six stay clean — the exact shape the parent ticket is now a case study in.
  • A key without a count. Would have let a partial burndown of devCockpit.mjs report green.

Related

  • Parent: #17239 (the relocation; stays open)
  • #17237 / PR #17243 — the same boundary eroding in the opposite direction
  • #17171 — required-status-context gap affecting every lint workflow

Origin Session ID: 3f264a19-c7d4-481e-bc80-5c288bca177f

Retrieval Hint: query_raw_memories("engine Brain boundary guard dynamic import from-anchored grep missed src/worker/App.mjs")

Live latest-open sweep: checked latest open issues at 2026-08-16T20:40Z; A2A claim sweep same time — #17239's owner has answered the fork in favour of this split and holds no competing claim.

tobiu closed this issue on Aug 17, 2026, 10:35 AM
tobiu referenced in commit eace3d1 - "feat(build): the engine → Brain boundary becomes enforceable, nine crossings baselined (#17257) on Aug 17, 2026, 10:35 AM