{"id":50526414,"url":"https://github.com/mxcd/multiverse","last_synced_at":"2026-06-03T08:04:33.246Z","repository":{"id":361706101,"uuid":"1254705872","full_name":"mxcd/multiverse","owner":"mxcd","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-31T21:54:51.000Z","size":52,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-31T23:22:22.503Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mxcd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-30T22:53:44.000Z","updated_at":"2026-05-31T21:54:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mxcd/multiverse","commit_stats":null,"previous_names":["mxcd/multiverse"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/mxcd/multiverse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxcd%2Fmultiverse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxcd%2Fmultiverse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxcd%2Fmultiverse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxcd%2Fmultiverse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mxcd","download_url":"https://codeload.github.com/mxcd/multiverse/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxcd%2Fmultiverse/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33854135,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-03T08:04:32.008Z","updated_at":"2026-06-03T08:04:33.233Z","avatar_url":"https://github.com/mxcd.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# multiverse — `multi`\n\nA git-backed markdown **second brain** for agents and humans. `multi` is the\nstorage-layer CLI: it hides git transport behind `read` / `write` / `search` so\nan agent never thinks about sync, and it enforces the conventions that keep a\nbrain navigable — above all, **every note has a one-line summary**.\n\n## Why\n\n- **Markdown is the source of truth.** Plain `.md` in a git repo. No database, no\n  proprietary store, no obfuscation — readable and editable anywhere (Obsidian, an\n  editor, `grep`).\n- **Git is the transport.** Real conflict resolution (`*.md merge=union`), offline\n  commits, full history/audit. The agent calls `read`/`write`/`search`; `multi`\n  does pull/commit/push underneath.\n- **Writes are guaranteed structured.** `multi write` refuses without a `summary`,\n  auto-fills `created`/`retrieved`, and auto-commits. The \"never forgotten\"\n  guarantee is enforced at the only write path.\n- **Headless.** No Obsidian app required — works on servers where agents run.\n\n## Install\n\n```bash\njust install          # go install ./cmd/multi  →  $GOBIN/multi\n# or\njust build            # → ./bin/multi\n```\n\n## Control panel (TUI)\n\n```bash\nmulti                 # no args on a terminal → launches the TUI\nmulti tui             # explicit (aliases: dashboard, ui)\n```\n\nA Bubble Tea control panel with three tabbed views:\n\n- **Dashboard** — every brain with git state (branch · clean/dirty · ↑ahead ↓behind), note count, and lint status; plus the resolved scope for the current directory. Keys: `s` sync · `S` sync all · `l`/`L` lint · `r` refresh · `enter` set active.\n- **Brains** — manage the global registry: `a` add · `e` rename · `p` set path · `d` delete · `enter` set active.\n- **Scope** — bind the current directory: toggle each brain as `space` source / `t` target, then `w` to write `./.multi.yaml` (`c` clears it).\n\n`tab`/`shift+tab` switch views, `q` quits. On a non-interactive shell (agent/CI), `multi` with no args prints help instead of launching.\n\n## Onboarding\n\n```bash\nmulti onboard                                   # interactive: new or clone\nmulti init ~/vaults/mybrain --name mybrain --split domain,operations\nmulti clone git@host:me/brain.git ~/vaults/brain\nmulti brain list            # registered brains (* = active)\nmulti brain use mybrain     # set active brain\n```\n\n`init` scaffolds the governance docs (`README`, `read`, `write`, `Conventions`,\n`Code of Conduct`, `Home`), `Templates/`, a `.gitignore` that keeps large\nbinaries out of git, and a `.gitattributes` with `*.md merge=union` — then\n`git init`s with an initial commit.\n\n## Per-directory scope (multiple brains)\n\nThe directory you work in declares which brains it **reads from** (sources) and\n**writes to** (targets) via a `.multi.yaml`, walked up the tree like `.git`:\n\n```bash\ncd ~/github.com/asolabs/qvm-website\nmulti use qvm                       # read+write the qvm brain here and below\nmulti use qvm --read-only           # read-only: no writes land here\nmulti scope set --source qvm,deepthought --target qvm   # read both, write only qvm\nmulti scope                         # show the resolved scope\nmulti scope clear                   # remove ./.multi.yaml\n```\n\n`.multi.yaml`:\n\n```yaml\nsources: [qvm, deepthought]   # read commands span all of these\ntargets: [qvm]                # writes land here (first = default); omit → = sources\nread_only: true               # no write targets at all (overrides targets)\n```\n\nWith a scope active, **reads span every source** (results labeled by brain) and\n**writes go to the target**:\n\n```bash\nmulti list                    # notes from qvm AND deepthought, brain-labeled\nmulti search \"iso 17024\"      # searches all sources\nmulti read deepthought:Home   # brain:note qualifier when a name exists in several\nmulti write --title ... --summary ...   # lands in qvm (the target)\nmulti write -b deepthought --title ...  # override target for one write\nmulti sync                    # syncs every brain in scope\n```\n\n## Resolution order\n\nEach command resolves its scope as: `--brain \u003cname|path\u003e` (one brain, overrides\neverything) → nearest `.multi.yaml` → the brain the cwd sits inside → the active\nbrain in the registry.\n\n## For agents / LLMs\n\n`multi` is meant to be driven directly by shell-capable agents (Claude Code,\nHermes) — no MCP server needed. To make one fluent in one shot:\n\n```bash\nmulti guide              # compact mental model + cheatsheet (the read→write→sync loop)\nmulti guide --claude-md  # emit a CLAUDE.md block to paste into a project repo\n```\n\nErrors are self-correcting (they say how to fix), and read commands take `--json`.\n\n## The agent loop\n\n```bash\n# read — summary first, body only on confirmed relevance\nmulti list                          # index: every note + its summary\nmulti summary \"QVM Overview\"        # one note's summary\nmulti fm \"QVM Overview\"             # full front-matter block\nmulti search \"iso 17024\" [--body]   # match path/summary/tags (+ bodies)\nmulti find --type reference --tag domain --status active\nmulti read \"QVM Overview\"           # the deliberate full read\nmulti links / backlinks \"...\" / orphans\n\n# write — structured + auto-committed\nmulti write --title \"Mediation Basics\" --dir domain \\\n  --summary \"what mediation is and why QVM certifies it\" \\\n  --tags domain,mediation --source \"...\" --freshness \"current\" \\\n  --body \"...\"                      # or --stdin\nmulti append \"Mediation Basics\" --content \"addendum\"   # or --stdin\n\n# transport \u0026 integrity\nmulti sync [-m \"msg\"]               # commit local → pull --rebase → push\nmulti status\nmulti lint [--summary|--tags|--fresh] [--json]\n```\n\nMost read commands accept `--json` for machine consumption.\n\n## The brain conventions\n\nFront matter (`multi write` enforces the core; `multi lint` checks all):\n\n```yaml\ntype: reference        # moc | reference | decision | hub | meta\nstatus: active         # active | draft | deprecated\ntags: [\u003csplit\u003e, ...]   # content notes carry one split tag + topic tags\ncreated: \u003cYYYY-MM-DD\u003e   # auto-filled\nsummary: One-line description — the gate readers read first\nsource: ...            # provenance\nretrieved: \u003cYYYY-MM-DD\u003e# auto-filled\nfreshness: ...         # one-line currency/trust note\n```\n\n**Standing rules** (enforced by `multi lint`): every note has a `summary`; every\n*content* note carries one split tag and records `source`/`retrieved`/`freshness`;\nhubs and the `[[wikilink]]` graph are the index, not folders.\n\n## Large files\n\nMarkdown lives in git. **Large binaries (PDFs, images, archives) do not** — they\nbloat every clone forever. Keep them in object storage and link them (see a\nbrain's `.gitignore`). Object-storage attachment handling is a planned follow-up.\n\n## Ingester — automatic session-end integration (`ingester`)\n\nA companion binary that runs on Claude Code's **Stop** hook and weaves each session's\nlearnings into a brain — **extending and cross-linking existing notes** instead of\ndumping standalone files. It keeps a per-session **ledger** (transcript cursor + the\nnotes touched so far) so repeated Stop firings *continue* one integration rather than\nduplicating, and it does the actual editing by steering a dedicated, **subscription-\nbacked** interactive Claude session over tmux (so it never spends Agent-SDK / API\ncredit).\n\nFlow: `Stop → ingester hook` (enqueue + kick the dispatcher, returns instantly) →\ndetached `ingester dispatch` (single-flight via `flock`) computes the transcript delta,\nsteers the tmux session to integrate it through `multi --brain \u003cbrain\u003e`, waits for a\nsentinel report, updates the ledger, then `multi sync`s. A job that stalls times out\ninto a dead-letter queue — nothing is lost and the host session never blocks.\n\n```\ningester hook       # Stop-hook entry: reads hook JSON on stdin (fast, non-blocking)\ningester dispatch   # detached worker; drains the queue (one integration per session)\ningester run --session \u003cid\u003e --transcript \u003cpath\u003e   # one cycle in the foreground (debug)\ningester status     # queue, tmux session, ledgers\ningester session ensure | kill                     # manage the tmux session\n```\n\n### Local install (LLM-friendly runbook)\n\nPrerequisites: `go` ≥ 1.26, `tmux`, the `multi` binary, a registered **target brain**\n(`multi brain list` shows it), and `claude` (Claude Code) logged in on a subscription.\n\n1. **Build \u0026 install both binaries** (ingester ships alongside multi):\n   ```bash\n   cd \u003cmultiverse-repo\u003e\n   just install            # → $GOBIN/multi and $GOBIN/ingester  (e.g. ~/go/bin)\n   ```\n2. **Choose the target brain.** The ingester writes to the brain named `deep-thought`\n   by default — see `const BrainName` in `internal/ingest/brain.go`. To target another,\n   change that constant and re-run `just install`. Confirm it resolves:\n   ```bash\n   multi brain list        # the target brain must be registered\n   ingester status         # prints the home dir, a (down) session, and 0 jobs\n   ```\n3. **Wire the Stop hook.** Add this object to the `Stop` array in\n   `~/.claude/settings.json` (keep any existing entries; use an absolute path):\n   ```json\n   { \"type\": \"command\", \"command\": \"/ABSOLUTE/PATH/TO/ingester hook\", \"timeout\": 10 }\n   ```\n4. **Recursion guard — already built in, nothing to do.** The steered session is\n   launched with `DEEPTHOUGHT_INGEST=1` and a hooks-disabled settings file, and\n   `ingester hook` no-ops whenever that variable is set, so ingestion can never trigger\n   itself.\n5. **Verify steering** without a real integration:\n   ```bash\n   ingester session ensure              # launches the tmux Claude session (subscription)\n   tmux attach -t deepthought-ingest     # watch it; Ctrl-b then d to detach\n   ingester session kill\n   ```\n6. **Full dry-run** on a throwaway transcript (a trivial one should report\n   \"nothing worth keeping\"):\n   ```bash\n   ingester run --session test --transcript \u003csome-session\u003e.jsonl\n   cat ~/.claude/ingester/reports/*_test.md     # ends with:  INGEST-STATUS: done\n   cat ~/.claude/ingester/state/test.json        # the ledger\n   ```\n\nData lives under `~/.claude/ingester/` (override via `INGESTER_HOME`): `state/` ledgers ·\n`queue/`(+`done`,`failed`) jobs · `reports/` sentinels · `prompts/` per-job instructions ·\n`dispatch.log`. Model: **Sonnet** (interactive = subscription quota). To disable, remove\nthe Stop-hook entry — any queued jobs are inert without it.\n\n## Layout\n\n```\ncmd/multi            multi entrypoint\ncmd/ingester         ingester entrypoint (session-end integration)\ninternal/brain       Brain, Note/front matter, index/search, graph, lint, git, scaffold\ninternal/cli         urfave/cli v3 command tree\ninternal/config      ~/.config/multi registry of brains\ninternal/ingest      ingester: ledger, transcript delta, tmux steering, dispatcher\ninternal/tui         Bubble Tea control panel\n```\n\n## Roadmap (deferred from v1)\n\n- Object-storage attachment path (`mv`-free large-file handling).\n- Embedding / semantic search + an MCP server surface for agents.\n- Background sync daemon (watch + debounced sync) so reads are always current.\n- Safe front-matter updates that preserve unknown keys.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmxcd%2Fmultiverse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmxcd%2Fmultiverse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmxcd%2Fmultiverse/lists"}