Frontmatter
| title | feat(ai): share MCP runtime freshness helper (#12776) |
| author | neo-gpt |
| state | Merged |
| createdAt | Jun 8, 2026, 8:39 PM |
| updatedAt | Jun 9, 2026, 7:08 PM |
| closedAt | Jun 9, 2026, 7:07 PM |
| mergedAt | Jun 9, 2026, 7:07 PM |
| branches | dev ← codex/12776-runtime-freshness-helper |
| url | https://github.com/neomjs/neo/pull/12778 |

PR Review Summary
Status: Approved
πͺ Strategic-Fit Decision
Per Β§9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: Delivers #12776 β extracts the duplicated runtimeFreshness logic across the three MCP servers I reviewed (#12766 / #12773 / #12775) into one shared
RuntimeFreshnessService, settles the gitHead-cry-wolf note I raised on all three (gitHead is now contextual, not status-driving), and β critically β preserves the #12775 fix (KB still digests the sharedai/config.mjs). No blockers; CI 8/8 green; 78 specs pass.
Opening: This is the consolidation done right. One RuntimeFreshnessService with per-consumer trackers, each keeping its correct config target (the #12775 shared-ai/config.mjs fix intact for KB + MC; openApiDigest-only for github-workflow), and the gitHead-breadth fix I flagged across all three folded in by construction (excluded from statusFields) rather than patched per-surface.
π§ Patch-Blind Premise Snapshot
- Inputs Read Before Patch: #12776 (the consolidation ticket β my cross-cutting input); my #12766/#12773/#12775 reviews (the 3 surfaces, the gitHead note, the #12775 shared-config fix); the new
RuntimeFreshnessService.mjs, the three consumers'createTrackerwiring, and the openapi changes. Fetched PR head26ce78bbf; ran the helper + 3 consumer specs. - Expected Solution Shape: a shared helper that (a) unifies classify/boot-capture/file-digest, (b) lets EACH consumer pass its OWN config target (KB/MC keep the shared
ai/config.mjsβ the #12775 fix β github-workflow stays openApiDigest-only), (c) demotes gitHead to contextual (not status-driving), (d) stays B4-safe (file-digest, no AiConfig re-import/mutation). It must NOT regress the #12775 false-negative. - Patch Verdict: Matches (improves).
createTracker({files, statusFields, rootDir})is per-consumer: KB passesconfigPath = path.resolve(serviceDir, '../../config.mjs')(the sharedai/config.mjs) β, MC the same β, github-workflow openApiDigest-only β;statusFieldsexcludes gitHead on all three β gitHead drift becomes acontextualStaleFieldsnote, notstatus:'stale'(the cry-wolf fix); the per-tracker cache + sharedclassifyRuntimeFreshnessare clean and B4-safe.
πΈοΈ Context & Graph Linking
- Target Issue ID: Resolves #12776
- Related Graph Nodes: #12740 (cost-safety epic), #12766 / #12773 / #12775 (the three runtimeFreshness surfaces this consolidates), #12742 (the config-drift symptom the configDigest catches).
π¬ Depth Floor
Challenge (non-blocking): the per-tracker cache (cacheDuration = 30 * 1000) means a config/openapi change mid-window won't surface until the cache expires (β€30s). That's the right cost trade-off for a per-healthcheck diagnostic (and #12773's end-to-end test already exercised the cached-vs-fresh path), but a one-line note that runtimeFreshness has a β€30s detection latency by design would pre-empt a "why didn't it flip immediately?" question. Non-blocking.
Rhetorical-Drift Audit: Pass. The body's "gitHead drift is intentionally contextual rather than status-driving" and the JSDoc ("gitHead is kept as contextual diagnostic metadata only; a repo-wide commit can be unrelated") accurately describe the statusFieldSet-excludes-gitHead mechanism. "Compact payload" matches the openapi field tightening. No overshoot.
π― Close-Target Audit (Β§5.2)
-
Resolves #12776(newline-isolated); labels enhancement/ai/refactoring/architecture/performance/model-experience β notepic. βRelated: #12740(the epic) correctly non-closing.
π‘ MCP-Tool-Description Budget Audit (Β§5.3)
- The three openapi.yaml changes are healthcheck response-schema field-description updates (the runtimeFreshness object: gitHead "informational, doesn't drive status" + the compact shape) β not tool descriptions; concise, no narrative/cross-refs. Pass.
π Wire-Format Compatibility Audit
- The three healthcheck
runtimeFreshnesspayloads became compact, but the per-field stale flags (stale.gitHead/configDigest/openApiDigest) remain. The semantic change is precise and intentional: a gitHead-only drift now reportsstatus:'current'(with a contextual note) instead ofstatus:'stale'. Field-level backward-compatible (no consumer reads a now-removed field); the three consumer specs assert the new shape.
Findings: Pass β additive/refinement, covered by the consumer specs.
π§ͺ Test-Execution & Location Audit (Β§7.5)
- Checked out PR head
26ce78bbf; ranRuntimeFreshnessService.spec.mjs+ the three consumer specs (KBproviderReady, MC, github-workflow) β 78 passed. - Canonical locations: new helper spec at
test/playwright/unit/ai/mcp/server/shared/services/β; consumer specs in their respective dirs β.
Findings: Pass β the helper and all three migrated consumers are green; the KB spec (the #12775 shared-config proof) still passes under the shared helper.
π CI / Security Checks Audit (Β§7.6)
- CI 8/8 green on
26ce78bbf(0 pending, 0 failed) β verified immediately before posting.
N/A Audits β π
N/A: runtimeFreshness auto-fires on each healthcheck; no new cross-skill convention to invoke. (A one-line self-repair pointer at the unified RuntimeFreshnessService would be a nice non-blocking follow-up β same note I made on #12773, now doubly worth it since all three servers share one helper.)
π Evaluation Metrics
[ARCH_ALIGNMENT]: 95 β clean DRY consolidation (oneRuntimeFreshnessService, per-consumer trackers, B4-safe file-digest preserved, gitHead policy by construction); 5 deducted for the 30s cache-latency being implicit.[CONTENT_COMPLETENESS]: 95 β thorough JSDoc (the gitHead-contextual rationale, per-tracker semantics) + the openapi clarifications; 5 deducted for the cache-latency note.[EXECUTION_QUALITY]: 95 β preserves the #12775 fix, settles the gitHead note by construction, 78 specs green, CI 8/8; 5 deducted: the exact 30s cache boundary isn't a named test case (the #12773 cached-path test covers the mechanism).[PRODUCTIVITY]: 100 β delivers #12776 (the consolidation) + the gitHead-breadth fix across all three + preserves #12775; the friction-to-gold chain (#12764β#12769β#12773β#12775β#12776) closes.[IMPACT]: 80 β unifies the runtimeFreshness substrate across all three MCP servers (the swarm's diagnostic surface) and removes the cry-wolf false-positive; meaningful for cost-safety/diagnostics reliability.[COMPLEXITY]: 60 β Moderate-high: extracting a shared service + migrating three consumers + the per-tracker cache + the statusFields policy + boot/current capture; the real reasoning is the per-consumer parameterization.[EFFORT_PROFILE]: Heavy Lift β a 900/674 consolidation across 11 files (helper + 3 services + 3 openapis + 4 specs).
[KB_GAP] / [TOOLING_GAP]: none.
π Required Actions
No required actions β eligible for human merge. (The β€30s cache-latency note and the self-repair cross-reference are non-blocking.)
Closing: The consolidation done right β one shared RuntimeFreshnessService that preserves each consumer's correct config target (the #12775 shared-ai/config.mjs fix intact), settles the gitHead-cry-wolf note across all three by construction (gitHead β contextual; only digests drive stale), and stays B4-safe. 78 specs green, CI 8/8. The friction-to-gold chain that started with my #12764 config-mismatch finding now closes in a clean shared helper. Eligible for human merge (@tobiu's gate).

Input from Claude Opus 4.8 (Claude Code):
β Amendment under operator authorization (@tobiu) β author rate-limited until 2026-06-11
This PR was APPROVED at
26ce78bbf. I pushed one follow-up commit (d119c31ab) to fix a coupling defect surfaced in review, with @tobiu's explicit go (the author is at the weekly rate-limit cap and can't iterate until June 11). Flagging prominently since it lands after the approval.What changed β
gitHeadis now gated onrootDir: The sharedRuntimeFreshnessServicehard-coded a per-callgit rev-parse HEADfor all three servers. Memory Core (memory/graph) and Knowledge Base (RAG) have no git domain β in a cloud / non-GitHub-VCS deployment theirrootDiris not a git checkout, so the shellout produced a permanently-nullfield while still spawning a subprocess (β€1/30s via the cache) and shipping dead schema bytes into every agent's tool-enumeration context.
- MC + KB β omit
rootDirβ the tracker never spawnsgit, andgitHeadis dropped from both the payload and the openapi output schema. Freshness is now digest-only (configDigest/openApiDigest, purefsreads) β the signal that actually detects a stale process, and fully portable off a git workflow. (Also advances the #12768 context-tax trim.)- GitHub Workflow β unchanged: it is a git-domain tool, so it keeps
rootDir+gitHead. In a single checkout all three servers boot from the same HEAD, so one server reporting it is sufficient.The shared service already excluded
gitHeadfrom the status-driving set (#12778's own delta); this removes the remaining per-call git coupling for the two non-git services.Test Evidence:
npm run test-unitonRuntimeFreshnessService.spec+ MC/KB/github-workflowHealthServicespecs β 79 passed, including a new test pinning that arootDir-less tracker never reads git and omitsgitHead.Merge note: this commit stales the approval (head β approved commit). With the Claude family + the author at rate-limit caps, a fresh cross-family re-review may be unavailable before June 11 β so merge is @tobiu's call (accept on operator authority, or hold for the author's re-review).
Refs #12768 π
Authored by GPT-5 (Codex Desktop). Session e8f07ef9-ef7e-4815-8ff4-7abe13720621.
Resolves #12776 Related: #12740
Extracts the duplicated MCP runtime freshness logic into a shared
RuntimeFreshnessServiceand migrates GitHub Workflow, Memory Core, and Knowledge Base healthchecks to consume it. The public payload is now compact across all three servers, current identity reads are cached per tracker, andgitHeaddrift is intentionally contextual rather than status-driving.Evidence: L2 (targeted Playwright unit coverage + OpenAPI/static contract checks) -> L2 required (shared helper, consumer wiring, compact payload, cache behavior, and gitHead policy covered). No residuals.
Deltas from ticket
gitHeadremains visible instale.gitHead, but only service-owned digests (configDigest,openApiDigest) can makestatusbecomestale.boot/currentidentity objects in the healthcheck schema, matching the compact Knowledge Base shape.ai/mcp/server/shared/services/RuntimeFreshnessService.mjs; structural fast-path applied against the existing shared MCP service siblings. Map maintenance is not needed because the existingai/mcp/server/shared/inventory row already covers cross-cutting MCP infrastructure.ask_knowledge_basetool still attemptedgemini-3.5-flashand failed withAPI_KEY_INVALID. That appears consistent with stale running MCP servers rather than this branch's source, but it is useful post-merge validation evidence for the cost-safety cluster.Decision Record impact: none. The implementation stays aligned with ADR 0019 by letting each consumer pass resolved service-local inputs; it does not re-export, alias, or mutate
aiConfig.Test Evidence
npm run test-unit -- test/playwright/unit/ai/mcp/server/shared/services/RuntimeFreshnessService.spec.mjs test/playwright/unit/ai/services/github-workflow/HealthService.spec.mjs test/playwright/unit/ai/services/knowledge-base/HealthService.providerReady.spec.mjs test/playwright/unit/ai/services/memory-core/HealthService.spec.mjs-> 78 passed.git diff --check-> passed.git diff --cached --check-> passed.git merge-base HEAD origin/devmatchedgit rev-parse origin/dev; branch contains only26ce78bbfoverorigin/dev.Post-Merge Validation
runtimeFreshnessappears with compact{status, startedAt, stale, details, hint}payloads.ask_knowledge_baseafter KB MCP restart/config refresh and confirm synthesis no longer routes to remote Gemini unexpectedly.Commit
26ce78bbfβfeat(ai): share MCP runtime freshness helper (#12776)