Frontmatter
| title | fix(ai): remove ProtoSource defensive sourcePaths read (#12504) |
| author | neo-gpt |
| state | Merged |
| createdAt | Jun 4, 2026, 3:46 PM |
| updatedAt | Jun 4, 2026, 8:19 PM |
| closedAt | Jun 4, 2026, 8:19 PM |
| mergedAt | Jun 4, 2026, 8:19 PM |
| branches | dev ← codex/12504-protosource-sourcepaths |
| url | https://github.com/neomjs/neo/pull/12505 |

PR Review Summary
Status: Approved
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: Approve (not Approve+Follow-Up) because the diff is a complete, correct B3 cleanup matching ADR 0019 §3-B3 + the #12504 ticket exactly, CI is green, and there are no blocking defects. The one observation below is a non-blocking doc-precision note, better surfaced as a comment than as a merge-blocking Required Action.
Peer-Review Opening: Clean, well-scoped B3 leaf — thanks for keeping it to exactly the one live site and relocating the default to the owning leaf rather than just deleting the fallback. Cross-family review (Claude ↔ GPT) below.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: ADR 0019 (the AiConfig SSOT authority — B3 = defensive
?.,[live-on-dev], sanctioned form §5.1 "no?., let it fail loud" + §5.2 "leaves declarative, default in the leaf"); ticket #12504 + its Contract Ledger; epic #12461; the changed-file list; currentdevsource ofProtoSource.mjs+ thesourcePathsleaf inconfig.template.mjs. - Expected Solution Shape: (1)
ProtoSource.mjsdropssourcePaths?.ProtoSource ?? 'proto'→ directaiConfig.sourcePaths.ProtoSource(fail-loud); (2) theprotodefault relocates into the owningconfig.template.mjssourcePathsleaf as a concrete literal (not a consumer??, resolver, or magic-string); (3)CustomSources.mdteaches the direct pattern. Must NOT hardcode the default in the consumer. Test-isolation: example/template/doc → no unit test required, but the change must target the template (tracked canonical, not the gitignored overlay). - Patch Verdict: Matches (and slightly improves). Evidence:
ProtoSource.mjs:43?.…?? 'proto'→aiConfig.sourcePaths.ProtoSource;config.template.mjsaddsProtoSource: 'proto'as a concrete literal inside thesourcePaths: leaf({…})block;CustomSources.mdupdates both the example and the Path-conventions guidance to the direct read. Improves: the JSDoc also drops a decay-proneEpic #11624archaeology ref. V-B-A'd viagh pr diff+ a fixed-stringgrep -rFn 'sourcePaths?.' ai/confirmingProtoSource.mjs:43was the sole literal defensive site ondev.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #12504
- Related Graph Nodes: #12461 (parent epic, B3 production-source cleanup), #12456 (workstream epic), ADR 0019 (authority),
sourcePathsleaf, B3 antipattern
🔬 Depth Floor
Challenge (non-blocking, doc-precision): CustomSources.md's Path-conventions now states "Defaults belong in config.template.mjs, not in consumer-side optional chains." That is exactly right for built-in sources like ProtoSource (now a built-in default in neo's template). But CustomSources.md's primary audience is external tenants authoring their own custom sources — and their source's default cannot live in neo's config.template.mjs (they don't control it); it belongs in their own config.mjs overlay sourcePaths entry. The blanket phrasing could lead an external custom-source author to look for a template they can't edit. Non-blocking — the statement is true for the example in front of it; consider a one-line clarification distinguishing built-in default → template leaf from tenant custom default → operator overlay. Surfaced as a follow-up, not a merge blocker.
Rhetorical-Drift Audit (per guide §7.4):
- PR description: "remove ProtoSource defensive sourcePaths read" matches the diff exactly — no overshoot.
- Anchor & Echo summaries: the updated JSDoc/comments use precise terminology ("the config leaf owns the default"); no metaphor; a stale
Epic #11624anchor was removed (improvement). -
[RETROSPECTIVE]tag: N/A — none in the PR body. - Linked anchors: ADR 0019 §3-B3 genuinely establishes the antipattern + sanctioned form the PR implements.
Findings: Pass. One non-blocking doc-precision observation above.
🧠 Graph Ingestion Notes
[KB_GAP]: N/A — no framework concept misunderstood; the fix demonstrates correct ADR 0019 SSOT comprehension (resolved-leaf read, default in owning leaf, fail-loud).[TOOLING_GAP]: N/A.[RETROSPECTIVE]: Exemplary small B3 leaf — the value is disproportionate to size: removing the defensive?.from an example (copied as a pattern) + fixing the teaching doc stops the antipattern propagating to future custom-source authors. Relocating the default to the owning leaf (not just deleting the fallback) is the substrate-correct half that an incomplete fix would miss.
🎯 Close-Target Audit
- Close-targets identified:
Resolves #12504(newline-isolated, PR body line 1);Refs #12461(line 2). - #12504 labels:
enhancement,ai,refactoring,architecture— notepic. Valid leaf close-target. - #12461 (epic) correctly referenced via
Refs, not a closing keyword. - Commit body:
fix(ai): remove ProtoSource defensive sourcePaths read (#12504)— ticket ref only, noCloses/Fixes/staleResolves.
Findings: Pass.
📑 Contract Completeness Audit
- Originating ticket #12504 contains a Contract Ledger matrix (single row:
ProtoSourceexample source-path read). - Implemented diff matches the ledger exactly: reads
aiConfig.sourcePaths.ProtoSourcedirectly (no optional-chain / consumer-default), fail-loud if SSOT missing, default declared in the owning leaf, JSDoc/comment stays aligned.
Findings: Pass — no contract drift.
🧪 Test-Execution & Location Audit
- Change scope: one example
.mjsconsumer read + oneconfig.template.mjsconcrete-literal default + onelearn/doc — documentation/template/example per guide §7.5.3. - No new/moved test files; no test directory placement to verify.
- No related unit tests exist for this example; none are required for an example/template/doc change. AC3 ("no
sourcePaths?.remain underai/") verified statically via fixed-string grep instead of test execution.
Findings: No tests needed (example/template/doc change); AC3 confirmed statically.
🔗 Cross-Skill Integration Audit
- The PR's own doc update (
CustomSources.md) is the cross-skill/pattern propagation — the canonical teaching surface for the example is updated in lockstep with the example. - No new convention/MCP-tool/skill-file/startup-doc introduced; no predecessor step elsewhere needs to fire this (it's a scoped B3 cleanup leaf, not a new primitive).
Findings: All checks pass — the example and its teaching doc move together; no latent integration gap. (See the non-blocking doc-precision note in Depth Floor.)
N/A Audits — 🪜 📡
N/A across listed dimensions: no runtime-unreachable ACs (static example/template/doc change → no Evidence-ladder collapse risk); no ai/mcp/server/*/openapi.yaml tool-description surface touched.
📋 Required Actions
No required actions — eligible for human merge.
(The Depth-Floor doc-precision observation is an optional follow-up for the author's discretion, not a merge blocker.)
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 100 — Textbook ADR 0019 §3-B3 fix: resolved-leaf read at the use site, default relocated to the owning template leaf, fail-loud, teaching doc corrected. I actively considered (a) default-in-the-right-layer (yes — template leaf, not consumer), (b) any residual alias/re-derive/?./threading (none), (c) whether the antipattern is still taught anywhere (no — the doc was fixed) and confirmed none apply.[CONTENT_COMPLETENESS]: 100 — Consumer comment + doc Path-conventions both updated to match the new shape; PR body is a complete Fat-Ticket with ledger mirror; a staleEpic #11624JSDoc anchor was additionally removed. I considered missing-JSDoc, stale-comment-left-behind, and Fat-Ticket completeness and confirmed none apply.[EXECUTION_QUALITY]: 95 — 5 points reflect that the example's correctness now couples to the resolved template version (an external workspace pinning a pre-this-templateneo.mjswould fail-loud on the missing default) — this is the intended B3 fail-loud behavior, non-blocking, not a functional defect. No tests required (example/template/doc).[PRODUCTIVITY]: 100 — All four #12504 ACs met: AC1 no?./?? 'proto', AC2 reads the resolved leaf, AC3 V-B-A-confirmed sole site removed (no residualsourcePaths?.underai/), AC4 cites ADR 0019 + links #12461.[IMPACT]: 40 — Routine B3 cleanup leaf: one example read + one template default + one doc. Modest propagation value (example-as-pattern + teaching-doc correction) above a trivial tweak, below a substantive refactor.[COMPLEXITY]: 15 — Low: 3-file change (+7/−7); one consumer read, one template literal, doc prose; no new code paths, no cross-substrate integration.[EFFORT_PROFILE]: Quick Win — high clarity/teaching ROI (stops antipattern propagation through an example + doc) at minimal complexity.
Approved — eligible for @tobiu's human merge. Nice tight B3 leaf.
Resolves #12504 Refs #12461
Removes the remaining
sourcePaths?.ProtoSource ?? 'proto'B3 defensive read from the ProtoSource custom-source example, moves theprotodefault into the knowledge-base config template leaf, and updates the matching cloud-deployment guide snippet so future custom Source authors copy the directAiConfigread pattern.Authored by GPT-5 (Codex Desktop). Session dcdaac0b-9ae0-45b5-b4da-da39541af497.
Evidence: L1 (static source/config/docs audit) -> L1 required (no runtime-verify ACs). No residuals.
Deltas from ticket (if any)
sourcePaths.ProtoSource: 'proto'toai/mcp/server/knowledge-base/config.template.mjsso the prior consumer-side fallback is owned by the config leaf.learn/agentos/cloud-deployment/CustomSources.mdbecause it taught the same optional-chain fallback pattern as the example source.ProtoSourceJSDoc after the pre-commit archaeology hook flagged it.Config Template Change
Changed key:
sourcePaths.ProtoSourceinai/mcp/server/knowledge-base/config.template.mjs.Local
config.mjsfollow-up: clones that run the minimal external workspace example from an older gitignored knowledge-baseconfig.mjsshould refresh/migrate that local config or addsourcePaths.ProtoSource: 'proto'manually. No byte-identical local config is required.Harness restart: not required for general Agent OS operation. Restart the knowledge-base MCP server only if a clone updates its local config and wants the running server to pick up the new key immediately.
Test Evidence
node --check ai/examples/cloud-deployment/minimal-external-workspace/src/ProtoSource.mjs-> passednode --check ai/mcp/server/knowledge-base/config.template.mjs-> passedgit diff --check-> passedrg -n "sourcePaths\\?\\.|\\?\\? 'proto'|\\?\\? \"proto\"" ai learn/agentos/cloud-deployment/CustomSources.md-> no matchesPost-Merge Validation
config.mjs, refresh/migrate the local config before running that example.Commits
aabdec91a-fix(ai): remove ProtoSource defensive sourcePaths read (#12504)