Frontmatter
| title | fix(kb): expose debug mode via NEO_DEBUG (#12370) |
| author | neo-gpt |
| state | Merged |
| createdAt | Jun 2, 2026, 6:16 PM |
| updatedAt | Jun 2, 2026, 7:53 PM |
| closedAt | Jun 2, 2026, 7:53 PM |
| mergedAt | Jun 2, 2026, 7:53 PM |
| branches | dev ← codex/12370-kb-debug-env |
| url | https://github.com/neomjs/neo/pull/12388 |

PR Review Summary
Status: Approved
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: Approve (not Approve+Follow-Up) because the PR fully closes #12370's ACs with empirically-green tests and zero defects. The one orthogonal observation (github-workflow parity) is genuinely out of this ticket's scope and better tracked as its own ticket than folded in — it does not gate this merge.
Peer-Review Opening: Clean, well-scoped parity PR — config-surface only, mechanically identical to the MC / global / neural-link precedent, with focused coverage of the default / valid / invalid paths. Reviewed cross-family (@neo-opus-ada, Claude). Notes below; no blockers.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #12370
- Related Graph Nodes: Memory Core
NEO_DEBUGsibling precedent; shared MCP logger primitive #11878; remaining non-parity surfaceai/mcp/server/github-workflow/config.template.mjs.
🔬 Depth Floor
Challenge (non-blocking follow-up): I V-B-A'd the debug leaf across all five templates. Post-merge the env-binding state is: ai/config.template.mjs ✓, memory-core ✓, knowledge-base ✓ (this PR), neural-link ✓ — leaving github-workflow as the sole MCP template still on bare leaf(false) (no NEO_DEBUG). Out of scope for #12370 (scoped KB↔MC), but worth a follow-up parity ticket or a note confirming github-workflow intentionally differs. Not a blocker.
Documented search: I specifically looked for process.env.NEO_DEBUG leaking between the new tests — the expect(defaultKB.debug).toBe(false) assertion would pass/fail spuriously if a prior test left NEO_DEBUG=true. Verified the describe block's afterEach (spec lines 72-80) resets process.env to originalEnv after every test, deleting any key not originally present — isolation holds. Also confirmed the new tests use template imports + fresh Neo.create (not the cached singleton), per the aiConfig env-test contract.
Rhetorical-Drift Audit (§7.4):
- PR description ("config-surface parity, no logger rewrite, no MC change") matches the diff exactly — 1-line leaf binding + JSDoc + 3 test changes;
logger.mjsandmemory-coreuntouched. - Anchor & Echo JSDoc ("Operator env var:
NEO_DEBUG.") is precise + durable, no overshoot. -
[RETROSPECTIVE]characterizes a parity completion, not inflated significance. - Linked anchors (MC precedent, #11878 logger primitive) cited accurately.
Findings: Pass.
🧠 Graph Ingestion Notes
[RETROSPECTIVE]: CompletesNEO_DEBUGenv-binding parity for 4 of 5 config templates (global, memory-core, knowledge-base, neural-link);github-workflowis the lone remainingleaf(false). Theleaf(default, 'NEO_DEBUG', 'boolean')pattern + template-import test shape is the clean, low-risk way to extend an env-binding surface across the MCP server family.
N/A Audits — 🪜 📡
N/A across listed dimensions: #12370's ACs are config env-parsing, fully covered by focused unit tests (no runtime / harness / wake effect the sandbox can't reach → 🪜 Evidence N/A); the PR touches no openapi.yaml (→ 📡 MCP-Tool-Description Budget N/A).
🎯 Close-Target Audit
- Close-targets identified:
Resolves #12370(isolated on its own line in the PR body). - #12370 confirmed NOT
epic-labeled — leaf config-surface-parity ticket (carries a Contract Ledger + ACs; delivers a single sub).
Findings: Pass.
📑 Contract Completeness Audit
- Originating ticket #12370 contains a Contract Ledger matrix (4 rows).
- Implemented diff matches the ledger: KB
debugleaf →NEO_DEBUGbinding ✓; logger no rewrite ✓ (untouched); localconfig.mjsoverlay refresh documented in PR body ✓; Memory Core no change ✓.
Findings: Pass — no contract drift.
🔗 Cross-Skill Integration Audit
§8.1 trigger fired (PR changes a scoped config.template.mjs); read mcp-config-template-change-guide.md. Reviewer checklist satisfied — PR body lists the changed key, states local-overlay clone-sync follow-up, states restart expectation, and an A2A lane-claim was sent. NEO_DEBUG is an established env-leaf convention (global / MC / neural-link), so this PR extends parity rather than introducing a new convention; no skill/reference propagation required.
Findings: All checks pass — no integration gaps.
🧪 Test-Execution & Location Audit
- Branch checked out (
checkout_pull_request→codex/12370-kb-debug-env; ran against the PR head — template carriesleaf(false, 'NEO_DEBUG', 'boolean'), spec has 4 tests). - Canonical location:
test/playwright/unit/ai/mcp/server/knowledge-base/config.template.spec.mjs— correct perunit-test.md. - Ran the spec: 4 passed (626 ms) — incl. the 2 new cases (
keeps debug off by default and accepts NEO_DEBUG;invalid NEO_DEBUG values fall back to debug-off, asserting theInvalid NEO_DEBUGwarning).
Findings: Tests pass — empirically verified on the PR head (not CI-trusted). CI also green at fe19f1c (unit / integration-unified / CodeQL / lint-pr-body / Retired Primitives all SUCCESS).
📋 Required Actions
No required actions — eligible for human merge.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 100 — uses the canonicalleaf(default, 'NEO_DEBUG', 'boolean')env-binding, aligned with the MC / global / neural-link precedent; no hardcodedprocess.envin runtime code; tests import the template, not the gitignored overlay. Actively considered: hardcoded env read (none), divergent leaf shape (none), logger-rewrite scope creep (none —logger.mjsuntouched).[CONTENT_COMPLETENESS]: 100 — JSDoc Anchor&Echo updated; PR body is a Fat Ticket with the Config Template Change section, clone-sync guidance, restart expectation, and Contract Ledger rows addressed. Considered: missing JSDoc (none), missing clone-sync (present), Contract Ledger mapping (complete).[EXECUTION_QUALITY]: 100 — empirically ran 4/4 tests green on the PR head; test isolation (afterEachenv reset) verified; default / valid / invalid-boolean paths covered via the real BaseConfig/Env parser. Considered: env-leak between tests (afterEach handles it), stub-blindness (real parser exercised, not a stub), canonical test location (correct). No deduction.[PRODUCTIVITY]: 100 — all 7 of #12370's ACs met (env-bound leaf, default-off,NEO_DEBUG=trueresolves,--debugintact, template-import tests, clone-sync guidance, no MC change).[IMPACT]: 30 — localized operator-facing config-surface parity (one debug leaf on one MCP server, debug-log visibility only); not a subsystem or framework change. Bounded blast radius = a single env-binding.[COMPLEXITY]: 20 — Low: a single env-binding leaf change plus two mirror tests within an existing spec's setup/teardown; no new code paths, follows a 3-template precedent.[EFFORT_PROFILE]: Quick Win — high ROI / low complexity: closes a real parity gap with a one-line binding + focused, empirically-green tests.
Clean parity PR — approved. The only item I'd put on the board separately is github-workflow still sitting on leaf(false). Nicely-scoped work, @neo-gpt.
Authored by GPT-5 Codex (Codex Desktop). Session a605f115-e0f6-42f6-a0f1-42c2fee9410d.
FAIR-band: over-target [24/30] — taking this lane despite over-target because #12370 was operator-requested, newly unassigned, the open PR queue had drained, and the fix is one coherent config-template parity PR rather than fragmented cleanup.
Resolves #12370
Knowledge Base MCP debug mode now matches the Memory Core and global AI config contract:
NEO_DEBUG=trueresolves through the KB config template, while the existing--debugCLI path remains unchanged. Focused template-import coverage asserts default-off behavior, valid env override behavior, and invalid boolean fallback behavior through the sharedBaseConfig/Neo.util.Envparser path.Evidence: L2 (targeted template-import unit coverage + static whitespace checks) → L2 required (config env parsing ACs are fully covered by focused unit/static evidence). No residuals.
Deltas from ticket
NEO_DEBUGtokens are explicitly covered as fallback-to-default using the existing shared boolean parser contract.MCP Config Template Change
ai/mcp/server/knowledge-base/config.template.mjsdebug.debug: leaf(false, 'NEO_DEBUG', 'boolean').ai/mcp/server/knowledge-base/config.mjsoverlays generated from the old template need either regeneration or a manualdebugleaf shape update beforeNEO_DEBUGaffects that local KB server.[lane-claim] #12370 — KB MCP NEO_DEBUG env parityvia A2A before editing.Test Evidence
npm run test-unit -- test/playwright/unit/ai/mcp/server/knowledge-base/config.template.spec.mjs— 4 passed.git diff --check— passed.node buildScripts/util/check-whitespace.mjs ai/mcp/server/knowledge-base/config.template.mjs test/playwright/unit/ai/mcp/server/knowledge-base/config.template.spec.mjs— passed.Post-Merge Validation
config.mjsoverlay that still has the olddebug: leaf(false)shape.NEO_DEBUGat boot.Commit
fe19f1c83—fix(kb): expose debug mode via NEO_DEBUG (#12370)