ADR-0012: Ticket-driven agent commands, GitHub Projects, and Obsidian sync
Status: Accepted — agent-roster and command-set parts superseded by ADR-0022
Date: 2026-07-20
Supersedes: ADR-0008 (the command-set portion only — the layer
structure it defined, AGENTS.md/.agents//.claude/ ownership, stayed in force until
ADR-0018 later folded it entirely into
.claude/).
Partially superseded by ADR-0016: /br-sync-ticket
and /br-sync-board, described below as mirroring GitHub state into obsidian/Tickets/
and obsidian/Board/board.md, were deleted — ticket/board state is now queried live. The
five-command framing and the sync-command sections below describe the design as decided at
the time; the current command set is three (/br-take-ticket, /br-implement,
/br-sync-docs). Everything else in this ADR (the specialist-agent split, model
assignments, /br-implement routing, self-contained-command pattern, confirm-before-mutate
rule) is unaffected and still in force. ADR-0017 later
removed the obsidian/ vault entirely — every mention of it below (as a sync target or as
"source of truth for ticket state") is historical only.
Also partially superseded by ADR-0021: the
"self-contained, no agent file" decision for /br-take-ticket and /br-sync-docs (in
"Alternatives considered" below) is reversed — both now dispatch to a new read-only
discovery agent (br-ticket, br-docs) by default. /br-implement's --agent-gated
routing is also reversed — dispatch is now the default, not an opt-in flag. The
confirm-before-mutate rule and the specialist-agent split itself are unaffected.
Context
ADR-0008 defined five coarse dev-task commands (/br-plan, /br-develop, /br-debug,
/br-review, /br-test), each a 1:1 pairing of a slash command with its own heavy --agent
specialist. That pairing had no connection to how work is actually tracked — a GitHub
Projects board with issues and pull requests. Picking up a ticket, syncing its state, and
opening a PR were all manual steps outside the agent layer.
The project also added a working knowledge base (obsidian/, see
.claude/rules/knowledge-base.md) and a graphify-generated codebase map, but nothing tied
GitHub ticket state to that vault.
Decision
- Replace the five
br-*commands with five ticket-driven commands:/br-take-ticket,/br-implement,/br-sync-ticket,/br-sync-board,/br-sync-docs. Commands are the entrypoints — they decide scope and stay in the current session by default. - Keep the classic specialist agents, renamed for clarity:
br-planner(wasbr-plan),br-developer(wasbr-develop),br-debugger(wasbr-debug),br-tester(wasbr-test),br-reviewer(unchanged name). Their bodies are otherwise unchanged from ADR-0008:br-planneris plan-only and asks clarifying questions;br-developerwrites code and auto-invokesbr-revieweron diffs over 100 lines/5 files;br-debuggerreproduces → isolates → fixes → verifies;br-testerwrites/runs one focused spec;br-reviewerdoes the mechanical pass + architecture checklist walk. - Model is fixed per agent, in its own frontmatter:
br-planner→ Fable (light, fast-turnaround planning);br-developer→ Sonnet (routine implementation);br-debugger,br-tester,br-reviewer→ Opus (the three verification-heavy roles, where a missed edge case in a bug repro, a test, or a review is expensive). This is not a per-invocation choice — changing it means editing the agent file. - What changed is the pairing: these five no longer each have their own 1:1 slash
command.
/br-implement [--agent] [--plan] [--review]is the single entrypoint that routes to whichever specialist the task needs (br-plannerfor--planor a non-trivial task,br-developerfor a feature,br-debuggerfor a bug,br-reviewerfor--reviewor a large diff), or does the equivalent narrow-scope work itself in-session when no isolated agent is warranted. /br-take-ticketfinds a GitHub issue (viagh, from the GitHub Projects board or a direct reference), moves its board card, and checks out a branch./br-sync-ticketand/br-sync-boardmirror GitHub issue/PR/board state intoobsidian/Tickets/andobsidian/Board/board.md. Both are strictly read-only on GitHub./br-sync-docsfinds and (with confirmation) fixes drift betweenapps/docs/and the rule/ADR sources — see ADR-0013./br-take-ticket,/br-sync-ticket,/br-sync-board, and/br-sync-docsare fully self-contained — their instructions live directly in the command file, there is no separate agent file, and there is no--agentflag for them. They talk to GitHub themselves: prefer an MCP GitHub server if one is connected in the session, otherwise theghCLI (the only proven working path at the time this was written — no GitHub MCP was connected). Only/br-implementhas named specialist agents behind it.- Every command and every agent (the five
/br-implementspecialists plus the four self-contained commands) has access to any skill under.claude/skills/, not a fixed subset —tools:frontmatter includesSkillon every agent file that has one. /br-take-ticketand/br-implement(whether in-session or via a dispatched specialist) are the only paths that mutate GitHub state (board card moves, issue comments,git push, PR create/edit), and both confirm with the user before every such action — a prior approval in the conversation does not carry over to a later mutating action. The five specialist agents themselves never push or open/update a PR; that responsibility stays at the/br-implementorchestration level.- GitHub Projects access requires the
read:projectOAuth scope (projectfor writes) on the localghtoken; this is a per-developer one-timegh auth refreshstep, not something the agent layer can grant itself.
Consequences
- The specialist personas (plan/develop/debug/test/review) keep their full depth —
br-reviewer's architecture-checklist walk andbr-debugger's reproduce-first discipline are unchanged from ADR-0008 — while the commands a developer actually types collapse to the five ticket-workflow ones. Routing logic (which specialist a given task needs) now lives in/br-implementinstead of being implicit in "which command did you type."/br-implement's in-session (no--agent) path still does lint/type-check as the baseline gate for small tasks that don't warrant dispatching a specialist. - The four GitHub/Obsidian-sync commands stay simple on purpose: they're mechanical (fetch data, write a file, confirm before mutating), not reasoning-heavy, so a dedicated agent file added indirection without adding capability. Their instructions living directly in the command means one file to read, not two.
- The Obsidian vault (
obsidian/) becomes the source of truth for "what's the state of ticket #N locally," independent of and read-only against GitHub —obsidian/Tickets/*.mdpreserves a## Notessection across syncs specifically so working notes survive. - Changing any of the five agents or five commands requires synchronising: the command doc
(and its agent doc, for
/br-implement's five),AGENTS.md's command table,.claude/README.md,.claude/TOKEN_BUDGET.md,.claude/rules/knowledge-base.md, and any rule file's "Related rules and skills" section that names a command or agent.
Alternatives considered
- Fold planning/debug/review/test into
br-implementas inline, non-specialist work — tried first in this session, then rejected: it discarded the specialist personas' accumulated depth (the full architecture-checklist walk, the reproduce-first debugging discipline) for no benefit once the real fix was just re-pairing existing agents with new commands, not removing the agents. - Keep
br-*(one command per agent) alongside the four new ticket commands — rejected; two overlapping command sets for "do development work" would fragment the workflow and confuse routing. Keeping the agents but retiring their 1:1 commands in favor of/br-implement's routing gets the same specialist depth without the fragmentation. - Let
/br-implementpush and open PRs without confirmation — rejected; opening/updating a PR and moving a board card are both visible to the rest of the team and stay behind an explicit per-action confirmation, consistent with this session's safety defaults. - Give
br-take-ticket/br-sync-ticket/br-sync-board/br-sync-docstheir own agent files too — tried first in this session, then rejected: these four are mechanical (fetch, write, confirm), not the kind of isolated multi-step reasoning the--agentpattern exists for, so a 1:1 command↔agent split just duplicated near-identical content across two files per command for no behavioural benefit.