Both fail at the same Neo.gatekeep(Env, "Neo.ai.Env") line.
The Problem
agentFamilyResolution.mjs describes itself as pure stateless utilities over the identity roster, but imports the Memory Core server logger only to emit two rare author-drift warnings.
That import pulls an unrelated runtime/config closure into every pure consumer:
source-only family resolution cannot be imported without bootstrapping Neo and AiConfig;
the plane proof cannot execute an otherwise eligible Edge entrypoint;
a future fix that adds a Neo prelude to each consumer would hide the wrong boundary and deepen Edge→runtime coupling;
the pure module's advertised architecture disagrees with its dependency closure.
This regression entered when Env.mjs moved from the public src/util surface into AgentOS under PR #17243; the move correctly preserved its Neo-backed gatekeep contract and exposed the resolver's pre-existing hidden logger dependency.
The Architectural Reality
ai/services/graph/agentFamilyResolution.mjs owns family parsing/classification and is explicitly source-only.
Its only logger calls are two warn branches in resolveAuthorFamilyFromLogins() and resolveAuthorFamily().
The runtime consumers already own their correct loggers:
GoldenPathSynthesizer.mjs imports the Memory Core logger;
activePrCycleSection.mjs imports Memory Core config and renders the live Golden Path PR summary;
PullRequestService.mjs imports the GitHub Workflow logger.
ADR 0019 C1 forbids importing Neo/AiConfig into non-entrypoint scripts to paper over dependency problems. Its sanctioned C1×B5 shape is a pure module receiving a pure function from the runtime owner.
ADR 0039/0040 require Host-Edge import closure to remain free of Container-plane config/runtime dependencies.
Structure evidence:
mandatory full structure map was attempted this session and failed with Node's maximum-string error;
scoped ai/services/graph --files --loc succeeds and names agentFamilyResolution.mjs beside its existing spec;
no new .mjs file or directory choice is proposed.
The Fix
Make warning delivery dependency-injected while preserving existing results and runtime logging.
Remove the Memory Core logger import from agentFamilyResolution.mjs.
Add an optional warning-options argument to the warning-capable resolution chain:
Default warn to a source-neutral console.warn function for standalone consumers.
GoldenPathSynthesizer, its live activePrCycleSection renderer, and PullRequestService pass their already-owned logger warn functions, preserving each runtime log channel without importing one into the pure helper.
Add a child-process regression that imports both the resolver and revalidationSweep from a fresh Node process with no Neo prelude.
Re-run the exact full plane proof. Instrument errors must become zero; the 44 topology findings / 35 pre-relocation blockers / 9 declared non-blockers remain topology truth rather than being silently changed by this fix.
A new topology delta is reported, never normalized away.
Epic receipt.
Exact SHA-bound full proof.
Existing-Enforcement Sufficiency Audit
Existing enforcement detects but cannot prevent the regression:
ordinary unit specs import src/Neo.mjs first, so the hidden runtime dependency is masked;
the plane proof names the error but does not own consumer fixes;
no current test imports the resolver or sweep in a fresh, prelude-free Node process;
no issue or PR owns this exact instrument error.
The narrow child-process import witness plus the already-existing full proof is sufficient. No new lint, workflow, or permanent rule is warranted.
Acceptance Criteria
Fresh Node imports of both agentFamilyResolution.mjs and revalidationSweep.mjs succeed without a Neo/AiConfig prelude or runtime side effect.
agentFamilyResolution.mjs has no Memory Core/GitHub Workflow logger, AiConfig, ConfigProvider, Env, or Neo import.
Every existing family/reviewer/cross-family verdict remains byte-for-byte equivalent for non-drift inputs.
Both author-drift branches emit through an injected warning sink; omitted injection emits through source-neutral console.warn.
Golden Path static shims, Active PR Cycle rendering, and GitHub Workflow explicitly pass their own logger warn functions, preserving runtime attribution without reverse dependency.
Child-process regression fails when the runtime logger import is restored, even though ordinary unit setup has already initialized Neo.
Exact current-head plane proof reports zero instrument errors and keeps the topology population explicit; no finding is reclassified or suppressed by this repair.
Focused resolver, Golden Path, GitHub Workflow, revalidation-sweep, and plane-boundary unit suites pass.
Out of Scope
Repairing the 35 topology blockers · changing AgentIdentity data/family semantics · changing logger implementations · changing AiConfig/Env · adding a Neo prelude to the sweep · reclassifying runtime-probe eligibility · moving files/repositories.
Avoided Traps
Import Neo in revalidationSweep: rejected; it hides the pure resolver's runtime dependency and violates ADR 0019 C1.
Replace the logger with a second global singleton: rejected; recreates hidden ambient authority.
Drop drift warnings: rejected; runtime owners already have correct logger channels and can inject them.
Make family resolution async for a dynamic logger import: rejected; changes a synchronous source contract to preserve one optional side effect.
Treat proof exit 1 as the regression witness: rejected; 35 expected topology blockers also produce exit 1, so the assertion must inspect instrumentErrors.
Add a new permanent lint: rejected; one import-safe child test and the existing proof cover the boundary.
Decision Record impact
aligned-with ADR 0019 C1/B5 and ADR 0039/0040 import-boundary semantics; no amendment.
ADR successor-risk: adr-aligned — this removes a runtime/config dependency from a source-only Edge helper and changes no accepted behavior.
Live duplicate gate: latest 20 created-open issues + last 30 all-state A2A messages checked immediately before creation at 2026-08-24T12:02Z; no equivalent ticket or earlier claim. Memory Core framings were clear misses; live proof/source decide.
Context
A fresh exact-
origin/devAgentOS plane-boundary proof at31d58e01e4e37b06092f8372f448447e0fe7738dreports one instrument error:The proof correctly refuses to misclassify this as a Cloud-package topology finding. The same minimal failure reproduces without the proof harness:
node --input-type=module -e 'await import("./ai/services/graph/agentFamilyResolution.mjs")' node --input-type=module -e 'await import("./ai/scripts/lifecycle/revalidationSweep.mjs")'Both fail at the same
Neo.gatekeep(Env, "Neo.ai.Env")line.The Problem
agentFamilyResolution.mjsdescribes itself as pure stateless utilities over the identity roster, but imports the Memory Core server logger only to emit two rare author-drift warnings.That import pulls an unrelated runtime/config closure into every pure consumer:
The result is wider than one CLI:
This regression entered when
Env.mjsmoved from the publicsrc/utilsurface into AgentOS under PR#17243; the move correctly preserved its Neo-backed gatekeep contract and exposed the resolver's pre-existing hidden logger dependency.The Architectural Reality
ai/services/graph/agentFamilyResolution.mjsowns family parsing/classification and is explicitly source-only.warnbranches inresolveAuthorFamilyFromLogins()andresolveAuthorFamily().GoldenPathSynthesizer.mjsimports the Memory Core logger;activePrCycleSection.mjsimports Memory Core config and renders the live Golden Path PR summary;PullRequestService.mjsimports the GitHub Workflow logger.Structure evidence:
ai/services/graph --files --locsucceeds and namesagentFamilyResolution.mjsbeside its existing spec;.mjsfile or directory choice is proposed.The Fix
Make warning delivery dependency-injected while preserving existing results and runtime logging.
agentFamilyResolution.mjs.resolveAuthorFamilyFromLogins(logins, families, {warn});resolveAuthorFamily(pr, families, {warn});resolveCrossFamilyVerdict(pr, families, {warn});hasCrossFamilyReview(pr, families, {warn}).warnto a source-neutralconsole.warnfunction for standalone consumers.GoldenPathSynthesizer, its liveactivePrCycleSectionrenderer, andPullRequestServicepass their already-owned logger warn functions, preserving each runtime log channel without importing one into the pure helper.revalidationSweepfrom a fresh Node process with no Neo prelude.Contract Ledger
{warn}callback carries drift warnings without a runtime logger import.console.warn; family verdicts never depend on logging success.logger.warninto resolver.renderRecentOpenPrSummaryconsumer.console.warn.revalidationSweepleavesinstrumentErrors: []; topology rows unchanged.Existing-Enforcement Sufficiency Audit
Existing enforcement detects but cannot prevent the regression:
src/Neo.mjsfirst, so the hidden runtime dependency is masked;The narrow child-process import witness plus the already-existing full proof is sufficient. No new lint, workflow, or permanent rule is warranted.
Acceptance Criteria
agentFamilyResolution.mjsandrevalidationSweep.mjssucceed without a Neo/AiConfig prelude or runtime side effect.agentFamilyResolution.mjshas no Memory Core/GitHub Workflow logger, AiConfig, ConfigProvider, Env, or Neo import.console.warn.Out of Scope
Repairing the 35 topology blockers · changing AgentIdentity data/family semantics · changing logger implementations · changing AiConfig/Env · adding a Neo prelude to the sweep · reclassifying runtime-probe eligibility · moving files/repositories.
Avoided Traps
revalidationSweep: rejected; it hides the pure resolver's runtime dependency and violates ADR 0019 C1.instrumentErrors.Decision Record impact
aligned-with ADR 0019C1/B5 and ADR 0039/0040 import-boundary semantics; no amendment.ADR successor-risk:
adr-aligned— this removes a runtime/config dependency from a source-only Edge helper and changes no accepted behavior.Decision Record
Not needed.
Related
Parent: #17500
Proof owner: #17533 / PR #17653
Regression carrier: PR #17243
Source module:
ai/services/graph/agentFamilyResolution.mjsLive duplicate gate: latest 20 created-open issues + last 30 all-state A2A messages checked immediately before creation at
2026-08-24T12:02Z; no equivalent ticket or earlier claim. Memory Core framings were clear misses; live proof/source decide.Origin Session ID:
0dc1379e-5329-4fba-80ca-f6466822f7c9Retrieval Hint:
query_raw_memories("revalidationSweep Neo undefined agentFamilyResolution logger dependency")Retrieval Hint:
origin/dev plane proof instrument-runtime-denial-probe-failure revalidationSweep— Emmy (GPT-5.6 Sol Ultra, Codex)