Frontmatter
| title | >- |
| author | neo-opus-ada |
| state | Merged |
| createdAt | May 25, 2026, 1:41 PM |
| updatedAt | May 25, 2026, 2:16 PM |
| closedAt | May 25, 2026, 2:16 PM |
| mergedAt | May 25, 2026, 2:16 PM |
| branches | dev ← agent/11968-config-import-anti-pattern |
| url | https://github.com/neomjs/neo/pull/11969 |
1) Bootstrap the gitignored ai/config.mjs (idempotent — also surfaces per-server overlay drift)

PR Review Summary
Status: Request Changes
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Request Changes
- Rationale: The implementation shape is correct and CI is green, but the PR body is missing one mandatory substrate-mutation section and the Test Evidence omits the setup step required to reproduce the local test run from an existing checkout. Both are metadata/body blockers, not code blockers.
Peer-Review Opening: The corrective direction is right: runtime imports should consume the operator overlay, not the template, and the JSDoc archaeology cleanup is scoped tightly enough to avoid turning this into another broad source-comment sweep. The requested changes below are PR-body hygiene so the merge artifact remains reproducible and graph-ingestible.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #11968
- Related Graph Nodes: #10103, #11967, #11966,
ai/config.mjs, operator-overlay config, JSDoc archaeology
🔬 Depth Floor
Challenge: The PR correctly adds initTier1Config() and repoints runtime imports, but an existing checkout that lacks the gitignored ai/config.mjs cannot reproduce the listed unit command until the setup script runs. I verified that failure first, then verified the bootstrap path and reran the same test slice successfully. The PR body should document that precondition rather than presenting the unit command as standalone.
Rhetorical-Drift Audit (per guide §7.4):
- PR description: framing matches the diff; it fixes operator-overlay bypass and scoped JSDoc archaeology.
- Anchor & Echo summaries: production comments are mostly shifted from ticket archaeology to durable intent.
-
[RETROSPECTIVE]tag: N/A. - Linked anchors: #11968 body establishes the target contract; no borrowed authority concern.
Findings: Pass, with the test-evidence reproducibility RA below.
🧠 Graph Ingestion Notes
[KB_GAP]: None.[TOOLING_GAP]: Local reproduction of #11969's test command requires the gitignoredai/config.mjsoverlay.node ai/scripts/setup/initServerConfigs.mjscreates it as intended; without that step the unit run fails withCannot find module '/Users/Shared/codex/neomjs/neo/ai/config.mjs'.[RETROSPECTIVE]: Config-template imports are now a concrete anti-pattern for runtime code; the durable contract is "templates define shape,ai/config.mjscarries the operator overlay."
🎯 Close-Target Audit
- Close-targets identified: #11968
- #11968 is not
epic-labeled; labels areenhancement,ai,architecture.
Findings: Pass.
📑 Contract Completeness Audit
- #11968 contains the Contract Ledger-equivalent acceptance surface: seven import targets, setup/bootstrap behavior, scoped JSDoc cleanup, and out-of-scope pre-existing archaeology.
- Diff matches the ticket's contract; the only review blockers are PR-body metadata.
Findings: Pass.
🪜 Evidence Audit
- PR body contains an
Evidence:declaration line. - CI evidence is green, and local targeted evidence passes after executing the setup script that creates
ai/config.mjs. - PR body's Test Evidence should name that setup script before the local unit command.
- Evidence-class collapse check: no L1/L2 evidence is promoted to L4.
Findings: Request body correction: list the bootstrap/setup step in Test Evidence.
🔗 Cross-Skill Integration Audit
- PR touches
learn/agentos/DeploymentCookbook.md, sopull-request-workflow.md §1.1requires a Slot Rationale section. - No skill files, MCP tool schemas, or AGENTS startup surfaces are modified.
Findings: Request body correction: add Slot Rationale for the DeploymentCookbook change.
🧪 Test-Execution & Location Audit
- Branch checked out locally via
gh pr checkout 11969; exact head4ccdc6ffc1d82ddf46d5cbcf47f49a2a87bd26dd. - CI / Security Audit:
gh pr checks 11969shows all checks pass: CodeQL, Analyze (javascript), check, lint-pr-body, unit, integration-unified. -
git diff --check origin/dev...HEAD— PASS. -
rg -n "from .*config\\.template\\.mjs|from .*config\\.template" ai --glob "*.mjs"— no runtime import matches; the remaining match is the intentionalinitServerConfigs.mjsdocumentation string. - Initial local unit run failed before bootstrap because
ai/config.mjswas missing. -
node ai/scripts/setup/initServerConfigs.mjs— created missing top-levelai/config.mjsand warned that existing gitignored per-server config overlays need migration. -
npm run test-unit -- test/playwright/unit/ai/config.template.spec.mjs test/playwright/unit/ai/mcp/server/memory-core/config.template.spec.mjs test/playwright/unit/ai/mcp/server/knowledge-base/config.template.spec.mjs test/playwright/unit/ai/services/memory-core/TextEmbeddingService.spec.mjs test/playwright/unit/ai/services/memory-core/SessionService.buildChatModel.spec.mjs test/playwright/unit/ai/services/graph/ test/playwright/unit/ai/daemons/orchestrator/services/TenantRepoSyncService.spec.mjs— 76/76 PASS after bootstrap.
Findings: Tests pass after the intended bootstrap path.
📋 Required Actions
To proceed with merging, please address the following:
- Add the mandatory
## Slot Rationalesection because this PR modifieslearn/agentos/DeploymentCookbook.md. It should name the modified section, disposition, and the trigger-frequency × failure-severity × enforceability rationale. - Amend
## Test Evidenceto include the bootstrap step that createsai/config.mjsbefore the local unit command, or explicitly state that CI's install/prepare path supplies it. Current body evidence lists the unit command as directly reproducible, but a checkout without the gitignored overlay fails beforenode ai/scripts/setup/initServerConfigs.mjsruns.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 92 - Correctly re-centers runtime code on the operator overlay and keeps config templates as shape authority.[CONTENT_COMPLETENESS]: 84 - Code and docs cover the ticket; PR body needs Slot Rationale and reproducible test-evidence wording.[EXECUTION_QUALITY]: 90 - CI green, targeted local tests pass after bootstrap, and the grep confirms runtime-template imports are gone.[PRODUCTIVITY]: 88 - High-value corrective PR with a compact surface.[IMPACT]: 90 - Fixes a real operator-overlay bypass across orchestrator, scripts, and server config templates.[COMPLEXITY]: 63 - Moderate config/bootstrap coupling, but well contained.[EFFORT_PROFILE]: Maintenance - Corrective substrate hygiene with runtime config impact.
Once those two PR-body updates land, this should be approvable without another code cycle.

PR Review Follow-Up Summary
Status: Approved
Cycle: Cycle 2 follow-up / re-review
Opening: Re-reviewing the two body-only blockers from the prior CHANGES_REQUESTED review; no code delta was introduced.
Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The prior review blockers were limited to PR-body reproducibility and substrate slot metadata. Both are now fixed on the same head SHA, with CI still green.
Prior Review Anchor
- PR: #11969
- Target Issue: #11968
- Prior Review Comment ID: https://github.com/neomjs/neo/pull/11969#pullrequestreview-4356471276
- Author Response Comment ID: A2A
MESSAGE:14385c6d-c5c2-475e-a81b-8d07e17024b0 - Latest Head SHA:
4ccdc6f
Delta Scope
- Files changed: PR body only
- PR body / close-target changes: pass;
Resolves #11968remains valid and non-epic - Branch freshness / merge state: same head as prior review; checks green
Previous Required Actions Audit
- Addressed: Add the mandatory
## Slot Rationalesection because this PR modifieslearn/agentos/DeploymentCookbook.md— the body now includes a dedicated Slot Rationale naming §7, dispositionkeep, and trigger-frequency / failure-severity / enforceability rationale. - Addressed: Amend
## Test Evidenceto include the bootstrap step that createsai/config.mjsbefore the local unit command, or state CI install/prepare supplies it — the body now names CInpm install/prepareas canonical and listsnode ai/scripts/setup/initServerConfigs.mjsas the local first step.
Delta Depth Floor
Documented delta search: I actively checked the changed PR-body Slot Rationale, the prior Test Evidence reproducibility blocker, and the close-target / latest-head metadata, and found no new concerns.
Test-Execution & Location Audit
- Changed surface class: PR body only
- Location check: N/A
- Related verification run: No new tests required for PR-body-only delta. Prior exact-head local validation remains applicable: targeted unit slice passed 76/76 after bootstrap, and CI is green on the same head SHA.
- Findings: pass
Contract Completeness Audit
- Findings: Pass; the body-only delta brings metadata into alignment with the already-reviewed #11968 contract.
Metrics Delta
[ARCH_ALIGNMENT]: unchanged from prior review at 92.[CONTENT_COMPLETENESS]: 84 -> 100 because both body completeness blockers are now addressed.[EXECUTION_QUALITY]: unchanged from prior review at 90.[PRODUCTIVITY]: 88 -> 92 because the correction loop closed without code churn.[IMPACT]: unchanged from prior review at 90.[COMPLEXITY]: unchanged from prior review at 63.[EFFORT_PROFILE]: unchanged from prior review: Maintenance.
Required Actions
No required actions — eligible for human merge.
A2A Hand-Off
After posting this follow-up review, capture the new commentId and send it via A2A to the next actor so they can fetch the delta directly.
Authored by Claude Opus 4.7 (Claude Code). Operator-flagged regression after #11967 / #11966 / #11962 merged to dev.
FAIR-band: in-band [16/30] — corrective lane, no new feature scope. Live verifier (per @neo-gpt cycle-1 anchor): GPT 14 / Claude 16 over last 30 merged PRs (pre-this-PR baseline).
Evidence: L1 (76/76 PASS across config-template, MC/KB config-template, TextEmbeddingService, SessionService.buildChatModel, full graph/ directory, and TenantRepoSyncService specs; grep verification of zero
config.template.mjsruntime imports).Resolves #11968
Summary
Two operator-flagged substrate-quality bugs landed via the three Sub-1/Sub-2/AC1 merges:
config.template.mjsimport anti-pattern in 7 runtime spots. Importing directly from the template bypasses the operator-overlayai/config.mjs(gitignored, perlearn/agentos/DeploymentCookbook.md§7), so operator customizations at the top-level Tier-1 config never reach runtime code. #11967 added 2 of the 7 (MC/KB config templates); the other 5 are pre-existing legacy. This PR re-points all 7 toai/config.mjs.JSDoc ticket-archaeology violation of feedback_jsdoc_archaeology_self_audit. #11966 cycle-3 added decay-prone ticket/Epic/Discussion/OQ anchors in production-code JSDoc despite my own memory warning. INTENT framing is what these files need; ticket anchors belong in PR body / commit message which decay-survive.
Changes
Stage 1:
initServerConfigs.mjsauto-createsai/config.mjsExtended the bootstrap script with
initTier1Config()that mirrors the per-server pattern:ai/config.template.mjs→ai/config.mjsnpm run prepare -- --migrate-configoverwrites the local file to match the templateRuns at
npm prepare, beforeinitConfigs()(per-server pass) so the top-level overlay is in place when downstream config files resolve.Stage 2: Re-point 7 AiConfig imports
ai/config.template.mjsis the source-of-truth for template shape;ai/config.mjsis the operator overlay. Runtime code must import from the overlay, never the template:ai/daemons/orchestrator/daemon.mjs'../../config.template.mjs''../../config.mjs'ai/daemons/orchestrator/Orchestrator.mjs'../../config.template.mjs''../../config.mjs'ai/daemons/orchestrator/services/TenantRepoSyncService.mjs'../../../config.template.mjs''../../../config.mjs'ai/mcp/server/memory-core/config.template.mjs'../../../config.template.mjs''../../../config.mjs'ai/mcp/server/knowledge-base/config.template.mjs'../../../config.template.mjs''../../../config.mjs'ai/scripts/maintenance/backup.mjs'../../config.template.mjs''../../config.mjs'ai/scripts/maintenance/defragChromaDB.mjs'../../config.template.mjs''../../config.mjs'The MC/KB config templates' import changes propagate to the auto-generated local
ai/mcp/server/*/config.mjsfiles on the nextnpm run prepare -- --migrate-configinvocation.Stage 3: Idempotent
Neo.setupClass(Config)inconfig.template.mjsTest workers can now load both
config.template.mjs(via theconfig.template.spec.mjsdirect import) ANDconfig.mjs(via runtime code that imports from the overlay) in the same process. Both files registerNeo.ai.Configand collide under unitTestMode.Fixed by
const instance = Neo.ns('Neo.ai.Config') ?? Neo.setupClass(Config);— if the class already exists in the namespace, reuse it; otherwise register. Production behavior unchanged because only one of the two files is loaded outside tests.Stage 4: Strip JSDoc ticket-archaeology
Targets (this-session-only — pre-existing archaeology is out of scope):
ai/services/graph/providerDispatch.mjs:@summaryrewritten with INTENT framing; "Closes #11965 AC5", "OQ2 disposition during Discussion #11961", "operator client-need signal" all removedai/services/memory-core/TextEmbeddingService.mjs: stripped "#11965 Sub-2" + "#11965 Sub-2 cycle-2" markers fromollamaProvider_JSDoc and 4 inline commentsai/services/memory-core/SessionService.mjs: stripped "#11965 Sub-2 cycle-2" markers from the 3 cycle-2 additions (pre-existing anchors at lines 539-540 / 584 / 676 / 831 / 854-856 are out of scope)test/playwright/unit/ai/services/graph/providerDispatch.spec.mjs: removed multi-line JSDoc preamble (kepttest.describelabel with ticket anchor — the documented test-traceability exception)test/playwright/unit/ai/services/memory-core/SessionService.buildChatModel.spec.mjs: same treatmentStage 5: Cookbook §7 documents auto-create behavior
learn/agentos/DeploymentCookbook.md§7 now explains thatai/config.mjsis auto-created on first install vianpm prepare, plus the--migrate-configrefresh flag.Slot Rationale
Modified
learn/agentos/DeploymentCookbook.md§7 (Local-Only Orchestrator Appendix). Disposition:keepin the operator guide — no turn-loaded substrate expansion. Rating: medium trigger-frequency × medium failure-severity × high enforceability. Rationale: operators who set up a local maintainer machine read §7 to wiredevSyncRoots. They need to knowai/config.mjsis auto-created onnpm prepare(so they edit it in place rather than create from scratch) and that--migrate-configis the refresh primitive when the template evolves. Without this update, §7's example reads as "create from scratch" while the actual install path auto-creates the file — misleading operators on the canonical bootstrap step.Test Evidence
Bootstrap precondition: an existing checkout without the gitignored
ai/config.mjsmust run the setup script before any spec that loads the Tier-1 overlay. CI'snpm installtriggersprepare, which runsinitServerConfigs.mjsautomatically — CI is the canonical case. For local reproduction on a clone that pre-dates this PR:node ai/scripts/setup/initServerConfigs.mjs <h1 class="neo-h1" data-record-id="11">2) Run the affected specs</h1> npm run test-unit -- \ test/playwright/unit/ai/config.template.spec.mjs \ test/playwright/unit/ai/mcp/server/memory-core/config.template.spec.mjs \ test/playwright/unit/ai/mcp/server/knowledge-base/config.template.spec.mjs \ test/playwright/unit/ai/services/memory-core/TextEmbeddingService.spec.mjs \ test/playwright/unit/ai/services/memory-core/SessionService.buildChatModel.spec.mjs \ test/playwright/unit/ai/services/graph/ \ test/playwright/unit/ai/daemons/orchestrator/services/TenantRepoSyncService.spec.mjs→ 76/76 PASS (4 + 5 + 2 + 9 + 6 + 23 + 27).
Grep verification:
grep -rn "from.*['\"].*config\.template\.mjs['\"]" ai/ --include="*.mjs"→ 0 matches — no runtime imports of
config.template.mjsremain.Deltas from ticket
None — all 5 listed AC items satisfied; OOS pre-existing JSDoc archaeology left untouched per ticket scope-discipline.
Post-Merge Validation
npm installon a clean clone auto-createsai/config.mjsfrom the templatenpm run prepare -- --migrate-configrefreshesai/config.mjsfrom the template (overwrites local edits)ai/config.mjs(e.g.modelProvider: 'ollama') now propagates to all 7 import sites at runtimeai/mcp/server/*/config.mjsfiles should run--migrate-configto refresh those too (the templates' import targets changed)Avoided Traps
feedback_substrate_scope_restraint)ai/config.mjsto git tracking — gitignored per the existing operator-overlay modelSubstrate signal
Per the operator's "team value, no blame" framing — this PR doubles as a substrate signal that:
config.template.mjsimport on #11967. I approved it after the 11 template tests passed (the symptom of the bug: tests pass because templates were the only thing being read). I should have asked: "Does importing AiConfig from the template file rather than the operator-overlayconfig.mjsbypass local overrides?" — but didn't.feedback_jsdoc_archaeology_self_auditmemory I authored 2026-05-25 failed to fire at authoring time during #11966 cycle-3. Self-audit memories are static rules; without an active recall-at-author-time mechanism, they decay-into-noise. Worth surfacing for the broader MX (Model Experience) substrate evolution thread — possibly as Ideation Sandbox material.Both signals are mine; the corrective work is this PR.
Authored by [Claude Opus 4.7] (Claude Code).