Context
Found by the operator during the #17271 L1 drill-in (2026-08-17): the agent-detail Memories pane renders Memories unavailable · memories-read-failed — "The memories source did not answer." for neo-fable-clio — while the summaries corpus was demonstrably healthy (direct get_all_summaries calls answered rich payloads from the same plane, same tool, same identity).
Diagnosis — re-scoped after the falsifier ladder ran (see the ticket comments for the full ladder)
The original prime suspect (a malformed session UUID in the corpus + strict SDK output-schema validation) was falsified by a standalone reproducer: the exact fleet-child path (createPlaneMailboxClient → real admission → callTool('get_all_summaries')) answered all probes in ~110ms — the malformed row included, which parses fine and is retired to a cosmetic data-quality note.
What actually happened: the failing read was the first attempt after plane recovery on a dead session inside GitHub's auth-flap window — its one-reconnect re-proof hit a PAT revalidation that 503'd; the honest failure envelope then pinned itself forever, because the pane histories are request-driven with no cadence and nothing re-drives them when the transport heals. Two real defects survived the diagnosis:
- The source catch discarded the error entirely —
memories-read-failed was the whole story, and the five-probe diagnosis this ticket documents is exactly what that costs.
- The dead-pane gap:
reconnectFleet() ("every liveness seam, immediately") re-drove roster/activity/brain-health/wake-stream — but not the pane histories, the one read class with no cadence of its own.
The Fix (delivered by the resolving PR)
fleetMemoriesSource: a failure envelope carries a sanitized detail (message extracted, whitespace-collapsed, 240-bounded, credential families masked via the shared redaction authority); message-less failures omit the field rather than carrying an empty claim. The fleet child logs the same fact server-side ([fleet] memories read failed (<target>): <detail>).
FleetCockpit.reconnectFleet(): additionally re-drives the three pane histories (memories / catch-up / wake routes) THROUGH each pane's own refresh handler, whose guards (active agent, partition) decide whether a request exists — an unmounted pane is silence, never a throw.
Acceptance Criteria
Data-quality note (retired from scope)
summary_c4996813-01b9-4234-8bdd-4bd-ed3bf22c0970 carries a six-group sessionId — cosmetic, parses fine, not causal. If a summaries-hygiene lane ever exists, it belongs there; it blocks nothing here.
Out of Scope
Pane visual design + refresh affordances (#17268) · summaries content quality · new MC surface · a pane-level auto-retry cadence (the reconnect seam is the designed recovery path; a standing cadence would be new machinery the recovery button explicitly avoids).
Related
#17271 (origin L1 run — closed on the operator-witnessed evidence; this ticket continues as the hardening) · #17268 (pane design) · Epic #14560
Origin Session ID: 7ee47ccf-d1c7-469d-a75e-15cebf3b5ea5
Retrieval Hint: query_raw_memories("memories read failed detail redacted reconnect re-drive dead pane gap")
Context
Found by the operator during the #17271 L1 drill-in (2026-08-17): the agent-detail Memories pane renders
Memories unavailable · memories-read-failed — "The memories source did not answer."forneo-fable-clio— while the summaries corpus was demonstrably healthy (directget_all_summariescalls answered rich payloads from the same plane, same tool, same identity).Diagnosis — re-scoped after the falsifier ladder ran (see the ticket comments for the full ladder)
The original prime suspect (a malformed session UUID in the corpus + strict SDK output-schema validation) was falsified by a standalone reproducer: the exact fleet-child path (
createPlaneMailboxClient→ real admission →callTool('get_all_summaries')) answered all probes in ~110ms — the malformed row included, which parses fine and is retired to a cosmetic data-quality note.What actually happened: the failing read was the first attempt after plane recovery on a dead session inside GitHub's auth-flap window — its one-reconnect re-proof hit a PAT revalidation that 503'd; the honest failure envelope then pinned itself forever, because the pane histories are request-driven with no cadence and nothing re-drives them when the transport heals. Two real defects survived the diagnosis:
memories-read-failedwas the whole story, and the five-probe diagnosis this ticket documents is exactly what that costs.reconnectFleet()("every liveness seam, immediately") re-drove roster/activity/brain-health/wake-stream — but not the pane histories, the one read class with no cadence of its own.The Fix (delivered by the resolving PR)
fleetMemoriesSource: a failure envelope carries a sanitizeddetail(message extracted, whitespace-collapsed, 240-bounded, credential families masked via the shared redaction authority); message-less failures omit the field rather than carrying an empty claim. The fleet child logs the same fact server-side ([fleet] memories read failed (<target>): <detail>).FleetCockpit.reconnectFleet(): additionally re-drives the three pane histories (memories / catch-up / wake routes) THROUGH each pane's own refresh handler, whose guards (active agent, partition) decide whether a request exists — an unmounted pane is silence, never a throw.Acceptance Criteria
detailbeside the constantmemories-read-failedreason; credential-bearing messages are masked; whitespace collapsed; 240-bounded; message-less failures omit the field.reconnectFleetre-drives the pane histories through the panes' own refresh guards; unmounted panes tolerated.Data-quality note (retired from scope)
summary_c4996813-01b9-4234-8bdd-4bd-ed3bf22c0970carries a six-group sessionId — cosmetic, parses fine, not causal. If a summaries-hygiene lane ever exists, it belongs there; it blocks nothing here.Out of Scope
Pane visual design + refresh affordances (#17268) · summaries content quality · new MC surface · a pane-level auto-retry cadence (the reconnect seam is the designed recovery path; a standing cadence would be new machinery the recovery button explicitly avoids).
Related
#17271 (origin L1 run — closed on the operator-witnessed evidence; this ticket continues as the hardening) · #17268 (pane design) · Epic #14560
Origin Session ID: 7ee47ccf-d1c7-469d-a75e-15cebf3b5ea5
Retrieval Hint:
query_raw_memories("memories read failed detail redacted reconnect re-drive dead pane gap")