LearnNewsExamplesServices
Frontmatter
id17702
titlePure family resolution pulls Memory Core config into Edge imports
stateClosed
labels
bugaitestingregressionarchitectureagent-os
assigneesneo-gpt-emmy
createdAtAug 24, 2026, 2:03 PM
updatedAtAug 24, 2026, 5:18 PM
githubUrlhttps://github.com/neomjs/neo/issues/17702
authorneo-gpt-emmy
commentsCount0
parentIssue17500
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 24, 2026, 5:18 PM

Pure family resolution pulls Memory Core config into Edge imports

Closed Backlog/active-chunk-19 bugaitestingregressionarchitectureagent-os
neo-gpt-emmy
neo-gpt-emmy commented on Aug 24, 2026, 2:03 PM

Context

A fresh exact-origin/dev AgentOS plane-boundary proof at 31d58e01e4e37b06092f8372f448447e0fe7738d reports one instrument error:

instrument-runtime-denial-probe-failure
ai/scripts/lifecycle/revalidationSweep.mjs
ReferenceError: Neo is not defined
  at ai/Env.mjs:211

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.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:

revalidationSweep
  → agentFamilyResolution
  → memory-core/logger
  → memory-core/config
  → ConfigProvider
  → Env
  → Neo.gatekeep (Neo prelude absent)

The result is wider than one CLI:

  • 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.

  1. Remove the Memory Core logger import from agentFamilyResolution.mjs.
  2. Add an optional warning-options argument to the warning-capable resolution chain:
    • resolveAuthorFamilyFromLogins(logins, families, {warn});
    • resolveAuthorFamily(pr, families, {warn});
    • resolveCrossFamilyVerdict(pr, families, {warn});
    • hasCrossFamilyReview(pr, families, {warn}).
  3. Default warn to a source-neutral console.warn function for standalone consumers.
  4. 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.
  5. Add a child-process regression that imports both the resolver and revalidationSweep from a fresh Node process with no Neo prelude.
  6. 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.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
Family-resolution warning options Existing resolver functions + owning runtime loggers Optional {warn} callback carries drift warnings without a runtime logger import. Omitted callback uses console.warn; family verdicts never depend on logging success. Function JSDoc signatures. Injected-sink unit controls + unchanged result matrix.
Golden Path author-family shim Existing Memory Core logger owner Pass logger.warn into resolver. Logger failure must not change resolved family. Existing delegator JSDoc. Warning-spy regression.
Active PR Cycle rendering Existing Memory Core config/logger owner Pass the Memory Core logger at the live renderRecentOpenPrSummary consumer. Omitted sink must never downgrade a durable warning to console.warn. Existing renderer owner contract. Consumer-channel arm plus sink-removal mutation.
GitHub Workflow merge-readiness author resolution Existing GitHub Workflow logger owner Pass its logger warn function at the current source-id resolution site. No self-id/opener disagreement emits nothing. Existing merge-readiness comments. Exact author-drift fixture.
Source-only imports ADR 0019 C1 + module's pure contract Resolver and revalidation sweep import in fresh Node without Neo/AiConfig boot. Any transitive runtime/config import fails the child control. Module summary tightened. Child process + plane proof.
Plane-boundary instrument #17533 / PR #17653 revalidationSweep leaves instrumentErrors: []; topology rows unchanged. 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:

  1. ordinary unit specs import src/Neo.mjs first, so the hidden runtime dependency is masked;
  2. the plane proof names the error but does not own consumer fixes;
  3. no current test imports the resolver or sweep in a fresh, prelude-free Node process;
  4. 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.

Decision Record

Not needed.

Related

Parent: #17500
Proof owner: #17533 / PR #17653
Regression carrier: PR #17243
Source module: ai/services/graph/agentFamilyResolution.mjs

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.

Origin Session ID: 0dc1379e-5329-4fba-80ca-f6466822f7c9

Retrieval 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)

tobiu referenced in commit 3fb0402 - "fix(agentos): keep family resolution import-safe (#17702) (#17703) on Aug 24, 2026, 5:18 PM
tobiu closed this issue on Aug 24, 2026, 5:18 PM