Reference
Recipes.
1. Single-repo onboarding
Goal: turn a repo + tracker board into a Briar-managed autonomous flow in 10 minutes.
1.1 — Authenticate
$ briar auth login github-pat --company acme$ briar auth login jira-token --company acme$ briar secrets doctor --examples runbooks/ # confirm coverage
1.2 — Extract
$ briar extract --company acme \--pr-repo acme/widgets \--ticket-project KAN \--tracker jira
Mines merged-PR history and open Jira tickets into knowledge:acme — the blob every later step reads from.
1.3 — Build the plan
$ briar plan build jira:KAN --name q3 \--company acme --llm anthropic --with-knowledge
Pulls every card from the KAN board, synthesises scope / out-of-scope / risks per card with the LLM (company knowledge spliced in), and stores the result as plan:q3.
1.4 — Run
$ briar plan run q3 --company acme \--llm anthropic \--owner acme --repo widgets \--tracker jira --tracker-project KAN \--limit 3
Runs the first three cards end to end: the selector picks what's next, the agent implements it and opens a draft PR, and each card's learnings merge back into the plan blob.
Always --limit your first runs
--limit 3 lets you preview cost + quality before letting it run unbounded.2. Multi-company runbook on a schedule
Goal: one host runs daily knowledge refresh for three companies, surfacing failures via Slack.
2.1 — Write the runbook
# runbooks/all.yamlversion: 1companies:acme:knowledge: { store: postgres, name: knowledge:acme }messages:ops_chat: { kind: slack-channel }schedules:- task: daily-extractevery: "day at 07:00"extract:- name: pr-archaeologyargs: { pr_repo: [acme/widgets, acme/api] }- name: active-ticketsargs: { tracker: jira, ticket_project: KAN }- name: aws-infraargs: { aws_extract_region: us-east-1 }widgets:knowledge: { store: postgres, name: knowledge:widgets }schedules:- task: daily-extractevery: "day at 07:30"extract:- name: pr-archaeologyargs: { pr_repo: [widgets/core] }- name: code-hotspotsargs: { hotspots_repo: [widgets/core], hotspots_since_days: 14 }zenith:knowledge: { store: postgres, name: knowledge:zenith }schedules:- task: hourly-activeevery: "1 hour"extract:- name: active-workargs: { active_repo: [zenith/platform] }
Three companies, each with its own knowledge store and cadence — acme refreshes PRs / tickets / AWS every morning, widgets mines PRs and hotspots, and zenith sweeps open work hourly.
2.2 — Run the scheduler
$ export BRIAR_DATABASE_URL=postgres://briar:[email protected]:5432/briar$ export BRIAR_NOTIFY_SINKS=slack$ briar runbook serve runbooks/
Failures from any company's schedule emit a Slack message via the company's notify sink (or the global BRIAR_NOTIFY_SINKS).
2.3 — Add the dashboard
$ briar dashboard \--host 0.0.0.0 --port 8080 \--examples runbooks/ \--knowledge-store postgres \--log-file /var/log/briar/scheduler.log
The dashboard surfaces per-company schedule timings, recent journal sessions, knowledge-blob sizes, and disk usage.
3. PR-fixer on cron
Goal: every hour, check every open PR on acme/widgets and apply fixes for any unaddressed review comments.
3.1 — Loop script
$ #!/usr/bin/env bash# /opt/briar/prfix-loop.sh$ set -euo pipefail$ OPEN_PRS=$(gh pr list --repo acme/widgets --state open --json number,headRefName)$ echo "$OPEN_PRS" | jq -c '.[]' | while read -r pr; donum=$(echo "$pr" | jq -r .number)branch=$(echo "$pr" | jq -r .headRefName)briar agent prfix \--company acme --owner acme --repo widgets \--pr "$num" --branch "$branch" \--runbook /etc/briar/runbooks/acme.yaml || true$ done
Lists every open PR on the repo and runs prfix against each one, addressing unresolved review comments. || true stops a single failing PR from aborting the whole loop.
3.2 — Cron entry
# crontab -e$ 0 * * * * /opt/briar/prfix-loop.sh >> /var/log/briar/prfix.log 2>&1
Runs the loop once an hour, appending all output (stdout + stderr) to a log file.
Why prfix is idempotent
prfix reads which review comments already have agent replies and skips those. Running it every hour against the same PR is safe.4. Postgres-backed multi-host deploy
Goal: two hosts share knowledge / journal state via Postgres. One host runs the scheduler, the other runs the agent loop.
4.1 — Provision Postgres
# config.knowledge — fills the briar table on first writestore: postgresname: knowledge:acmeconfig:dsn_env: BRIAR_DATABASE_URL
Points the knowledge store at Postgres; the briar table is created on the first write, so no manual schema step is needed.
4.2 — Scheduler host
$ export BRIAR_DATABASE_URL=postgres://briar:***@db.internal:5432/briar$ export BRIAR_JOURNAL_STORE=file # journal stays local; not load-bearing across hosts$ briar runbook serve /etc/briar/runbooks/
The scheduler host keeps the shared Postgres knowledge fresh on its cadence; its journal stays on local disk.
4.3 — Agent host
$ export BRIAR_DATABASE_URL=postgres://briar:***@db.internal:5432/briar$ briar plan run q3 \--company acme --llm anthropic \--owner acme --repo widgets \--store postgres \--runbook /etc/briar/runbooks/acme.yaml
Both hosts share knowledge blobs via Postgres. The scheduler keeps them fresh; the agent reads the freshest version on every loop iteration.
Don't share journal across hosts
BRIAR_JOURNAL_STORE=file on each host or use a host prefix in the root path.5. Script Briar with JSON output
Goal: drive Briar from shell scripts and pipelines. Every command honours the global --format flag, and json output is safe to pipe into jq.
5.1 — Position of the flag
--format is extracted from anywhere in the argument list, so trailing position works even for nested subcommands like context list.
# Headline plan counts.$ briar plan status q3 --format json | jq '.counts'# Just the keys of every blocked card. The status snapshot groups# cards by state: counts / done[] / in_progress[] / blocked[] / pending[].$ briar plan status q3 --format json | jq -r '.blocked[].key'# Every knowledge blob as a flat list of names.$ briar context list --prefix knowledge: --format json | jq -r '.[].name'
5.2 — Gate a pipeline on state
# Fail early if a company has no knowledge extracted yet.$ n=$(briar context list --prefix knowledge:acme --format json | jq 'length')$ [ "$n" -gt 0 ] || { echo "no knowledge for acme yet"; exit 1; }
Output formats
--format accepts table (default), json, yaml, csv, and quiet. Use quiet when you only care about the exit code.6. Gate CI on credential coverage
Goal: never let a half-configured host start the scheduler. briar secrets doctor walks every runbook YAML's schedules: / messages: blocks and exits non-zero when any required env var is missing.
6.1 — GitHub Actions pre-flight
# .github/workflows/briar-preflight.ymlname: briar preflighton: [push]jobs:secrets:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- run: pip install briar-cli- name: Verify every runbook has its credentialsenv:GITHUB_TOKEN: ${{ secrets.BRIAR_GH }}JIRA_ACME_EMAIL: ${{ secrets.JIRA_ACME_EMAIL }}JIRA_ACME_TOKEN: ${{ secrets.JIRA_ACME_TOKEN }}run: briar secrets doctor --examples runbooks/
Exit codes
briar returns 0 on success, 1 on any runtime or coverage failure, and 2 on a usage error (unknown subcommand or bad flag) — so a bare run: step gates on $? with no extra glue.7. Cost-safe agent rollout
Goal: see prompt quality and cost before spending tokens at scale. The agent and plan commands make many LLM calls per card, so ratchet from free to wide.
7.1 — Dry-run (no LLM call)
$ briar agent implement \--company acme --owner acme --repo widgets \--ticket-project KAN --ticket-key KAN-42 \--runbook runbooks/acme.yaml \--dry-run
--dry-run prints the rendered prompt and the tool list, then exits without calling the model.
7.2 — One paid card, capped iterations
$ briar plan run q3 \--company acme --owner acme --repo widgets \--tracker jira --tracker-project KAN \--llm anthropic --model claude-sonnet-4-6 \--limit 1 --max-iter 20
Runs exactly one card with a hard iteration cap — your single paid smoke test for prompt quality and real per-card cost.
7.3 — Go wide, tolerate failures
$ briar plan run q3 \--company acme --owner acme --repo widgets \--tracker jira --tracker-project KAN \--llm anthropic --continue-on-failure
Once the smoke test looks good, drop the limit and let the loop work the whole plan, marking any failed card blocked and moving on instead of stopping.
Inspect what it decided
plan run opens a journal session. Replay the selector's picks and rationales with briar journal list --command plan.run. then briar journal show <session-id>.8. Repeatable flags (pass a flag more than once)
Goal: target several repos, projects, services, or filters in one invocation. Many flags accept multiple occurrences — repeat the flag, once per value. There is no comma-separated form: --pr-repo a,b is read as a single repo literally named a,b.
8.1 — Extract across repos, projects, services
$ briar extract --company acme \--include pr-archaeology --include active-work \--pr-repo acme/widgets --pr-repo acme/api \--pr-authors-block "dependabot[bot]" \--pr-authors-block "renovate[bot]" \--active-repo acme/widgets --active-repo acme/api \--ticket-project KAN --ticket-project PLAT \--include aws-infra \--aws-extract-service ecs --aws-extract-service rds \--aws-extract-service logs
Allow/block filter pairs compose as allow ∩ ¬block. Each repeated value accumulates into a list.
8.2 — Scaffold with multiple sources
$ briar scaffold implementation \--prefix acme-onerror \--source sentry --source github --source aws \--sentry-project backend --sentry-project worker \--sentry-environment prod --sentry-environment staging \--sentry-level error --sentry-level fatal \--sentry-secret-id <uuid> --auth-mode pat \--owner acme --repo widgets --github-secret-id <uuid> \--aws-services ecs --aws-services rds
Emits one config bundle fed by three sources, two Sentry projects, two environments, and two severities — every per-source list flag repeated once per value.
8.3 — Same idea in runbook YAML
In a runbook, repeated flags map onto YAML list values under each extractor's args: block.
extract:- name: pr-archaeologyargs:pr_repo: [acme/widgets, acme/api]pr_authors_block: ["dependabot[bot]", "renovate[bot]"]- name: active-ticketsargs:ticket_project: [KAN, PLAT]
8.4 — Four repo-list extractors in one pass
reviewer-profile, code-hotspots, github-deployments, and codebase-conventions each take their own repeatable --*-repo flag — refresh a whole service group's knowledge picture in a single command.
$ briar extract --company acme \--include reviewer-profile \--reviewer-repo acme/web --reviewer-repo acme/api \--reviewer-pr-sample 40 --reviewer-top-n 6 \--include code-hotspots \--hotspots-repo acme/web --hotspots-repo acme/api \--hotspots-since-days 45 --hotspots-max-commits 200 \--include github-deployments \--deploy-repo acme/web --deploy-repo acme/api \--include codebase-conventions \--conventions-repo acme/web --conventions-repo acme/api
8.5 — Open + closed ticket coverage
active-tickets and ticket-archaeology take independent project lists, so you can watch many boards live while mining history from only the noisy ones. --ticket-max is per project.
$ briar extract --company acme --tracker jira \--include active-tickets \--ticket-project KAN --ticket-project PLAT \--ticket-project BILLING --ticket-project GROWTH \--include ticket-archaeology \--ticket-archaeology-project KAN \--ticket-archaeology-project PLAT \--ticket-max 150
8.6 — Wide AWS inventory + meeting digest
--aws-extract-service is one of ecs, lambda, logs, rds, sqs, tagging-inventory; list the per-service ones for depth and tagging-inventory for account-wide breadth. Scalar caps like --pr-max apply per repo, so repeated repos don't shrink each other's budget.
$ briar extract --company acme \--include aws-infra --cloud aws \--aws-extract-region us-east-1 \--aws-extract-service ecs --aws-extract-service lambda \--aws-extract-service logs --aws-extract-service rds \--aws-extract-service sqs --aws-extract-service tagging-inventory \--include meeting-digest --meeting fireflies \--meeting-attendee-allow [email protected] \--meeting-attendee-allow [email protected] \--meeting-attendee-allow [email protected]
8.7 — Dashboard: watch several mounts
$ briar dashboard --host 0.0.0.0 --port 8080 \--examples runbooks/ \--du-path /var/lib/briar \--du-path /var/log/briar \--du-path /mnt/knowledge
Serves the status dashboard while reporting free space for three separate mounts — repeat --du-path once per directory you want tracked.
8.8 — Scaffold: per-source author/assignee filters
Each tracker source (github, bitbucket, jira) contributes its own repeatable author and assignee filters. Block the bots, keep only issues assigned to the on-call rotation — across two sources at once.
$ briar scaffold implementation \--prefix acme-triage \--source github --source jira \--owner acme --repo widgets --github-secret-id <uuid> \--github-authors-block "dependabot[bot]" \--github-assignees-allow alice --github-assignees-allow bob \--jira-project KAN --jira-project PLAT --jira-secret-id <uuid> \--jira-authors-allow [email protected] \--jira-assignees-allow [email protected] \--auth-mode pat --out scaffolds/acme-triage.json
8.9 — Scaffold: webhook event + label filters
The github_webhook (default) and bitbucket_webhook triggers each take repeatable event-name and label filters — fire the agent only on the events and labels you choose.
$ briar scaffold implementation \--prefix acme-onlabel \--source github \--owner acme --repo widgets --github-secret-id <uuid> --auth-mode pat \--trigger-kind github_webhook \--webhook-events issues.opened --webhook-events issues.labeled \--webhook-labels briar --webhook-labels needs-agent \--out scaffolds/acme-onlabel.json
Where assignee filters actually filter on assignees
--github-assignees-*, --bitbucket-assignees-*, --jira-assignees-*) match the issue's assignee. But extract's --pr-assignees-* / --active-assignees-* parse and accumulate yet currently match on the author — the normalised PR shape has no assignee. For extract, prefer the *-authors-allow/block pairs.Every repeatable flag
--include, --pr-repo, --pr-authors-allow/-block, --pr-assignees-allow/-block, --active-repo, --active-authors-allow/-block, --active-assignees-allow/-block, --deploy-repo, --conventions-repo, --reviewer-repo, --hotspots-repo, --ticket-project, --ticket-archaeology-project, --aws-extract-service, --meeting-attendee-allow. scaffold — --source, --jira-project, --sentry-project, --sentry-environment, --sentry-level, --aws-services, the per-source filters --{github,bitbucket,jira}-authors-allow/block and --{github,bitbucket,jira}-assignees-allow/block, and the webhook filters --webhook-events, --webhook-labels, --bitbucket-webhook-events, --bitbucket-webhook-labels. dashboard — --du-path.9. Remaining single-purpose flags
The flags that don't fit the scenarios above, each shown once so every flag has a worked example.
9.1 — Preview a telemetry event
# Render the exact event that WOULD be sent for a command, sending nothing.$ briar telemetry preview --for-command extract$ briar telemetry preview --for-command "plan run"
9.2 — Export a journal session
# --as picks the serialization (markdown | json); --out - writes to stdout.$ briar journal export <session-id> --as json --out audit.json$ briar journal export <session-id> --as markdown --out -
9.3 — Write context blobs three ways
$ briar context put memory:reviewer-alice --content "Focuses on typing rigor"$ briar context put knowledge:acme --from-file knowledge/acme.md$ briar context put lessons:typing --content - --category lessons < lessons/typing.md
9.4 — Advance a single plan card
# Set one card's state by hand (--status: pending | in_progress | done | blocked).$ briar plan advance acme-q3 --card KAN-7 --status in_progress
9.5 — Preview a plan without persisting
$ briar plan build jira:KAN --name preview \--default-branch develop --max-cards 20 --dry-run --print
Flags briar derives for you
--pr-target-repo and --pr-target-number are not passed directly — briar agent prfix derives them from --owner/--repo/--pr and feeds them to the JIT pr-review-context extractor.Where to go next
- briar extract — the source of truth for which extractors and flags you can use.
- Runbook YAML schema — every field documented.
- briar plan run — full flag reference for the loop command.