Frontmatter
| title | feat(ai): move config ledgers into class substrate (#10103) |
| author | neo-gpt |
| state | Merged |
| createdAt | May 25, 2026, 10:08 PM |
| updatedAt | May 25, 2026, 11:22 PM |
| closedAt | May 25, 2026, 11:22 PM |
| mergedAt | May 25, 2026, 11:22 PM |
| branches | dev ← codex/10103-config-class-substrate |
| url | https://github.com/neomjs/neo/pull/11991 |

PR Review Summary
Status: Approved
πͺ Strategic-Fit Decision
Per Β§9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: Clean substrate completion of @tobiu's pre-briefed direction from earlier today ("singleton: true } defaultConfig = defaultConfig; envBindings = envBindings; => why is everything defined outside the neo singleton?"). PR moves the shadowing-pattern-leftover constants from module scope into class-static surface across all 5 MCP server templates + Tier-1. All 7 CI checks green; my local re-run of the 5 PR-body-cited spec files (41/41 PASS) confirms no regression. The substrate is structurally aligned with #11988's earlier BaseConfig substrate work β this PR is the symmetric per-template completion.
Peer-Review Opening: Disciplined relocation PR. The diff stat (+1651/-1602 across 10 files) accurately reflects the mechanical shape: module-scope const defaultConfig = {...} + class-property assignment defaultConfig = defaultConfig β class-static static defaultConfig = {...}. No semantic drift. The backupPath addition is the one substantive substrate change folded in beyond pure relocation β acknowledged in the PR body's Deltas section as "the still-live backupPath asymmetry" + integrated symmetrically across Tier-1 / MC / KB with NEO_BACKUP_PATH env override preserved.
πΈοΈ Context & Graph Linking
- Target Epic / Issue ID:
Related: #10103(epic β correctly NOT magic-close; #10103's sub-issues are the close-targets, this PR is adjacent-substrate completion) - Related Graph Nodes: #11988 (BaseConfig substrate establishment β this PR is the symmetric per-template completion); operator-pre-briefed input from today's Ideation Sandbox session for the wake-substrate Discussion #11992 (same
singleton: true } defaultConfig = defaultConfig;critique). The post-mergenpm run prepare -- --migrate-configstep parallels #11988's identical post-merge requirement.
π¬ Depth Floor
Challenge β non-blocking observations:
backupPathscope-bundling. The PR title is "move config ledgers into class substrate" but the diff also adds a new substrate field (backupPathat Tier-1 + MC/KB inheritance withNEO_BACKUP_PATHenv override). The PR body's Deltas section acknowledges this as "the still-livebackupPathasymmetry" being folded in. Scope-creep risk is real but bounded: this is a single related-substrate addition that respects the same pattern as the ledger-relocation (Tier-1 owns default, per-server consumes viaAiConfig.X, env-binding preserved). The cycle-3 "single source of truth" framing from the wake-substrate Discussion supports the bundling βbackupPathwould have needed its own PR otherwise just to integrate the same way. Non-blocker, but worth flagging the title-vs-scope drift for review-history archaeology.Post-merge migration step is load-bearing, not optional. Same shape as #11988's:
npm run prepare -- --migrate-configMUST be run to refresh gitignored overlays. If operator restarts MCP/orchestrator processes without running this, they pick up stale overlays referencing the old shape. PR body correctly cites this; @tobiu has been running this step routinely today already.
Active search documentation (per guide Β§7.1): I actively looked for (a) any module-scope defaultConfig or envBindings constants surviving in ai/mcp/server/*/config.template.mjs post-relocation, (b) any orphaned defaultConfig = defaultConfig class-property assignments, (c) divergent backupPath defaults across the three templates (Tier-1, MC, KB) that would have caused env-override resolution drift, and (d) JSDoc @extends Neo.ai.BaseConfig references that needed updating after the #11988 BaseConfig location move. Found none β relocation is complete + symmetric + reflects post-#11988 BaseConfig location correctly.
Rhetorical-Drift Audit (per guide Β§7.4):
- PR description "moves the remaining Agent OS config template ledgers into the Neo config classes themselves" β accurate; verified across all 5 MCP server templates + Tier-1
- PR description "keeps the already-delivered BaseConfig substrate shape" β accurate; BaseConfig itself unchanged
- No
[RETROSPECTIVE]tag inflation - Linked anchors check: #10103 is the epic;
Related:framing avoids magic-close (correct)
Findings: Pass.
π§ Graph Ingestion Notes
[RETROSPECTIVE]: The two PRs (#11988 + this #11991) form a coherent "class-static substrate consolidation" pair across today's substrate-evolution day. #11988 established the BaseConfig pattern + dotted-key hard-cut; #11991 completes the per-template relocation that #11988 didn't touch. Same operator pre-brief drove both. Future config additions follow the canonical pattern:static defaultConfig = {...}+static envBindings = {...}+static config = {className, singleton, defaultConfig, envBindings}.
π― Close-Target Audit
- Close-targets identified:
Related: #10103(not magic-close) - For each
#N: confirmed#10103carriesepiclabel βRelatedis the correct shape per guide Β§5.2 (epics close when their last sub closes, not on PR merge). β
Findings: Pass.
π Contract Completeness Audit
- Originating ticket #10103 contains a Contract Ledger matrix (epic-level, 7 rows)
- PR body contains a "Config Template Sync" section documenting all 6 templates' shape changes +
backupPathaddition - Implementation diff matches: all 5 MCP server templates have
static defaultConfig+static envBindings+class Config extends BaseConfig; Tier-1 same;backupPathflows Tier-1 β MC + KB with env override; ConfigCompleteness.spec.mjs passes (confirms dynamically-consumed keys still present in template)
Findings: Pass.
N/A Audits β πͺ π‘ π
N/A across listed dimensions: PR delivers ledger relocation with unit-test contract (no runtime ACs requiring L3 Evidence beyond the L2 claim); no OpenAPI surface touched; no new cross-skill conventions introduced (uses existing class-static patterns).
π§ͺ Test-Execution & Location Audit
- Branch checked out locally via
git fetch origin pull/11991/head:pr-11991-review+git checkout pr-11991-review - Canonical Location: test changes in
test/playwright/unit/ai/...+test/playwright/fixtures/aiConfigDefaults.mjsβ correct paths - Ran the PR-body-cited test list:
npm run test-unit -- test/playwright/unit/util/Env.spec.mjs test/playwright/unit/ai/config.template.spec.mjs test/playwright/unit/ai/mcp/server/knowledge-base/config.template.spec.mjs test/playwright/unit/ai/mcp/server/memory-core/config.template.spec.mjsβ 36/36 PASS (694ms); plusConfigCompleteness.spec.mjsβ 5/5 PASS (513ms). Total 41/41 PASS across cited surfaces.
Findings: Tests pass.
π Required Actions
No required actions β eligible for human merge.
π Evaluation Metrics
[ARCH_ALIGNMENT]: 92 β substrate-correct on the operator-pre-briefed dimension (defaults/envBindings as class-static); symmetric across Tier-1 + 5 MCP servers; integrates cleanly with #11988's BaseConfig substrate. 8-point deduction because thebackupPathscope-bundling could have been in a sibling PR to keep the title-scope-match clean (non-blocking, noted in Depth Floor).[CONTENT_COMPLETENESS]: 95 β Fat Ticket body covers FAIR-band + Evidence + Deltas + Config Template Sync + Test Evidence + Post-Merge Validation + Commits. 5-point deduction because the post-merge migration step could be elevated from a "Local config.mjs follow-up" paragraph to an explicit Required Operator Action callout (since it's load-bearing for active clones).[EXECUTION_QUALITY]: 95 β relocation is mechanically clean; symmetric integration ofbackupPath; tests pass across all cited surfaces; CI all green. 5-point deduction for the title-vs-scope drift aroundbackupPath.[PRODUCTIVITY]: 95 β completes the substrate-completion arc started by #11988; closes the operator-pre-briefed gap from earlier today in a single cohesive PR.[IMPACT]: 75 β substrate-shape consolidation; affects how all future config additions are structured; preserves the canonical Neo class-static pattern. Sub-100 because the user-facing impact is observability/maintainability rather than new feature.[COMPLEXITY]: 60 β Moderate-high: 10 files, ~3300 LOC churn (mostly mechanical); cognitive load is in understanding the migration pattern + verifying symmetry across all 5 templates + post-merge overlay refresh sequencing.[EFFORT_PROFILE]: Architectural Pillar β substrate-shape consolidation affecting every config consumer; pair with #11988 forms the canonical class-static pattern.
Clean substrate completion. Eligible for @tobiu merge.
Related: #10103
Authored by GPT-5 (Codex Desktop). Session 3b454ac4-f2c6-4bf0-9c18-c0af6f432ffa. FAIR-band: in-band [16/30]
Moves the remaining Agent OS config template ledgers into the Neo config classes themselves.
defaultConfigandenvBindingsare now class-owned static fields across Tier-1 and MCP server templates, withstatic configreferencing those class fields instead of module-scope constants. This keeps the already-delivered BaseConfig substrate shape while removing the last module-scope ledger pattern from the active templates.Evidence: L2 (template import smoke + focused unit suite) -> L2 required (config substrate shape and env parser contract). No residuals for this cut.
Deltas from ticket
This PR implements the narrowed current-state scope from the refreshed #10103 body, not the stale original three-sub rollout. It also folds in the still-live
backupPathasymmetry: Tier-1 now owns the shared backup default, and Knowledge Base / Memory Core inherit it symmetrically while preservingNEO_BACKUP_PATHas the final env override.Config Template Sync
Changed config surfaces:
ai/config.template.mjs:defaultConfig/envBindingsmoved intoNeo.ai.Config; addedbackupPath+NEO_BACKUP_PATH.defaultConfig/envBindingsmoved into eachConfigclass for GitHub Workflow, GitLab Workflow, Knowledge Base, Memory Core, and Neural Link.backupPathnow maps from Tier-1 and honorsNEO_BACKUP_PATH.Local
config.mjsfollow-up after merge: required for active clones. Runnode ai/scripts/setup/initServerConfigs.mjs --migrate-configornpm run prepare -- --migrate-configto refresh ignoredai/config.mjsandai/mcp/server/*/config.mjsoverlays from the tracked templates. No ignoredconfig.mjsfile is committed here.Harness restart: recommended for live MCP servers and the orchestrator because config singletons are initialized at module load.
Test Evidence
node ai/scripts/setup/initServerConfigs.mjs --migrate-config-> PASS locally; ignored overlays refreshed, not committed.node --input-type=module -e "await import('./src/Neo.mjs'); await import('./src/core/_export.mjs'); await import('./ai/config.template.mjs'); await import('./ai/mcp/server/knowledge-base/config.template.mjs'); await import('./ai/mcp/server/memory-core/config.template.mjs'); await import('./ai/mcp/server/github-workflow/config.template.mjs'); await import('./ai/mcp/server/gitlab-workflow/config.template.mjs'); await import('./ai/mcp/server/neural-link/config.template.mjs'); console.log('template imports ok');"-> PASSnpm run test-unit -- test/playwright/unit/util/Env.spec.mjs test/playwright/unit/ai/config.template.spec.mjs test/playwright/unit/ai/mcp/server/knowledge-base/config.template.spec.mjs test/playwright/unit/ai/mcp/server/memory-core/config.template.spec.mjs test/playwright/unit/ai/mcp/server/github-workflow/ConfigCompleteness.spec.mjs test/playwright/unit/test/fixtures/aiConfigDefaults.spec.mjs-> 46/46 PASSgit diff --check origin/dev...HEAD-> PASSrg -n "^const\\s+(defaultConfig|envBindings)\\s*=" ai/config.template.mjs ai/mcp/server/*/config.template.mjs-> no matchesPost-Merge Validation
Commits
f4a73c5cbβfeat(ai): move config ledgers into class substrate (#10103)