Skip to content

Releases: escoffier-labs/brigade

v0.19.0

Choose a tag to compare

@solomonneas solomonneas released this 05 Jul 03:32

Added

  • Managed station tools now declare machine-readable surfaces: live doctor JSON, bounded markdown briefs, summary JSON, and verify commands where each tool supports them. brigade stations list --json includes those surfaces so profiles can show what a station can feed into automation before it is installed.
  • brigade add <path> can discover a local station.json manifest, report its install command and machine surfaces, and refuse to run manifest install commands unless --install is passed. Built-in station installation by station name still works as before.
  • brigade run now has a run-level brief budget. Code graph and upstream drift impact briefs are ranked by task type, clipped when needed, and recorded in run.json with attached brief names, sizes, and truncation flags.
  • brigade run can attach a fail-open upstream drift impact brief when a repo has a GraphTrail database and pending upstream-drift state. The brief combines drift report excerpts with graphtrail impact output so workers see likely blast radius before editing.
  • brigade memory care scan now validates evidence: frontmatter for receipt-like paths and MiseLedger evidence refs, reporting missing-evidence-ref issues and evidence reference counts.
  • brigade pantry expiry-alert reports near-expiry Agent Pantry sessions and plans an agent-notify message by default. It sends only when --send is passed.
  • brigade outcome rebuild-status, fork, and diff add a drift oracle for outcome receipts. Operators can rebuild status.json from records and compare alternate reconciliation configs without mutating live state.

Changed

  • The three largest modules are now packages: repos_cmd (6,417 lines -> 8 files), tools_cmd (6,079 -> 18), and phases_cmd (5,621 -> 7), each behind a facade that preserves the full external surface and monkeypatch semantics; no source file exceeds 2,000 lines. The mypy override list dropped from 45 entries to 21, and type-ratcheting surfaced and fixed four latent defects along the way (a friction-show crash on malformed JSON, a notifications tuple-shape crash, a fleet-health wrong-module read, and a research runner returning an object where callers expected text).
  • Agent Pantry health now prefers agentpantry doctor --json, uses the old status JSON as a compatibility fallback, and exposes the new inventory --markdown brief surface for near-expiry session summaries.

v0.18.0

Choose a tag to compare

@solomonneas solomonneas released this 03 Jul 12:40
b285839

Migration

Upgrading from 0.17.x, two breaking changes need one-time action:

  • Extras surface. If any script, cron, or habit runs release, center, repos, research, roadmap, friction, chat, context, projects, learn, runbook, dogfood, pantry, notifications, budgets, untrusted, either fragments group, or work phases, run brigade extras on once per machine before upgrading (or export BRIGADE_EXTRAS=1 in that environment). Disabled commands exit 2 with this guidance rather than failing silently.
  • Minimal repo installs. brigade init and operator quickstart at repo depth now write only AGENTS.md and SAFETY_RULES.md plus gitignored state. If your setup expects rules/, hooks/pre-push, INSTALL_FOR_AGENTS.md, or the default tool packs, pass --full (or add the repo-extras include). Existing repos are untouched by the upgrade itself; re-running quickstart on an existing repo only adds missing files and never overwrites.

Docs

  • README opening reframed: the one-liner now leads with the per-tool config and memory sprawl instead of abstract nouns, "What it does" defines a receipt as the file it is, and a sample verify-receipt ticket shows one. The receipts wording elsewhere in the opening was trimmed so the word appears where it is the feature, not as a refrain.

Added

  • brigade run artifacts now carry brigade-computed ground truth (issue #125): worker-results.json and synthesis.json include a ground_truth block with git diff --stat, the changed and untracked file lists, a changes.patch reference, and verify exit codes parsed from the actual .brigade/work/verify-runs receipts. The synthesis prompt gets a compact brigade-computed facts section, so the chef synthesizes against facts instead of worker narration.
  • brigade run now attaches a fail-open GraphTrail code-graph brief when .graphtrail/graphtrail.db exists. The read-only markdown context is prepended to orchestration and worker prompts, can be disabled with --no-code-graph, and records code_graph_brief metadata in run.json.

Changed

  • brigade work phases (the phase-execution ledger) moved behind the extras wall with the other operator-suite surface; it stubs out with enable guidance when extras are disabled.
  • The shared render.emit renderer now backs the mechanical output sites in tools_cmd, daily_cmd, center_cmd, and phases_cmd (110 sites converted, byte-identical output); sites with interleaved logic or stderr remain on direct prints.

Breaking

  • The CLI surface is now split into core and extras. 18 operator-suite command groups (release, center, repos, research, roadmap, friction, chat, context, projects, learn, runbook, dogfood, pantry, notifications, budgets, untrusted, openclaw-fragments, hermes-fragments) register only when extras are enabled. Enable once with brigade extras on, per invocation with BRIGADE_EXTRAS=1, and check with brigade extras status. A disabled extras command exits 2 with that guidance instead of a parse error. The 24 core groups (init, mcp, tools, skills, handoff, ingest, memory, work, outcome, operator, run, roster, runs, daily, security, scrub, doctor, status, add, stations, profiles, reconfigure, completions, extras) are unchanged.
  • Repo-depth installs default to a minimal footprint: AGENTS.md and SAFETY_RULES.md plus gitignored .brigade/ state and the selected harness inboxes and skills. The full kit (rules/, the inactive hooks/pre-push, INSTALL_FOR_AGENTS.md, and the four default tool packs projected into tools/ and scripts/) moved behind --full on brigade init and operator quickstart, or the repo-extras include. Workspace-depth installs are unchanged and always get the full kitchen.

Fixed

  • doctor's memory-card budget check now honors .brigade/memory-care.toml (max_card_bytes and exclude_paths), matching brigade memory care. It previously used a hardcoded 8000-byte limit and scanned excluded directories (e.g. archive/, decay/), so the two subsystems disagreed. The default card budget is now 12000 (single-sourced in budgets.MEMORY_CARD_BUDGET_BYTES), reconciling the prior 8000-vs-12000 default mismatch.
  • brigade run --worktree could write a corrupt changes.patch: trailing-whitespace trimming dropped a diff's final blank context line, and git apply rejected the file (issue #124). Patches are now written byte-faithful, validated with git apply --check --reverse before the run is declared done, and a failed validation keeps the worktree as the recoverable copy and exits nonzero.
  • Repo-depth installs no longer point agents at files that do not exist: the generated AGENTS.md, CLAUDE.md, and INSTALL_FOR_AGENTS.md referenced SOUL.md, USER.md, MEMORY.md, and memory/cards/, none of which a repo-depth install creates. Repo depth now gets repo-scoped variants; manifest file entries accept an optional depth key for per-depth template selection.
  • brigade mcp sync no longer grows a .vscode/ directory unasked. VS Code is included only when the repo already has .vscode/; the skip is reported in the plan notes and --harness vscode still forces it.
  • An empty tool catalog (.brigade/tools.toml with no [[tool]] entries) is now valid, and default tools that were never projected no longer block operator doctor readiness. Once tracked sources exist under tools/, a missing projection blocks again as drift.

Added

  • brigade operator quickstart --dry-run prints the file-by-file plan the README always promised: each planned step lists its dir and file writes, including the operator-init artifacts and the MCP catalog path.
  • brigade extras on|off|status manages the extras surface via a user-level marker under $XDG_CONFIG_HOME/brigade/extras.

Documentation

  • README: the sample doctor output now matches a fresh install (content-guard reported missing until brigade add guard), and the no-background-process claim names its one scoped exception (brigade tools runtime start).

v0.17.0

Choose a tag to compare

@solomonneas solomonneas released this 01 Jul 20:20
e7f145b

Added

  • Per-adapter model pinning: agents.<name>.model now pins a model on grok, opencode, pi, kimi, cursor, and antigravity, in addition to claude and codex. A registry places each adapter's model flag where that CLI expects it, so model = "grok-composer-2.5-fast" on a grok agent runs Grok Composer under a Brigade run. brigade roster doctor validates every pin and fails before dispatch when an adapter can't pin a model or when an ollama: ref carries a stray model =. Ollama cloud models run through the existing ollama:<model> ref, e.g. ollama:qwen3-coder-next:cloud.

Fixed

  • The grok, amp, and crush writer adapters invoked a --prompt flag that none of those CLIs accept, so every run through them failed at argument parsing. They now use each CLI's real one-shot form: grok -p, amp -x, and crush run.
  • brigade roster doctor no longer crashes on endpoint-mode agents (endpoint + model, no cli); it reports the endpoint and skips the CLI model-pin check.

v0.16.0

Choose a tag to compare

@solomonneas solomonneas released this 30 Jun 14:08

Added

  • Built-in station profiles with brigade profiles list/show and brigade stations list, so new installs can see the default repo, workspace, and fleet station bundles before adding sidecars.
  • A default skills station that wires brigade-work and ultra-work-scout into selected harnesses during brigade init. ultra-work-scout gives agents a broad Scout workflow for large or ambiguous work, and brigade add skills now points users at the optional Skillet roster instead of pretending Skillet is a local binary.

Changed

  • The token sidecar is now Token Glace throughout live templates, managed-tool wiring, docs, and tests. brigade add tokens installs and doctors token-glace.
  • The default repo profile now selects the core sidecar set for memory, guard, security, tokens, evidence, search, and skills while leaving host-global or heavier stations such as MCP, pantry, and notifications opt-in.

v0.15.0

Choose a tag to compare

@solomonneas solomonneas released this 29 Jun 21:06

The verified-learning loop can no longer silently mislead. An onboarding audit
adversarially traced the loop end to end and found several ways it reported
success while doing nothing, or quietly poisoned its own ranking. This release
closes them and makes the loop's own health visible.

Fixed

  • outcome reconcile --apply no longer marks a skill promoted when the physical install fails. The forward-only ratchet never re-emits install for a promoted artifact, so a false promotion was permanent and invisible; a failed install now keeps the skill a candidate (with cooldown) so a later skills inbox accept + reconcile retries. --apply output surfaces the execution result so it is never byte-identical to a dry-run that did nothing, and a skill missing from the registry reports install-skipped: not in registry. Cards (status-only promotion) are unaffected.
  • A verify command rejected by Brigade's own parser (shell metacharacters, a high-risk executable, an unresolvable binary) is recorded with status rejected, not failed. Invalid input is neutral (0) to outcome capture, never a verified regression (-1). The overall receipt is failed only when a command actually ran and failed or timed out.
  • outcome no longer collapses distinct manual signals. A record written without --evidence cannot be proven a duplicate, so it counts as its own signal instead of merging into one, and manual friction/learnings producers can reach the install threshold. Records that carry an evidence_ref still dedup as before.

Added

  • brigade work verify run --capture <id> [--capture-kind skill|card] captures the run's outcome in the same command, so the loop closes without a separate manual outcome capture step.
  • brigade work brief reports outcome_loop health: verify-run, record, scored, and promoted counts, plus a warning when verify runs exist but the ledger is empty (loop half-fed) or neither exists (loop dormant).
  • outcome capture warns when the artifact id is not a known installed skill or memory card, naming what is available, so a hallucinated id stops silently poisoning the ranking (the record is still written).
  • .brigade/work/verify-runs/ is capped (newest 50 retained) so receipts and raw command logs no longer grow without bound.

Changed

  • The brigade-work skill, README, and QUICKSTART teach the daily loop directly: capture against an id you actually have (a real skill, a memory card, or brigade-work itself), the one-step --capture form, and the registry-accept prerequisite for autonomous promotion.

v0.14.1

Choose a tag to compare

@solomonneas solomonneas released this 29 Jun 21:06

Changed

  • brigade init is now additive on an existing target instead of aborting: it keeps existing files (never clobbers without --force), writes only the missing ones, and always wires the brigade-work skill into the harness skill dirs. This fixes the upgrade/brownfield gap found in onboarding smoke tests, where a repo that already had AGENTS.md/CLAUDE.md (every previously-onboarded repo, and most real projects) got nothing wired because init refused to overwrite and exited. Re-running init after upgrading now wires the work loop without losing local edits; --force still overwrites to refresh the bootstrap directives.

v0.14.0

Choose a tag to compare

@solomonneas solomonneas released this 29 Jun 21:06

Added

  • brigade init and operator quickstart now wire the new brigade-work skill into each selected harness's skills directory by default (--no-wire to opt out) and print agent-facing onboarding, so a fresh install is actually used by the agent's work loop instead of sitting dormant. The skill teaches the loop: brigade work brief at the start, verify THROUGH brigade work verify run (not raw), brigade outcome capture <skill-or-card-id> --run-id latest after each verify, and a handoff at the end. Mandatory "Daily Work Loop" directives were added to the AGENTS.md and CLAUDE.md templates (replacing the conditional internal-dogfood block, keeping AGENTS.md under the bootstrap budget), plus a "use it, don't just sit next to it" section in INSTALL_FOR_AGENTS.md.

Changed

  • README now leads the quickstart with a recorded, clean-machine demo (docs/assets/quickstart.svg, reproducible from docs/assets/quickstart.cast) and adds real operator doctor readiness output plus a real brigade mcp sync dry-run diff, so the headline claims are shown working, not just described.

v0.13.0

Choose a tag to compare

@solomonneas solomonneas released this 24 Jun 03:56

Added

  • brigade mcp syncs one canonical MCP server catalog (.brigade/mcp.json) into each tool's native MCP config file. init/add/list build the catalog; plan previews; sync (dry-run unless --write) merges into Claude (.mcp.json), Cursor (.cursor/mcp.json), Codex (.codex/config.toml), VS Code (.vscode/mcp.json, with inputs), OpenCode (opencode.json), and Antigravity (~/.gemini/config/mcp_config.json, user-scoped via --user-scope); doctor validates; import reads an existing tool's config back into the catalog. The merge is by server key with ownership tracked in the gitignored .brigade/mcp/state.json: servers the user added are preserved, a server edited outside Brigade is a conflict (skipped unless --force), orphans are removed only with --prune and only when still pristine, and env values are always written as ${VAR} references (or VS Code ${input:VAR}), never inlined secrets. brigade operator sync-mcp wraps it with a validate->sync->summary receipt. New mcp station (alias brigadier).
  • brigade mcp user-global adapters codex-user (~/.codex/config.toml), claude-user (~/.claude.json), and openclaw (~/.openclaw/openclaw.json), so a machine's daily tools can be synced alongside repo-local configs. brigade mcp import --keep-secrets keeps literal env secrets verbatim instead of demoting them to ${VAR} references, for unioning existing working configs whose tools do not expand ${VAR}.
  • brigade outcome verified-autonomous learning loop (capture/record/score/explain/reconcile/rank): a learned skill is promoted only when a model-unauthored signal (verify exit codes, friction/learnings deltas) confirms it helped, Wilson-scored so thin evidence never out-ranks vetted skills. reconcile is dry-run by default; with --apply it installs across harnesses or rolls back on a measured regression. The durable ledger is git-tracked under memory/outcome/, readable without Brigade.
  • brigade context packs now carry a code_graph section from GraphTrail's read-only graphtrail context (entry points, related files, caller/callee counts for the selected task). The binary resolves via $GRAPHTRAIL_BIN, PATH, then ~/.cargo/bin, and the section is skipped gracefully when the binary, the repo's .graphtrail db, or a task is absent.
  • brigade operator quickstart now scaffolds the MCP on-ramp: it creates the canonical .brigade/mcp.json, previews the projection with a read-only mcp plan, and surfaces brigade mcp init / sync --write in the printed next steps. It never writes harness MCP configs automatically and respects --dry-run.

Changed

  • The "Brigade does not write runtime MCP configs / auto-sync harness configs" statements in the tool catalog and technical guide are reworded: runtime MCP server config sync is now an explicit, bounded capability provided by brigade mcp (dry-run by default, merge-by-key, never inlines secrets, never automatic). The tool-catalog mcp family projection remains a documentation stub.
  • The Hermes adapter is graduated from experimental to validated (verified against a real Hermes v0.17 install): the handoff contract and reviewed skill install both work, and the "experimental" framing is dropped across the harness picker, doctor, install/fragment notices, templates, README, and QUICKSTART.

Fixed

  • MCP sync is now idempotent for remote (http/sse) servers on Codex (_codex_render_table renders the type/transport, so a re-sync no longer falsely reports a conflict). Dotted/quoted server names (e.g. io.github.example) round-trip without duplicating into invalid TOML, and the Python 3.10 toml_compat fallback reader now parses quoted dotted table keys. Authorization headers for remote servers are emitted and parsed for codex, vscode, opencode, and openclaw (previously dropped), kept as ${VAR} references.
  • brigade outcome no longer double-counts a re-captured or retried verify run: scoring counts distinct verified evidence keyed on (source, evidence_ref, task_id), so an identical receipt cannot cross the auto-install threshold on its own.
  • brigade runbook run honors only an operator-supplied --approved; a file-embedded approved: true no longer authorizes shell execution. Commands are validated whole (not just the first token), inline-script shell wrappers that negate the allowlist are rejected with a warning, and SECURITY.md documents that runbook steps are arbitrary shell, as trustworthy as the file author.
  • Hermes skill installs now reach the real Hermes store ($HERMES_HOME/skills/brigade-imports/<id>) with rendered frontmatter, gated on the Hermes home existing, so reviewed skills appear in hermes skills list instead of an unread repo-local path.

v0.12.0

Choose a tag to compare

@solomonneas solomonneas released this 16 Jun 20:38
88c0fe8

[0.12.0] - 2026-06-16

Added

  • brigade doctor --json and brigade status --json emit machine-readable output (target, harnesses, owner, depth, per-check status/name/detail, summary counts, and a ready flag), so the two most diagnostic surfaces can feed scripts and a future fleet aggregation instead of being text-only.
  • brigade security diff --base <dir> --against <dir> [--json] compares two security reports and reports new, resolved, and persisting findings (matched by the scan's stable per-finding fingerprint). It returns nonzero when there are new findings, so a change that introduces a finding can be caught in review or CI.
  • brigade operator checkup [--json] runs every read-only first-run doctor (doctor, operator doctor, handoff doctor, tools doctor, skills doctor, security doctor) in one pass and rolls them up to a single ready / blocking_surfaces verdict with the next command to run, so a new operator no longer has to copy-paste each doctor from the first-10-minutes guide.
  • brigade doctor now lints AGENTS.md quality: it warns (never fails) when the file lacks a "Definition of Done" section or a memory-handoff section, since agents work better with explicit done criteria and a handoff footer. The Brigade-seeded AGENTS.md now ships a Definition of Done section (issue #84).
  • brigade run --read-only now warns when an assigned agent cannot hard-enforce read-only. Each adapter is classified hard (native sandbox or tool allowlist), soft (prompt-only), or none; soft and none agents are listed on stderr and recorded in a read-only-enforcement.json run receipt, and a writable --sandbox override downgrades even natively-sandboxed CLIs to best-effort (issue #87).
  • brigade repos doctor --deep runs the operator checkup (every first-run doctor) in each enabled fleet repo and aggregates a fleet-wide ready / blocking_repo_count verdict, so you can health-check many repos in one pass instead of cd-ing into each (issue #78).
  • brigade completions bash|zsh|fish prints a static shell completion script generated from the CLI's own command tree (zero runtime dependencies; the tree is embedded, not shelled out). bash completes the full command tree, zsh reuses it via bashcompinit, and fish completes the top level plus one subcommand level (issue #89).
  • brigade memory search <query> [--json] runs a deterministic keyword search over memory cards, ranking title, tag, and summary matches above body matches (the stdlib precursor to the roadmapped on-device semantic retrieval) (issue #90).
  • brigade memory serve-mcp --stdio exposes memory cards over a read-only MCP stdio server under a card:// scheme (resources plus list_cards / get_card / search_cards tools), reusing the proven skills MCP pattern; reads are scoped to the configured card roots and it never edits canonical memory (issue #88).
  • brigade projects doctor adds the station doctor that every peer station already has, reporting project-consolidation health and exiting nonzero on issues (issue #90).
  • brigade skills uninstall <skill> --target <harness|all> removes an installed skill (the inverse of skills install), records an uninstall receipt in the install history, and refuses cleanly when nothing is installed (issue #90).
  • brigade friction show [--severity] [--json] reads back the latest friction scan, which previously could only be written (issue #90).

Changed

  • Internal: the skills and memory MCP stdio servers now share one harness (mcp_server.serve_stdio) instead of carrying near-identical JSON-RPC loops. No command surface or protocol change; a new read-only MCP surface is now a few callbacks.
  • The repo fleet scan now summarizes repos on a small thread pool instead of serially. Each summary is independent and IO-bound (git calls plus file stats), so a multi-repo fleet scans noticeably faster while output stays in config order; a single-repo fleet is unchanged.
  • brigade doctor now groups host-global findings (OpenClaw config, the content-guard clone, uninstalled managed tools) under a "machine-level (not specific to this repo)" header in text output and tags each check with a scope of repo or machine in --json, so a single-repo run no longer reads as if the repo is responsible for machine-wide state (issue #80).
  • brigade security suppress and brigade security unsuppress gain --json, so an agent or CI step can parse the suppression result (issue #90).
  • brigade scrub gains --json and now writes a summary-only .brigade/scrub/latest.json receipt (verdict, policy, exit code, never the matched snippets), with --no-receipt to opt out, giving the egress gate the audit trail every other station already has (issue #90).
  • brigade runbook closeout --import-issues [--dry-run] routes each failed step of a runbook run into the work import inbox (deduped by run id and step), so a mid-run failure reaches the same review queue every other station's failures land in (issue #90).
  • brigade init --git-exclude writes Brigade's ignore block to the local-only .git/info/exclude instead of the tracked .gitignore, for third-party clones you do not want to commit Brigade ignores into (issue #81). Automatic detection of a third-party clone is intentionally deferred: there is no reliable repo-owner signal, and a guess would false-positive on your own published repos.

Fixed

  • brigade init --no-gitignore is now honored. The flag was parsed but never forwarded to the installer, so a .gitignore was written anyway; install_selection now takes update_gitignore and skips the write when asked.
  • brigade init --git-exclude now resolves a linked-worktree .git file (gitdir: <path>) to write the exclude under the worktree's own git dir, instead of silently falling back to a tracked .gitignore.
  • The seeded pre-push content-guard hook no longer reports a scanner error as a content leak. It now discriminates content-guard's exit codes: exit 1 (findings) blocks with the leak message, any other nonzero exit is reported as "scanner failed to run" rather than mislabeled as violations (issue #82).
  • brigade doctor memory-care freshness no longer reports a same-day scan as "in the future". The scanner stamps scan_date in UTC, but doctor compared it against the host's local date, so an evening run in a behind-UTC timezone warned falsely (issue #83). Doctor now compares in UTC.
  • brigade init --depth workspace now creates .brigade/memory-care/decay, the directory doctor actually checks, instead of the legacy memory/cards/decay. A fresh workspace no longer draws a "staleness scanner not wired" warning on first contact (issue #79).
  • localio.write_json now writes receipts atomically (temp file plus os.replace), so a reader or a crashed writer never observes a half-written JSON receipt; on failure the original file is left intact and the temp file is removed.
  • Apply the v0.11.0 subprocess hang-guard (closed stdin plus a timeout) to the remaining direct subprocess.run sites that lacked it: localio.check_git_ignored, the work-family _git helper, and scrub's git probes. A stuck git call now fails fast instead of hanging the command.
  • brigade scrub fails closed when the content-guard scan times out: a hung scanner is reported as blocked (exit 124) instead of being able to let content past the egress gate.

v0.11.0

Choose a tag to compare

@solomonneas solomonneas released this 13 Jun 01:16

Added

  • brigade run now guards dirty git worktrees by default, supports --allow-dirty, prevents concurrent runs with a local lock, and can run agents in a detached --worktree while capturing the resulting changes.patch.
  • brigade run plans can stage worker assignments so dependent workers receive earlier-stage results while same-stage workers still run in parallel.
  • Roster agents can pin a model with model = "..." for the claude and codex adapters (claude --model, codex exec -m), so one roster can split an architect model from builder models; pins are recorded in run artifacts.
  • Rosters can set limits.sandbox (read-only, workspace-write, or danger-full-access) as the default native Codex sandbox for brigade run, and runs without a repo roster now fall back to Path.home()/.brigade/roster.toml.
  • brigade run --sandbox to override the native Codex sandbox mode while keeping --read-only available for prompt-level review rules.
  • brigade friction: mine workflow friction from notes and session artifacts into a reviewable report.
  • Three new writer harnesses: Grok CLI (grok), Amp (amp), and Crush (crush), each with its own .{harness}/memory-handoffs inbox, tool projections, skills adapter, and agent argv, bringing the writer-harness total to eighteen.

Fixed

  • Agent subprocesses now run with stdin closed, so codex exec no longer hangs until the roster timeout when brigade itself runs with a piped, never-closing stdin (background launchers, CI wrappers).
  • brigade research sources no longer misreports route status when a configured source adapter is missing its type: the malformed entry previously shifted every following source's executable check onto the wrong adapter.

Changed

  • Split the work_cmd test suite into per-area modules while preserving facade patch coverage.
  • Internal restructuring with no command surface changes: operator_cmd and work_cmd/services split into focused modules, the CLI moved to per-command dispatch modules, and shared git-ignore/TOML/datetime helpers moved to neutral homes. The lint gate now includes ruff bugbear (B).

Documentation

  • README opens with a "Try it in 60 seconds" block (install, wire one repo, verify) above the project story, so a first-time visitor reaches a runnable command without scrolling.
  • Added .github/PULL_REQUEST_TEMPLATE.md covering the contributor checklist already documented in CONTRIBUTING.md: tests, changelog discipline, the content-guard PII gate, zero-runtime-deps, and conventional commits.