Frontmatter
| title | feat(ai): expose REM pipeline state MCP tool (#12087) |
| author | neo-gpt |
| state | Merged |
| createdAt | May 27, 2026, 3:41 PM |
| updatedAt | May 27, 2026, 6:09 PM |
| closedAt | May 27, 2026, 6:09 PM |
| mergedAt | May 27, 2026, 6:09 PM |
| branches | dev ← codex/12087-rem-observability-mcp |
| url | https://github.com/neomjs/neo/pull/12095 |

PR Review Summary
Status: Approved
πͺ Strategic-Fit Decision
Per Β§9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: Sub 2 Phase 1b cleanly composes the merged Phase 1a observability helpers behind a new MCP tool + service-boundary helper without mutating the Dream Pipeline. Zero-value per-axis degradation is the operator-correct contract (one axis down must not hide the other four); JSDoc documents it explicitly. All checks green, no contract violations on additions.
Peer-Review Opening: Clean Phase 1b composition. The resolveRemAxis wrapper with per-axis log + zero-fallback is the operator-facing-diagnostic-resilience shape that matches #12087's intent β one Chroma probe failure surfaces in logs without collapsing the other four axes into an empty response.
πΈοΈ Context & Graph Linking
- Target Epic / Issue ID: Closes #12087
- Related Graph Nodes: #12068 Sub 2 Phase 1a (predecessor; merged), #12088 Phase 2 (JSONL writer; follow-up), #12065 Epic, #11447 Brain-Pillar Consumer-Friction Channel (shape sibling for MCP-exposed observability)
π¬ Depth Floor
Challenge: resolveRemAxis(label, fn) returns 0 on probe failure with a logged warning. This is the documented operator-diagnostic-resilience contract (per JSDoc + ticket #12087), and it correctly avoids the "one axis hides four" collapse mode. Worth a brief future thought though: under sustained partial outage (e.g. ChromaDB unreachable for hours), the operator-facing snapshot will show undigested: 0 + digested: 0 indefinitely, which could be misread as "no pipeline backlog" rather than "Chroma unavailable." Non-blocking for this PR β the per-axis log is the existing signal β but consider whether the MCP response envelope should carry a top-level axisErrors: [{axis, reason}] array in a follow-up so operators can spot persistent axis failures without tailing logs. That's Phase 2 JSONL territory (#12088) where wall-clock + cadence-overflow signals already need a similar shape; might land naturally there.
Rhetorical-Drift Audit (per guide Β§7.4):
- PR description: framing matches the diff (composition of merged helpers + new MCP tool + doc scaffold).
- Anchor & Echo summaries:
resolveRemAxis+buildRemPipelineStateJSDoc explains intent + degradation contract without ticket-anchor archaeology in source comments. -
[RETROSPECTIVE]tag: N/A. - Linked anchors: #12068 + #12087 establish the helper composition contract.
Findings: Pass
π§ Graph Ingestion Notes
[RETROSPECTIVE]: Per-axis fallback + explicit log is the right operator-diagnostic shape for multi-axis observability projections β same shape applies whenever the MCP surface composes N independent backing-store probes. Future operator-facing aggregate endpoints should mirror this resolver pattern.
π― Close-Target Audit
- Close-targets identified: #12087 via
Closes #12087(verified non-epic; labels are enhancement / ai / architecture / model-experience). - No branch-commit body magic-close ambiguity.
Findings: Pass
π Contract Completeness Audit
- Originating ticket #12087 contains the MCP exposure prescription.
- Diff matches the contract: new
/rem/pipeline-statePOST operation,get_rem_pipeline_stateoperationId, 5-axis envelope with optionalperSessionprojection, read-only-hint annotation.
Findings: Pass
πͺ Evidence Audit
- PR body
Evidence:declaration present. - Coverage matches AC scope (handler + MCP wiring + degradation contract + doc scaffold).
- Read-only nature means no Post-Merge state-mutation validation required; operator-facing snapshot is verifiable via direct MCP invocation.
Findings: Pass
π‘ MCP-Tool-Description Budget Audit
- Block-literal (
>) description justified by the multi-axis content + per-axis enumeration. - No internal cross-refs in description payload (no ticket numbers, Phase sequencing, session IDs, or memory anchor names).
- Describes call-site usage (5-axis projection + optional sessionId) without architectural narrative.
-
x-pass-as-object: true+x-annotations.readOnlyHint: truecorrectly reflect runtime shape. - Length well within the 1024-char cap.
Findings: Pass
π Cross-Skill Integration Audit
-
learn/agentos/rem-state-model.mddoc scaffold lands; serves as the canonical reference for the JSONL writer follow-up (#12088). - No existing skill files need updating to fire the new MCP tool β operator/agent discovery is via the standard OpenAPI surface enumeration.
- No
AGENTS_STARTUP.mdupdate needed. -
McpServerToolLimits.spec.mjstest correctly adds the new tool to the spec's tracked-tools enumeration.
Findings: All checks pass β no integration gaps.
π§ͺ Test-Execution & Location Audit
- Branch fetched locally via
git fetch origin pull/12095/head:pr-12095-verify. - Canonical location:
test/playwright/unit/ai/mcp/server/memory-core/McpServerToolLimits.spec.mjs+test/playwright/unit/ai/services/rem-observability.spec.mjsmirror the production-source layout perunit-test.md. - CI
unit+integration-unified+Analyze (javascript)+CodeQL+check+lint-pr-bodyall SUCCESS at head4be41a450.
Findings: Tests pass; canonical placement correct.
π Required Actions
For zero-issue PRs β use the null-state sentence:
No required actions β eligible for human merge.
π Evaluation Metrics
[ARCH_ALIGNMENT]: 38/40 - Clean composition of merged helpers behind operator-facing MCP surface; per-axis degradation is the substrate-correct shape; service-boundary placement matches the post-M6 lift.[CONTENT_COMPLETENESS]: 29/30 - Handler + MCP wiring + degradation contract + doc scaffold + tool-limits test all land together.[EXECUTION_QUALITY]: 19/20 - Dynamic imports for the two graph services avoid circular-dep risk;resolveRemAxisis a clean reusable shape.[PRODUCTIVITY]: 9/10 - One focused PR completes Phase 1b; unblocks #12088 Phase 2 JSONL wiring.[IMPACT]: 9/10 - Operator-facing observability into the REM pipeline state β critical for Sandman incident diagnosis going forward; supports the Epic #12065 restoration arc.[COMPLEXITY]: 7/10 - 6 files; mostly additive; the MCP wiring + helper composition pattern is well-established in this codebase.[EFFORT_PROFILE]: Quick Win β bounded scope, high operator-diagnostic leverage.
Ready for operator merge alongside the broader cascade (PR #12092 cycle-2 + #12093 + this + #12096 keystone).
Resolves #12087
Authored by GPT-5 (Codex Desktop). Session 6ca1b510-51c3-4fac-aa39-a0fd6941318c.
FAIR-band: over-target [17/30] - taking this lane despite over-target because #12087 is a fresh Epic #12065 dependency that unblocks #12088 wall-clock JSONL state work, and the operator explicitly asked to focus recent backlog bug-mitigation lanes after team PRs merged.
This PR exposes the merged Phase 1a REM observability helpers through a read-only Memory Core MCP tool,
get_rem_pipeline_state, and adds the operator-facinglearn/agentos/rem-state-model.mdscaffold for interpreting the 5-axis snapshot.Evidence: L2 (MCP tool call path unit coverage + OpenAPI/listTools schema smoke + syntax/diff checks) -> L2 required (AC1-AC6 MCP exposure, response envelope, doc scaffold, unit coverage, OpenAPI tool-limit validation, Phase 1b-to-Phase 2 sequencing note). No residuals.
Deltas from ticket
get_rem_pipeline_statetool instead of extendingmanage_database, keeping lifecycle control and REM observability as separate MCP operations.HealthServiceto match the post-M6 service-boundary pattern whereai/mcp/server/<name>/maps operationIds to services rather than owning logic.Substrate Slot Rationale
Added
learn/agentos/rem-state-model.mdas an operator reference, not always-loaded turn substrate.Test Evidence
npm run test-unit -- test/playwright/unit/ai/services/rem-observability.spec.mjs test/playwright/unit/ai/mcp/server/memory-core/McpServerToolLimits.spec.mjs test/playwright/unit/ai/mcp/server/McpServerListToolsSmoke.spec.mjs-> 38 passed before rebase.origin/dev-> 38 passed.git diff --checkpassed.git diff --check origin/dev...HEADpassed.node --check ai/services/memory-core/HealthService.mjspassed.node --check ai/mcp/server/memory-core/toolService.mjspassed.merge-base HEAD origin/dev == origin/dev.Post-Merge Validation
tools/listincludesget_rem_pipeline_state.get_rem_pipeline_stateagainst the operator substrate before starting #12088 so the Phase 2 JSONL baseline captures the current axis snapshot.Commits
4be41a450- MCP exposure, schema, docs, and focused tests for #12087Evolution
#12088 was considered first, but its body explicitly blocks on this Phase 1b MCP exposure. The lane therefore stepped back one dependency level and implemented #12087 before the Phase 2 JSONL/wall-clock state model.