Open Second Brain
Memory server
First committed by hermes-vps-agent
Published in itechmeat/open-second-brain. Publisher page
550 GitHub stars
What it is
Second brain for AI agents using Obsidian-compatible Markdown vaults. Works with Hermes, Claude Code, Codex, and OpenClaw.
AutoGineer overview, from the brain’s own files
Open Second Brain acts as a memory provider for AI agents, enabling them to read and write persistent knowledge directly into an Obsidian-compatible Markdown vault. It employs a deterministic 'dream' pass to convert repeated signals into actionable rules, while maintaining a hash-chained log for auditability. The system supports various agent clients through MCP servers, lifecycle hooks, and a dedicated CLI, ensuring that agent-learned information remains accessible, versioned, and searchable as standard Markdown files.
How it works
Memory model: Hybrid
AutoGineer overview, from the brain’s own files
The system organizes data into a Brain folder containing Markdown files. Agents interact with this vault via MCP servers, lifecycle hooks, or the o2b CLI. Signals from agents are stored in an inbox, processed through a dream pass to generate preferences, and stored as rules in active.md. A search index is maintained in a hidden directory and can be rebuilt from the source files. The system also supports truth ledgers, decision models, and staged review gates for agent writes.
| Folder | Role | Files |
|---|---|---|
| .github | agent-config | 7 |
| bin | scripts | 1 |
| docs | docs | 774 |
| hooks | hooks | 35 |
| scripts | scripts | 22 |
| skills | agent-instructions | 6 |
| src | source-code | 1496 |
| templates | templates | 23 |
| tests | tests | 2101 |
| .agents | folder | 1 |
| .ai-notes | folder | 1 |
| .apb | folder | 87 |
| .claude-plugin | folder | 2 |
| .codex-plugin | folder | 1 |
| .githooks | folder | 2 |
| install | folder | 16 |
| openclaw | folder | 1 |
| openspec | folder | 33 |
| plugins | folder | 21 |
| schemas | folder | 5 |
The agent reads
- install/codex.md evidence: README.md
- search_iterative_recall_enabled evidence: README.md
- search_pool_max_per_session evidence: README.md
- docs/decision-models.md evidence: README.md
The agent writes
- package.json evidence: CLAUDE.md
- CHANGELOG.md evidence: CLAUDE.md
- docs/brain-store.md evidence: README.md
- docs/updating.md evidence: README.md
Requirements
Runtimes: Node.js, Python >=3.11, Bun
Databases: SQLite
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Google Antigravity, Kiro, OpenCode, Amp, Roo Code, Cline, JetBrains Junie, Devin (ex-Windsurf)
Set it up
This brain runs code automatically: 54 hooks (codex), 3 scripts. Review .githooks/pre-commit, .githooks/pre-push, hooks/hooks.json, package.json, plugins/codex/hooks/hooks.json before opening the folder in Claude Code. No step below turns a hook on for you.
.githooks/pre-commit:runs on git pre-commit.githooks/pre-push:runs on git pre-pushhooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" post-write-reminder; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook post-write-reminder; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" subagent-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook subagent-inject; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" reground-deliver; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook reground-deliver; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" active-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook active-inject; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" gap-agenda; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook gap-agenda; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" backlog-nudge; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook backlog-nudge; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" log-catchup; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook log-catchup; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" view-render; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook view-render; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" recall-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook recall-inject; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" nav-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook nav-inject; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" counterparty-brief; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook counterparty-brief; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" reground-deliver; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook reground-deliver; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" pretool-orient; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook pretool-orient; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" pretool-host-backup; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook pretool-host-backup; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" stop-log-guardrail; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook stop-log-guardrail; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" answer-quote-check; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook answer-quote-check; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" hygiene-digest; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook hygiene-digest; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" subagent-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook subagent-inject; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" gap-promote; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook gap-promote; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" active-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook active-inject; exit 0hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0package.json:bun scripts/prepare.ts || exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" post-write-reminder; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook post-write-reminder; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" subagent-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook subagent-inject; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" reground-deliver; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook reground-deliver; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" active-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook active-inject; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" gap-agenda; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook gap-agenda; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" backlog-nudge; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook backlog-nudge; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" log-catchup; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook log-catchup; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" view-render; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook view-render; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" recall-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook recall-inject; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" nav-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook nav-inject; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" counterparty-brief; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook counterparty-brief; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" reground-deliver; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook reground-deliver; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" pretool-orient; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook pretool-orient; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" pretool-host-backup; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook pretool-host-backup; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" stop-log-guardrail; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook stop-log-guardrail; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" answer-quote-check; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook answer-quote-check; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" hygiene-digest; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook hygiene-digest; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" subagent-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook subagent-inject; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" gap-promote; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook gap-promote; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" active-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook active-inject; exit 0plugins/codex/hooks/hooks.json:r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0
- Not scanned by AutoGineerThe author’s MCP configuration (.claude-plugin/plugin.json) also starts it in a way AutoGineer does not offer. Read that file: AutoGineer did not scan that path; what it runs is listed under “This brain runs”. https://github.com/itechmeat/open-second-brain/blob/233b91d1bdc7cf74c47ea1c1fd72e949887e1fc4/.claude-plugin/plugin.json
First committed by hermes-vps-agent. Published in itechmeat/open-second-brain. Licence: MIT License.
Usage
AutoGineer overview, from the brain’s own files
- Initialize a new vault for agent memory
- Connect agents like Claude Code or Codex via MCP
- Manage agent preferences and rules through automated dream passes
- Audit agent activity using hash-chained logs
- Perform semantic or keyword searches across agent-generated notes
- Enforce write-path integrity with staged review gates
- “o2b brain today”
- Displays the current day's view and active memory markers for the agent session.
- “o2b brain rollback”
- Restores the vault state from the last snapshot, reversing recent brain mutations.
Documentation by hermes-vps-agent
Open Second Brain
Image: Open Second Brain - your knowledge, amplified by AI
Open Second Brain is a memory layer for AI agents that lives in an Obsidian vault. Agents read and write it through MCP servers, lifecycle hooks and the o2b CLI. Everything the agent learns is a Markdown file under Brain/, so you can open, edit, grep and version it like any other note. A deterministic dream pass turns repeated signals into rules and retires the ones nothing uses; no model runs inside that algorithm.
How it fits
flowchart LR
subgraph Clients["Agent clients"]
Plug["Plugins: Claude Code, Codex,<br/>Hermes, opencode, Grok Build"]
Mcp["MCP config: Cursor, kiro, Copilot CLI,<br/>Gemini CLI, ZCode, any MCP host"]
Claw["OpenClaw<br/>in-process plugin"]
Cliu["Aider, Pi<br/>CLI and context file"]
end
subgraph Product["Open Second Brain"]
Srv["MCP servers<br/>open-second-brain, open-second-brain-writer"]
Hooks["Lifecycle hooks<br/>o2b-hook"]
Cli["CLI<br/>o2b"]
Core["Core"]
end
subgraph Vault["Your vault"]
Brain["Brain/<br/>Markdown the agent writes"]
Notes["Your notes"]
Index[(".open-second-brain/brain.sqlite<br/>rebuildable search index")]
end
Plug --> Srv
Plug --> Hooks
Mcp --> Srv
Claw --> Core
Cliu --> Cli
Srv --> Core
Hooks --> Core
Cli --> Core
Core --> Brain
Core --> Index
Core -. reads, writes a named note on request .-> NotesEach client reaches the same core through a plugin, an MCP registration or the CLI. The core keeps its own records under Brain/ and a generated search index under .open-second-brain/ that it can rebuild from the files. Your notes are read; the note tools write one only at a path the caller names.
flowchart LR
Agent["Agent"] -->|brain_feedback| Inbox["Brain/inbox/<br/>signal"]
Inbox -->|dream pass| Pref["Brain/preferences/<br/>rule"]
Pref -->|rendered into| Active["Brain/active.md"]
Active -->|read at session start| Agent
Agent -->|brain_apply_evidence| Log["Brain/log/"]
Log -->|next dream pass| PrefThe learning loop: signals become rules, rules reach the next session through Brain/active.md, and applied or violated evidence confirms, quarantines or retires them. Details: docs/how-it-works.md.
Install
Install Bun 1.1 or later:
install/prerequisites.md.Install the plugin for your client (guides below), or get the
o2bCLI:install/prerequisites.md.Create the vault files:
o2b init --vault /path/to/vault --name "My Second Brain" o2b brain init --vault /path/to/vaultConnect the client (table below), then check the result:
o2b doctor --vault /path/to/vault o2b install --check
The full router with readiness criteria is install.md; native Windows is covered in install/windows.md.
Supported clients
| Client | Integration | Guide |
|---|---|---|
| Claude Code | Marketplace plugin: MCP servers and hooks | install/claudecode.md |
| OpenAI Codex | Marketplace plugin, then o2b install --target codex --apply | install/codex.md |
| ChatGPT desktop | Reads the shared Codex config: o2b install --target codex --apply | install/codex.md |
| Hermes Agent | Plugin and memory provider | install/hermes.md |
| OpenClaw | Native plugin, no MCP | install/openclaw.md |
| opencode | o2b install --target opencode --apply: MCP servers and a native plugin | install/opencode.md |
| Grok Build | o2b install --target grok --apply: MCP servers and hooks | install/grok.md |
| Cursor | o2b install --target cursor --apply | install/cursor.md |
| kiro | o2b install --target kiro --apply | install/kiro.md |
| GitHub Copilot CLI | o2b install --target copilot-cli --apply | install/copilot-cli.md |
| Gemini CLI | o2b install --target gemini-cli --apply | install/gemini-cli.md |
| ZCode | MCP servers added to its config by hand | install/zcode.md |
| Aider | o2b install --target aider --apply: context file, no MCP | install/aider.md |
| Pi | o2b install --target pi --apply: skill over the CLI | install/pi.md |
| Any other MCP host | o2b install --target generic --apply --out - prints the server entries | install/generic.md |
o2b uninstall --target <name> --apply removes what o2b install wrote; the vault is never touched (install.md).
Capabilities
Preferences that learn and expire. Signals, a deterministic dream pass, confidence and retirement: how it works.
Reversible changes. Brain mutations take a snapshot first;
o2b brain rollbackrestores it: snapshots.Attributed writes.
o2b brain writeslists every note write by agent and device,writes revertplans a restore,o2b brain freezestops all writers, ando2b brain log verifychecks the hash-chained log: Brain CLI.Search. Keyword search with an optional semantic lane, result explanations, recall profiles and compact cards; an opt-in iterative loop (
search_iterative_recall_enabled, default off) keeps querying when coverage gaps survive, pausing with a plan the caller answers throughbrain_search's round trip; and an opt-in per-source-session cap (search_pool_max_per_session, default off) keeps one long imported session from filling the candidate window, so diversity spreads across sessions: search CLI, iterative recall, pool cap, ranking.Session recall. Import agent transcripts already on disk, search them, or select whole-thread coverage under a character budget (
o2b brain session-grep --operation coverage --char-budget <n>, with--entity-keyseeding the fan-out from mined entity mentions): session logs, coverage.Hygiene.
o2b brain hygiene scanfinds contested, duplicate, stale and unused memories;applyruns only the findings you pick: maintenance.Claim ledger.
o2b brain truth ingestrecords an entity claim with an optional validity window (--valid-from/--valid-until; with the flags absent, a window on the source record's frontmatter is adopted and frozen at ingest),truth eventsrecalls a windowed slice of the ledger, andtruth stategrounds an agent-stated claim with an anchoring verdict - committed, or reported back with reason codes.truth stateaccepts an optional opaque--sample-idnaming the context-pack sample the claim drew on, and claim reads report the receipt and outcome provenance behind it at the caller's reach - "receipt known, outcome unknown", never an invented verdict: entity truth CLI.Corrections.
o2b brain lifecycle correct <target>reports a correction's blast radius and retires the affected records - validity-closed by default, tombstoned with--flatly-wrong, dry run by default and--applyto write. A retired record that recall can still serve is served only beside its correction, never alone: belief lifecycle CLI.Sharing and backup. Knowledge packs export a chosen subset;
o2b brain bank-exportwrites a one-file backup bundle: knowledge packs.Secret custody. Credentials live encrypted in the vault's state dir behind a capability-gated store;
$secret:NAMEreferences resolve at the use sites,o2b brain secret unlockwraps the keyfile under a passphrase, andsecret export/importmove the store between installs as one passphrase-encrypted bundle: custody CLI.Today view and note markers.
o2b brain today,@osb loopand@osb setmarkers: Brain CLI.Self-inspection.
o2b version,o2b install --frictionando2b state statusreport what is installed and where state lives: CLI reference.MCP surface. Tools, tool profiles for hosts with tool limits, and the always-loaded writer server:
docs/mcp.md.
Optional features
Semantic search: an embedding provider plus
sqlite-vec; theembeddings-setupskill walks through it:skills/embeddings-setup/SKILL.md.Decision models: a typed judgment model that can rerank search and filter candidates, off by default per use:
docs/decision-models.md.Deep relational recall: a fourth search arm over typed links, off by default. Its traversal runs under width budgets - 8 seeds, 4 edges per node, 16 nodes in total, and a hub above 12 walked edges is reached but not expanded - each overridable through an
OPEN_SECOND_BRAIN_SEARCH_TRAVERSAL_*environment variable or asearch_traversal_*config key; entity co-occurrence bridges join the walk by default and switch off separately (OPEN_SECOND_BRAIN_SEARCH_ENTITY_BRIDGES): retrieval quality.Staged review for agent writes, off by default. With no key set every write publishes exactly as before.
write_approval.notes/OPEN_SECOND_BRAIN_WRITE_APPROVAL_NOTES_ENABLEDandwrite_approval.ingest/OPEN_SECOND_BRAIN_WRITE_APPROVAL_INGEST_ENABLED(each falling back to thewrite_approval.enabledmaster, default off) stage note creates and ingest summary pages intoBrain/pending/beside the staged signals, where they stay out of the search index until an operator runso2b brain pending listand applies or rejects them; write-path integrity.A permissions document, absent by default.
Brain/_permissions.yaml(an operator-edited vault file) resolvesallow/ask/denyper agent, role and target for the write, ingest and owner-write actions; with the file absent every check behaves exactly as today.askstages the write,denyrefuses with thewrite-refusedtoken and the next commando2b brain permissions show, and every ask/deny verdict lands in a queryable decision ledger underBrain/logs/decisions/;o2b brain permissions showdry-runs the decision table,ledgerreads the rows; Brain CLI.The owner-write gate, off by default.
integrity.owner_scope_writesinBrain/_brain.yaml(off|warn|fail, defaultoff) refuses a caller-named owner that differs from the caller's resolved identity on the preference and note lanes (warnallows and records one decision-ledger row); a documentowner_writeverdict composes most-restrictive-wins with the gate; write-time integrity.Named MCP tokens, optional.
o2b mcp token mint|rotate|revoke|listkeeps a hash-at-rest token per agent (.open-second-brain/secrets/mcp-tokens.json; material shown exactly once). Over HTTP a valid token authenticates as its agent per request, the shared--api-keystays valid as the operator master credential, andmcp_tokens_required/OPEN_SECOND_BRAIN_MCP_TOKENS_REQUIRED(defaultfalse) makes a non-empty token map refuse credential-less requests.o2b bootstrap --target <harness> [--token] [--rotate] [--check]provisions MCP registration, token and receipt in one idempotent command, ando2b bootstrap --remove <harness>tears a provision down again; the minted token authenticates HTTP clients configured by hand, while the registered stdio harness presents no credential and keeps its config-derived identity; core CLI.Ambient capture consent, opt-out.
guardrails.ambient_writeback: falsesuppresses the ambient extraction lane with a countedambient-withheldevent (absent keeps today's behavior), andguardrails.ambient_ttl_daysstamps anexpiration_dateon ambient-extracted signals so reads drop them after the window (absent stamps nothing); a TTL-stamped signal still stages when the review gate is on and survives apply verbatim.Open decisions.
o2b brain decision open --title <t> --question <q> --option <o> [...]parks a question with enumerated options atBrain/decisions/open-<slug>.md;resolvemints the realtype: decisionpage,discardcloses without deciding, and the morning brief renders up to five open questions: belief lifecycle.
What is new
Open Second Brain 1.98.0 is the agent-presence and self-improvement release. o2b install --target <host> --apply now writes the brain-usage block into the agent-instruction file the installed host reads at the vault root (AGENTS.md for codex, cursor, opencode and aider; GEMINI.md for gemini-cli) under the same consent prompt as the config writes, preserving every byte outside the block and recording its ownership so uninstall removes exactly the pair the tool wrote; the dream pass gains an operator-approved exit into those same files, where a lesson promotes into a managed lessons block only with a fresh approval pinned to the approved text, and the doctor grades every block state it can name. The skill lane gains a benchmark-gated rewrite loop: a skill is rewritten only after a candidate beats the incumbent on scored dev tasks with full coverage and survives the one held-out check - Open Second Brain never calls a model, the scorer reads structural predicates and nothing the agent claims about its own work, and the accept stays an operator step on the command line. And ChatGPT desktop is named where its operators look for it: it reads the shared Codex config, so one codex registration serves both. Every release is described in the CHANGELOG.
Documentation
| Topic | Page |
|---|---|
| Mental model, vault layout, dream pass, safety properties | docs/how-it-works.md |
| Every CLI verb and flag | docs/cli-reference.md |
| MCP protocol, tools, writer split | docs/mcp.md |
| Brain store: setup, sync, migration, the human view | docs/brain-store.md |
| Architecture and configuration model | docs/architecture.md |
Updating (o2b update) and upgrade notes | docs/updating.md |
| Observability events | docs/observability.md |
| Metrics data contract | docs/metrics.md |
| Cross-project pointer | docs/cross-project-pointer.md |
| Scheduled Brain digest (Hermes cron) | docs/hermes-cron.md |
| Stability policy | docs/stability.md |
| Origin of the idea | docs/idea.md |
Project
CHANGELOG · Security policy · Source on GitHub · MIT License
docs/brain-store.md
The brain store: setup, sync and migration
Open Second Brain keeps its machine data (signals, preferences, the log,
ledgers, settings) in the brain store: a folder of append-only files
outside your Obsidian vault. People read the brain through the human
view: a few plain Markdown pages that one machine writes into a folder you
choose. This guide covers setting both up on one or more machines, syncing
them, moving an existing install whose data still lives in the vault's
Brain/ folder, and what to do when doctor reports a problem.
The on-disk format is documented in FORMAT.md at the root of every store.
Every flag of every command below is in the CLI reference.
The command blocks in this guide are run as written by a test
(tests/docs/brain-store-guide.test.ts) against throwaway machines. The
HTML comment above each block tells that test which machine runs it and how
the commands should exit; a Markdown viewer does not show it.
The pieces
| Piece | Where | Synced |
|---|---|---|
shared/ partition | <store root>/shared | Yes, to every machine that runs an agent |
private/ partition | <store root>/private | Yes, but only to machines you trust with private records |
| Store root | store_root in the machine config | No: the root is never a sync folder itself |
| Device-local state | the platform state directory, keyed by store id | Never |
| Human view | view_target in the machine config | Its own folder, to the view writer and to phones |
The store root is a plain folder that holds the two partition folders and a copy of
FORMAT.md. It is never synced as a whole.shared/holds everything that is not private.private/has the same shape and holds records about private pages (a note whose frontmattervisibilityincludesprivate, an informal marker such asaccess: private) and text inside a<private>...</private>region.The device-local state directory holds this machine's search index, locks, caches, hook state, snapshots and migration backups. On Linux and macOS it is
${XDG_STATE_HOME:-~/.local/state}/open-second-brain/stores/<store id>, on Windows%LOCALAPPDATA%\open-second-brain\stores\<store id>. It must never be synced: two machines sharing it would share clocks and locks.The human view is the only part meant for people. It is written by one machine, the view writer, and can live inside your vault or anywhere else.
The store root comes from OPEN_SECOND_BRAIN_STORE_ROOT, then store_root
in the machine config, then a per-user default
(${XDG_DATA_HOME:-~/.local/share}/open-second-brain/store on Linux and
macOS). A root inside the vault is refused. The machine config is
~/.config/open-second-brain/config.yaml on Linux and macOS and
%LOCALAPPDATA%\open-second-brain\config.yaml on Windows; XDG_CONFIG_HOME
moves it on every platform, and OPEN_SECOND_BRAIN_CONFIG names another file. It is a simple
key: value file; edit it with any text editor.
Setup
The first machine
Pick where the store and the view live before the first command, so the folders you will sync have stable names. Add to the machine config:
<!-- doc-test: scenario=setup machine=laptop config -->
store_root: ~/brain-store
view_target: ~/brain-viewThen initialise. With no vault the brain works from the store alone:
<!-- doc-test: scenario=setup machine=laptop exit=0 expect="This machine" -->
o2b init --agent-name laptop-agent
o2b store patho2b init creates the store (both partitions, one store id) and makes this
machine the view writer. o2b store path prints where everything is: the
store root, each partition and whether this machine holds it, the
device-local state directory and the view target, each with the setting
that put it there (env, config or default) and whether it exists:
<!-- doc-test: scenario=setup machine=laptop exit=0 expect="(config, missing)" -->
o2b store pathThe view target line reads view target: <folder> (config, missing) until
the first render creates the folder, and none when view_target is not
set. It creates nothing, so it is safe to run at
any time; --json gives the same answer to scripts, and agents read it from
the store block of second_brain_status.
With an Obsidian vault for your own notes, name it in o2b init:
<!-- doc-test: scenario=vault machine=laptop exit=0 expect="initialized the brain store" -->
o2b init --vault ~/vault --agent-name laptop-agentOn a vault that has no Brain/ folder yet this also creates the store, so
the brain never writes machine data into the vault. On a vault that already
has Brain/, o2b init only records the vault: follow
Moving an existing install below.
o2b store init is the explicit way to create a store. You need it when
o2b init did not create one (a vault with a legacy Brain/ tree), or to
add a partition later. It refuses a store that already exists, so it never
replaces one by accident:
<!-- doc-test: scenario=setup machine=laptop exit=1 expect="already" -->
o2b store initMore machines
A second machine does not create a store. It receives the partitions through sync and joins them:
On the new machine, set the same kind of config. The paths are local to that machine and may differ from the first one:
<!-- doc-test: scenario=setup machine=desktop config -->
store_root: ~/brain-store view_target: ~/brain-viewPoint your sync tool at
~/brain-store/sharedand~/brain-store/privateon this machine (see Syncing) and wait until both folders have arrived.Check that this machine sees the same store id as the first one, then initialise:
<!-- doc-test: scenario=setup machine=desktop exit=0 expect="already exists" -->
o2b store path o2b init --agent-name desktop-agento2b initsays the store already exists and binds this machine to it.
Run o2b init only after the partitions have arrived. On an empty store
root it creates a new, separate store with its own id; if that happens,
stop, delete the new empty store folder, wait for sync and run o2b init
again.
Every machine needs its own device_id. o2b init generates one and saves
it in the machine config. Never copy a machine config, or the device-local
state directory, from one machine to another.
A server that holds only shared data
A server or VPS that runs an agent but should never hold private records
gets only shared/. Configure it like any other machine, sync only
~/brain-store/shared to it, and initialise:
<!-- doc-test: scenario=setup machine=server config -->
store_root: ~/brain-store<!-- doc-test: scenario=setup machine=server exit=0 expect="not held" -->
o2b init --agent-name vps-agent
o2b store path
o2b brain note "The nightly backup finished"
o2b brain doctoro2b store path lists private as not held. Reads work on what is
present, and every write that is not private lands in shared/. A write
that would create a private record is refused, and nothing is written:
<!-- doc-test: scenario=setup machine=server exit=1 expect="does not hold the private partition" -->
o2b brain note "Rotated the deploy key <private>key id 1234</private>"error: the brain store write failed: this machine does not hold the private partition of the brain store at /home/me/brain-store; the record was not written. Sync that partition's folder of the store to this machine, or make the write from a machine that holds it.Agents over MCP get the same refusal as a tool error. Make such writes from
a machine that holds private/.
If the server is the very first machine, create the store there with only the shared partition:
<!-- doc-test: scenario=server-first machine=server exit=0 -->
o2b store init --partitions sharedLater, on a machine you trust with private records and that has received
shared/, add the private partition. It gets the same store id; sync it
from there to the other trusted machines:
<!-- doc-test: scenario=server-first machine=desktop exit=0 -->
o2b store init --partitions shared,privateSyncing
Open Second Brain never syncs anything itself. Use any file sync tool: Syncthing, a cloud drive folder, or similar.
Sync
shared/andprivate/as two separate folders. That lets you give each machine exactly the partitions it should hold.Never sync the store root itself. It would sync both partitions as one unit, and a machine could no longer leave
private/out.Never sync the device-local state directory. It lives outside the store root by default; keep it out of every sync folder. Doctor reports it as
store-device-state-foreignwhen another device's entries show up in it.Every machine that runs an agent gets
shared/. Machines you trust with private records also getprivate/.A server or VPS that should hold only shared data gets only
shared/.Phones get only the view folder (
view_targeton the view writer), never the store. A phone has no Open Second Brain install; it reads and edits pages, and the view writer picks up the edits (see The human view).
Files in the store are append-only and every device writes only its own files, so two machines never edit the same file and sync conflicts do not arise in normal use. A record from another machine is visible as soon as your sync tool has delivered the file: search and the other readers catch up with the store before they read.
The human view
The view is a small, stable set of plain Markdown pages, rendered from the
store into the view_target folder:
| Page | What it holds |
|---|---|
about-me.md | What the brain knows about you: confirmed rules, grouped by subject |
history/<YYYY>-W<ww>.md | One page per week of what happened, in plain language |
decisions.md | Decisions that were recorded |
Each page starts with one HTML comment line that names the store and the
page; there is no frontmatter and there are no Obsidian-only links, so any
Markdown viewer shows them. Raw signals, log events, ledgers and caches
never appear in the view. The number of files grows with weeks, not with
signals, and a render with nothing new changes no file. Generated headings
and introductions follow the shared view.language setting (English when
it is unset; English and Russian ship); rules and quotes stay in the
language they were written in. Set it once, on any machine, and every
machine's view follows after sync:
<!-- doc-test: scenario=setup machine=laptop exit=0 expect="view.language: null ->" -->
o2b brain settings set view.language ru
o2b brain settings unset view.languageA language the view has no strings for is refused and the command names
the ones it has; a regional tag of one (ru-RU) is accepted.
o2b brain settings unset view.language goes back to English.
With no view_target no page is written anywhere, and the brain works the
same.
A view folder inside the vault belongs to the view writer: the note tools
(brain_create_note, brain_update_note, brain_append_note, the write
batch and the note and folder lifecycle) refuse a path in it, as they refuse
Brain/, because an edit of a view page is read back as yours. When the view
folder is the vault root, only the view's own pages, their conflict copies and
history/ are refused.
The view writer
Exactly one machine writes the view: the view writer. The machine that creates the store becomes the view writer. It renders at the end of every dream pass and, at most once an hour, when a session starts. You can also render by hand:
<!-- doc-test: scenario=setup machine=laptop exit=0 -->
o2b view writer
o2b view render<!-- doc-test: scenario=setup machine=laptop exit=0 expect="about-me.md" -->
o2b view renderA machine that has just taken the role renders from its next catch-up, so
its first o2b view render may only say so. A machine that is not the view
writer never writes pages; o2b view render there names the view writer.
To move the role, run this on the machine that should render the view:
<!-- doc-test: scenario=setup machine=desktop exit=0 expect="hand the view writer role" -->
o2b view writer --hereThe current writer releases the role at its next catch-up (its next render, dream pass or session start). This machine starts rendering only after that release has synced here, so no page is ever written by both:
<!-- doc-test: scenario=setup machine=laptop exit=0 expect="Handed the view writer role" -->
o2b view render<!-- doc-test: scenario=setup machine=desktop exit=0 expect="(this machine)" -->
o2b view writerWhen the old writer is gone (a dead laptop), take the role at once:
<!-- doc-test: scenario=setup machine=laptop exit=0 expect="did not release it" -->
o2b view writer --here --forceA forced move warns that the old writer, if it is still running somewhere, may render once more before the change reaches it; it stops at its first catch-up after that. Move the view folder in your sync tool along with the role, so the new writer renders into the folder your phone reads.
If the view writer stays silent for more than 3 days, doctor on every
machine reports view-writer-silent and names the command to move the
role. Pages go stale meanwhile, but no data is lost.
Editing pages on a phone
Sync the view folder to your phone and edit a page in any Markdown editor.
On about-me.md, rewrite a rule's wording to correct it, or delete its
line to retire it. Before the view writer rewrites a page it compares the
file with what it rendered last; a difference is your edit, which it stores
as a human record (human records win over anything an agent or a model
recorded) and then keeps in the new render. The render report says
1 edit(s) stored for that page.
An edit that lands while a render is in progress is never silently lost. The writer keeps the bytes it replaces for 30 days, and when those bytes differ from what it rendered last, it records them as an edit and renders again, so the edit shows up one render later. A sync-conflict copy of a page, when your sync tool makes one, is taken in the same way and removed. To see or restore an older version of a page:
<!-- doc-test: scenario=setup machine=laptop exit=0 -->
o2b view recover about-me.mdIt lists the replaced versions of the last 30 days with an id each;
o2b view recover about-me.md --print <id> prints one.
Moving an existing install
An install from before the brain store keeps its machine data in the
vault: Brain/ and .open-second-brain/. o2b brain migrate-store moves
it into the store. Nothing moves until you run it; status and doctor only
say that a migration is available.
Every machine migrates on its own, one after the other. The commands below
assume the machine config already names the vault (it does on any existing
install) and that you have set store_root as in Setup.
1. Check and dry run on the first machine
<!-- doc-test: scenario=migration machine=laptop exit=any expect="migration-available" -->
o2b brain doctorDoctor lists migration-available and the commands to run. This note, and
the other migration notes below, do not change doctor's exit code.
Create the store, then do a dry run:
<!-- doc-test: scenario=migration machine=laptop exit=0 expect="Every legacy entry has a destination" -->
o2b store init
o2b brain migrate-store --dry-runThe dry run writes nothing anywhere. It lists the devices found in the
legacy tree (the migration cohort), where each surface would go (a
store stream and partition, the device-local state, an explicit backup, or
drop with the reason), every item it cannot read, and every legacy file no
mapping covers. It exits 1 while anything is unmapped; move such a file out
of Brain/ (or report it) and run the dry run again.
2. Migrate the first machine
<!-- doc-test: scenario=migration machine=laptop exit=0 expect="device-switched" -->
o2b brain migrate-storeThe migration:
closes a migration gate on this machine, so agents here are refused with a "migration in progress" message while it runs (other machines keep working);
snapshots
Brain/and backs up every surface nothing can rebuild (secrets, keys, attestations, checkpoints) into the device-local state, each verified by a test restore;imports every item through a journal, then re-scans until a pass imports nothing, and verifies every item against the store;
records
migration-doneand this machine'sdevice-switched, and makes this machine the view writer if no machine is.
The legacy tree stays in the vault. If the run is interrupted,
o2b brain migrate-store --resume continues without importing anything
twice. If verification finds a gap, the legacy tree is left untouched and
the report names each missing item. If a run that is gone (a crash, a
closed terminal) still holds the gate and you will not resume it right
away, o2b brain migrate-store --force-release-gate opens it again; it
refuses while the run that holds the gate is still running.
From now on this machine writes only to the store. Render the view twice (the first render after the claim only catches up), and check doctor:
<!-- doc-test: scenario=migration machine=laptop exit=0 -->
o2b view render
o2b view render<!-- doc-test: scenario=migration machine=laptop exit=any expect="legacy-devices-pending" -->
o2b brain doctorDoctor now reports legacy-devices-pending with the devices of the cohort
that have not switched yet.
3. Migrate the later machines
On every other machine, upgrade, set store_root, let sync deliver
shared/ and private/, and run the same commands. Do not run
o2b store init here: the store comes through sync.
Run the first migration on one machine, and wait for its completion
record to sync before migrating the others. A machine that already holds
another device's migration-done takes the later-machine path; two
machines that migrate before either record has synced both run as the
first machine, and doctor then reports migration-done-twice.
<!-- doc-test: scenario=migration machine=desktop exit=0 expect="later machine" -->
o2b brain migrate-store --dry-run
o2b brain migrate-storeA later machine first waits until its copy of the store holds everything
the first machine recorded in migration-done. Until then it writes
nothing, names the missing files and exits 1; run it again later, or add
--wait <seconds> to keep polling. A partition this machine does not hold
is skipped and named. It then imports the legacy items the store does not
hold yet (this machine may have records the first one never saw), copies
its own device-local state and records device-switched.
4. The transition
While some machines still run an older release, they keep writing into
the legacy Brain/ tree, and your sync tool delivers those files to the
switched machines. A switched machine imports them, line by line and
exactly once, at every dream pass and at most once an hour at session
start. To import them right away:
<!-- doc-test: scenario=migration machine=laptop exit=0 expect="imported late legacy writes" -->
o2b brain migrate-storeA switched machine never writes into the legacy tree. Doctor on every
switched machine names the devices still on the legacy layout
(legacy-devices-pending) until each has migrated or been retired.
5. Rolling back a machine
Until the legacy tree leaves the vault, any machine can go back to the legacy layout:
<!-- doc-test: scenario=migration machine=desktop exit=0 expect="back on the legacy layout" -->
o2b brain migrate-store --rollbackRollback restores Brain/ from this machine's migration snapshot and its
backups, then writes back every store record the restored tree lacks
(signals, log events, preferences, pinned context and record pages,
including records from other machines that arrived after the snapshot), in
order and without duplicates. Records with no legacy form (view renders,
migration records) stay in the store, and the report lists them. Ledger
rows written after the switch (idempotency receipts, continuity, truth
claims and the other ledgers) are not written back either: they stay in
the store only, so the old release does not see them, and the report
warns with their count per ledger (ledger_rows_kept in --json). An
interrupted rollback resumes without writing anything twice. Doctor on that
machine reports migration-available again; to switch again, run
o2b brain migrate-store once more.
6. Removing the legacy tree
The legacy tree leaves the vault only when every device of the migration cohort (every device id found anywhere in the legacy tree, however old) has switched or been retired. Until then the removal refuses and names the devices it waits for:
<!-- doc-test: scenario=migration machine=laptop exit=1 expect="the legacy layout" -->
o2b brain migrate-store --remove-legacyo2b store device list shows every device the store knows: its id, its
last record, and whether it switched, is still on the legacy layout, or
was retired:
<!-- doc-test: scenario=migration machine=laptop exit=0 expect="dev-c" -->
o2b store device listMigrate each named machine that is still in use. Retire a machine that is
gone for good, from any other machine (never from the machine itself,
which is refused). Retiring writes one record in the shared settings that
takes the machine off the digest roster (store-digest-silent stops naming
it) and out of the devices the removal waits for:
<!-- doc-test: scenario=migration machine=laptop exit=0 expect="Retired dev-c" -->
o2b store device retire dev-c --reason "old laptop, sold"If a retired machine writes again later (it came back, or a new machine
reuses its id), it is on the roster again and doctor reports
store-device-retired-returned.
Here the desktop was rolled back in the previous step, so it switches again first:
<!-- doc-test: scenario=migration machine=desktop exit=0 expect="device-switched" -->
o2b brain migrate-storeNow every cohort device has switched or been retired, and the removal goes ahead:
<!-- doc-test: scenario=migration machine=laptop exit=0 expect="nothing was deleted" -->
o2b brain migrate-store --remove-legacyTo remove the tree while a machine that is still in use stays on the
legacy layout, --force removes it anyway and the report names the
devices that will no longer reach the store; prefer migrating or retiring
them.
The removal first imports any late legacy writes, then moves Brain/ and
.open-second-brain/ out of the vault into a dated archive in this
machine's device-local state. Nothing is deleted; the archive leaves out
only what a rebuild recreates (the search index, caches, generated pages),
and the report lists those. Afterwards the vault holds your notes and, if
view_target points into it, the view folder. A rollback is no longer
possible:
<!-- doc-test: scenario=migration machine=laptop exit=1 expect="rollback is only possible until then" -->
o2b brain migrate-store --rollbackIf a Brain/ folder appears in the vault again (an agent or tool still
follows old instructions), doctor reports legacy-tree-reappeared with the
writer when a file names it. Nothing reads that folder; stop the writer and
move the folder out of the vault.
What the partitions protect, and what they do not
The partitions decide which machines receive which records. They are a routing rule, not encryption.
What they do:
A machine that never receives
private/never holds a private record. A write there that would create one is refused with the message above; nothing is written and nothing falls back toshared/.A record that cannot be judged (a page that cannot be read, a reference the brain cannot resolve) counts as private, so a mistake keeps data out of
shared/rather than in it.Records never move between partitions after they are written.
What they do not do:
No encryption at rest. Store files are plain JSON lines, readable by anyone who can read the folder. The store keeps its folders at mode 0700 and its files at 0600, and doctor reports looser modes (
store-mode-loose), but disk encryption and the security of your sync tool (who it shares a folder with, whether a cloud provider can read it) are their job, not the store's. Choose a sync tool you trust forprivate/in particular.Removed is not erased. Shards are append-only. Retiring a rule, correcting it on a view page or unpinning context appends a new record; the old line stays in the shard, on every machine that holds the partition, until a future compaction rewrites that shard. Do not put a secret into the brain expecting a later delete to scrub it from every copy.
The view is outside the partitions. Pages are rendered by the view writer from what it holds, and they go wherever you sync
view_target. Do not sync the view folder to a device that should not see what the view writer knows.Backups and archives stay local. Migration backups and the legacy archive live in the device-local state of the machine that made them. Back up that directory with the rest of the machine if you need to.
Troubleshooting
Run o2b brain doctor on the machine in question. These are the findings
that come from the store, the migration and the view:
| Code | What it means | What to do |
|---|---|---|
store-missing | No store exists at the configured root. | Run o2b init (or o2b store init) on the first machine; on other machines check store_root and wait for sync. |
store-root-invalid | The store root cannot be used: it is inside the vault, or holds partitions of two different stores. | Point store_root outside the vault, and keep only one store's partitions under it. |
store-partition-lost | A partition this machine has held (it opened or initialised it here) no longer shows its store.json. The store is not opened: every protection fails closed and every store write is refused, because the partition's records cannot be read. | Restore that partition's store.json from sync or a backup. No command takes a partition off this machine's list. |
store-device-state-foreign | The device-local state directory holds entries of other devices: it was put into a sync folder. | Remove it from the sync tool, sync only shared/ and private/, then delete the other devices' entries in it. |
machine-state-adopt-conflicts | When this machine switched, two fresh vaults held a machine-state file with different bytes; the first vault's copy is live and the other is kept in the adopt-conflicts/ folder the finding names, with the file count. | Compare each kept file with the live copy at the same path, copy over what is still needed, then delete the folder. |
store-mode-loose | Store files or folders are readable by other accounts on this machine. | Run the chmod -R go-rwx command the finding prints. |
store-partition-unreadable, store-shard-unreadable | A partition or a shard could not be read, often while a sync client holds the file. | Run doctor again after sync settles; if it persists, check file permissions. |
store-shard-tail-held | The last line of another device's shard is incomplete (a crash in an append, or a partial sync copy). | Usually nothing: the next append by that device starts a new line. Check that device's sync if it lasts. |
store-digest-silent | A device wrote to a partition but has published no state digest for 7 days. | Bring that machine online and let it sync. Retire a machine that is gone for good with o2b store device retire <device-id>; the finding changes no data. |
store-digest-divergent | Two machines computed different state from the same records: a bug. | Keep both machines' store folders as they are and report it. |
store-record-id-conflict | One record id arrived with different content: a shard file was edited, or a writer has a bug. | Find the edited shard; records must never change after they are written. |
store-record-id-cross-partition | One record id is in both shared/ and private/. | Remove the line from the shard that should not hold it. |
store-device-retired-returned | A device you retired wrote a record after its retirement, so it is on the digest roster again. | Nothing to do if the machine is back on purpose (migrate it if it still keeps the legacy tree). If a new machine reused the id, give it its own device_id and retire the old id again. |
store-clock-ahead | Records carry a clock more than a day ahead of now. | Fix the clock of the device the finding names. |
store-device-dir-reserved | A peer's device id is a name Windows reserves (such as con), so its folder cannot exist on Windows. | Give that peer another device_id in its machine config. |
store-write-fail-open | Writes from hooks or telemetry did not land (no store yet, no device id, a missing partition); their callers went on. | Fix the cause the finding names, then delete the counter file store-write.json in the stores state directory (~/.local/state/open-second-brain/stores/ on Linux) to reset it. |
store-dual-write-failures, store-dual-write-skipped, store-dual-write-no-store | Only on a machine running the phase 1 dual-write trial (store_dual_write): store copies of legacy writes failed or were skipped. | Fix the cause, or migrate the machine and turn the trial off. |
migration-available | This machine still keeps its brain in the vault's Brain/ tree, or it switched before this vault was configured and the vault's legacy tree was never imported. | Follow Moving an existing install; on a switched machine run o2b brain migrate-store, which imports the tree and binds the vault. |
legacy-devices-pending | This machine switched, but the named devices still write the legacy tree. | Migrate each named machine, and retire the ones that are gone with o2b store device retire <device-id>. |
legacy-tree-reappeared | A Brain/ folder is back in the vault after the legacy tree was removed. | Stop the writer the finding names and move the folder out of the vault. |
migration-done-twice | Two devices each ran the first migration of this vault, before either completion record had synced, so items both imported are in the store twice. | Nothing is lost and both records stay. Migrate every other machine only after one completion record has synced. |
view-writer-silent | The view writer has published nothing for more than 3 days. | Run o2b view writer --here on the machine that should render the view, with --force if the old writer is unreachable. |
Other questions that come up:
A machine shows a different store id. It ran
o2b initbefore sync delivered the partitions and made a store of its own. Delete that empty store, wait for sync and runo2b initagain.Records from another machine are missing. Check that your sync tool has delivered the partition folders (
o2b store pathon both machines shows the same store id and both partitions as held where expected).A later machine's migration exits 1 and names missing shards. The first machine's files have not arrived yet. Wait for sync and run it again, or use
--wait <seconds>.No page appears in the view folder. Check
view_targeton the view writer, and thato2b view writernames that machine.
512 files · 486 not served here
- .agents/plugins/marketplace.json (not served here)
- .ai-notes/.gitignore (not served here)
- .apb/.gitignore (not served here)
- .apb/config.yaml (not served here)
- .apb/playbooks/osb-feature-release/1.1.0/playbook.yaml (not served here)
- .apb/playbooks/osb-feature-release/1.2.0/playbook.yaml (not served here)
- .apb/playbooks/osb-feature-release/1.3.0/playbook.yaml (not served here)
- .apb/playbooks/osb-feature-release/1.4.0/playbook.yaml (not served here)
- .apb/playbooks/osb-feature-release/current (not served here)
- .apb/playbooks/osb-feature-release/lifecycle (not served here)
- .apb/playbooks/osb-feature-release/meta/1.1.0.yaml (not served here)
- .apb/playbooks/osb-feature-release/meta/1.2.0.yaml (not served here)
- .apb/playbooks/osb-feature-release/meta/1.3.0.yaml (not served here)
- .apb/playbooks/osb-pr-prepare/1.0.0/playbook.yaml (not served here)
- .apb/playbooks/osb-pr-prepare/1.0.0/scripts/arch-gate.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.0.0/scripts/check-context.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.0.0/scripts/check-pr.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.0.0/scripts/check-release.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.0.0/scripts/ci-wait.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.0.0/scripts/lib.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.0.0/scripts/qa-gates.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.0.0/scripts/zg-index.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.1.0/playbook.yaml (not served here)
- .apb/playbooks/osb-pr-prepare/1.1.0/scripts/arch-gate.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.1.0/scripts/check-context.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.1.0/scripts/check-pr.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.1.0/scripts/check-release.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.1.0/scripts/ci-wait.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.1.0/scripts/final-gates.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.1.0/scripts/lib.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.1.0/scripts/qa-gates.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.1.0/scripts/zg-index.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.2.0/playbook.yaml (not served here)
- .apb/playbooks/osb-pr-prepare/1.2.0/scripts/arch-gate.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.2.0/scripts/check-context.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.2.0/scripts/check-pr.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.2.0/scripts/check-release.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.2.0/scripts/ci-wait.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.2.0/scripts/final-gates.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.2.0/scripts/lib.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.2.0/scripts/qa-gates.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.2.0/scripts/zg-index.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.4.0/playbook.yaml (not served here)
- .apb/playbooks/osb-pr-prepare/1.4.0/scripts/arch-gate.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.4.0/scripts/check-context.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.4.0/scripts/check-pr.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.4.0/scripts/check-release.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.4.0/scripts/ci-wait.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.4.0/scripts/cycle-run.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.4.0/scripts/final-gates.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.4.0/scripts/lib.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.4.0/scripts/qa-gates.sh (not served here)
- .apb/playbooks/osb-pr-prepare/1.4.0/scripts/zg-index.sh (not served here)
- .apb/playbooks/osb-pr-prepare/current (not served here)
- .apb/playbooks/osb-pr-prepare/lifecycle (not served here)
- .apb/playbooks/osb-pr-prepare/meta/1.0.0.yaml (not served here)
- .apb/playbooks/osb-pr-prepare/meta/1.1.0.yaml (not served here)
- .apb/playbooks/osb-pr-prepare/meta/1.4.0.yaml (not served here)
- .apb/playbooks/osb-release/1.0.0/playbook.yaml (not served here)
- .apb/playbooks/osb-release/1.0.0/scripts/discard.sh (not served here)
- .apb/playbooks/osb-release/1.0.0/scripts/lib.sh (not served here)
- .apb/playbooks/osb-release/1.0.0/scripts/publish.sh (not served here)
- .apb/playbooks/osb-release/1.0.0/scripts/release-image-style.md (not served here)
- .apb/playbooks/osb-release/1.0.0/scripts/render.sh (not served here)
- .apb/playbooks/osb-release/1.0.0/scripts/render.ts (not served here)
- .apb/playbooks/osb-release/1.0.0/scripts/scope.sh (not served here)
- .apb/playbooks/osb-release/1.0.0/scripts/stage.sh (not served here)
- .apb/playbooks/osb-release/current (not served here)
- .apb/playbooks/osb-release/lifecycle (not served here)
- .apb/playbooks/osb-release/meta/1.0.0.yaml (not served here)
- .apb/playbooks/osb-triage-validator/1.2.0/playbook.yaml (not served here)
- .apb/playbooks/osb-triage-validator/1.3.0/playbook.yaml (not served here)
- .apb/playbooks/osb-triage-validator/current (not served here)
- .apb/playbooks/osb-triage-validator/lifecycle (not served here)
- .apb/playbooks/osb-triage-validator/meta/1.2.0.yaml (not served here)
- .apb/playbooks/osb-triage-validator/meta/1.3.0.yaml (not served here)
- .apb/playbooks/osb-upstream-watch/1.0.0/playbook.yaml (not served here)
- .apb/playbooks/osb-upstream-watch/1.0.0/scripts/materialize-collector.sh (not served here)
- .apb/playbooks/osb-upstream-watch/current (not served here)
- .apb/playbooks/osb-upstream-watch/lifecycle (not served here)
- .apb/playbooks/osb-upstream-watch/meta/1.0.0.yaml (not served here)
- .apb/profiles/osb-collector/SOUL.md (not served here)
- .apb/profiles/osb-collector/profile.yaml (not served here)
- .apb/profiles/osb-developer/SOUL.md (not served here)
- .apb/profiles/osb-developer/profile.yaml (not served here)
- .apb/profiles/osb-reviewer/SOUL.md (not served here)
- .apb/profiles/osb-reviewer/profile.yaml (not served here)
- .apb/profiles/osb-validator/SOUL.md (not served here)
- .apb/profiles/osb-validator/profile.yaml (not served here)
- .claude-plugin/marketplace.json (not served here)
- .claude-plugin/plugin.json
- .codex-plugin/plugin.json (not served here)
- .codexignore (not served here)
- .gitattributes (not served here)
- .githooks/pre-commit (not served here)
- .githooks/pre-push (not served here)
- .github/dependabot.yml (not served here)
- .github/scripts/ci-scope.sh (not served here)
- .github/scripts/windows-timings.sh (not served here)
- .github/windows-test-timings.json (not served here)
- .github/workflows/ci.yml (not served here)
- .github/workflows/plugin-scanner.yml (not served here)
- .github/workflows/release.yml (not served here)
- .gitignore (not served here)
- .oxfmtrc.json (not served here)
- ATTRIBUTION.md
- AUTOGINEER-RUNS.md
- CHANGELOG.md
- CLAUDE.md
- LICENSE
- README.md
- SECURITY.md
- __init__.py (not served here)
- after-install.md
- bin/o2b-discipline-report (not served here)
- bun.lock (not served here)
- bunfig.toml (not served here)
- cli.py (not served here)
- docs/architecture.md
- docs/brain-store.md
- docs/brainstorm/a-label-is-not-a-boundary/cli-output/claude.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/cli-output/prompt.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/design.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/plan.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/recon/census-lexer.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/recon/conventions-and-release-machinery.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/recon/egress-boundary.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/recon/fleet-and-shared-scope.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/recon/identity-and-attribution.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/recon/mcp-instruction-surface.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/recon/owner-scope-isolation.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/recon/retrieval-confidence-floor.md (not served here)
- docs/brainstorm/a-label-is-not-a-boundary/variants.md (not served here)
- docs/brainstorm/actionable-now-batch/cli-output/consultant.md (not served here)
- docs/brainstorm/actionable-now-batch/cli-output/prompt.md (not served here)
- docs/brainstorm/actionable-now-batch/design.md (not served here)
- docs/brainstorm/actionable-now-batch/plan.md (not served here)
- docs/brainstorm/actionable-now-batch/variants.md (not served here)
- docs/brainstorm/agent-boundary-control-surfaces/README.md (not served here)
- docs/brainstorm/agent-boundary-control-surfaces/cli-output/claude.md (not served here)
- docs/brainstorm/agent-boundary-control-surfaces/cli-output/prompt.md (not served here)
- docs/brainstorm/agent-boundary-control-surfaces/design.md (not served here)
- docs/brainstorm/agent-boundary-control-surfaces/plan.md (not served here)
- docs/brainstorm/agent-boundary-control-surfaces/variants.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/README.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/adr.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/cli-output/claude.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/cli-output/prompt.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/context.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/design.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/implementation-notes.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/notes.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/phase-log.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/plan.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/pr-notes.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/scope.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/task-body.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/test-matrix.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/variants.md (not served here)
- docs/brainstorm/agent-capability-cli-integration/verification.md (not served here)
- docs/brainstorm/agent-presence-self-improvement/cli-output/consultant.md (not served here)
- docs/brainstorm/agent-presence-self-improvement/cli-output/prompt.md (not served here)
- docs/brainstorm/agent-presence-self-improvement/design.md (not served here)
- docs/brainstorm/agent-presence-self-improvement/plan.md (not served here)
- docs/brainstorm/agent-presence-self-improvement/variants.md (not served here)
- docs/brainstorm/agent-surface-suite/cli-output/claude.md (not served here)
- docs/brainstorm/agent-surface-suite/cli-output/prompt.md (not served here)
- docs/brainstorm/agent-surface-suite/design.md (not served here)
- docs/brainstorm/agent-surface-suite/plan.md (not served here)
- docs/brainstorm/agent-surface-suite/variants.md (not served here)
- docs/brainstorm/agent-write-contract-suite/cli-output/claude.md (not served here)
- docs/brainstorm/agent-write-contract-suite/cli-output/prompt.md (not served here)
- docs/brainstorm/agent-write-contract-suite/design.md (not served here)
- docs/brainstorm/agent-write-contract-suite/plan.md (not served here)
- docs/brainstorm/agent-write-contract-suite/variants.md (not served here)
- docs/brainstorm/answer-trust/cli-output/consultant.md (not served here)
- docs/brainstorm/answer-trust/cli-output/prompt.md (not served here)
- docs/brainstorm/answer-trust/design.md (not served here)
- docs/brainstorm/answer-trust/plan.md (not served here)
- docs/brainstorm/answer-trust/variants.md (not served here)
- docs/brainstorm/auto-migrate-on-upgrade/design.md (not served here)
- docs/brainstorm/auto-migrate-on-upgrade/plan.md (not served here)
- docs/brainstorm/auto-migrate-on-upgrade/variants.md (not served here)
- docs/brainstorm/belief-lifecycle-decision-memory/cli-output/claude.md (not served here)
- docs/brainstorm/belief-lifecycle-decision-memory/cli-output/prompt.md (not served here)
- docs/brainstorm/belief-lifecycle-decision-memory/design.md (not served here)
- docs/brainstorm/belief-lifecycle-decision-memory/plan.md (not served here)
- docs/brainstorm/belief-lifecycle-decision-memory/variants.md (not served here)
- docs/brainstorm/brain-centric-layout/design.md (not served here)
- docs/brainstorm/brain-centric-layout/plan.md (not served here)
- docs/brainstorm/brain-integrity-safety-hardening/cli-output/claude.md (not served here)
- docs/brainstorm/brain-integrity-safety-hardening/cli-output/prompt.md (not served here)
- docs/brainstorm/brain-integrity-safety-hardening/design.md (not served here)
- docs/brainstorm/brain-integrity-safety-hardening/plan.md (not served here)
- docs/brainstorm/brain-integrity-safety-hardening/variants.md (not served here)
- docs/brainstorm/brain-integrity-suite/cli-output/claude.md (not served here)
- docs/brainstorm/brain-integrity-suite/cli-output/prompt.md (not served here)
- docs/brainstorm/brain-integrity-suite/design.md (not served here)
- docs/brainstorm/brain-integrity-suite/plan.md (not served here)
- docs/brainstorm/brain-integrity-suite/pr-body.md (not served here)
- docs/brainstorm/brain-integrity-suite/variants.md (not served here)
- docs/brainstorm/brain-lifecycle-review-suite/cli-output/claude.md (not served here)
- docs/brainstorm/brain-lifecycle-review-suite/cli-output/prompt.md (not served here)
- docs/brainstorm/brain-lifecycle-review-suite/design.md (not served here)
- docs/brainstorm/brain-lifecycle-review-suite/plan.md (not served here)
- docs/brainstorm/brain-lifecycle-review-suite/variants.md (not served here)
- docs/brainstorm/brain-lifecycle-suite/cli-output/claude.md (not served here)
- docs/brainstorm/brain-lifecycle-suite/cli-output/prompt.md (not served here)
- docs/brainstorm/brain-lifecycle-suite/design.md (not served here)
- docs/brainstorm/brain-lifecycle-suite/plan.md (not served here)
- docs/brainstorm/brain-lifecycle-suite/variants.md (not served here)
- docs/brainstorm/brain-model-semantics-foundation/adr.md (not served here)
- docs/brainstorm/brain-model-semantics-foundation/cli-output/claude.md (not served here)
- docs/brainstorm/brain-model-semantics-foundation/cli-output/prompt.md (not served here)
- docs/brainstorm/brain-model-semantics-foundation/design.md (not served here)
- docs/brainstorm/brain-model-semantics-foundation/plan.md (not served here)
- docs/brainstorm/brain-model-semantics-foundation/variants.md (not served here)
- docs/brainstorm/brain-portability-interop/cli-output/claude.md (not served here)
- docs/brainstorm/brain-portability-interop/cli-output/prompt.md (not served here)
- docs/brainstorm/brain-portability-interop/design.md (not served here)
- docs/brainstorm/brain-portability-interop/plan.md (not served here)
- docs/brainstorm/brain-portability-interop/variants.md (not served here)
- docs/brainstorm/brain-safety-governance-suite/cli-output/claude.md (not served here)
- docs/brainstorm/brain-safety-governance-suite/cli-output/prompt.md (not served here)
- docs/brainstorm/brain-safety-governance-suite/design.md (not served here)
- docs/brainstorm/brain-safety-governance-suite/plan.md (not served here)
- docs/brainstorm/brain-safety-governance-suite/variants.md (not served here)
- docs/brainstorm/cjk-schema-lifecycle-recovery/cli-output/claude.md (not served here)
- docs/brainstorm/cjk-schema-lifecycle-recovery/cli-output/prompt.md (not served here)
- docs/brainstorm/cjk-schema-lifecycle-recovery/design.md (not served here)
- docs/brainstorm/cjk-schema-lifecycle-recovery/plan.md (not served here)
- docs/brainstorm/cjk-schema-lifecycle-recovery/variants.md (not served here)
- docs/brainstorm/codegraph-link-depth-mcp/cli-output/claude.md (not served here)
- docs/brainstorm/codegraph-link-depth-mcp/cli-output/prompt.md (not served here)
- docs/brainstorm/codegraph-link-depth-mcp/design.md (not served here)
- docs/brainstorm/codegraph-link-depth-mcp/plan.md (not served here)
- docs/brainstorm/codegraph-link-depth-mcp/variants.md (not served here)
- docs/brainstorm/codegraph-mcp-operational-readability/cli-output/claude.md (not served here)
- docs/brainstorm/codegraph-mcp-operational-readability/cli-output/prompt.md (not served here)
- docs/brainstorm/codegraph-mcp-operational-readability/design.md (not served here)
- docs/brainstorm/codegraph-mcp-operational-readability/plan.md (not served here)
- docs/brainstorm/codegraph-mcp-operational-readability/variants.md (not served here)
- docs/brainstorm/context-continuity-receipts-suite/cli-output/claude.md (not served here)
- docs/brainstorm/context-continuity-receipts-suite/cli-output/prompt.md (not served here)
- docs/brainstorm/context-continuity-receipts-suite/design.md (not served here)
- docs/brainstorm/context-continuity-receipts-suite/plan.md (not served here)
- docs/brainstorm/context-continuity-receipts-suite/variants.md (not served here)
- docs/brainstorm/context-injection-pipeline/cli-output/consultant.md (not served here)
- docs/brainstorm/context-injection-pipeline/cli-output/prompt.md (not served here)
- docs/brainstorm/context-injection-pipeline/design.md (not served here)
- docs/brainstorm/context-injection-pipeline/plan.md (not served here)
- docs/brainstorm/context-injection-pipeline/variants.md (not served here)
- docs/brainstorm/context-integrity-gates/cli-output/claude.md (not served here)
- docs/brainstorm/context-integrity-gates/cli-output/prompt.md (not served here)
- docs/brainstorm/context-integrity-gates/design.md (not served here)
- docs/brainstorm/context-integrity-gates/plan.md (not served here)
- docs/brainstorm/context-integrity-gates/variants.md (not served here)
- docs/brainstorm/context-pack-economics-observability/cli-output/claude.md (not served here)
- docs/brainstorm/context-pack-economics-observability/cli-output/prompt.md (not served here)
- docs/brainstorm/context-pack-economics-observability/design.md (not served here)
- docs/brainstorm/context-pack-economics-observability/plan.md (not served here)
- docs/brainstorm/context-pack-economics-observability/variants.md (not served here)
- docs/brainstorm/continuity-hygiene-freshness/cli-output/claude.md (not served here)
- docs/brainstorm/continuity-hygiene-freshness/cli-output/prompt.md (not served here)
- docs/brainstorm/continuity-hygiene-freshness/design.md (not served here)
- docs/brainstorm/continuity-hygiene-freshness/plan.md (not served here)
- docs/brainstorm/continuity-hygiene-freshness/variants.md (not served here)
- docs/brainstorm/cross-agent-query-foundation/cli-output/claude.md (not served here)
- docs/brainstorm/cross-agent-query-foundation/cli-output/prompt.md (not served here)
- docs/brainstorm/cross-agent-query-foundation/design.md (not served here)
- docs/brainstorm/cross-agent-query-foundation/plan.md (not served here)
- docs/brainstorm/cross-agent-query-foundation/variants.md (not served here)
- docs/brainstorm/crossvault-cards-eventtrace-fixes/design.md (not served here)
- docs/brainstorm/crossvault-cards-eventtrace-fixes/plan.md (not served here)
- docs/brainstorm/crossvault-cards-eventtrace-fixes/variants.md (not served here)
- docs/brainstorm/cycle-20261020/cli-output/claude.md (not served here)
- docs/brainstorm/cycle-20261020/cli-output/prompt.md (not served here)
- docs/brainstorm/cycle-20261020/design.md (not served here)
- docs/brainstorm/cycle-20261020/plan.md (not served here)
- docs/brainstorm/cycle-20261020/variants.md (not served here)
- docs/brainstorm/dated-commitments/cli-output/claude.md (not served here)
- docs/brainstorm/dated-commitments/cli-output/prompt.md (not served here)
- docs/brainstorm/dated-commitments/design.md (not served here)
- docs/brainstorm/dated-commitments/plan.md (not served here)
- docs/brainstorm/dated-commitments/variants.md (not served here)
- docs/brainstorm/default-scope-feedback/cli-output/claude.md (not served here)
- docs/brainstorm/default-scope-feedback/cli-output/prompt.md (not served here)
- docs/brainstorm/default-scope-feedback/design.md (not served here)
- docs/brainstorm/default-scope-feedback/plan.md (not served here)
- docs/brainstorm/default-scope-feedback/variants.md (not served here)
- docs/brainstorm/delivery-trust/cli-output/consultant.md (not served here)
- docs/brainstorm/delivery-trust/cli-output/prompt.md (not served here)
- docs/brainstorm/delivery-trust/design.md (not served here)
- docs/brainstorm/delivery-trust/plan.md (not served here)
- docs/brainstorm/delivery-trust/variants.md (not served here)
- docs/brainstorm/distilled-provenance/cli-output/claude.md (not served here)
- docs/brainstorm/distilled-provenance/cli-output/expected-output.md (not served here)
- docs/brainstorm/distilled-provenance/cli-output/prompt.md (not served here)
- docs/brainstorm/distilled-provenance/design.md (not served here)
- docs/brainstorm/distilled-provenance/plan.md (not served here)
- docs/brainstorm/distilled-provenance/variants.md (not served here)
- docs/brainstorm/embedding-provider-suite/cli-output/claude.md (not served here)
- docs/brainstorm/embedding-provider-suite/cli-output/prompt.md (not served here)
- docs/brainstorm/embedding-provider-suite/design.md (not served here)
- docs/brainstorm/embedding-provider-suite/plan.md (not served here)
- docs/brainstorm/embedding-provider-suite/variants.md (not served here)
- docs/brainstorm/entity-truth-dream-suite/cli-output/claude.md (not served here)
- docs/brainstorm/entity-truth-dream-suite/cli-output/prompt.md (not served here)
- docs/brainstorm/entity-truth-dream-suite/design.md (not served here)
- docs/brainstorm/entity-truth-dream-suite/plan.md (not served here)
- docs/brainstorm/entity-truth-dream-suite/variants.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/cli-output/claude.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/cli-output/prompt.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/design.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/plan.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/recon/0e79f0-lint-on-write.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/recon/130-hermes-readiness.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/recon/155-include-paths.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/recon/160-source-trust.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/recon/161-slug-race.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/recon/3309-retrieval-trail.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/recon/a3254-readiness-liveness.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/recon/conventions.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/recon/e24c6d-schema-completeness.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/recon/e5f447-recall-channels.md (not served here)
- docs/brainstorm/evidence-at-the-boundary/variants.md (not served here)
- docs/brainstorm/grok-native-integration/cli-output/claude.md (not served here)
- docs/brainstorm/grok-native-integration/cli-output/prompt.md (not served here)
- docs/brainstorm/grok-native-integration/design.md (not served here)
- docs/brainstorm/grok-native-integration/plan.md (not served here)
- docs/brainstorm/grok-native-integration/variants.md (not served here)
- docs/brainstorm/hermes-memory-provider/cli-output/claude.md (not served here)
- docs/brainstorm/hermes-memory-provider/cli-output/prompt.md (not served here)
- docs/brainstorm/hermes-memory-provider/design.md (not served here)
- docs/brainstorm/hermes-memory-provider/plan.md (not served here)
- docs/brainstorm/hermes-memory-provider/variants.md (not served here)
- docs/brainstorm/hermes-static-tool-schemas/cli-output/claude.md (not served here)
- docs/brainstorm/hermes-static-tool-schemas/cli-output/prompt.md (not served here)
- docs/brainstorm/hermes-static-tool-schemas/design.md (not served here)
- docs/brainstorm/hermes-static-tool-schemas/plan.md (not served here)
- docs/brainstorm/hermes-static-tool-schemas/variants.md (not served here)
- docs/brainstorm/hindsight-brain-loop-ops/cli-output/claude.md (not served here)
- docs/brainstorm/hindsight-brain-loop-ops/cli-output/prompt.md (not served here)
- docs/brainstorm/hindsight-brain-loop-ops/design.md (not served here)
- docs/brainstorm/hindsight-brain-loop-ops/plan.md (not served here)
- docs/brainstorm/hindsight-brain-loop-ops/variants.md (not served here)
- docs/brainstorm/honest-embedding-spend/cli-output/claude.md (not served here)
- docs/brainstorm/honest-embedding-spend/cli-output/prompt.md (not served here)
- docs/brainstorm/honest-embedding-spend/design.md (not served here)
- docs/brainstorm/honest-embedding-spend/plan.md (not served here)
- docs/brainstorm/honest-embedding-spend/variants.md (not served here)
- docs/brainstorm/honest-query-embed-and-safe-upgrades/cli-output/claude.md (not served here)
- docs/brainstorm/honest-query-embed-and-safe-upgrades/cli-output/prompt.md (not served here)
- docs/brainstorm/honest-query-embed-and-safe-upgrades/design.md (not served here)
- docs/brainstorm/honest-query-embed-and-safe-upgrades/plan.md (not served here)
- docs/brainstorm/honest-query-embed-and-safe-upgrades/variants.md (not served here)
- docs/brainstorm/hook-update-resilience/design.md (not served here)
- docs/brainstorm/hook-update-resilience/plan.md (not served here)
- docs/brainstorm/hook-update-resilience/variants.md (not served here)
- docs/brainstorm/index-freshness/design.md (not served here)
- docs/brainstorm/index-freshness/plan.md (not served here)
- docs/brainstorm/indexer-durability/cli-output/claude.md (not served here)
- docs/brainstorm/indexer-durability/cli-output/prompt.md (not served here)
- docs/brainstorm/indexer-durability/design.md (not served here)
- docs/brainstorm/indexer-durability/plan.md (not served here)
- docs/brainstorm/indexer-durability/variants.md (not served here)
- docs/brainstorm/ingestion-import-robustness/design.md (not served here)
- docs/brainstorm/ingestion-import-robustness/plan.md (not served here)
- docs/brainstorm/ingestion-import-robustness/variants.md (not served here)
- docs/brainstorm/integrity-control-agent-memory-surface/cli-output/claude.md (not served here)
- docs/brainstorm/integrity-control-agent-memory-surface/cli-output/prompt.md (not served here)
- docs/brainstorm/integrity-control-agent-memory-surface/design.md (not served here)
- docs/brainstorm/integrity-control-agent-memory-surface/plan.md (not served here)
- docs/brainstorm/integrity-control-agent-memory-surface/variants.md (not served here)
- docs/brainstorm/knowledge-intake-and-consolidation/cli-output/claude.md (not served here)
- docs/brainstorm/knowledge-intake-and-consolidation/cli-output/prompt.md (not served here)
- docs/brainstorm/knowledge-intake-and-consolidation/design.md (not served here)
- docs/brainstorm/knowledge-intake-and-consolidation/plan.md (not served here)
- docs/brainstorm/knowledge-intake-and-consolidation/variants.md (not served here)
- docs/brainstorm/knowledge-provenance/cli-output/claude.md (not served here)
- docs/brainstorm/knowledge-provenance/cli-output/prompt.md (not served here)
- docs/brainstorm/knowledge-provenance/design.md (not served here)
- docs/brainstorm/knowledge-provenance/plan.md (not served here)
- docs/brainstorm/knowledge-provenance/variants.md (not served here)
- docs/brainstorm/language-agnostic-fact-extraction/cli-output/claude.md (not served here)
- docs/brainstorm/language-agnostic-fact-extraction/cli-output/prompt.md (not served here)
- docs/brainstorm/language-agnostic-fact-extraction/design.md (not served here)
- docs/brainstorm/language-agnostic-fact-extraction/plan.md (not served here)
- docs/brainstorm/language-agnostic-fact-extraction/variants.md (not served here)
- docs/brainstorm/link-graph-surfaces/cli-output/claude.md (not served here)
- docs/brainstorm/link-graph-surfaces/cli-output/prompt.md (not served here)
- docs/brainstorm/link-graph-surfaces/design.md (not served here)
- docs/brainstorm/link-graph-surfaces/plan.md (not served here)
- docs/brainstorm/link-graph-surfaces/variants.md (not served here)
- docs/brainstorm/link-recall-intelligence/cli-output/claude.md (not served here)
- docs/brainstorm/link-recall-intelligence/cli-output/prompt.md (not served here)
- docs/brainstorm/link-recall-intelligence/design.md (not served here)
- docs/brainstorm/link-recall-intelligence/plan.md (not served here)
- docs/brainstorm/link-recall-intelligence/variants.md (not served here)
- docs/brainstorm/manifest-dependency-facts/cli-output/claude.md (not served here)
- docs/brainstorm/manifest-dependency-facts/cli-output/expected-output.md (not served here)
- docs/brainstorm/manifest-dependency-facts/cli-output/prompt.md (not served here)
- docs/brainstorm/manifest-dependency-facts/design.md (not served here)
- docs/brainstorm/manifest-dependency-facts/plan.md (not served here)
- docs/brainstorm/manifest-dependency-facts/variants.md (not served here)
- docs/brainstorm/mcp-context-economy/cli-output/claude.md (not served here)
- docs/brainstorm/mcp-context-economy/cli-output/prompt.md (not served here)
- docs/brainstorm/mcp-context-economy/design.md (not served here)
- docs/brainstorm/mcp-context-economy/plan.md (not served here)
- docs/brainstorm/mcp-context-economy/variants.md (not served here)
- docs/brainstorm/mcp-error-codes/cli-output/claude.md (not served here)
- docs/brainstorm/mcp-error-codes/cli-output/prompt.md (not served here)
- docs/brainstorm/mcp-error-codes/design.md (not served here)
- docs/brainstorm/mcp-error-codes/plan.md (not served here)
- docs/brainstorm/mcp-error-codes/variants.md (not served here)
- docs/brainstorm/memory-integrity/cli-output/claude.md (not served here)
- docs/brainstorm/memory-integrity/cli-output/prompt.md (not served here)
- docs/brainstorm/memory-integrity/design.md (not served here)
- docs/brainstorm/memory-integrity/plan.md (not served here)
- docs/brainstorm/memory-integrity/variants.md (not served here)
- docs/brainstorm/memory-observability-suite/atof-atif-mapping.md (not served here)
- docs/brainstorm/memory-observability-suite/cli-output/claude.md (not served here)
- docs/brainstorm/memory-observability-suite/cli-output/prompt.md (not served here)
- docs/brainstorm/memory-observability-suite/design.md (not served here)
- docs/brainstorm/memory-observability-suite/plan.md (not served here)
- docs/brainstorm/memory-observability-suite/variants.md (not served here)
- docs/brainstorm/memory-signal-provenance-lifecycle/cli-output/claude.md (not served here)
- docs/brainstorm/memory-signal-provenance-lifecycle/cli-output/prompt.md (not served here)
- docs/brainstorm/memory-signal-provenance-lifecycle/design.md (not served here)
- docs/brainstorm/memory-signal-provenance-lifecycle/plan.md (not served here)
- docs/brainstorm/memory-signal-provenance-lifecycle/variants.md (not served here)
- docs/brainstorm/memory-subsystem-alignment/cli-output/claude.md (not served here)
- docs/brainstorm/memory-subsystem-alignment/cli-output/prompt.md (not served here)
- docs/brainstorm/memory-subsystem-alignment/design.md (not served here)
- docs/brainstorm/memory-subsystem-alignment/plan.md (not served here)
- docs/brainstorm/memory-subsystem-alignment/variants.md (not served here)
- docs/brainstorm/memory-write-path-integrity/cli-output/claude.md (not served here)
- docs/brainstorm/memory-write-path-integrity/cli-output/prompt.md (not served here)
- docs/brainstorm/memory-write-path-integrity/design.md (not served here)
- docs/brainstorm/memory-write-path-integrity/plan.md (not served here)
- docs/brainstorm/memory-write-path-integrity/variants.md (not served here)
- docs/brainstorm/near-duplicate-defense/cli-output/claude.md (not served here)
- docs/brainstorm/near-duplicate-defense/cli-output/codex.md (not served here)
- docs/brainstorm/near-duplicate-defense/cli-output/opencode.md (not served here)
- docs/brainstorm/near-duplicate-defense/cli-output/prompt.md (not served here)
- docs/brainstorm/near-duplicate-defense/cli-output/second-claude.md (not served here)
- docs/brainstorm/near-duplicate-defense/design.md (not served here)
- docs/brainstorm/near-duplicate-defense/plan.md (not served here)
- docs/brainstorm/near-duplicate-defense/variants.md (not served here)
- docs/brainstorm/no-dead-ends/cli-output/claude.md (not served here)
- docs/brainstorm/no-dead-ends/cli-output/prompt.md (not served here)
- docs/brainstorm/no-dead-ends/design.md (not served here)
- docs/brainstorm/no-dead-ends/plan.md (not served here)
- docs/brainstorm/no-dead-ends/variants.md (not served here)
- docs/brainstorm/non-markdown-ingest/cli-output/claude.md (not served here)
- docs/brainstorm/non-markdown-ingest/cli-output/expected-output.md (not served here)
- docs/brainstorm/non-markdown-ingest/cli-output/prompt.md (not served here)
- docs/brainstorm/non-markdown-ingest/design.md (not served here)
- docs/brainstorm/non-markdown-ingest/plan.md (not served here)
- docs/brainstorm/non-markdown-ingest/variants.md (not served here)
- docs/brainstorm/note-change-truth-maintenance/cli-output/claude.md (not served here)
- docs/brainstorm/note-change-truth-maintenance/cli-output/prompt.md (not served here)
- docs/brainstorm/note-change-truth-maintenance/cli-output/task-bodies.md (not served here)
- docs/brainstorm/note-change-truth-maintenance/design.md (not served here)
- docs/brainstorm/note-change-truth-maintenance/plan.md (not served here)
- docs/brainstorm/note-change-truth-maintenance/variants.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/cli-output/claude.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/cli-output/prompt.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/design.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/plan.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/recon/architect-module.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/recon/concurrency-and-cancellation.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/recon/durability-and-ownership.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/recon/failure-mode-bench.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/recon/ingest-adapters-and-lease.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/recon/progress-reporting.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/recon/provider-sunset.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/review/claims-and-refusals.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/review/cross-cutting.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/review/locks-and-races.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/review/progress-and-cancellation.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/review/tests-and-docs.md (not served here)
- docs/brainstorm/nothing-runs-unwatched/variants.md (not served here)
- docs/brainstorm/nothing-writes-silently/cli-output/claude.md (not served here)
- docs/brainstorm/nothing-writes-silently/cli-output/prompt.md (not served here)
- docs/brainstorm/nothing-writes-silently/design.md (not served here)
- docs/brainstorm/nothing-writes-silently/plan.md (not served here)
- docs/brainstorm/nothing-writes-silently/variants.md (not served here)
- docs/brainstorm/opencode-native-integration/cli-output/claude.md (not served here)
- docs/brainstorm/opencode-native-integration/cli-output/prompt.md (not served here)
- docs/brainstorm/opencode-native-integration/design.md (not served here)
- docs/brainstorm/opencode-native-integration/plan.md (not served here)
- docs/brainstorm/opencode-native-integration/variants.md (not served here)
- docs/brainstorm/operability-first-run/design.md (not served here)
- docs/brainstorm/operability-first-run/plan.md (not served here)
- docs/brainstorm/operability-first-run/variants.md (not served here)
- docs/brainstorm/operational-friction-reduction/design.md (not served here)
- docs/cli-reference.md
- docs/cross-project-pointer.md
- docs/decision-models.md
- docs/hermes-cron.md
- docs/how-it-works.md
- docs/idea.md
- docs/ingest-manifest.md
- docs/mcp.md
- docs/metrics.md
- docs/observability.md
- docs/stability.md
- docs/updating.md
- hooks/hooks.json
- install.md
- plugins/codex/LICENSE
Advantages
- Human-readable and editable memory stored as standard Markdown files in an Obsidian vault. evidence: README.md
- Deterministic dream pass ensures rules are derived from repeated signals without requiring additional model runs. evidence: README.md
- Supports reversible changes through snapshots and rollback capabilities. evidence: README.md
Limitations
- Requires Bun runtime for the CLI and core operations. evidence: README.md
- Advanced features like semantic search require additional setup with sqlite-vec. evidence: README.md
- Some integrations depend on specific client-side plugin support or MCP host capabilities. evidence: README.md
Security
Risk level: Low risk
This brain runs
MCP servers (2)
.claude-plugin/plugin.json(open-second-brain):${CLAUDE_PLUGIN_ROOT}/scripts/o2b mcp --harness claude-code.claude-plugin/plugin.json(open-second-brain-writer):${CLAUDE_PLUGIN_ROOT}/scripts/o2b mcp --scope writer --harness claude-code
Git hooks (2)
.githooks/pre-commit(pre-commit):runs on git pre-commit.githooks/pre-push(pre-push):runs on git pre-push
Agent instructions that run or fetch something (46)
CLAUDE.md:bun run scripts/sync-version.tsCLAUDE.md:CI gates on `bun run scripts/sync-version.ts --check` (the `validate` job, step "Verify manifest version sync").CLAUDE.md:Run the `--check` form locally before pushing a version change.CLAUDE.md:Bump `package.json` (and run `sync-version.ts`) on the feature branch and include it in the SAME pull request as the feature, before you push.CLAUDE.md:Bump `package.json` to `X.Y.Z` and run `bun run scripts/sync-version.ts`.CLAUDE.md:After changing a skill or `hooks/hooks.json`, run:CLAUDE.md:bun run sync-plugin-mirrorsCLAUDE.md:CI gates on `bun run sync-plugin-mirrors:check` (the `validate` and `windows` jobs), and the pre-commit hook runs the same check.docs/legacy-skills/agent-event-log/SKILL.md:Read-only queries (running `git log`, `o2b status`, `vault_health`, `second_brain_query`).docs/legacy-skills/agent-event-log/SKILL.md:**Technical identifiers stay verbatim regardless of surrounding language**: command names (`bun test`, `o2b doctor`), file paths (`src/core/event-log.ts`), package and library names (`proper-lockfile`, `@anthropic-ai/sdk`), API symbols, error messages quoted from logs.plugins/codex/skills/brain-memory/SKILL.md:Read-only inspection (running `git log`, `o2b status`, `vault_health`).plugins/codex/skills/brain-memory/SKILL.md:After scan, the source line becomes `@osb✓ [[sig-...]]` so a second run is idempotent.plugins/codex/skills/codegraph-partner/SKILL.md:Run these checks in order.plugins/codex/skills/codegraph-partner/SKILL.md:No install talk.plugins/codex/skills/codegraph-partner/SKILL.md:| | not_indexed (CLI present, no `.codegraph/` or `initialized: false`) | Offer one line: "run `codegraph init <path>` to index this repo".plugins/codex/skills/codegraph-partner/SKILL.md:Whenever you run `codegraph init` in any repository on the user's behalf, immediately read that repo's `.gitignore` and append a `.codegraph/` line if one is not already present.plugins/codex/skills/decision-model-setup/SKILL.md:That is the operator's command, and only the operator can run it: the key is operator-only, so the `brain_settings` tool refuses an agent's write to it with `operator_only_setting` on every machine, switched or not.plugins/codex/skills/decision-model-setup/SKILL.md:Ask the operator to run the command;plugins/codex/skills/decision-model-setup/SKILL.md:Does not install servers or download model weights.plugins/codex/skills/embeddings-setup/SKILL.md:Every run that uses it prints one stderr warning per endpoint.plugins/codex/skills/embeddings-setup/SKILL.md:If the install path missed it, force a rebuild:plugins/codex/skills/embeddings-setup/SKILL.md:bun pm ls | grep sqlite-vecplugins/codex/skills/embeddings-setup/SKILL.md:bun install --forceplugins/codex/skills/embeddings-setup/SKILL.md:When the index already exists and only some chunks lack vectors, price the work first with the dry run, then apply it:plugins/codex/skills/embeddings-setup/SKILL.md:Does not invoke `brew install` on the user's behalf.plugins/codex/skills/schema-author/SKILL.md:Preview the batch first with `schema_apply_mutations` (`dry_run=true`) or `o2b brain schema apply --dry-run --mutation ...`: it returns the pack that would result and its diff and writes nothing at all - no config write, no audit record, no lock file.plugins/codex/skills/schema-author/SKILL.md:It does not run the two checks that exist only because the apply writes: the vault-identity write guard, and the atomic writer's re-parse of the rendered YAML.plugins/codex/skills/schema-author/SKILL.md:Re-run lint/stats after mutation and report changed tokens plus any remaining findings.skills/brain-memory/SKILL.md:Read-only inspection (running `git log`, `o2b status`, `vault_health`).skills/brain-memory/SKILL.md:After scan, the source line becomes `@osb✓ [[sig-...]]` so a second run is idempotent.skills/codegraph-partner/SKILL.md:Run these checks in order.skills/codegraph-partner/SKILL.md:No install talk.skills/codegraph-partner/SKILL.md:| | not_indexed (CLI present, no `.codegraph/` or `initialized: false`) | Offer one line: "run `codegraph init <path>` to index this repo".skills/codegraph-partner/SKILL.md:Whenever you run `codegraph init` in any repository on the user's behalf, immediately read that repo's `.gitignore` and append a `.codegraph/` line if one is not already present.skills/decision-model-setup/SKILL.md:That is the operator's command, and only the operator can run it: the key is operator-only, so the `brain_settings` tool refuses an agent's write to it with `operator_only_setting` on every machine, switched or not.skills/decision-model-setup/SKILL.md:Ask the operator to run the command;skills/decision-model-setup/SKILL.md:Does not install servers or download model weights.skills/embeddings-setup/SKILL.md:Every run that uses it prints one stderr warning per endpoint.skills/embeddings-setup/SKILL.md:If the install path missed it, force a rebuild:skills/embeddings-setup/SKILL.md:bun pm ls | grep sqlite-vecskills/embeddings-setup/SKILL.md:bun install --forceskills/embeddings-setup/SKILL.md:When the index already exists and only some chunks lack vectors, price the work first with the dry run, then apply it:skills/embeddings-setup/SKILL.md:Does not invoke `brew install` on the user's behalf.skills/schema-author/SKILL.md:Preview the batch first with `schema_apply_mutations` (`dry_run=true`) or `o2b brain schema apply --dry-run --mutation ...`: it returns the pack that would result and its diff and writes nothing at all - no config write, no audit record, no lock file.skills/schema-author/SKILL.md:It does not run the two checks that exist only because the apply writes: the vault-identity write guard, and the atomic writer's re-parse of the rendered YAML.skills/schema-author/SKILL.md:Re-run lint/stats after mutation and report changed tokens plus any remaining findings.
Hooks (54)
hooks/hooks.json(PostToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json(PostToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" post-write-reminder; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook post-write-reminder; exit 0hooks/hooks.json(PostToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" subagent-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook subagent-inject; exit 0hooks/hooks.json(PostToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" reground-deliver; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook reground-deliver; exit 0hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" active-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook active-inject; exit 0hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" gap-agenda; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook gap-agenda; exit 0hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" backlog-nudge; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook backlog-nudge; exit 0hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" log-catchup; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook log-catchup; exit 0hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" view-render; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook view-render; exit 0hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json(UserPromptSubmit):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json(UserPromptSubmit):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" recall-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook recall-inject; exit 0hooks/hooks.json(UserPromptSubmit):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" nav-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook nav-inject; exit 0hooks/hooks.json(UserPromptSubmit):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" counterparty-brief; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook counterparty-brief; exit 0hooks/hooks.json(UserPromptSubmit):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" reground-deliver; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook reground-deliver; exit 0hooks/hooks.json(PreToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" pretool-orient; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook pretool-orient; exit 0hooks/hooks.json(PreToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" pretool-host-backup; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook pretool-host-backup; exit 0hooks/hooks.json(Stop):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json(Stop):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" stop-log-guardrail; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook stop-log-guardrail; exit 0hooks/hooks.json(Stop):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" answer-quote-check; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook answer-quote-check; exit 0hooks/hooks.json(Stop):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" hygiene-digest; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook hygiene-digest; exit 0hooks/hooks.json(SubagentStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" subagent-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook subagent-inject; exit 0hooks/hooks.json(SubagentStop):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json(SessionEnd):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0hooks/hooks.json(SessionEnd):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" gap-promote; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook gap-promote; exit 0hooks/hooks.json(PostCompact):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" active-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook active-inject; exit 0hooks/hooks.json(PostCompact):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json(PostToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json(PostToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" post-write-reminder; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook post-write-reminder; exit 0plugins/codex/hooks/hooks.json(PostToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" subagent-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook subagent-inject; exit 0plugins/codex/hooks/hooks.json(PostToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" reground-deliver; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook reground-deliver; exit 0plugins/codex/hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" active-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook active-inject; exit 0plugins/codex/hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" gap-agenda; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook gap-agenda; exit 0plugins/codex/hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" backlog-nudge; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook backlog-nudge; exit 0plugins/codex/hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" log-catchup; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook log-catchup; exit 0plugins/codex/hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" view-render; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook view-render; exit 0plugins/codex/hooks/hooks.json(SessionStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json(UserPromptSubmit):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json(UserPromptSubmit):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" recall-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook recall-inject; exit 0plugins/codex/hooks/hooks.json(UserPromptSubmit):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" nav-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook nav-inject; exit 0plugins/codex/hooks/hooks.json(UserPromptSubmit):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" counterparty-brief; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook counterparty-brief; exit 0plugins/codex/hooks/hooks.json(UserPromptSubmit):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" reground-deliver; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook reground-deliver; exit 0plugins/codex/hooks/hooks.json(PreToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" pretool-orient; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook pretool-orient; exit 0plugins/codex/hooks/hooks.json(PreToolUse):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" pretool-host-backup; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook pretool-host-backup; exit 0plugins/codex/hooks/hooks.json(Stop):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json(Stop):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" stop-log-guardrail; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook stop-log-guardrail; exit 0plugins/codex/hooks/hooks.json(Stop):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" answer-quote-check; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook answer-quote-check; exit 0plugins/codex/hooks/hooks.json(Stop):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" hygiene-digest; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook hygiene-digest; exit 0plugins/codex/hooks/hooks.json(SubagentStart):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" subagent-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook subagent-inject; exit 0plugins/codex/hooks/hooks.json(SubagentStop):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json(SessionEnd):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0plugins/codex/hooks/hooks.json(SessionEnd):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" gap-promote; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook gap-promote; exit 0plugins/codex/hooks/hooks.json(PostCompact):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" active-inject; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook active-inject; exit 0plugins/codex/hooks/hooks.json(PostCompact):r="$CLAUDE_PLUGIN_ROOT"; if [ -n "$r" ] && [ -x "$r/scripts/o2b-hook" ]; then exec "$r/scripts/o2b-hook" session-capture; fi; command -v o2b-hook >/dev/null 2>&1 && exec o2b-hook session-capture; exit 0
Package scripts (1)
package.json(prepare):bun scripts/prepare.ts || exit 0
- Low risk: scripts-present (.githooks/pre-commit)
- Low risk: scripts-present (.githooks/pre-push)
- Low risk: network-instructions (plugins/codex/skills/codegraph-partner/SKILL.md:115)
- Low risk: scripts-present (scripts/prepare.ts)
- Low risk: network-instructions (skills/codegraph-partner/SKILL.md:115)
Attribution and licence
- First committed by
hermes-vps-agent
- Declared authors
- Open Second Brain contributors (declared in .claude-plugin/plugin.json)
- Open Second Brain contributors (declared in pyproject.toml)
- Publisher
- Serg Eroshe (Community)
- Source
- itechmeat/open-second-brain · commit 233b91d
- Licence
- MIT License (files served here)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Contributors
- solaitken, itechmeat, Yori940619, hermes-vps-agent, DanBennettUK
AutoGineer is not affiliated with or endorsed by hermes-vps-agent or Serg Eroshe.
Install from source
486 of its files are not served here, so there is no ZIP. itechmeat/open-second-brain at 233b91d