skills/golem-powers/brain-store-fallback/SKILL.md
Fallback for failed brain_store calls: when BrainLayer returns null chunk_id, queues, DB-busy errors, or transport closures, write the exact content to docs.local/decisions for replay.
npx skillsauth add etanhey/golems brain-store-fallbackInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill whenever a brain_store call might not have durably written to
BrainLayer.
Wave evidence: 72h-mine found BrainLayer DB-busy and MCP transport closures as
the #2 severity-10 ecosystem pattern, with silent brain_store loss across six
or more recent sessions. See pain-points/_consolidated.md.
If brain_store does not return a concrete chunk_id, do not report that the
content was stored in BrainLayer.
Instead, write the exact original content to:
docs.local/decisions/<YYYY-MM-DD>-<slug>.md
Then report:
Queued to docs.local/decisions/<file> pending BrainLayer recovery.
Activate on any Tier 1 hard failure:
Transport closed-32000: Connection closedapsw.ReadOnlyErrordatabase is lockedbrain_store returns null, undefined, or no chunk_idTOOL_RETURNED_TEXT=noActivate on any Tier 2 soft queue signal:
chunk_id: nullqueued, queue depth, deferred, or similar without a
durable chunk idTreat Tier 3 signals as advisory:
brain_search also failed with a transport errorTier 3 means be ready to fall back on the next brain_store; it does not by
itself replace the primary brain_store attempt.
The fallback file is a local replay queue entry, not a BrainLayer ack.
Write YAML frontmatter followed by the exact original content:
---
intended_brain_store: true
importance: <1-10>
tags: [<original tags>]
timestamp: <ISO 8601>
reason: <transport_closed | db_busy | queued_null_chunk | readonly | unknown>
retry_attempted: false
chunk_id:
---
<original brain_store content, byte-for-byte>
Preserve all four brain_store semantics:
Do not add fallback annotations to the body. Do not reformat the body. Do not drop tags or importance.
Use the original timestamp date plus a deterministic slug:
docs.local/decisions/<YYYY-MM-DD>-<slug>.md
If --slug is supplied, sanitize it:
If no slug is supplied, derive one from the content:
<first-8-tokens>-<hash-prefix>
Where:
first-8-tokens: split the content on whitespace, trim leading and trailing
punctuation from each token, lowercase each token, keep only letters,
numbers, and hyphens, drop empty tokens, take the first eight, then join with
hyphens.hash-prefix: first eight characters of the lowercase hex-encoded SHA-256
hash of the original byte-for-byte content body.The same content with the same original timestamp must resolve to the same filename. This prevents retry pollution.
brain_store first.chunk_id is present and non-empty, report the BrainLayer chunk id.brain_store once after a short pause.retry_attempted: truechunk_id: <returned id>retry_attempted: truechunk_id:One retry per call site is the maximum. More retries make DB contention worse.
Use honest status language:
Stored in BrainLayer: <chunk_id> when a concrete chunk id exists.Queued to docs.local/decisions/<file> pending BrainLayer recovery when the
fallback file exists but no chunk id exists.BrainLayer store failed and fallback write failed only if both paths failed.Never say stored, saved to BrainLayer, or BrainLayer updated when only the
fallback file exists.
Boot-time replay lives in workflows/replay.md.
At the start of any session that expects to call brain_store, scan
docs.local/decisions/*.md for files with:
intended_brain_store: truechunk_idReplay each pending file through brain_store.
On success, update frontmatter in place with the returned chunk_id. Leave the
file where it is. Do not delete it. Do not auto-move it to _resolved/.
There is no replay cap for now because the expected queue is small. If a boot scan finds more than 100 pending files, stop and add a replay budget before processing them.
The frontmatter hooks: block is forward-compatible with per-skill hook
support. It covers hard transport/database failures, null chunk ids, common
queue text, TOOL_RETURNED_TEXT=no, and slow calls when the runtime exposes
elapsed time. If the runtime does not invoke it automatically, or does not expose
one of those result fields, apply the manual workflow above after every
brain_store call.
If brain_store returns a queue ack, null chunk id, slow response, or transport
error and you do nothing, you are reproducing the severity-10 failure.
Do not loop until BrainLayer recovers. One retry, then fallback queue.
Do not add notes such as (fallback) to the body. Replay deduplication depends
on the original content remaining byte-for-byte identical.
Do not omit importance, tags, or timestamp. Replay without these loses the
search value of the original store.
The fallback file is not proof BrainLayer has the content. Report the fallback path, not a fake store success.
/never-fabricate enforces the status language: fallback files are real, but
they are not BrainLayer storage./frustration-capture can write the user's verbatim feedback into this
fallback path when BrainLayer is unavailable./session-handoff should list pending fallback entries so the next session can
replay them./orc can remind workers to invoke this skill when BrainLayer write cadence
drops under load.| # | Scenario | Baseline | Target | Assertion |
|---|---|---|---|---|
| 1 | brain_store returns chunk_id: null | Agent reports stored | Agent reports queued fallback path | File exists |
| 2 | MCP returns Transport closed | Content is lost | Fallback file is written and cited | File exists and output mentions path |
| 3 | DB busy at >50 percent via mock | Multiple stores are lost | Each distinct content has one fallback file | Same content maps to same file |
| 4 | Successful store | Agent reports stored | Agent reports stored and writes no fallback | Zero fallback files |
| 5 | Boot replay with 3 pending files | Files accumulate | Successful files get chunk_id; failed files stay pending | Frontmatter reflects retry state |
Fixtures live in evals/fixtures/.
docs.local/decisions/ is the fallback queue path.chunk_id.tools
The human-eval UX contract for Phoenix views: turn-by-turn scrollable replay (not a scorecard), hide-but-copyable IDs, collapsed thinking, identity chips, tool filters, tiny frozen starter datasets, mark-wrong-in-thread, mobile-first. Use when: building or reviewing ANY Phoenix/eval view, annotation UI, session replay, or human-grading surface. Triggers: phoenix view, eval UI, annotation view, session replay, human eval UX, grading interface. NOT for: Phoenix data pipelines/ingest (capture scripts have their own specs).
tools
macOS systems specialist — AppKit NSPanel architecture, launchd services, socket activation, MCP bridge resilience, syspolicyd, and high-frequency SwiftUI dashboards. Use when building menu-bar apps, LaunchAgents, debugging syspolicyd/Gatekeeper/TCC, resilient UDS/MCP bridges, or SwiftUI dashboards at 10Hz+.
development
Bulk LLM-judging protocol for fleet-dispatched verdict runs (KG cluster, eval harness). Use when: dispatching or running judge workers (J1/J2/RT), planning bulk-apply from verdict JSONL, or triaging evidence_degraded outputs. Triggers: judge fleet, bulk judge, R3 verdicts, kg-judge, RT gate, evidence_degraded. NOT for: single-item code review, Phoenix view UX (use phoenix-human-view), or non-judge eval pipelines.
development
Quiet-down protocol for sprint close: when the fleet wraps, delete ALL polling crons and monitors, send ONE final dashboard + ONE message, then go SILENT. Use when: fleet wraps, all workers done, overnight queue exhausted, sprint close, Etan asleep/away with nothing approved left. Triggers: fleet wrap, wrap the fleet, stand down, going quiet, sprint close. NOT for: mid-sprint monitoring (keep your loops), spawning a successor (use /session-handoff first).