Obsidian Vault

The Obsidian vault is the company's human-readable memory palace: a rebuildable projection of tasks, journals, and agent-to-agent conversations into a folder of wikilinked markdown notes you browse in Obsidian. It's a read surface on top of the database, not a second source of truth — the vault can be deleted and rebuilt from Postgres at any time.

It's off by default and isn't on the panel's Feature Flags card — like DB network isolation and Cloud auth, it's an environment/compose setting, not a runtime toggle.

Not a panel toggle

Arming the vault means setting environment variables and restarting the backend. There's nothing to flip in Settings → Feature Flags for it.

What it does

Every journal entry, every A2A message, and every task status change materializes as a markdown note with YAML frontmatter, written best-effort — a vault write failure never blocks the verb that triggered it. Private journal entries (is_private) are excluded from the projection.

A task's note isn't a projection you wait for: TaskService.create materializes it the moment the task is created, so a board or Kanban view built on the vault shows live work from creation, not just once it's curated or the vault is rebuilt.

Vault layout

Notes land under a fixed RoboCo/ tree:

text
1RoboCo/2  Tasks/<project-slug>/<title> (<id8>).md3  Journals/<agent-slug>/<date> <title> (<id8>).md4  A2A/<date> <agents> (<thread-id8>).md5  Agents/<slug>.md6  Archive/<year>/Tasks/<project-slug>/<title> (<id8>).md7  Reports/<ISO-week>.md8  Notes/9  _meta/

Every note carries a stable aliases: [<id8>] in its frontmatter, and cross-links are written as [[<id8>|<title>]] rather than by filename. That means renaming a task's title updates the note's own title line without breaking a single link that points at it elsewhere in the vault — archival and reorganization are free.

The vault ships a pre-configured .obsidian/ folder (Dataview queries, Kanban board views, graph color groups by team/status, and a couple of native Bases views — a Task Board and a Reports index) and a RoboCo/_meta/ folder with starter dashboards, materialized the first time the vault is enabled and never overwritten if you've already customized them.

The Auditor's narrative

Deterministic sections (status, links, metadata) always exist on a task note. A free-text ## Narrative section — what happened, the decisions made, the rework story — is written by the Auditor, who gets a dedicated curate_vault verb and is spawned once a root task completes specifically to fill it in. That narrative is preserved across a full rebuild (below); nothing else about the Auditor's role changes.

The drift janitor: repair, archival, and a weekly report

A projection built from best-effort event seams can miss a write — a container restart mid-verb, a rare exception swallowed at the write site. Once the vault's been on for a while, an hourly-ticked janitor closes that gap in one sweep, gated on the master flag alone (the sweep and the archival pass), plus a second flag for the report:

  • Re-projection is capped, not unbounded. Each sweep re-projects up to 200 changed tasks and drift-checks a random sample of 20 more, so a long-downtime backlog drains across several hourly ticks instead of one large burst; a state file (RoboCo/_meta/.janitor_state.json) tracks how far the sweep got, so a restart resumes rather than restarts the count.
  • One bad row never wedges the sweep. Each task is re-projected in isolation — a failure is logged and skipped, and the task re-qualifies next time it changes (or via the sample check).
  • Archival moves a completed or cancelled task's note into RoboCo/Archive/<year>/Tasks/<project-slug>/ once it's been terminal for ROBOCO_VAULT_ARCHIVE_DAYS (default 30; 0 disables archival). Because links are alias-based, an archived task's note keeps every wikilink pointing at it working — nothing to fix up. The shipped Dataview queries and graph groups already account for the Archive/ tree.
  • The weekly report lands in RoboCo/Reports/<ISO-week>.md once per elapsed ISO week — a deterministic summary (tasks completed/created, completion rate, average cycle time, rework rate and cost, token/dollar spend, plus the per-stage and bottleneck breakdown) assembled from MetricsService/UsageService, no LLM involved — and notifies you. It's on by default (ROBOCO_VAULT_REPORT_ENABLED) whenever the vault itself is.

Making your own notes fleet-searchable (KB ingest)

Tasks, journals, and A2A threads are already retrievable by the fleet straight from Postgres — the vault projection is a read surface on data the RAG layer already indexes. Your own writing isn't: notes you drop into RoboCo/Notes/ (or whatever folders ROBOCO_VAULT_KB_DIRS names) are pure filesystem content the database has never seen. KB ingest closes that gap, embedding them into a dedicated vault_notes RAG index so roboco_kb_search, the mentor's default search domain, and claim-time briefings can all surface something you personally wrote.

It's off by default (ROBOCO_VAULT_KB_ENABLED, needs the master vault flag too) and scoped tightly:

  • Human folders only, never the projection dirs. ROBOCO_VAULT_KB_DIRS (default RoboCo/Notes) is validated at startup against every reserved projection folder (Tasks/, Journals/, A2A/, Agents/, Archive/, Reports/, _meta/, .obsidian/, and the intake inbox) plus path-traversal — it can never be pointed at data that's already a first-class DB-backed index, or escape the vault outright.
  • Injection-screened as a hard gate, not a soft flag. Every note's body runs through the same untrusted-content screen the #roboco intake loop and the X-mentions engine use, but here a flagged note is quarantined outright — skipped, logged, and marked with a callout explaining why — rather than passed through neutralized. An indexed chunk that later gets retrieved into an agent's context is a stricter bar than a note that just becomes a task draft.
  • Bounded and incremental. A scan cycle (ROBOCO_VAULT_KB_INTERVAL_SECONDS, default 900s) re-embeds only changed notes (content-hash deduped) and ingests at most 50 per cycle; a deleted note is de-indexed on the next scan.

To actually write into RoboCo/Notes/ from your Mac, you need the vault synced locally first — see Syncing the Vault to Your Mac.

The rebuild / relocate CLI

bash
1python -m roboco.vault rebuild2python -m roboco.vault relocate /new/path

Both subcommands refuse to run unless ROBOCO_OBSIDIAN_VAULT_ENABLED is on.

  • rebuild re-projects every live agent, task, journal entry, and A2A thread from the database into the vault from scratch, and (re-)materializes the shipped .obsidian/ config and _meta/ dashboards for anything not already present. A task's Auditor-authored ## Narrative is read back from the existing note first, so a rebuild never erases it.
  • relocate <new-path> moves the vault tree. If new-path doesn't exist yet, the whole tree moves there. If it does exist — your own personal vault, say — only the RoboCo/ subtree is grafted into it, plus whatever shipped assets are missing; your personal vault's own .obsidian/ config is never touched. Because links are alias-based, nothing inside the moved notes needs rewriting.

The #roboco inbox → board-review loop

A second, independently-gated capability turns vault notes into task drafts. Write a note anywhere in the watched inbox folder, tag it #roboco (in frontmatter or inline in the body), and it becomes one held task the Product Owner and Head of Marketing review — exactly the same board-review path a chat-confirmed "Board review & Start" draft takes.

  • Never starts work on its own. The draft is PENDING, Product-Owner-assigned, team=board — routed to the same two-reviewer board review as any other board-originated task, ending in a notification to you. Nothing enters delivery until your explicit Approve & Start.
  • Local model only. Extraction (title, description, acceptance-criterion candidates) runs on the local LLM, with a deterministic fallback (first heading, raw body, or checkbox lines) if that fails — never a cloud LLM in the hot path.
  • Screened before it reaches a prompt. The note body passes through the same untrusted-content screen the X engine applies to tweet text before it's used for extraction or shown to the board/CEO.
  • Deduplicated, not reprocessed. A (path, content hash) ledger means an unchanged note is scanned once; editing it afterward makes it eligible again.
  • Bounded. ROBOCO_VAULT_INTAKE_MAX_PER_CYCLE caps how many drafts one scan can originate; ROBOCO_VAULT_INTAKE_MAX_OPEN_DRAFTS caps how many can sit open at once.

Flags

VariableDefaultPurpose
ROBOCO_OBSIDIAN_VAULT_ENABLEDfalseMaster switch. Off: no note is ever written, rebuild/relocate refuse to run, and every event seam is a no-op.
ROBOCO_VAULT_PATH/data/vaultRoot directory the vault materializes into (bind-mounted from ${ROBOCO_DATA_DIR}/vault on the host in both tracked compose files). Only consulted when the master flag is on.
ROBOCO_VAULT_INTAKE_ENABLEDfalseSecond switch for the #roboco inbox watcher. Both this and the master flag must be on — either off leaves the watcher inert.
ROBOCO_VAULT_INTAKE_INTERVAL_SECONDS300Seconds between inbox scan cycles.
ROBOCO_VAULT_INTAKE_DIRRoboCo/InboxVault-relative folder scanned for #roboco-tagged notes (non-recursive).
ROBOCO_VAULT_INTAKE_MAX_PER_CYCLE3Max held drafts one scan cycle may originate.
ROBOCO_VAULT_INTAKE_MAX_OPEN_DRAFTS10Rolling cap on concurrently-open held vault-note drafts.
ROBOCO_VAULT_ARCHIVE_DAYS30Age (since going terminal) past which a completed/cancelled task's note moves to Archive/<year>/. 0 disables archival.
ROBOCO_VAULT_REPORT_ENABLEDtrueWeekly Reports/<ISO-week>.md org-report note + CEO notification. Needs the master flag too.
ROBOCO_VAULT_KB_ENABLEDfalseMaster switch for KB ingest. Off: nothing is ever embedded and the vault_notes index stays empty.
ROBOCO_VAULT_KB_DIRSRoboCo/NotesCSV of vault-relative folders scanned for KB ingest. Validated at startup against the reserved projection dirs and path traversal.
ROBOCO_VAULT_KB_INTERVAL_SECONDS900Seconds between KB-ingest scan cycles.

Getting the vault onto your own machine

The vault materializes on the server (the NAS, in a production deploy) under ${ROBOCO_DATA_DIR}/vault — not on your laptop. To actually browse it in the Obsidian app on your Mac, sync that folder down. See Syncing the Vault to Your Mac for the full step-by-step (Syncthing, SMB, or Obsidian Sync).

This is read access, not two-way editing

The projection is one-directional (database → vault) except for the #roboco inbox loop above. Editing a Tasks/, Journals/, or A2A/ note directly in Obsidian doesn't write back to RoboCo — the next event or rebuild overwrites it. Only notes in the intake folder are read back in.

Next

Syncing the Vault to Your Mac — the full runbook for reading it locally. → MegaTask and Org & roles — the Auditor's other duties. → back to Optional subsystems.

llms.txt