AGENTS.md · git:20261001.0e1598e · 2026-10-01 · sha256 d7091b8d0c9e555b
AGENTS.md git:20261001.0e1598eA
Immutable. This exact content never changes and is served at /api/v1/blob/d7091b8d0c9e555b.
# AGENTS.md `dotbrain` — one tool that wires **project Brainspaces** and **skills** into whatever coding agent you use (Claude Code, Codex). Engineering-centered. ## What this is dotbrain separates the durable context an agent needs from the code it works on. For each project you keep a **Brainspace** that holds the project's **Brain** (`.brain/` — domain vocabulary, decisions, operating rules), an **execution store** (`.beads/`), and **agent workspaces** (`.claude/`, `.codex/`). Your code repo gets gitignored symlinks into that Brainspace, so agents pick up project memory and a live issue tracker without that material living in the code repo. Skills are agent-owned, not project-owned: a Brain only *configures* the skills it uses. The bundled `src/dotbrain/resources/skills/brain/` set is dotbrain's own operating manual (wiring, brain authoring, execution). ## Public / private boundary This repository is the **tool**, and it is public. A user's **Brainspaces and Brains are private** and live in a separate data root (by convention `~/dotbrain`) that this tool operates on. The tool never contains anyone's project data. dotbrain's own design record (ADRs) lives in its private Brain; this repo ships only the *derived* [docs/architecture.md](docs/architecture.md). If you are an agent working in this repo, treat it as a normal public codebase: do not assume a `.brain/` is present (it is local, gitignored wiring on the maintainer's machine only). ## Layout - `src/dotbrain/` — the Python CLI (`wire`, `unwire`, `bootstrap`, `refresh`, `skills link`, …). - `src/dotbrain/resources/` — packaged runtime assets: - `skills/brain/` — bundled product skills (the system's own operating manual). - `templates/brain/` — Brain scaffold seeded into a new Brainspace. - `scripts/` — hook implementations invoked through `dotbrain hook ...`. - `config.yaml` — shipped example config; seeded into data root by bootstrap. - `tests/` — the CLI test suite (`uv run pytest`). - `docs/architecture.md` — the design narrative. ## Quickstart ```bash ./scripts/dev-install.sh # installs uv, Beads (bd), and an editable dotbrain CLI dotbrain bootstrap # install agent hooks and link global skills dotbrain wire --repo <repo> # connect a code repo to a Brainspace under your data root ``` See [README.md](README.md) for more, and [docs/architecture.md](docs/architecture.md) for the model. ## Development ```bash uv sync # create the venv and install deps uv run pytest # run the full suite uv run pytest tests/test_wiring.py # one file uv run pytest -k worktree # match by name uv run pytest tests/test_workflows.py::test_unwire_all_disconnects_every_repo # one test uv tool install --editable --force . # install the `dotbrain` CLI from this checkout ``` The package entrypoint is `dotbrain.cli:app` (Typer); `python -m dotbrain` is not wired. Tests are `tmp_path`-based — they never touch a real `$HOME` or the live data root. There is no configured linter; the stray `# noqa: A002` markers are advisory only. ## Codebase architecture For the product model (Brainspaces, the Brain/execution split, the public/private boundary) read [docs/architecture.md](docs/architecture.md). For the *code*, the shape is a strict dependency layering under `src/dotbrain/`: - **`paths.py`** — the pure foundation. Encodes the wiring contracts (the four `BRAINSPACE_LINKS`, exclude entries, the adopter pointer, data-root resolution) as side-effect-free functions. No filesystem mutation here; everything else builds on it and depends *into* it, never the reverse. - **Concept modules**, each owning one concept and depending only on `paths` (and sometimes `config`): `adopter_repos` (repo-facing symlinks, `.git/info/exclude`, AGENTS.md pointer), `brainspaces` (Brain + agent-workspace seeding, offboarding), `beads` (the `bd` tracker), `skills` and `subagents` (curated symlink linking), `bootstrap` (machine-global setup), `migrate` (embedded→server beads, composing `beads` helpers), `doctor` (read-only health). - **`workflows.py`** — cross-concept orchestration; the bodies behind `wire`, `wire --all`, `unwire`, `refresh`. It stitches the concept modules together. - **`cli.py`** — a thin Typer parsing/rendering layer over `workflows` and the modules. Keep logic out of here. - **`resource_loader.py`** — the only accessor for packaged `dotbrain.resources` (skills, templates, scripts) via `importlib.resources`. Two patterns to know before changing anything: - **Subprocess seam.** Modules that shell out to `bd`/`git` take an injected `run` callable (`Runner`, same shape as `subprocess.run`). Tests pass a fake that records argv instead of executing. Preserve this seam — assertions are on the recorded commands. - **Checkout vs. data root.** The *checkout* (this repo) is the tool source. The *data root* (`$DOTBRAIN_HOME`, by convention `~/dotbrain`) holds `brainspaces/`, `skills/`, and the seeded `config.yaml`; it is resolved by `paths.resolve_dotbrain_home()`. Config splits into a global `config.yaml` (infra defaults like `beads.server`) and a per-project `brainspaces/<name>/.brain/project.yaml` (beads mode, skill and subagent selection). Don't conflate the two roots. ## Conventions - `AGENTS.md` is canonical; `CLAUDE.md` is a symlink to it. - Prefer the nearest local context file in any directory tree. - Symlinks whose targets are outside the containing git repo are local wiring: gitignore them, never track them.