Context
Early standalone graduation from Discussion #15595 (Local Runtime Parity) — OQ8, declared in its Graduation Criteria as a do-now decoupler. This is a live gap today, not just a parity prerequisite: in the production cloud deployment, agents connecting remotely have no way to read sandman_handoff.md — the morning surface carrying Dream Pipeline typed gaps + Golden Path recommendations. Local agents read it as a repo file; remote/container agents cannot.
Live latest-open sweep: checked latest 20 open issues at 2026-07-20T11:45Z — no equivalent. A2A in-flight claim sweep (last 30, all read-states): no competing claim. KB semantic + exact sweeps: #14570 (handoff direction-weather section — writer-side, different), #13956 / #14663 / #14885 (handoff bloat/v2/concept-slice — writer-side, closed). No ticket covers serving the handoff to remote agents.
The Problem
handoffFilePathProd resolves resources/content/sandman_handoff.md from cwd (ai/mcp/server/memory-core/configBase.mjs:504, env override NEO_HANDOFF_FILE_PATH). The DreamService (a cloud-deployable orchestrator lane per ADR 0014) writes it on that path. Two consequences in a container/cloud topology: (1) the container has no repo checkout, so the write lands on ephemeral container fs or fails silently — the handoff is "written into a void"; (2) even where written, remote agents have no read path — it is a local file, and the only remote surfaces are the KB/MC MCP servers. Result: a cloud deployment's agents operate without the morning surface that anchors local agent stand-ups.
The Architectural Reality
ai/mcp/server/memory-core/configBase.mjs:44-47,504 — the handoff path leaf (handoffFilePathProd, NEO_HANDOFF_FILE_PATH) and the test-handoff resolution formula.
ai/daemons/orchestrator/services/DreamService.mjs:1069 — the DreamService is the handoff's author (sandman references in the consolidation pipeline).
- MC server tool surface: tools are registered in the MC MCP server with an openapi-shaped manifest (siblings:
query_recent_turns, get_rem_pipeline_state, inspect_deployment — the last being the precedent for a read-only operational-surface tool).
- Consumer contract: agents at session start (boot/recovery), human operators reading the morning surface remotely.
The Fix
Add a read-only get_sandman_handoff tool to the Memory Core MCP server:
- Tool:
get_sandman_handoff — reads the file at the resolved handoff path (handoffFilePathProd / NEO_HANDOFF_FILE_PATH), returns {content, path, mtimeMs, staleAfterMs, stale} where stale flags the handoff as older than the expected nightly cadence (mirror the freshness-gate pattern used by inspect_deployment's staleAfterMs). Missing file → explicit {content: null, reason: 'handoff-not-found'} — never a silent empty string.
- Registration: add to the MC server tool manifest/openapi surface following the
inspect_deployment precedent (read-only, no identity mutation, team-visible content).
- Tests: unit specs — present file (content + freshness), missing file (explicit null-reason), stale file (stale flag at threshold), custom
NEO_HANDOFF_FILE_PATH override.
- Docs: MemoryCore tool-surface doc + one line in the cloud-deployment operations guide (remote agents CAN now read the handoff; the writer persistence story is deployment-owned, see Out of Scope).
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
get_sandman_handoff MCP tool |
MC server tool manifest |
Returns {content, path, mtimeMs, staleAfterMs, stale} |
Missing file → explicit null-reason payload |
MemoryCore.md |
unit: 4 specs above |
| Handoff path resolution |
ai/mcp/server/memory-core/configBase.mjs:504 |
Tool reads the same resolved leaf — no second path source |
NEO_HANDOFF_FILE_PATH override honored |
Configuration.md |
unit: override spec |
| Freshness contract |
inspect_deployment staleAfterMs pattern |
stale: true beyond threshold; default 36h (nightly cadence + slack) |
Threshold overridable per call |
MemoryCore.md |
unit: stale-threshold spec |
Decision Record impact
none — additive read-only tool on an existing surface; no ADR conflict. Discussion-origin classification: Not needed (low-blast early graduation per D#15595 Graduation Criteria).
Discussion Criteria Mapping
- D#15595 Graduation Criteria: "Early standalone graduations: OQ8 (handoff serving) … may graduate as
[GRADUATED_TO_TICKET] items ahead of the main matrix" → this ticket.
- D#15595 OQ8 (Handoff serving path) → AC 1–4 below; the OQ's shape choice (MC tool vs MCP resource vs KB-ingested doc) is decided here in favor of the MC tool, with alternatives recorded under Avoided Traps.
Acceptance Criteria
Out of Scope
- Writer-side persistence in containers (the DreamService writing into ephemeral container fs) — a deployment concern owned by the parity epic / deployment overlay (volume mount or graph-backed handoff store); this ticket only creates the read path.
- Handoff content changes (v2 render work lives elsewhere —
#14663 line).
- KB ingestion of the handoff (see Avoided Traps).
Avoided Traps / Gold Standards Rejected
- MCP resource instead of tool — rejected: this codebase's MC surface is tool-shaped end-to-end; introducing the first resource for one read breaks surface consistency for zero gain.
- KB-ingest the handoff as a typed doc — rejected: the handoff is ephemeral daily state (refreshed nightly), not corpus; ingestion would pollute the KB with churn and serve stale embeddings.
- Graph-backed handoff store in this ticket — rejected as scope: the read path is independently valuable against the file contract; the store migration belongs to the parity epic's writer-side work.
Related
- Discussion: #15595 (source; OQ8 early standalone graduation)
- Handoff writer lineage:
#13956, #14663, #14885 (closed)
- Tool-shape precedent:
inspect_deployment (read-only operational surface + freshness gate)
- Forward consumer: D#15595's parity epic; ADR 0020 harness boot/recovery flows
Origin Session ID: 8d4ce1c3-0bf2-4bb0-bad9-e49836248afe
Retrieval Hint: "sandman handoff serving remote agents get_sandman_handoff cloud DreamService void"
Context
Early standalone graduation from Discussion #15595 (Local Runtime Parity) — OQ8, declared in its Graduation Criteria as a do-now decoupler. This is a live gap today, not just a parity prerequisite: in the production cloud deployment, agents connecting remotely have no way to read
sandman_handoff.md— the morning surface carrying Dream Pipeline typed gaps + Golden Path recommendations. Local agents read it as a repo file; remote/container agents cannot.Live latest-open sweep: checked latest 20 open issues at 2026-07-20T11:45Z — no equivalent. A2A in-flight claim sweep (last 30, all read-states): no competing claim. KB semantic + exact sweeps:
#14570(handoff direction-weather section — writer-side, different),#13956/#14663/#14885(handoff bloat/v2/concept-slice — writer-side, closed). No ticket covers serving the handoff to remote agents.The Problem
handoffFilePathProdresolvesresources/content/sandman_handoff.mdfrom cwd (ai/mcp/server/memory-core/configBase.mjs:504, env overrideNEO_HANDOFF_FILE_PATH). The DreamService (a cloud-deployable orchestrator lane per ADR 0014) writes it on that path. Two consequences in a container/cloud topology: (1) the container has no repo checkout, so the write lands on ephemeral container fs or fails silently — the handoff is "written into a void"; (2) even where written, remote agents have no read path — it is a local file, and the only remote surfaces are the KB/MC MCP servers. Result: a cloud deployment's agents operate without the morning surface that anchors local agent stand-ups.The Architectural Reality
ai/mcp/server/memory-core/configBase.mjs:44-47,504— the handoff path leaf (handoffFilePathProd,NEO_HANDOFF_FILE_PATH) and the test-handoff resolution formula.ai/daemons/orchestrator/services/DreamService.mjs:1069— the DreamService is the handoff's author (sandman references in the consolidation pipeline).query_recent_turns,get_rem_pipeline_state,inspect_deployment— the last being the precedent for a read-only operational-surface tool).The Fix
Add a read-only
get_sandman_handofftool to the Memory Core MCP server:get_sandman_handoff— reads the file at the resolved handoff path (handoffFilePathProd/NEO_HANDOFF_FILE_PATH), returns{content, path, mtimeMs, staleAfterMs, stale}wherestaleflags the handoff as older than the expected nightly cadence (mirror the freshness-gate pattern used byinspect_deployment'sstaleAfterMs). Missing file → explicit{content: null, reason: 'handoff-not-found'}— never a silent empty string.inspect_deploymentprecedent (read-only, no identity mutation, team-visible content).NEO_HANDOFF_FILE_PATHoverride.Contract Ledger Matrix
get_sandman_handoffMCP tool{content, path, mtimeMs, staleAfterMs, stale}ai/mcp/server/memory-core/configBase.mjs:504NEO_HANDOFF_FILE_PATHoverride honoredinspect_deploymentstaleAfterMspatternstale: truebeyond threshold; default 36h (nightly cadence + slack)Decision Record impact
none— additive read-only tool on an existing surface; no ADR conflict. Discussion-origin classification:Not needed(low-blast early graduation per D#15595 Graduation Criteria).Discussion Criteria Mapping
[GRADUATED_TO_TICKET]items ahead of the main matrix" → this ticket.Acceptance Criteria
get_sandman_handoffcallable via the MC MCP server over streamable-http, returning content + path + freshness metadatastaleflag fires past the freshness threshold; threshold overridable per callNEO_HANDOFF_FILE_PATHoverride honoredOut of Scope
#14663line).Avoided Traps / Gold Standards Rejected
Related
#13956,#14663,#14885(closed)inspect_deployment(read-only operational surface + freshness gate)Origin Session ID: 8d4ce1c3-0bf2-4bb0-bad9-e49836248afe
Retrieval Hint: "sandman handoff serving remote agents get_sandman_handoff cloud DreamService void"