Bitterblossom
Operate the event plane. Do not move workload judgment into the plane.
Bitterblossom is bb: tasks + agents + triggers as files, with a durable run
ledger, budgets, retries, dead letters, and optional webhook/cron serving.
Agents are CLI users, so prefer stable --json surfaces over prose parsing.
When working in the Bitterblossom source checkout, read VISION.md for the
runtime-vs-workload boundary before adding or reshaping tasks.
Stance
- Treat
bb as runtime and ledger, not an agent brain.
- Workloads are config:
plane.toml, agents/<name>.toml,
tasks/<name>/task.toml, and tasks/<name>/card.md.
- New workload behavior should be a task/card/agent change, not a Rust branch.
- Use
--config <plane> explicitly unless the user has set BB_PLANE_DIR.
- Use
--json for agent-readable output. Text is for humans.
- Human-mode
bb run prints an early run id and periodic stderr heartbeats;
bb run --json stays quiet until it emits the final run bundle.
- If
bb is not on PATH, use cargo run --quiet -- from the source repo or
./target/debug/bb after cargo build.
First Probe
Run these before changing or dispatching anything:
bb --config <plane> check
bb --config <plane> task list --json
bb --config <plane> runs list --json
Read the output for:
- loaded tasks and agent versions;
- parked tasks and budget ceilings;
- recent failures, dead letters, in-flight cap kills, and costs;
- whether a task is reflex (
webhook/cron) or dispatch (manual).
Authority And Readiness
Classify the run before dispatch. Mode B work belongs in Bitterblossom, but the
allowed authority depends on trigger source, auth class, and task policy.
| Mode |
Allowed |
Refuse |
Readiness |
| Supervised dispatch |
Operator-initiated bb run/submission work with the task's declared side effects; subscription-auth builders only when the task is manual and the operator asked for that authority. |
Hidden cron/webhook dispatch, unbounded continuation, merge/deploy/recovery authority not named by the task or operator. |
bb --config <plane> check; bb --config <plane> task list --json; bb --config <plane> preflight <task> --json; bb --config <plane> status --json. |
| Unsupervised reflex |
Webhook/cron API-auth work inside declared repo/org filters, budgets, required artifacts, authority, and side-effect policy. |
Subscription auth, broad repo discovery, secret values in payloads, merge/deploy/run-resolution authority, or any action beyond the task card. |
bb --config <plane> check; inspect task policy and budget in task list --json; run preflight; inspect status --json, dlq list --json, and notify list --json. |
| Read-only inspection |
MCP/CLI/API reads for status, config, runs, gates, dead letters, and artifacts. |
Any tools/call mutation, dispatch, replay, resolve, park/unpark, submit, merge, or credential provisioning over MCP. |
Prefer MCP tools when available; fall back to bb ... --json; use bb_artifacts_list/bb_artifact_read or bb artifacts list/read for evidence. |
A closeout receipt is incomplete until it names the exact command/surface used,
run id or submission id, ledger state, cost/budget status, side effects,
artifact reads via MCP or bb artifacts list/read, and residual risk.
Rollout Scorecards
Autonomous task families ship at less than full authority (read-only,
report-only, dry-run, PR-only) and climb an authority ladder only on evidence.
The single reusable scorecard template and promotion doctrine live in
docs/rollout-scorecards.md.
Refuse autonomy expansion from vibes. Do not recommend or take a higher
authority action (open a branch/PR, merge, deploy, resolve, unpark) for a task
family unless that level's scorecard is green and an operator has approved the
promotion. "It has been working" is not evidence; the scorecard is. Green
metrics only make the next-level ticket eligible for explicit operator approval;
they never flip authority by themselves. Merge, unpark, production mutation, and
broad rollout stay operator authority until a scorecard plus an operator
decision says otherwise.
Route
| Need |
Use |
| Validate config and see loaded agents/tasks |
bb --config <plane> check |
| Decision-ready task/run/DLQ health |
bb --config <plane> status --json |
| Task inventory, parked state, budgets |
bb --config <plane> task list --json |
| Trigger manual work |
bb --config <plane> run <task> --payload '<json>' --json |
| Dispatch a manual builder lane |
bb --config <plane> run build --payload '{"backlog":"<id-or-path>"}' --json |
| Diagnose failed CI |
bb --config <plane> run ci-diagnose --payload '{"repo":"owner/repo","head_sha":"<sha>"}' --json |
| Run a report-only lifecycle reflex |
bb --config <plane> run <reflex> --payload-file EVENT.json --json where <reflex> is fix-prompt, deploy-prod-verify, canary-triage, backlog-chewer-dry-run, or lifecycle-orchestrator (each writes REPORT.json, no mutation; see docs/rollout-scorecards.md) |
| Compare candidate model configs |
Run at least three candidate tasks, then bb --config <plane> run model-eval --payload '<json>' --json |
| Inspect ledger |
bb --config <plane> runs list --json; bb --config <plane> runs show <id> --json |
| Export run telemetry |
bb --config <plane> runs export (bb.run_telemetry.v1 JSONL) |
| Inspect run artifacts |
bb --config <plane> artifacts list <run-id> --json (top-level artifact files); bb --config <plane> artifacts read <run-id> REPORT.json (safe text/JSON read, including known nested relative paths; binary, oversized, and traversal paths refused) |
| Handle pre-execute failures |
bb --config <plane> dlq list --json; bb --config <plane> dlq replay <id> --json; bb --config <plane> dlq ack <id> --reason <text> --json to close a superseded DLQ |
| Handle notification failures |
bb --config <plane> notify list --json; bb --config <plane> notify retry --json; bb --config <plane> notify ack <id> --reason <text> --json |
| Provision scoped OpenRouter child keys |
bb --config <plane> keys mint <agent> --json; bb --config <plane> keys rotate <agent> --json; bb --config <plane> keys revoke <agent> --json; bb --config <plane> keys list --remote --json; bb --config <plane> keys sync --all --check --json |
| Park or unpark workload dispatch |
`bb --config task park |
| Classify inherited running rows after host restart |
bb --config <plane> recover |
| Run webhook/cron plane |
bb --config <plane> serve |
| Submission storm / review factory |
bb submit ..., verdict bb run <kind> ..., then bb gate --json |
| Read-only inspection for agents over MCP |
bb --config <plane> mcp serve (stdio JSON-RPC; bb_status, bb_check, bb_tasks, bb_runs_list, bb_runs_show, bb_artifacts_list, bb_artifact_read, bb_dlq_list, bb_preflight, bb_gate) |
Detailed command recipes: references/operator-recipes.md. Authority-promotion
rules and per-task scorecards: docs/rollout-scorecards.md.
Dispatch Rules
- A
bb run can have external side effects. Do not blindly re-run a successful
or executing task.
- Secrets travel through declared env/secrets and stdin plumbing. Never put
tokens in argv, task cards, or payload JSON unless the task contract explicitly
says the value is non-secret.
- For GitHub-backed runs, prefer
GH_TOKEN=$(gh auth token) bb ... over copying
tokens into shell history.
- Reflex triggers must use API-auth agents. Subscription-auth agents belong to
manual dispatch only.
- The checked-in
build task is a manual API-auth OMP/GLM builder lane. Use
it for shaped implementation work only; it creates/pushes a branch and report
but does not merge or replace the submission gate.
- For uncertain model fit, run a cohort: at least three materially different
candidate tasks for the same flow and payload, then the
model-eval task.
First-class cohorts for build, review, gardener, ci-diagnose, and
submission-storm members are listed under
docs/model-evals/. Record accepted
findings there before promoting a new default.
- A parked task is intentionally blocked. Inspect the reason before
unpark.
- Dead letters are pre-execute failures. At/after execute, use operator
resolution paths because the run may have side effects.
- Streaming harness usage is metered while the run is executing. If
max_cost_per_run_usd is breached, the agent policy chooses kill,
quarantine, or log; kill and quarantine must emit notification
outbox rows such as run_in_flight_cap_killed.
Submission Storm
Verdict tasks (correctness, security, product, simplification,
arbiter, verify) expect a submission payload. Do not call them with an
arbitrary repo/rev payload.
Shape:
bb --config <plane> submit open --change <change> --rev <rev> --json
bb --config <plane> run correctness --payload '{"submission":"<submission>"}' --json
bb --config <plane> gate --submission <submission> --json
If a verdict task fails with payload has no 'submission' field, the plane is
correct; the invocation was wrong.
If bb gate --json reports a canonical member as run:failure, read that
member's safe_next_command. Replays prove the failed pre-execute path can run,
but they do not count for the canonical gate key; the safe recovery is a clean
replacement submission after fixing the operator or infrastructure issue. The
command includes the loaded plane's --config path so an agent can run it from
another cwd.
Recovery
bb recover classifies inherited running rows after a host restart.
bb recover --json exposes probe_state, probe_reason,
lease_disposition, and operator_action; unknown probes retain the host
lease.
bb runs resolve is for awaiting_recovery after side-effect inspection.
bb status --json marks awaiting_recovery older than one hour as
escalate_stale_recovery, with age fields, but the operator still resolves
the run only after inspecting side effects.
bb dlq replay --json mints a new run linked to a pre-execute dead letter
and returns the replayed run bundle.
bb dlq ack <id> --reason <text> --json acknowledges a superseded
pre-execute dead letter without replaying it, recording reason + timestamp.
Acknowledged DLQs cannot be replayed; bb status --json no longer counts
them as open operator work.
bb preflight <task> | --storm --json checks missing declared secrets,
missing policy-bound provider keys, and unspawnable command-harness
binaries before dispatch creates run rows.
Serving
bb serve exposes webhook ingress, cron scheduling, the HTML operator view, and
read APIs. Do not bind publicly without BB_API_TOKEN; the server refuses
non-loopback binds without it.
Useful API mirrors:
GET /api/tasks
GET /api/status
GET /api/runs
GET /api/runs/<id>
GET /api/dlq
GET /api/notify
GET /api/submissions
MCP (read-only)
bb --config <plane> mcp serve runs a read-only MCP stdio server: JSON-RPC
2.0 over stdin/stdout, no network listener, no external credentials for
local-plane inspection. Consume it MCP-first where a host agent supports it;
fall back to bb ... --json for anything the MCP tool table does not yet
cover. The registered read tools (bb_status, bb_check, bb_tasks,
bb_runs_list, bb_runs_show, bb_artifacts_list, bb_artifact_read,
bb_dlq_list, bb_preflight, bb_gate) return the same shapes as their
CLI/API counterparts — MCP is a typed adapter, not a second implementation.
This slice ships read-only tools only. No mutating MCP tool exists; a
tools/call for an unknown or would-be mutating name is rejected with a
JSON-RPC -32602 error. Do not expect bb runs cancel, bb dlq replay,
bb run, or submission/gate mutations over MCP until a separate
writable-MCP backlog lands its graduation signals.
Routing:
| Need |
First choice |
Fallback |
| Decision-ready plane health |
MCP bb_status |
bb status --json |
| Config/task inventory |
MCP bb_check, MCP bb_tasks |
bb check --json; bb task list --json |
| Runs |
MCP bb_runs_list, MCP bb_runs_show |
bb runs list --json; bb runs show <id> --json |
| Run artifacts |
MCP bb_artifacts_list, MCP bb_artifact_read |
bb artifacts list <id> --json; bb artifacts read <id> <path> --json |
| Dead letters |
MCP bb_dlq_list |
bb dlq list --json |
| Pre-dispatch readiness |
MCP bb_preflight |
bb preflight <task> --json |
| Submission gate evaluation |
MCP bb_gate |
bb gate --change <key> --json |
| Submission mutation |
(not yet MCP) |
bb submit ... --json |
Operator Dispatch Loop
Use the ergonomic dispatch surface when the operator wants bb to own a
supervised lane instead of running a bare shell:
bb --config <plane> dispatch --repo <path> --brief <file> [--model <slug>] [--label <text>]
bb --config <plane> logs -f <run-id>
dispatch prints only the accepted run id and exits. It chooses the task from
BB_DISPATCH_TASK, then dispatch, then build, then a single manual task if
that is the only unambiguous option. The brief file is read at dispatch time and
persisted into the run payload as bb.dispatch_job.v1 with repo, canonical
prompt, optional model, label, and branch_slug; the brief file path
itself is not persisted. model, when provided, overrides the selected task
agent's model for that run. It does not run synchronously; a running local or
deployed plane drains the pending run. logs -f follows ledger events plus
released text artifacts until the run reaches a terminal state.
Distribution
The portable artifact is this whole folder: skills/bitterblossom/. Consumers
should copy or symlink the folder, not just SKILL.md, so references and agent
metadata travel with it.
Harness Kit integration should keep one source of truth. Prefer a source entry,
bootstrap projection, or explicit symlink from Harness Kit to this folder over a
manual copied skill that can drift. The durable decision is
docs/adr/006-skill-projection.md.
Closeout Evidence
When using Bitterblossom, report:
- exact plane path and
bb binary used;
- commands run and relevant run ids;
- ledger state, costs, parked/DLQ status, and external side effects;
- generated artifacts, inspected through
bb artifacts list/read rather than local path spelunking, plus any API/CLI JSON read;
- residual risk, including failed probes that remain in the ledger.
1---2name: bitterblossom3description: Operate Bitterblossom's `bb` event-plane CLI for agent workloads. Use when Codex needs to inspect or run `bb`, configure `plane.toml`, `agents/`, or `tasks/`, dispatch or audit tasks, handle runs, dead letters, recovery, parked tasks, submissions, gates, review-factory workflows, or help another repo consume Bitterblossom. Trigger phrases: "Bitterblossom", "bb", "event plane", "agent workload", "run a task", "inspect runs", "DLQ", "parked task", "submission loop", "review factory".4---56# Bitterblossom78Operate the event plane. Do not move workload judgment into the plane.910Bitterblossom is `bb`: tasks + agents + triggers as files, with a durable run11ledger, budgets, retries, dead letters, and optional webhook/cron serving.12Agents are CLI users, so prefer stable `--json` surfaces over prose parsing.13When working in the Bitterblossom source checkout, read `VISION.md` for the14runtime-vs-workload boundary before adding or reshaping tasks.1516## Stance1718- Treat `bb` as runtime and ledger, not an agent brain.19- Workloads are config: `plane.toml`, `agents/<name>.toml`,20 `tasks/<name>/task.toml`, and `tasks/<name>/card.md`.21- New workload behavior should be a task/card/agent change, not a Rust branch.22- Use `--config <plane>` explicitly unless the user has set `BB_PLANE_DIR`.23- Use `--json` for agent-readable output. Text is for humans.24- Human-mode `bb run` prints an early run id and periodic stderr heartbeats;25 `bb run --json` stays quiet until it emits the final run bundle.26- If `bb` is not on `PATH`, use `cargo run --quiet --` from the source repo or27 `./target/debug/bb` after `cargo build`.2829## First Probe3031Run these before changing or dispatching anything:3233```bash34bb --config <plane> check35bb --config <plane> task list --json36bb --config <plane> runs list --json37```3839Read the output for:4041- loaded tasks and agent versions;42- parked tasks and budget ceilings;43- recent failures, dead letters, in-flight cap kills, and costs;44- whether a task is reflex (`webhook`/`cron`) or dispatch (`manual`).4546## Authority And Readiness4748Classify the run before dispatch. Mode B work belongs in Bitterblossom, but the49allowed authority depends on trigger source, auth class, and task policy.5051| Mode | Allowed | Refuse | Readiness |52|---|---|---|---|53| Supervised dispatch | Operator-initiated `bb run`/submission work with the task's declared side effects; subscription-auth builders only when the task is manual and the operator asked for that authority. | Hidden cron/webhook dispatch, unbounded continuation, merge/deploy/recovery authority not named by the task or operator. | `bb --config <plane> check`; `bb --config <plane> task list --json`; `bb --config <plane> preflight <task> --json`; `bb --config <plane> status --json`. |54| Unsupervised reflex | Webhook/cron API-auth work inside declared repo/org filters, budgets, required artifacts, authority, and side-effect policy. | Subscription auth, broad repo discovery, secret values in payloads, merge/deploy/run-resolution authority, or any action beyond the task card. | `bb --config <plane> check`; inspect task policy and budget in `task list --json`; run `preflight`; inspect `status --json`, `dlq list --json`, and `notify list --json`. |55| Read-only inspection | MCP/CLI/API reads for status, config, runs, gates, dead letters, and artifacts. | Any `tools/call` mutation, dispatch, replay, resolve, park/unpark, submit, merge, or credential provisioning over MCP. | Prefer MCP tools when available; fall back to `bb ... --json`; use `bb_artifacts_list`/`bb_artifact_read` or `bb artifacts list/read` for evidence. |5657A closeout receipt is incomplete until it names the exact command/surface used,58run id or submission id, ledger state, cost/budget status, side effects,59artifact reads via MCP or `bb artifacts list/read`, and residual risk.6061## Rollout Scorecards6263Autonomous task families ship at less than full authority (read-only,64report-only, dry-run, PR-only) and climb an authority ladder only on evidence.65The single reusable scorecard template and promotion doctrine live in66[`docs/rollout-scorecards.md`](../../docs/rollout-scorecards.md).6768Refuse autonomy expansion from vibes. Do not recommend or take a higher69authority action (open a branch/PR, merge, deploy, resolve, unpark) for a task70family unless that level's scorecard is green *and* an operator has approved the71promotion. "It has been working" is not evidence; the scorecard is. Green72metrics only make the next-level ticket eligible for explicit operator approval;73they never flip authority by themselves. Merge, unpark, production mutation, and74broad rollout stay operator authority until a scorecard plus an operator75decision says otherwise.7677## Route7879| Need | Use |80|---|---|81| Validate config and see loaded agents/tasks | `bb --config <plane> check` |82| Decision-ready task/run/DLQ health | `bb --config <plane> status --json` |83| Task inventory, parked state, budgets | `bb --config <plane> task list --json` |84| Trigger manual work | `bb --config <plane> run <task> --payload '<json>' --json` |85| Dispatch a manual builder lane | `bb --config <plane> run build --payload '{"backlog":"<id-or-path>"}' --json` |86| Diagnose failed CI | `bb --config <plane> run ci-diagnose --payload '{"repo":"owner/repo","head_sha":"<sha>"}' --json` |87| Run a report-only lifecycle reflex | `bb --config <plane> run <reflex> --payload-file EVENT.json --json` where `<reflex>` is `fix-prompt`, `deploy-prod-verify`, `canary-triage`, `backlog-chewer-dry-run`, or `lifecycle-orchestrator` (each writes `REPORT.json`, no mutation; see `docs/rollout-scorecards.md`) |88| Compare candidate model configs | Run at least three candidate tasks, then `bb --config <plane> run model-eval --payload '<json>' --json` |89| Inspect ledger | `bb --config <plane> runs list --json`; `bb --config <plane> runs show <id> --json` |90| Export run telemetry | `bb --config <plane> runs export` (`bb.run_telemetry.v1` JSONL) |91| Inspect run artifacts | `bb --config <plane> artifacts list <run-id> --json` (top-level artifact files); `bb --config <plane> artifacts read <run-id> REPORT.json` (safe text/JSON read, including known nested relative paths; binary, oversized, and traversal paths refused) |92| Handle pre-execute failures | `bb --config <plane> dlq list --json`; `bb --config <plane> dlq replay <id> --json`; `bb --config <plane> dlq ack <id> --reason <text> --json` to close a superseded DLQ |93| Handle notification failures | `bb --config <plane> notify list --json`; `bb --config <plane> notify retry --json`; `bb --config <plane> notify ack <id> --reason <text> --json` |94| Provision scoped OpenRouter child keys | `bb --config <plane> keys mint <agent> --json`; `bb --config <plane> keys rotate <agent> --json`; `bb --config <plane> keys revoke <agent> --json`; `bb --config <plane> keys list --remote --json`; `bb --config <plane> keys sync --all --check --json` |95| Park or unpark workload dispatch | `bb --config <plane> task park|unpark <task>` |96| Classify inherited running rows after host restart | `bb --config <plane> recover` |97| Run webhook/cron plane | `bb --config <plane> serve` |98| Submission storm / review factory | `bb submit ...`, verdict `bb run <kind> ...`, then `bb gate --json` |99| Read-only inspection for agents over MCP | `bb --config <plane> mcp serve` (stdio JSON-RPC; `bb_status`, `bb_check`, `bb_tasks`, `bb_runs_list`, `bb_runs_show`, `bb_artifacts_list`, `bb_artifact_read`, `bb_dlq_list`, `bb_preflight`, `bb_gate`) |100101Detailed command recipes: `references/operator-recipes.md`. Authority-promotion102rules and per-task scorecards: [`docs/rollout-scorecards.md`](../../docs/rollout-scorecards.md).103104## Dispatch Rules105106- A `bb run` can have external side effects. Do not blindly re-run a successful107 or executing task.108- Secrets travel through declared env/secrets and stdin plumbing. Never put109 tokens in argv, task cards, or payload JSON unless the task contract explicitly110 says the value is non-secret.111- For GitHub-backed runs, prefer `GH_TOKEN=$(gh auth token) bb ...` over copying112 tokens into shell history.113- Reflex triggers must use API-auth agents. Subscription-auth agents belong to114 manual dispatch only.115- The checked-in `build` task is a manual API-auth OMP/GLM builder lane. Use116 it for shaped implementation work only; it creates/pushes a branch and report117 but does not merge or replace the submission gate.118- For uncertain model fit, run a cohort: at least three materially different119 candidate tasks for the same flow and payload, then the `model-eval` task.120 First-class cohorts for `build`, `review`, `gardener`, `ci-diagnose`, and121 submission-storm members are listed under122 [`docs/model-evals/`](../../docs/model-evals/README.md). Record accepted123 findings there before promoting a new default.124- A parked task is intentionally blocked. Inspect the reason before `unpark`.125- Dead letters are pre-execute failures. At/after execute, use operator126 resolution paths because the run may have side effects.127- Streaming harness usage is metered while the run is executing. If128 `max_cost_per_run_usd` is breached, the agent policy chooses `kill`,129 `quarantine`, or `log`; `kill` and `quarantine` must emit notification130 outbox rows such as `run_in_flight_cap_killed`.131132## Submission Storm133134Verdict tasks (`correctness`, `security`, `product`, `simplification`,135`arbiter`, `verify`) expect a submission payload. Do not call them with an136arbitrary repo/rev payload.137138Shape:139140```bash141bb --config <plane> submit open --change <change> --rev <rev> --json142bb --config <plane> run correctness --payload '{"submission":"<submission>"}' --json143bb --config <plane> gate --submission <submission> --json144```145146If a verdict task fails with `payload has no 'submission' field`, the plane is147correct; the invocation was wrong.148149If `bb gate --json` reports a canonical member as `run:failure`, read that150member's `safe_next_command`. Replays prove the failed pre-execute path can run,151but they do not count for the canonical gate key; the safe recovery is a clean152replacement submission after fixing the operator or infrastructure issue. The153command includes the loaded plane's `--config` path so an agent can run it from154another cwd.155156## Recovery157158- `bb recover` classifies inherited `running` rows after a host restart.159- `bb recover --json` exposes `probe_state`, `probe_reason`,160 `lease_disposition`, and `operator_action`; unknown probes retain the host161 lease.162- `bb runs resolve` is for `awaiting_recovery` after side-effect inspection.163- `bb status --json` marks `awaiting_recovery` older than one hour as164 `escalate_stale_recovery`, with age fields, but the operator still resolves165 the run only after inspecting side effects.166- `bb dlq replay --json` mints a new run linked to a pre-execute dead letter167 and returns the replayed run bundle.168- `bb dlq ack <id> --reason <text> --json` acknowledges a superseded169 pre-execute dead letter without replaying it, recording reason + timestamp.170 Acknowledged DLQs cannot be replayed; `bb status --json` no longer counts171 them as open operator work.172- `bb preflight <task> | --storm --json` checks missing declared secrets,173 missing policy-bound provider keys, and unspawnable `command`-harness174 binaries before dispatch creates run rows.175176## Serving177178`bb serve` exposes webhook ingress, cron scheduling, the HTML operator view, and179read APIs. Do not bind publicly without `BB_API_TOKEN`; the server refuses180non-loopback binds without it.181182Useful API mirrors:183184- `GET /api/tasks`185- `GET /api/status`186- `GET /api/runs`187- `GET /api/runs/<id>`188- `GET /api/dlq`189- `GET /api/notify`190- `GET /api/submissions`191192## MCP (read-only)193194`bb --config <plane> mcp serve` runs a read-only MCP stdio server: JSON-RPC1952.0 over stdin/stdout, no network listener, no external credentials for196local-plane inspection. Consume it MCP-first where a host agent supports it;197fall back to `bb ... --json` for anything the MCP tool table does not yet198cover. The registered read tools (`bb_status`, `bb_check`, `bb_tasks`,199`bb_runs_list`, `bb_runs_show`, `bb_artifacts_list`, `bb_artifact_read`,200`bb_dlq_list`, `bb_preflight`, `bb_gate`) return the same shapes as their201CLI/API counterparts — MCP is a typed adapter, not a second implementation.202203This slice ships read-only tools only. No mutating MCP tool exists; a204`tools/call` for an unknown or would-be mutating name is rejected with a205JSON-RPC `-32602` error. Do not expect `bb runs cancel`, `bb dlq replay`,206`bb run`, or submission/gate mutations over MCP until a separate207writable-MCP backlog lands its graduation signals.208209Routing:210211| Need | First choice | Fallback |212|---|---|---|213| Decision-ready plane health | MCP `bb_status` | `bb status --json` |214| Config/task inventory | MCP `bb_check`, MCP `bb_tasks` | `bb check --json`; `bb task list --json` |215| Runs | MCP `bb_runs_list`, MCP `bb_runs_show` | `bb runs list --json`; `bb runs show <id> --json` |216| Run artifacts | MCP `bb_artifacts_list`, MCP `bb_artifact_read` | `bb artifacts list <id> --json`; `bb artifacts read <id> <path> --json` |217| Dead letters | MCP `bb_dlq_list` | `bb dlq list --json` |218| Pre-dispatch readiness | MCP `bb_preflight` | `bb preflight <task> --json` |219| Submission gate evaluation | MCP `bb_gate` | `bb gate --change <key> --json` |220| Submission mutation | (not yet MCP) | `bb submit ... --json` |221222## Operator Dispatch Loop223224Use the ergonomic dispatch surface when the operator wants `bb` to own a225supervised lane instead of running a bare shell:226227```bash228bb --config <plane> dispatch --repo <path> --brief <file> [--model <slug>] [--label <text>]229bb --config <plane> logs -f <run-id>230```231232`dispatch` prints only the accepted run id and exits. It chooses the task from233`BB_DISPATCH_TASK`, then `dispatch`, then `build`, then a single manual task if234that is the only unambiguous option. The brief file is read at dispatch time and235persisted into the run payload as `bb.dispatch_job.v1` with `repo`, canonical236`prompt`, optional `model`, `label`, and `branch_slug`; the brief file path237itself is not persisted. `model`, when provided, overrides the selected task238agent's model for that run. It does not run synchronously; a running local or239deployed plane drains the pending run. `logs -f` follows ledger events plus240released text artifacts until the run reaches a terminal state.241242## Distribution243244The portable artifact is this whole folder: `skills/bitterblossom/`. Consumers245should copy or symlink the folder, not just `SKILL.md`, so references and agent246metadata travel with it.247248Harness Kit integration should keep one source of truth. Prefer a source entry,249bootstrap projection, or explicit symlink from Harness Kit to this folder over a250manual copied skill that can drift. The durable decision is251`docs/adr/006-skill-projection.md`.252253## Closeout Evidence254255When using Bitterblossom, report:256257- exact plane path and `bb` binary used;258- commands run and relevant run ids;259- ledger state, costs, parked/DLQ status, and external side effects;260- generated artifacts, inspected through `bb artifacts list/read` rather than local path spelunking, plus any API/CLI JSON read;261- residual risk, including failed probes that remain in the ledger.