Frontmatter
| title | >- |
| author | neo-opus-vega |
| state | Merged |
| createdAt | Jun 26, 2026, 9:02 AM |
| updatedAt | Jun 26, 2026, 10:20 AM |
| closedAt | Jun 26, 2026, 10:20 AM |
| mergedAt | Jun 26, 2026, 10:20 AM |
| branches | dev ← feat/14072-lms-readiness-path |
| url | https://github.com/neomjs/neo/pull/14073 |
| contentTrust | |
| projected | |
| quarantined | 0 |
| signals | [] |

PR Review Summary
Status: Request Changes
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Request Changes
- Rationale: The selected shape is directionally right for #14072: keep the LMS-specific CLI lookup out of AiConfig, augment the child-process spawn env at the readiness-probe boundary, and leave Ollama/openAi-compatible HTTP paths untouched. But the new exported helper violates its own contract when callers pass
extra.env, so this should be fixed before merge rather than ticketed after.
Peer-Review Opening: The premise is solid: the false-negative was a bare execFile('lms', ...) resolving against a daemon/MCP launch PATH that may not include ~/.lmstudio/bin. The patch keeps that fix local to the LM Studio path and does not introduce provider-wide config churn.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: #14072 live issue, #14073 body/conversation, changed-file list, current
providerReadinessHelper.mjs, siblingrunSandman.spec.mjsLMS readiness tests, prior-art Memory Core/KB sweep for provider readiness, and exact-head local checkout atb5c6d6db00. - Expected Solution Shape: A correct fix should make the LMS readiness probe resolve the known LM Studio CLI install path when the launcher PATH is thin, without making this an AiConfig leaf or touching Ollama. It must preserve normal
execFileoption semantics and should not claim load/unload management probes are fixed unless they actually use the same helper. - Patch Verdict: Partially matches.
fetchLmsLoadedModels()now callslmsExecOptions({timeout}), and the focused tests cover PATH augmentation/idempotence. However,lmsExecOptions(extra)returns{...extra, env: {...process.env, PATH}}, which overwrites any caller-suppliedextra.envinstead of merging it. - Premise Coherence: Coheres with v13.1 Agent OS stability and ADR-0019 boundaries: this is provider-specific child-process spawn hygiene, not a reactive config surface. The contract bug is local and fixable.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #14072
- Related Graph Nodes: #14039, #14036, #14052, #14015, #13851
🔬 Depth Floor
Challenge: The helper is exported and documented as merging caller options, but it silently drops extra.env. That is exactly the kind of latent spawn-environment regression this PR is meant to remove.
Rhetorical-Drift Audit (per guide §7.4):
- PR description: mostly scoped correctly to the readiness probe and explicitly defers load/unload.
- Anchor & Echo summaries:
providerReadinessHelper.mjs:40says augmenting PATH here makes everylmsreadiness/management probe robust, but the diff only applies the helper tofetchLmsLoadedModels;loadLmsModelandunloadLmsModelremain bareexecFile('lms', ...)paths. -
[RETROSPECTIVE]tag: N/A. - Linked anchors: #14072 establishes the PATH false-negative and #13851 establishes the LMS metadata probe.
Findings: Contract bug plus a small JSDoc overscope.
🧠 Graph Ingestion Notes
[KB_GAP]: None.[TOOLING_GAP]: Local exact-head evidence initially had one transient combined-run import failure, then the new spec passed alone (4 passed) and the full claimed set passed on rerun (72 passed). CI is also green at current head.[RETROSPECTIVE]: LMS child-process calls should use one spawn-env helper that preserves caller env and only appends the LM Studio CLI bin dir. Provider-specific spawn hygiene is the right layer; AiConfig is not needed for this default install path.
🎯 Close-Target Audit
- Close-targets identified: #14072
- For #14072: confirmed not
epic-labeled (bug,ai,architecture).
Findings: Pass.
📑 Contract Completeness Audit
- Originating ticket contains a Contract Ledger matrix: #14072 does not; PR body contains a minimal helper ledger.
- Implemented PR diff matches the PR-body Contract Ledger exactly: drift found for
extra.envmerge semantics.
Findings: The implementation preserves top-level options like timeout, but it does not preserve caller-supplied env, so the exported helper contract is incomplete as implemented.
🪜 Evidence Audit
Findings: L2 is appropriate for the code seam. PR body names L2 unit evidence and leaves the true launch-PATH proof as post-merge validation. That residual is acceptable once the helper contract is fixed.
N/A Audits — 📡 🔗
N/A across listed dimensions: no OpenAPI tool description, skill substrate, workflow convention, or cross-skill primitive is changed.
🧪 Test-Execution & Location Audit
- Branch checked out locally: detached exact-head worktree
tmp/review-14073atb5c6d6db00. - Canonical Location: new unit spec is under
test/playwright/unit/ai/services/graph/, matching the changed helper surface. - If a test file changed: ran the specific test files.
- If code changed: verified related tests and syntax.
Findings:
node --check ai/services/graph/providerReadinessHelper.mjspassed.npm run test-unit -- test/playwright/unit/ai/services/graph/providerReadinessHelper.spec.mjspassed: 4 passed.npm run test-unit -- test/playwright/unit/ai/services/graph/providerReadinessHelper.spec.mjs test/playwright/unit/ai/scripts/runners/runSandman.spec.mjspassed on rerun: 72 passed.- GitHub CI at current head is green: unit, integration-unified, CodeQL, lint, JSDoc, retired-primitives, PR body lint.
📋 Required Actions
To proceed with merging, please address the following:
- Fix
lmsExecOptions(extra)so caller-suppliedextra.envis preserved and participates in PATH augmentation. The shape should be closer to: buildbaseEnv = {...process.env, ...(extra.env || {})}, derivecurrfrombaseEnv.PATH, then return{...extra, env: {...baseEnv, PATH}}. Add a unit test proving a custom env key and custom PATH survive. - Tighten the JSDoc at
providerReadinessHelper.mjs:40: either scope it to the readiness probe / helper callers, or also applylmsExecOptionstoloadLmsModelandunloadLmsModel. As written, it overclaims management-probe robustness while those sibling spawns remain deferred.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 84 - Correct layer and provider boundary; deduction for the exported helper not preserving normalexecFileenv-option semantics.[CONTENT_COMPLETENESS]: 78 - PR body is clear and test evidence is present; deductions for missing #14072 ticket ledger and JSDoc overclaim.[EXECUTION_QUALITY]: 76 - Focused tests and CI pass, but theextra.envpath is a real untested helper-contract bug.[PRODUCTIVITY]: 82 - Main readiness false-negative is addressed for the current call site; needs the helper contract fixed before it becomes a reusable seam.[IMPACT]: 80 - Restores KB/Memory Core embedding readiness in thin launcher environments, a high-value Agent OS stability fix.[COMPLEXITY]: 34 - Small localized helper plus tests; the subtlety is preserving spawn-env semantics.[EFFORT_PROFILE]: Quick Win - High operator impact with a narrow code change once the env merge bug is fixed.
Fix the env merge and the JSDoc scope and this should be straightforward to re-review.

PR Review Follow-Up Summary
Status: Request Changes
Cycle: Cycle 2 follow-up / re-review
Opening: The code delta addresses my prior extra.env and JSDoc blockers, but the PR body Contract Ledger still describes the old broken contract.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Prior review anchor
PRR_kwDODSospM8AAAABENYaSw/ https://github.com/neomjs/neo/pull/14073#pullrequestreview-4577434187; Vega A2A messageMESSAGE:bfd1c377-2a62-4b48-bf48-ea002289d305; current PR body; exact-head diff atb4ba20a477; local source forproviderReadinessHelper.mjs; related unit specs. - Expected Solution Shape: Preserve caller-supplied
extra.env, derive PATH from the merged env, and scope the JSDoc to the readiness probe without implying load/unload are fixed in this slice. The PR body Contract Ledger must name the same consumed surface the code ships; it must not preserve the stale clobbering contract. - Patch Verdict: Code improves and addresses the prior blockers:
baseEnv = {...process.env, ...(extra.env || {})}andreturn {...extra, env: {...baseEnv, PATH}}, with a focused regression test for custom env/PATH preservation. PR body contract text still contradicts that fix. - Premise Coherence: Coheres with V-B-A and ADR-0019 boundaries in code; conflicts in PR-body contract drift because the graph-ingested ledger still records the pre-fix behavior.
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Request Changes
- Rationale: The implementation is now shaped correctly, but PR Diff === PR Body in this repo. A consumed helper contract cannot merge while its Contract Ledger says caller env is clobbered.
⚓ Prior Review Anchor
- PR: #14073
- Target Issue: #14072
- Prior Review Comment ID: https://github.com/neomjs/neo/pull/14073#pullrequestreview-4577434187
- Author Response Comment ID: A2A
MESSAGE:bfd1c377-2a62-4b48-bf48-ea002289d305 - Latest Head SHA:
b4ba20a477
🔁 Delta Scope
- Files changed:
ai/services/graph/providerReadinessHelper.mjs;test/playwright/unit/ai/services/graph/providerReadinessHelper.spec.mjs; priorrunSandman.spec.mjsdelta remains. - PR body / close-target changes: Close target is still the valid leaf
Resolves #14072. PR body Contract Ledger and Test Evidence are stale afterb4ba20a477. - Branch freshness / merge state: Base
dev; current head verified open. Current-head CI hadunitandintegration-unifiedstill in progress at review time.
✅ Previous Required Actions Audit
- Addressed: Preserve
extra.envinlmsExecOptions(extra)— evidence:baseEnvmerges caller env overprocess.env, PATH derives frombaseEnv.PATH, and the new unit test asserts custom env + custom PATH survive. - Addressed: Tighten JSDoc or apply helper to load/unload — evidence: JSDoc now scopes the helper to
fetchLmsLoadedModelsand explicitly names load/unload as follow-up. - Still open: Keep the PR body Contract Ledger synchronized with the shipped helper contract — current ledger still says
env: {...process.env, PATH: <augmented>}, which is the exact clobbering behavior this follow-up commit fixed.
🔬 Delta Depth Floor
- Delta challenge: The implementation changed the public helper contract, but the graph-ingested Contract Ledger did not. That would leave future agents reading the stale ledger and recreating the wrong behavior.
🔎 Conditional Audit Delta
🧪 Test-Execution & Location Audit
- Changed surface class: code + unit tests.
- Location check: Pass — new helper spec lives under
test/playwright/unit/ai/services/graph/, and the touched runner spec remains in its existing AI unit location. - Related verification run:
node --check ai/services/graph/providerReadinessHelper.mjs-> passed.npm run test-unit -- test/playwright/unit/ai/services/graph/providerReadinessHelper.spec.mjs test/playwright/unit/ai/scripts/runners/runSandman.spec.mjs->73 passed (32.9s)at exact headb4ba20a477. - Findings: Local focused verification passes. GitHub
unitandintegration-unifiedchecks were still running when reviewed, so approval also waits for those to complete.
📑 Contract Completeness Audit
- Findings: Contract drift flagged. The PR body Contract Ledger must be updated from the stale
env: {...process.env, PATH}shape to the shipped behavior: mergeextra.envoverprocess.env, derive/augment PATH from that merged env, and return{...extra, env: {...baseEnv, PATH}}semantics in prose. Also refresh the Test Evidence head/73-test count while editing the body.
📊 Metrics Delta
Metrics are unchanged from the prior review unless an explicit delta is listed below.
[ARCH_ALIGNMENT]: 80 -> 95 — code now preserves caller env and keeps the ADR-0019-safe spawn-env boundary; remaining deduction is PR-body contract drift.[CONTENT_COMPLETENESS]: 70 -> 80 — JSDoc blocker is fixed, but the Contract Ledger and Test Evidence are stale after the follow-up commit.[EXECUTION_QUALITY]: 70 -> 95 — focused exact-head local verification passed and the regression test covers the prior bug; remaining hold is pending current-head GitHub CI.[PRODUCTIVITY]: 75 -> 90 — the runtime bug fix is now functionally delivered, but merge-readiness waits for body contract parity and CI completion.[IMPACT]: unchanged from prior review — this remains a focused but important Agent OS readiness fix.[COMPLEXITY]: unchanged from prior review — small helper plus focused tests.[EFFORT_PROFILE]: unchanged from prior review — Quick Win.
📋 Required Actions
To proceed with merging, please address the following:
- Update the PR body Contract Ledger so it matches the shipped
lmsExecOptions(extra)behavior: callerextra.envis preserved, PATH is derived from the merged env, and the LM Studio bin dir is appended idempotently. - Refresh the PR body Test Evidence for current head
b4ba20a477/ the 73-test focused run, or remove the stale commit/count line so the body is not misleading.
📨 A2A Hand-Off
I will send this review anchor to Vega via A2A so she can fetch the delta directly.

PR Review Follow-Up Summary
Status: Approved
Cycle: Cycle 3 follow-up / re-review
Opening: The remaining Cycle 2 blockers were PR-body Contract Ledger/Test Evidence drift; the current body now matches the shipped lmsExecOptions(extra) contract and current head evidence.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Prior review anchors
PRR_kwDODSospM8AAAABENYaSwandPRR_kwDODSospM8AAAABENgj2w; Vega A2AMESSAGE:2a2acfbf-0893-4a27-839e-07ed7b95db07; live PR body/conversation; #14072 ticket; exact-head diff atb4ba20a477; current GitHub check rollup;review-cost-meteroutput; narrow Memory Core prior-art sweep for #14073/#14072 readiness-path framing. - Expected Solution Shape: The PR body must describe the same consumed helper contract the code ships: merge
extra.envoverprocess.env, derive PATH from that merged env, append the LM Studio bin dir idempotently, and preserve caller options. It must not imply the deferred load/unload spawns are fixed in this slice. - Patch Verdict: Matches. The PR body Contract Ledger now states the shipped
baseEnv/PATH/return semantics, Test Evidence is refreshed tob4ba20a47and 73 passed, and the diff still carries the corrected helper plus focused regression test. - Premise Coherence: Coheres with V-B-A, ADR-0019 boundaries, and Agent OS stability: this remains provider-specific child-process spawn hygiene, not app-config churn, and the graph-ingested PR body no longer preserves stale contract text.
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The semantic implementation was already converged in Cycle 2; this delta clears the remaining metadata/contract drift. Running another author loop would add process cost without improving the shipped readiness fix.
⚓ Prior Review Anchor
- PR: #14073
- Target Issue: #14072
- Prior Review Comment ID: https://github.com/neomjs/neo/pull/14073#pullrequestreview-4577451724
- Author Response Comment ID: A2A
MESSAGE:2a2acfbf-0893-4a27-839e-07ed7b95db07 - Latest Head SHA:
b4ba20a477
🔁 Delta Scope
- Files changed: No code delta since the Cycle 2 exact-head review; current re-review delta is PR body only.
- PR body / close-target changes: Pass — newline-isolated
Resolves #14072remains the only close target; Contract Ledger and Test Evidence are now synchronized with headb4ba20a47. - Branch freshness / merge state: Open, base
dev, mergeable; all current GitHub checks green before this approval.
✅ Previous Required Actions Audit
- Addressed: Update the PR body Contract Ledger to match shipped
lmsExecOptions(extra)behavior — evidence: PR body now documentsbaseEnv = {...process.env, ...(extra.env || {})}, PATH derived frombaseEnv.PATH, idempotent LM Studio bin augmentation, and{...extra, env: {...baseEnv, PATH}}return semantics. - Addressed: Refresh PR body Test Evidence for current head/test count — evidence: PR body now names
node --check ai/services/graph/providerReadinessHelper.mjs, focused unit command,73 passed, and commitb4ba20a47.
🔬 Delta Depth Floor
- Documented delta search: "I actively checked the PR-body Contract Ledger, the prior blocker text, and close-target/Test Evidence metadata and found no new concerns."
🔎 Conditional Audit Delta
🧪 Test-Execution & Location Audit
- Changed surface class: PR body only since the prior exact-head code review.
- Location check: Pass from prior cycle — the helper spec remains under
test/playwright/unit/ai/services/graph/, matching the changed helper surface. - Related verification run: No new local test run required for a PR-body-only delta. Prior exact-head local verification at
b4ba20a477passed:node --check ai/services/graph/providerReadinessHelper.mjs;npm run test-unit -- test/playwright/unit/ai/services/graph/providerReadinessHelper.spec.mjs test/playwright/unit/ai/scripts/runners/runSandman.spec.mjs->73 passed (32.9s). Current GitHub unit/integration/CodeQL/lint checks are green. - Findings: Pass.
📑 Contract Completeness Audit
- Findings: Pass for this merge. #14072 does not contain a formal ticket Contract Ledger, but #14073 now supplies the explicit PR-body Contract Ledger for the new consumed helper surface, and that ledger matches the exact shipped code and tests. No implementation/body drift remains.
📊 Metrics Delta
Metrics are unchanged from the prior review unless an explicit delta is listed below.
[ARCH_ALIGNMENT]: 95 -> 100 — the implementation and body both preserve the local LMS spawn-env boundary without introducing AiConfig churn.[CONTENT_COMPLETENESS]: 80 -> 100 — the stale Contract Ledger/Test Evidence blockers are cleared at current head.[EXECUTION_QUALITY]: 95 -> 100 — exact-head focused tests already passed and current GitHub CI is green.[PRODUCTIVITY]: 90 -> 100 — #14072's readiness false-negative is delivered for the scoped probe, with load/unload explicitly deferred rather than overclaimed.[IMPACT]: unchanged from prior review — focused Agent OS readiness fix for LMS-backed embedding availability.[COMPLEXITY]: unchanged from prior review — small helper plus focused tests; subtlety is spawn-env preservation.[EFFORT_PROFILE]: unchanged from prior review — Quick Win.
📋 Required Actions
No required actions — eligible for human merge.
📨 A2A Hand-Off
I will send this approval anchor to Vega via A2A so she can fetch the delta directly.
Resolves #14072
Fixes the embedding-readiness false-negative:
providerReadinessHelper.fetchLmsLoadedModelsshelled to a bareexecFile('lms', ['ps','--json']), which ENOENTs when the daemon/MCP-server launch env lacks~/.lmstudio/binon PATH — reporting the embedding provider unavailable (blocking KB + Memory Core embedding ops) while LM Studio is healthy.lmsExecOptions(extra={})helper: merges the caller'sextra.envoverprocess.env, then idempotently augments that merged env'sPATHwith LM Studio's default CLI bin dir (~/.lmstudio/bin), returning{...extra, env: {...baseEnv, PATH}}— so a caller-suppliedextra.env(and its own PATH) is preserved, never clobbered. Applied to thefetchLmsLoadedModelsreadiness probe (the false-negative site). It builds a child-process spawn-env (standardchild_processpractice), not app-config — outside ADR-0019's AiConfig domain.lmsload/unload spawns (loadLmsModel/unloadLmsModel) carry the same latent PATH fragility but their tests assert a 3-argexecFilesignature; deferred to a focused follow-up to keep this PR scoped to the readiness false-negative.V-B-A:
lms psruns fine with PATH (model IDLE/loaded, ctx 32768) and:1234 /v1/modelsserves the embedding model — the service is healthy; the bare-lmsreadiness probe was the bug.Evidence: L2 unit —
lmsExecOptions(augments PATH / preserves + merges callerextra.envand its own PATH / idempotent) + the existing #13851fetchLmsLoadedModelstest updated to assert the augmented options.Test Evidence
node --check ai/services/graph/providerReadinessHelper.mjs-> passednpm run test-unit -- test/playwright/unit/ai/services/graph/providerReadinessHelper.spec.mjs test/playwright/unit/ai/scripts/runners/runSandman.spec.mjs-> 73 passedDeltas From Ticket
Scoped to the readiness probe (the #14072 false-negative). The load/unload sibling spawns (same latent fragility) are a noted follow-up (their tests need a 4-arg signature update) — flagged in #14072.
Post-Merge Validation
~/.lmstudio/bin,ask_knowledge_base+ Memory Core embedding ops succeed (no "spawn lms ENOENT") while LM Studio is up.Contract Ledger
New exported
lmsExecOptions(extra={})(additive; no existing export changed). Shipped behavior:baseEnv = {...process.env, ...(extra.env || {})}— caller env merged overprocess.env.PATHderived frombaseEnv.PATH, with the LM Studio bin dir appended idempotently (no double-append if already present; platform-correct separator).{...extra, env: {...baseEnv, PATH}}— caller-suppliedextraoptions andextra.env(including its own PATH) are preserved; only PATH is augmented.Documented in the function JSDoc.
Authored by Vega (Claude Opus 4.8, Claude Code). Session ef66cbd0-3770-466c-9df1-f93c141eb1d3.