dotbrain 0.3.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. dotbrain/__init__.py +7 -0
  2. dotbrain/_cli_reference.py +115 -0
  3. dotbrain/adopter_repos.py +573 -0
  4. dotbrain/beads.py +511 -0
  5. dotbrain/bootstrap.py +199 -0
  6. dotbrain/brainspaces.py +238 -0
  7. dotbrain/cli.py +660 -0
  8. dotbrain/config.py +428 -0
  9. dotbrain/doctor.py +279 -0
  10. dotbrain/hooks.py +84 -0
  11. dotbrain/migrate.py +304 -0
  12. dotbrain/paths.py +139 -0
  13. dotbrain/resource_loader.py +47 -0
  14. dotbrain/resources/__init__.py +1 -0
  15. dotbrain/resources/agents/claude/implementer.md +47 -0
  16. dotbrain/resources/agents/claude/investigator.md +35 -0
  17. dotbrain/resources/agents/claude/reviewer.md +38 -0
  18. dotbrain/resources/agents/claude/verifier.md +35 -0
  19. dotbrain/resources/agents/codex/implementer.toml +26 -0
  20. dotbrain/resources/agents/codex/investigator.toml +21 -0
  21. dotbrain/resources/agents/codex/reviewer.toml +27 -0
  22. dotbrain/resources/agents/codex/verifier.toml +21 -0
  23. dotbrain/resources/config.yaml +20 -0
  24. dotbrain/resources/core.yaml +18 -0
  25. dotbrain/resources/templates/brain/AGENTS.md +9 -0
  26. dotbrain/resources/templates/brain/DOTBRAIN.md +105 -0
  27. dotbrain/resources/templates/brain/adr/README.md +8 -0
  28. dotbrain/resources/templates/brain/designs/README.md +28 -0
  29. dotbrain/resources/templates/brain/docs/README.md +9 -0
  30. dotbrain/resources/templates/brain/project.yaml +27 -0
  31. dotbrain/resources/templates/gitignore +17 -0
  32. dotbrain/skills.py +264 -0
  33. dotbrain/subagents.py +252 -0
  34. dotbrain/updater.py +105 -0
  35. dotbrain/workflows.py +529 -0
  36. dotbrain-0.3.4.dist-info/METADATA +21 -0
  37. dotbrain-0.3.4.dist-info/RECORD +40 -0
  38. dotbrain-0.3.4.dist-info/WHEEL +4 -0
  39. dotbrain-0.3.4.dist-info/entry_points.txt +2 -0
  40. dotbrain-0.3.4.dist-info/licenses/LICENSE +21 -0
dotbrain/paths.py ADDED
@@ -0,0 +1,139 @@
1
+ """Pure path and contract helpers for the dotbrain wiring convention.
2
+
3
+ These encode the compatibility contracts of the wiring convention as data
4
+ and side-effect-free functions. No filesystem mutation happens here; the wiring
5
+ mutators build on top of these.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import os
11
+ from pathlib import Path
12
+
13
+ # The Brainspace links an adopter repo symlinks into its root, in convention order.
14
+ BRAINSPACE_LINKS: tuple[str, ...] = (".brain", ".beads")
15
+
16
+ # Data-root directory holding the project Brainspaces, in preference order. ``brainspaces`` is
17
+ # the current name; ``projects`` is the legacy name still accepted for back-compat.
18
+ DATA_DIRS: tuple[str, ...] = ("brainspaces", "projects")
19
+
20
+ # Matching anchored entries written to an adopter repo's .git/info/exclude.
21
+ EXCLUDE_ENTRIES: tuple[str, ...] = ("/.brain", "/.beads")
22
+
23
+ # Breadcrumb appended to an adopter repo's real AGENTS.md / CLAUDE.md.
24
+ ADOPTER_POINTER: str = (
25
+ "@.brain/CLAUDE.md\n"
26
+ "Dotbrain: private project context lives at `.brain/AGENTS.md`; "
27
+ "read it before substantial agent work."
28
+ )
29
+
30
+ # Disabled for now: brain context (DOTBRAIN.md + .brain/AGENTS.md) is injected at
31
+ # session start via the SessionStart hook, so the adopter pointer is
32
+ # redundant. Flip to True to re-enable wire/doctor pointer management.
33
+ INJECT_ADOPTER_POINTER: bool = False
34
+
35
+ # Windows WinError raised when creating a directory symlink without Developer Mode or elevation.
36
+ _WIN_PRIVILEGE_NOT_HELD = 1314
37
+
38
+ DEVELOPER_MODE_MESSAGE: str = (
39
+ "creating a directory symlink requires Windows Developer Mode (or Administrator "
40
+ "privileges); enable Developer Mode in Settings > Privacy & security > For developers, "
41
+ "then retry"
42
+ )
43
+
44
+
45
+ def symlink_privilege_message(exc: OSError) -> str | None:
46
+ """Translate a Windows directory-symlink privilege ``OSError`` into a dotbrain message.
47
+
48
+ Returns ``None`` when ``exc`` isn't that specific failure, so callers re-raise everything
49
+ else unchanged.
50
+ """
51
+ if getattr(exc, "winerror", None) == _WIN_PRIVILEGE_NOT_HELD:
52
+ return DEVELOPER_MODE_MESSAGE
53
+ return None
54
+
55
+
56
+ # Windows extended-length path prefix. os.readlink() can surface it on a symlink's stored target
57
+ # even when the string originally passed to symlink_to() didn't have it, so exact-string comparisons
58
+ # against a freshly computed target must strip it on both sides first.
59
+ _WIN_EXTENDED_PREFIX = "\\\\?\\"
60
+
61
+
62
+ def _strip_extended_prefix(path_str: str) -> str:
63
+ if path_str.startswith(_WIN_EXTENDED_PREFIX):
64
+ return path_str[len(_WIN_EXTENDED_PREFIX):]
65
+ return path_str
66
+
67
+
68
+ def symlink_target_matches(existing: str, expected: str) -> bool:
69
+ """True when a symlink's ``os.readlink()`` target already matches the expected target string."""
70
+ return _strip_extended_prefix(existing) == _strip_extended_prefix(expected)
71
+
72
+
73
+ def resolve_dotbrain_home() -> Path:
74
+ """The dotbrain home: ``$DOTBRAIN_HOME`` if set, else inferred from this file.
75
+
76
+ ``$DOTBRAIN_HOME`` overrides the data home only; it does not point the installer at a tool
77
+ checkout (dev-install.sh derives that from its own location). Pure helpers still take an
78
+ explicit home so tests never depend on this.
79
+ """
80
+ env = os.environ.get("DOTBRAIN_HOME")
81
+ if env:
82
+ return Path(env)
83
+ inferred = Path(__file__).resolve().parents[2]
84
+ if (inferred / ".git").exists() and any((inferred / d).is_dir() for d in DATA_DIRS):
85
+ return inferred
86
+ return Path.home() / "dotbrain"
87
+
88
+
89
+ def data_dir(dotbrain_home: Path) -> Path:
90
+ """The data-root directory holding Brainspaces.
91
+
92
+ Prefers ``brainspaces/`` and falls back to a legacy ``projects/`` when only that exists; a
93
+ fresh root with neither defaults to ``brainspaces/``.
94
+ """
95
+ root = Path(dotbrain_home)
96
+ for name in DATA_DIRS:
97
+ if (root / name).is_dir():
98
+ return root / name
99
+ return root / DATA_DIRS[0]
100
+
101
+
102
+ def brainspace(dotbrain_home: Path, name: str) -> Path:
103
+ """Return the Brainspace path for a project: ``<dotbrain_home>/<data-dir>/<name>``."""
104
+ return data_dir(dotbrain_home) / name
105
+
106
+
107
+ def brainspaces(dotbrain_home: Path) -> list[Path]:
108
+ """Sorted project Brainspaces under the data-root directory.
109
+
110
+ Excludes ``.archive/`` and any other dot-prefixed directories.
111
+ """
112
+ base = data_dir(dotbrain_home)
113
+ if not base.is_dir():
114
+ return []
115
+ return sorted(p for p in base.iterdir() if p.is_dir() and not p.name.startswith("."))
116
+
117
+
118
+ def brainspace_link_targets(dotbrain_home: Path, name: str) -> dict[str, Path]:
119
+ """Map each Brainspace link name to its target inside the project's Brainspace."""
120
+ root = brainspace(dotbrain_home, name)
121
+ return {link: root / link for link in BRAINSPACE_LINKS}
122
+
123
+
124
+ def is_wired(repo: Path) -> bool:
125
+ """True when ``repo`` has all Brainspace links present as symlinks."""
126
+ repo = Path(repo)
127
+ return all((repo / link).is_symlink() for link in BRAINSPACE_LINKS)
128
+
129
+
130
+ def exclude_entries(repo: Path) -> set[str]:
131
+ """Return the exclude lines present in ``repo``'s .git/info/exclude (empty if absent)."""
132
+ exclude_file = Path(repo) / ".git" / "info" / "exclude"
133
+ if not exclude_file.is_file():
134
+ return set()
135
+ return {
136
+ line.strip()
137
+ for line in exclude_file.read_text(encoding="utf-8").splitlines()
138
+ if line.strip()
139
+ }
@@ -0,0 +1,47 @@
1
+ """Helpers for packaged dotbrain runtime resources."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from contextlib import contextmanager
6
+ from importlib.resources import as_file, files
7
+ from importlib.resources.abc import Traversable
8
+ from pathlib import Path
9
+ from typing import Iterator
10
+
11
+ RESOURCE_PACKAGE = "dotbrain.resources"
12
+
13
+
14
+ def resource(path: str) -> Traversable:
15
+ """Return a packaged resource path."""
16
+
17
+ current = files(RESOURCE_PACKAGE)
18
+ for part in path.split("/"):
19
+ if part:
20
+ current = current.joinpath(part)
21
+ return current
22
+
23
+
24
+ def iter_resource_files(path: str) -> Iterator[tuple[Path, Traversable]]:
25
+ """Yield ``(relative_path, file)`` entries below a packaged resource dir."""
26
+
27
+ root = resource(path)
28
+ if not root.is_dir():
29
+ raise FileNotFoundError(f"package resource {path} is missing")
30
+
31
+ def walk(node: Traversable, prefix: Path = Path()) -> Iterator[tuple[Path, Traversable]]:
32
+ for child in sorted(node.iterdir(), key=lambda item: item.name):
33
+ rel = prefix / child.name
34
+ if child.is_dir():
35
+ yield from walk(child, rel)
36
+ elif child.is_file():
37
+ yield rel, child
38
+
39
+ yield from walk(root)
40
+
41
+
42
+ @contextmanager
43
+ def resource_file(path: str) -> Iterator[Path]:
44
+ """Materialize a packaged resource as a real filesystem path if needed."""
45
+
46
+ with as_file(resource(path)) as resolved:
47
+ yield resolved
@@ -0,0 +1 @@
1
+ """Bundled dotbrain resource package."""
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: implementer
3
+ description: Carry out one small, already-scoped change end-to-end in the current checkout, then report back. The lightweight alternative to a worktree slice for low-risk work.
4
+ tools: Read, Grep, Glob, Edit, Write, Bash
5
+ model: sonnet
6
+ ---
7
+
8
+ You are a focused implementer. You take one small, already-specified change,
9
+ make it in the current checkout, verify it, and report back. You are the
10
+ in-session counterpart to a worktree worker: workers own epic slices on their
11
+ own branch; you own a single low-risk change here, with no branch and no
12
+ worktree.
13
+
14
+ Work from the specification you were given, whether that is a beads issue, a
15
+ diff to apply, or a described change. Read enough surrounding code to implement
16
+ it the way the codebase already does things; match the nearest local
17
+ conventions over any global habit.
18
+
19
+ Use project context when it is present. If the repo carries a Brain (`.brain/`
20
+ with decisions in `adr/`, requirements in `prd/`, vocabulary in `CONTEXT.md`)
21
+ or an issue tracker (`.beads/`), read the records relevant to this change so
22
+ your work matches what was asked and contradicts no recorded decision. If that
23
+ context is absent, implement against the code on its own and move on.
24
+
25
+ Stay inside the scope you were handed. Change only what the task needs and what
26
+ that change forces; do not refactor adjacent code, add features, or harden
27
+ beyond the request. If you discover the work is larger than a small change,
28
+ stop, leave the tree clean, and report that it should become a worktree slice
29
+ or its own beads issue instead of finishing it half-scoped.
30
+
31
+ Verify before reporting. Run the change's natural check and report the real
32
+ result. If tests fail, say so with the output; do not claim success you did not
33
+ observe.
34
+
35
+ Boundaries:
36
+
37
+ - Never commit or push. Commits and pushes are the user's action; leave the
38
+ change staged in the working tree for review.
39
+ - Never create branches or worktrees. If isolation is warranted, that is the
40
+ signal to escalate, not to do it yourself.
41
+ - Never leak private Brain context into anything that may become public. Do not
42
+ put Brain paths, ADR numbers, or decision-record ids in code, comments, or
43
+ commit-ready text; state the underlying reason in plain terms instead.
44
+
45
+ Report back with what you changed, the verification result, and anything that
46
+ warrants a new beads issue or an escalation to a slice. If the change was sound
47
+ and verified, say so plainly.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: investigator
3
+ description: Answer a question about the codebase read-only — how something works, where it lives, what a change would touch — reported as one fact per line with file:line references.
4
+ tools: Read, Grep, Glob, Bash
5
+ model: sonnet
6
+ ---
7
+
8
+ You are a focused investigator. Given a question or research target, search the
9
+ codebase, read the relevant files, and report findings. You never modify
10
+ anything; your product is facts.
11
+
12
+ Use project context when it is present. If the repo carries a Brain (`.brain/`
13
+ with decisions in `adr/` and vocabulary in `CONTEXT.md`) or an issue tracker
14
+ (`.beads/`), read the records relevant to the question so the answer matches
15
+ the project, not just the code.
16
+
17
+ Report rules:
18
+
19
+ - One fact per line, most important first.
20
+ - Ground every code fact in `file:line`.
21
+ - Do not hedge, and do not fabricate.
22
+ - If the question involves a decision or trade-off, give one line per option
23
+ and one line of recommendation.
24
+ - If the investigation surfaces a defect or risk, flag it with a severity word
25
+ (`critical`, `major`, `minor`) on its own line.
26
+
27
+ Boundaries:
28
+
29
+ - Do not modify any files.
30
+ - Do not run tests or builds. Running the gate is the verifier's job; Bash here
31
+ is for read-only exploration.
32
+ - Keep findings in plain terms. Do not cite Brain paths or decision-record
33
+ identifiers in anything that may become public.
34
+ - If the question cannot be answered from this codebase, say so plainly and
35
+ name what is missing.
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: reviewer
3
+ description: Review recent code changes for correctness, regressions, security issues, and missing tests.
4
+ tools: Read, Grep, Glob, Bash
5
+ ---
6
+
7
+ You are a focused code review agent. Review the current change like an owner who
8
+ has to maintain it. Report findings only; do not modify code.
9
+
10
+ Start from the diff (`git diff`, or the changes named in the request) and read
11
+ enough surrounding code to judge intent. Review only what changed and what it
12
+ touches, not the whole tree.
13
+
14
+ Use project context when it's there. If the repo carries a Brain (`.brain/` —
15
+ decisions in `adr/`, designs in `designs/`, vocabulary in `CONTEXT.md`) or an
16
+ issue tracker (`.beads/`), read the records relevant to this change and judge
17
+ intent: does it do what the issue asked, and does it contradict a recorded
18
+ decision? Flag such conflicts. If that context is absent, review the diff on its
19
+ own and move on.
20
+
21
+ Keep findings in plain terms. Do not cite Brain paths or decision-record
22
+ identifiers in anything that may become public (PR or commit text); give the
23
+ underlying reason instead.
24
+
25
+ Prioritize, in order:
26
+ 1. Correctness — logic errors, wrong edge cases, broken contracts, regressions.
27
+ 2. Security — unvalidated input, injection, unsafe deserialization, leaked
28
+ secrets, auth or permission gaps.
29
+ 3. Failure modes — unhandled errors, swallowed exceptions, races, resource leaks.
30
+ 4. Tests — missing coverage for new paths, weak assertions, tests that can't fail.
31
+ 5. Maintainability — only where it hides a real defect or will cause one.
32
+
33
+ For each finding give: severity (critical / major / minor), `file:line`, what is
34
+ wrong, and the concrete fix. Lead with the highest severity. Flag questions as
35
+ questions, not defects.
36
+
37
+ Skip pure style and formatting unless it masks a bug. If the change is sound, say
38
+ so plainly instead of inventing nits.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: verifier
3
+ description: Run the mechanical verification gate and report verification evidence — commands run, real outputs, pass/fail — plus an audience-safe evidence block for PR use. Never modifies code.
4
+ tools: Read, Grep, Glob, Bash
5
+ model: sonnet
6
+ ---
7
+
8
+ You are a verifier. You run the mechanical gate against the current state of
9
+ the work and report verification evidence. You have no write tools on purpose:
10
+ you cannot fix, adjust, or "help" the work pass. Your product is evidence, not
11
+ green checkmarks.
12
+
13
+ If the task gives you a concrete gate, run it. If it names criteria without
14
+ commands, use the smallest faithful command set that checks those criteria. If
15
+ you cannot identify a real gate, report that as a verification gap instead of
16
+ improvising one.
17
+
18
+ Report verification evidence in two renderings:
19
+
20
+ 1. **Full record** — for the caller: each command as run, the meaningful output
21
+ it produced, and a pass/fail per criterion.
22
+ 2. **PR-ready block** — a short `Verification` section suitable for a public
23
+ PR body: what was verified and how, in plain public terms. Never include
24
+ Brain references in this block.
25
+
26
+ Boundaries:
27
+
28
+ - Never edit files, never commit, never push, never retry with modifications.
29
+ - If the gate fails, the report is the failure, verbatim.
30
+ - Report only what you observed. A check you did not run is `not run`, not
31
+ `assumed passing`.
32
+ - Do not soften failures. Exit codes, failing test names, and error output go
33
+ in the report as they occurred.
34
+ - If the gate itself looks broken, say so. A rotten gate is a finding, not a
35
+ pass.
@@ -0,0 +1,26 @@
1
+ name = "implementer"
2
+ description = "Carry out one small, already-scoped change end-to-end in the current checkout, then report back."
3
+ developer_instructions = """
4
+ Take one small, already-specified change, implement it in the current checkout,
5
+ verify it, and report back.
6
+
7
+ Work from the task as given. Read enough surrounding code to match the local
8
+ patterns instead of imposing a new style.
9
+
10
+ Use project context when present. If the repo carries a Brain (.brain/ with
11
+ adr/, prd/, CONTEXT.md) or an issue tracker (.beads/), read the relevant
12
+ records so the change matches what was asked and does not contradict a recorded
13
+ decision. If that context is absent, implement against the code on its own.
14
+
15
+ Stay inside scope. Change only what the task needs and what that change forces.
16
+ Do not refactor adjacent code, add features, or harden beyond the request. If
17
+ the work turns out to be larger than a small change, stop and report that it
18
+ should become a larger slice instead of finishing it half-scoped.
19
+
20
+ Verify before reporting. Run the natural check for the change and report the
21
+ real result. If verification fails, say so plainly with the observed failure.
22
+
23
+ Never commit, push, or create branches or worktrees. Do not leak private Brain
24
+ references into code, comments, or commit-ready text; state the underlying
25
+ reason in plain terms instead.
26
+ """
@@ -0,0 +1,21 @@
1
+ name = "investigator"
2
+ description = "Answer a question about the codebase read-only with grounded findings and file references."
3
+ sandbox_mode = "read-only"
4
+ developer_instructions = """
5
+ Investigate the requested question or code area and report findings only.
6
+
7
+ Use project context when present. If the repo carries a Brain (.brain/ with
8
+ adr/ and CONTEXT.md) or an issue tracker (.beads/), read the relevant records
9
+ so the answer matches the project rather than just the code.
10
+
11
+ Report one fact per line, most important first. Ground every code fact in
12
+ file:line. Do not hedge and do not fabricate.
13
+
14
+ If the question involves options or tradeoffs, give one line per option and one
15
+ line of recommendation. If you discover a defect or risk, flag it with a
16
+ severity word (critical / major / minor).
17
+
18
+ Do not modify files. Do not run tests or builds. Bash is for read-only
19
+ exploration only. Do not cite Brain paths or decision-record identifiers in
20
+ anything that may become public.
21
+ """
@@ -0,0 +1,27 @@
1
+ name = "reviewer"
2
+ description = "Review recent code changes for correctness, regressions, security issues, and missing tests."
3
+ sandbox_mode = "read-only"
4
+ developer_instructions = """
5
+ Review the current change like an owner who has to maintain it. Report findings
6
+ only; do not modify code.
7
+
8
+ Start from the diff (git diff, or the changes named in the request) and read
9
+ enough surrounding code to judge intent. Review only what changed and what it touches.
10
+
11
+ Use project context when present. If the repo carries a Brain (.brain/ with adr/,
12
+ designs/, CONTEXT.md) or an issue tracker (.beads/), read the records relevant to this
13
+ change and judge intent: does it do what the issue asked, and does it contradict a
14
+ recorded decision? Flag such conflicts; if that context is absent, review the diff
15
+ on its own. Keep findings in plain terms: do not cite Brain paths or decision-record
16
+ identifiers in anything that may become public (PR or commit text); give the
17
+ underlying reason instead.
18
+
19
+ Prioritize in order: correctness (logic, edge cases, broken contracts, regressions);
20
+ security (unvalidated input, injection, unsafe deserialization, leaked secrets,
21
+ auth gaps); failure modes (unhandled errors, races, resource leaks); tests (missing
22
+ coverage for new paths, weak assertions); maintainability only where it hides a real defect.
23
+
24
+ For each finding give severity (critical / major / minor), file:line, what is wrong,
25
+ and the concrete fix. Lead with the highest severity. Skip pure style unless it masks
26
+ a bug. If the change is sound, say so plainly.
27
+ """
@@ -0,0 +1,21 @@
1
+ name = "verifier"
2
+ description = "Run the mechanical verification gate and report the real evidence, including a short PR-safe verification block."
3
+ sandbox_mode = "read-only"
4
+ developer_instructions = """
5
+ Run the mechanical verification gate against the current state of the work and
6
+ report evidence. Your product is evidence, not a pass opinion.
7
+
8
+ If the task gives a concrete gate, run it. If it names criteria without exact
9
+ commands, use the smallest faithful command set that actually checks those
10
+ criteria. If you cannot identify a real gate, report that as a verification gap
11
+ instead of improvising one.
12
+
13
+ Report in two forms:
14
+ 1. A full record with each command as run, the meaningful output, and a
15
+ pass/fail per criterion.
16
+ 2. A short public-safe Verification block suitable for a PR body.
17
+
18
+ Never edit files, never commit, never push, and never retry with code changes.
19
+ If the gate fails, report the failure as observed. A check you did not run is
20
+ not run, not assumed passing. If the gate itself looks broken, say so.
21
+ """
@@ -0,0 +1,20 @@
1
+ # dotbrain global settings
2
+ # Seeded into ~/dotbrain/config.yaml by ``dotbrain bootstrap``.
3
+ # Per-project identity (including beads mode) lives in brainspaces/<name>/.brain/project.yaml.
4
+ # Never put credentials (passwords, tokens) here — those belong in your secrets store.
5
+
6
+ # Beads execution store. Each project picks a mode in its .brain/project.yaml:
7
+ # embedded — local Dolt store in the Brainspace, optionally synced to a remote (the default)
8
+ # server — shared Dolt sql-server, configured by the block below (cross-machine, multi-project)
9
+ # none — no execution store (e.g. a project that tracks work via tracker: gh)
10
+ #
11
+ # The block below is only needed for server-mode projects. Uncomment and point it
12
+ # at your shared Dolt sql-server; leave it out entirely for the embedded default.
13
+ #
14
+ # beads:
15
+ # server:
16
+ # host: db.example.internal
17
+ # port: 3307
18
+ # user: beads
19
+ # # Optional SSH hop that can reach the sql-server (used by beads drop-db).
20
+ # ssh_host: ""
@@ -0,0 +1,18 @@
1
+ version: 1
2
+
3
+ # dotbrain's packaged subagent core (read-only product data).
4
+ # Subagents declared here are force-wired by the tool and cannot be removed by
5
+ # operators.
6
+ #
7
+ # Operators configure skills and subagents at separate scopes:
8
+ # - skills/global: ~/dotbrain/skills/skills.yaml (global_extra)
9
+ # - skills/per-project: brainspaces/<name>/.brain/project.yaml (skills:)
10
+ # - subagents/global: ~/dotbrain/agents/agents.yaml (global:)
11
+ # - subagents/project: brainspaces/<name>/.brain/project.yaml (subagents:)
12
+
13
+ subagents:
14
+ project_required:
15
+ - implementer
16
+ - investigator
17
+ - reviewer
18
+ - verifier
@@ -0,0 +1,9 @@
1
+ # AGENTS.md
2
+
3
+ Private agent context for this project. The repo-root `AGENTS.md` points here because this Brain holds the project's source of truth — vocabulary, decisions, operating rules, and skill config — that stays private while the code repo may be public. Execution lives in beads (`bd`), not in here.
4
+
5
+ `DOTBRAIN.md` carries the shared operating rules (wiring, conventions, public/private boundary) and is rehydrated by `dotbrain refresh`.
6
+
7
+ ## Project
8
+
9
+ Cross-cutting rules with no structured home: build and test commands, project-wide constraints, gotchas, and project tracker conventions (linking rules, ADR-pairing policy, priority deviations) read by `operate-execution` and `triage-public` — absent or empty means pure defaults. Vocabulary goes in CONTEXT.md, decisions in adr/, skill selection in project.yaml.
@@ -0,0 +1,105 @@
1
+ # DOTBRAIN.md
2
+
3
+ Shared operating rules for all dotbrain brains. Owned by dotbrain; rehydrated by
4
+ `dotbrain refresh`. Do not edit per project — changes to the packaged dotbrain
5
+ Brain template propagate to every brain.
6
+
7
+ ## Wiring
8
+
9
+ - This Brain lives in the private dotbrain home at
10
+ `~/dotbrain/brainspaces/<name>/.brain`, not in the code repo.
11
+ - Repo-root `.brain` and `.beads` are gitignored symlinks into that Brainspace. `.claude` and
12
+ `.codex` are real project directories containing gitignored links to selected agent resources.
13
+ Those links are local machine wiring: never commit them to the code repo.
14
+ - Brain changes are committed in `~/dotbrain`. The code repo's `git status` never shows them.
15
+ - Worktrees reach this same Brain through their own `.brain` and `.beads` symlinks; never copy it
16
+ per worktree.
17
+ - In the main checkout, repair missing or dangling links with `dotbrain wire` from the repo root.
18
+ - In a git worktree with no `.brain`, use `wire-brain`'s worktree repair branch. It derives the main
19
+ checkout from Git and creates real `.brain` and `.beads` symlinks without the CLI.
20
+
21
+ ## Rules
22
+
23
+ - Read `.brain/AGENTS.md` before substantial work. It holds this project's own rules and is
24
+ not injected at session start. If it is missing, note the gap and continue.
25
+ - Brain writes are agent-managed (git-tracked in dotbrain, so changes are revertable).
26
+ - Execution lives in beads. Work from `bd ready`; record multi-step plans as epics with
27
+ `blocks` dependencies, not as markdown checklists.
28
+ - Use `CONTEXT.md` vocabulary when naming concepts in issues, plans, tests, and proposals.
29
+ Do not drift to synonyms.
30
+ - If a proposed change conflicts with an ADR, call it out before proceeding.
31
+ - If `CONTEXT.md` or `adr/` are missing or empty, proceed silently — note the gap, don't
32
+ scaffold them unasked.
33
+ - `.brain/docs/` holds project-scoped knowledge (runbooks, references, derived notes) that
34
+ is not auto-injected into context. Before answering how this project builds, runs, deploys,
35
+ integrates, or otherwise works, check and search `.brain/docs/` first — do not infer from
36
+ the public repo or generic conventions when the Brain has a documented answer.
37
+ - The code repo may be public; the Brain never is. Never mirror Brain content into the code
38
+ repo — for a public need, derive a fresh audience-specific doc instead.
39
+ - Public-facing repo docs (README.md, repo-root AGENTS.md) must not expose private Brain
40
+ paths or content. The only `.brain` reference allowed in the repo root is the one-line
41
+ agent pointer to `.brain/AGENTS.md`.
42
+ - Never reference private Brain context from code, tests, comments, commit messages, or
43
+ PR text: no ADR numbers, Brain paths, or decision-record identifiers in anything the
44
+ public repo carries. State the rationale in plain terms instead; the ADR linkage stays
45
+ in the Brain.
46
+
47
+ ## Working in loops
48
+
49
+ These invariants bind any iterative or autonomous execution, whatever skill or loop primitive
50
+ drives it:
51
+
52
+ - Verification, success, and acceptance criteria are human-owned. They can change, but only through
53
+ the human: surface the proposed wording and the reason, get approval, then record what changed.
54
+ Where no human is present to approve — an autonomous loop — that is a stop condition, not a
55
+ licence to decide. What is ruled out in every workflow is an agent weakening or rewriting them on
56
+ its own to match what the build does.
57
+ - Autonomous iteration always has a hard stop — a retry cap, budget, or turn limit. When the stop
58
+ is hit, report blocked with the attempt trail; do not keep iterating.
59
+ - An explicit automation-handoff contract — scope, branch/base, verification plan, review mode,
60
+ available provider/auth, draft-PR authorization, and an explicit `GO` — authorizes only the
61
+ agreed push of its dedicated branch and creation of a draft PR. Merge, deploy, publish,
62
+ dependency changes, and every other outward action end the loop and go to the human.
63
+ - Automation-handoff / agent-driven loop work runs on a dedicated branch, never directly on
64
+ `main`; manual turn-by-turn work needs no branch — it is reviewed as it happens.
65
+ - Beads are the state; the active design doc is the spec. State says where you are, the spec says
66
+ where to go. Reread the spec every iteration, not just at loop start.
67
+
68
+ ## Unknowns
69
+
70
+ The Brain exists to shrink the gap between the map (what the agent has been told — vocabulary,
71
+ decisions, rules) and the territory (the codebase and its real constraints). That gap is the
72
+ project's unknowns. Name them in four quadrants and use the terms exactly, so skills, issues, and
73
+ design docs speak one language:
74
+
75
+ - **Known knowns** — stated and settled. Live in `CONTEXT.md`, `adr/`, and `AGENTS.md`.
76
+ - **Known unknowns** — open questions you can name. Live in a design doc's `Known Unknowns` and in beads.
77
+ - **Unknown knowns** — tacit preferences and domain expectations, recognized only when shown.
78
+ Surfaced by grilling and prototypes, then written into canon.
79
+ - **Unknown unknowns** — constraints, edge cases, and existing behavior you have not thought to
80
+ consider. Surfaced by a blind-spot pass before implementation; caught mid-build as discoveries.
81
+
82
+ Cheap moves early — orient, grill, prototype — turn expensive late unknowns into known knowns.
83
+
84
+ ## Brain structure
85
+
86
+ - `CONTEXT.md` — domain vocabulary for this project
87
+ - `project.yaml` — per-project skill selection and engine/tracker config
88
+ - `adr/` — Architecture Decision Records, one file per decision
89
+ - `designs/` — design docs, one initiative per file. Each design doc carries a `lifecycle:` field:
90
+ `draft`, `active`, `shipped`, `abandoned`, or `superseded`. Agents must update lifecycle when the
91
+ document's mutability changes. While a design is `active`, it is the living design authority for
92
+ the initiative: current design, verification / success criteria, known unknowns, deviations, and
93
+ design-relevant implementation discoveries live here. Authored by `to-design`, decomposed into
94
+ bead epics by `to-issues`.
95
+ Beads still own execution state. Once a design is `shipped`, `abandoned`, or `superseded`, it
96
+ freezes as a point-in-time record; durable residue lands in `adr/` (decisions) and `CONTEXT.md`
97
+ (vocabulary). Driving a design to a terminal state is `close-design`'s job.
98
+ Design frontmatter is one field set across every Brain: `lifecycle:` (required), `started:` and
99
+ `ended:` (dates), `extends:` (a design this one builds on), `residue:` (ADR ids produced). Per-doc
100
+ invented fields drift the vocabulary apart; say anything else in prose
101
+ - `docs/` — derived docs, runbooks, reference material. Optional, never authoritative —
102
+ canon wins
103
+
104
+ Skills are cross-project; the Brain only configures them. Skill *selection* lives in
105
+ `project.yaml` (`skills:`); project tracker conventions live in `AGENTS.md` under Project.
@@ -0,0 +1,8 @@
1
+ # adr/
2
+
3
+ Architecture Decision Records — one decision per file.
4
+
5
+ Each ADR captures the context, decision, consequences, and alternatives considered
6
+ for a design choice that affects this project's architecture or conventions.
7
+
8
+ See `DOTBRAIN.md` for the read order and operating rules.
@@ -0,0 +1,28 @@
1
+ # designs/
2
+
3
+ Design docs - one initiative per file.
4
+
5
+ An `active` design doc is a living unknowns ledger for the initiative. It should capture the
6
+ current design, verification / success criteria, known unknowns, design-relevant implementation
7
+ discoveries, deviations, and any
8
+ human design calls still needed. Author only the sections the initiative needs.
9
+
10
+ Use `lifecycle:` frontmatter to mark document mutability: `draft`, `active`, `shipped`,
11
+ `abandoned`, or `superseded`. This is not execution status; beads own execution state.
12
+
13
+ Once a design is `active`, criteria changes are human decisions: record them in the doc
14
+ (`Deviations` or `Human Decisions Needed`), not silently edited in place. When a design ships,
15
+ record the verification evidence achieved, so a later reader can check the gate still catches the
16
+ failure it was written for (gates rot).
17
+
18
+ Typical sections include motivation, goals, non-goals, current design, verification / success
19
+ criteria, known unknowns, implementation notes, deviations, human decisions needed, alternatives
20
+ considered, and rollout.
21
+
22
+ Authored by the `to-design` skill, then decomposed into a bead epic by `to-issues`. Beads own
23
+ execution state, dependencies, claim status, and acceptance criteria. When a design reaches
24
+ `shipped`, `abandoned`, or `superseded`, it freezes as a point-in-time record. Durable residue
25
+ lands in `adr/` (decisions) and `CONTEXT.md` (vocabulary); a maintained "how it works now"
26
+ description is a `docs/` runbook. On conflict with canon, canon wins.
27
+
28
+ See `DOTBRAIN.md` for the read order and operating rules.
@@ -0,0 +1,9 @@
1
+ # docs/
2
+
3
+ Derived documents, runbooks, and reference material.
4
+
5
+ This directory is optional — create it when the first doc exists. Content here is useful
6
+ but never the authority. On conflict with the canon (`AGENTS.md`, `DOTBRAIN.md`,
7
+ `CONTEXT.md`, `adr/`, `agents/`), the canon wins.
8
+
9
+ Examples: runbooks, adopter guides, design reviews, procedural references.