Skip to content

Reference

Recipes.

Four end-to-end walkthroughs you can copy-paste and adapt. Each one is a complete workflow from a fresh repo to a running system.

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

The LLM agent makes many calls per card. --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.yaml
version: 1
companies:
acme:
knowledge: { store: postgres, name: knowledge:acme }
messages:
ops_chat: { kind: slack-channel }
schedules:
- task: daily-extract
every: "day at 07:00"
extract:
- name: pr-archaeology
args: { pr_repo: [acme/widgets, acme/api] }
- name: active-tickets
args: { tracker: jira, ticket_project: KAN }
- name: aws-infra
args: { aws_extract_region: us-east-1 }
widgets:
knowledge: { store: postgres, name: knowledge:widgets }
schedules:
- task: daily-extract
every: "day at 07:30"
extract:
- name: pr-archaeology
args: { pr_repo: [widgets/core] }
- name: code-hotspots
args: { hotspots_repo: [widgets/core], hotspots_since_days: 14 }
zenith:
knowledge: { store: postgres, name: knowledge:zenith }
schedules:
- task: hourly-active
every: "1 hour"
extract:
- name: active-work
args: { 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; do
num=$(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 write
store: postgres
name: knowledge:acme
config:
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

The journal is a per-process timeline; sharing it between hosts produces interleaved records that the selector can't reason about. Keep 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.yml
name: briar preflight
on: [push]
jobs:
secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pip install briar-cli
- name: Verify every runbook has its credentials
env:
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

Every 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-archaeology
args:
pr_repo: [acme/widgets, acme/api]
pr_authors_block: ["dependabot[bot]", "renovate[bot]"]
- name: active-tickets
args:
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

The scaffold per-source filters (--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

extract--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