Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dev-workflow",
"version": "0.47.0",
"version": "0.48.0",
"description": "Nine skills for research, brainstorm, plan, review-plan, execute, review, compound, handoff, and propose — with triage, convention compliance, and knowledge compounding",
"author": {
"name": "Bruno Azevedo"
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,6 @@ Claude Code plugin providing brainstorm and plan skills with triage, convention
`ba-review` is on the stack-base axis but **not** the U-ID axis; `ba-review-plan` and `ba-plan` are on the U-ID axis but grammar-only for stack-base (they reference neither `<base>` nor a based `derive-state` call). `references/plan-sections.md` is the one non-skill file on either axis.
- **Reviewer model selection spans three mirror axes — two CI-pinned, one not.** (1) **Agent frontmatter `model:`** — all eight `agents/*-reviewer.md`; `security-reviewer` is `inherit` (follows the session model, the stakes carve-out), every other reviewer is `sonnet`. Pinned byte-for-byte by the `agent-model-pin` check in `scripts/check-invariants.mjs`, which owns the expected-value map; zero reviewer files reads UNKNOWN, not PASS. Do not hand-walk these files — the check is the inventory. This axis exists because the drift already shipped once: `comment-quality-reviewer` went out at `sonnet` while its own plan specified `inherit`, and nothing read agent frontmatter to notice. (2) **The `model:<value>` token grammar** — stated twice, once in each review skill's argument-parsing block, and the dispatch resolution rule twice more, in each skill's `## Dispatch instructions — apply to ALL templates`. The two conditional ledger lines under each roster's selection header are a third such copy. All three pairs are pinned by the `token-grammar-mirror` check, which compares the anchor-delimited spans byte-for-byte and is deliberately **not** whitespace-normalised. Inside the pinned span: the accepted spellings, the no-whitespace-tolerance-after-the-colon rule, matched-quote stripping, last-wins-with-a-bare-token-dropped, argument-string-only scanning, the exemption predicate, the four-branch resolution table, and the retry rule. Deliberately **outside** it, and therefore per-skill: the scan-ordering sentence (`--persist` vs `--auto`), the never-scan sentence (`/ba-review` says "never the captured diff", `/ba-review-plan` says "never the plan body"), `/ba-review`'s discovered-external sentence, and `/ba-review-plan`'s `[AUTO-SCORE: …]` sentinel clause. This duplication deliberately overrides the shareability convention's "two consumers → repo root `references/`": both copies sit on the always-executed parse path, where a reference file would buy de-duplication at the cost of a Read on every invocation. (3) **The exemption list** — the `dev-workflow:security-reviewer` literal in each skill's Model resolution entry is the *only* thing that exempts a reviewer from the override. The annotation on its roster row and ledger line is **descriptive**; annotating a second reviewer's row exempts nothing. **Unpinned**, and it stays that way: the list's contents are a judgment call CI cannot own. Do **not** extend the U-ID / stack-base grid with these — that grid is a grid because those two axes overlap on three files, which is not the case here. **Marginal cost of a ninth reviewer:** one frontmatter `model:` line plus one entry in the check's expected-value map, both CI-pinned. Only if it must be exempt, add: **three** `dev-workflow:security-reviewer`-shaped literals per skill — the exemption sentence, the Adjust → Other clause, and the resolution-table row — which sit inside the pinned span, so CI catches an *asymmetric* edit but never a *missed* one; plus **two** descriptive annotation lines per skill, the roster row and the ledger example line, which nothing checks. Count the literals with `grep`; do not trust a remembered number.
- Update README.md whenever skills, agents, or artifact paths are added or changed
- Git workflow skills (`ba-propose`) commit, push, and open PR/MR — they never modify source files outside the staged diff. The sole exception is the user-accepted `/ba-compound` **hand-off exception**: after the PR/MR is open, an accepted Step 5f capture offer hands off to `/ba-compound`, which writes only to `docs/solutions/` — after the push, never as part of the pushed diff (this convention line and `skills/ba-propose/SKILL.md` Guidelines are the two authoritative mirror sites; `README.md`'s `/ba-propose` feature list carries a user-facing summary of the same behavior — keep all three in sync)
- Git workflow skills (`ba-propose`) commit, push, and open PR/MR — they never modify source files outside the staged diff. **Two exceptions, both after the PR/MR is open and neither in the pushed diff.** (1) The user-accepted `/ba-compound` **hand-off exception**: an accepted Step 5f capture offer hands off to `/ba-compound`, which writes only to `docs/solutions/`. (2) The **second outward effect**: Step 5e posts one append-only comment to the **origin ticket** via the `record-ship` operation owned by `## Ship-Time Ticket Write-Back` in `skills/ba-propose/SKILL.md`. It writes no file at all, but it publishes outside this repository and is irreversible, so it is a scope exception in the same sense — it fires only on a run that *creates* the PR/MR, never on an edit-only run, and its disposition is always printed on the receipt. (This convention line and `skills/ba-propose/SKILL.md` Guidelines are the two authoritative mirror sites; `README.md`'s `/ba-propose` feature list carries a user-facing summary of the same behavior — keep all three in sync)
- This repo's product is prompt text, so a rule added to a skill, agent, or reference file is a runtime change. Before adding one, decide which kind it is: a **machine-boundary contract** (a sentinel, parser grammar, anchor format, ordering or path invariant — anything two processes must agree on) is specified to the character; **steering for the model's own judgment** states the goal and stops. Only the first earns literal specification. Prompt changes are decided by fixture A/B, not by argument — there is no automated suite, and a session cannot dry-run the body it loaded at start. Full convention, including the review checklist for prompt-touching diffs: `.claude/agent_docs/prompt-authoring.md` — read it when a diff touches `skills/`, `agents/`, or `references/`
- The roadmap lives in **GitHub issues**, hubbed by **#29** (`[meta] dev-workflow roadmap` — the "where do I start" map, not the raw issue list). Items use `[roadmap]`-prefixed titles, `cluster:*` lanes, `ready`/`deferred`/`declined`/`needs-brainstorm` states, and a documented revisit trigger for deferred/declined. Research/comparison docs are linked from issues as evidence — never spun into a competing roadmap doc (converge in issues). Full convention: `.claude/agent_docs/roadmap-management.md`
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ Implements an approved plan systematically: code changes, targeted testing, prog
- **Three plan detail levels** — MINIMAL (per unit), STANDARD (per unit), COMPREHENSIVE (per phase with automated checkpoints)
- **Targeted tests per task** — runs tests related to changed files, not the full suite; defers full suite + lint to completion or CI
- **Resume across sessions via git** — U-ID commit subjects + per-unit `Verify:` against code; no plan-file mutations
- **Deviation handling** — reports in Expected/Found/Why format, asks before proceeding; deviations surface in the MR/PR body and Linear ticket via `Deviation (U<n>):` commit trailers rolled up by `/ba-propose`, never the plan file
- **Deviation handling** — reports in Expected/Found/Why format, asks before proceeding; deviations surface in the MR/PR body via `Deviation (U<n>):` commit trailers rolled up by `/ba-propose` — and, when that run opens the PR/MR, in a comment on the origin ticket — never the plan file
- **VCS-agnostic completion** — detects GitHub/GitLab from git remote; discovers available MR/PR tools in the environment

### `/ba-review [ref range]`
Expand All @@ -167,6 +167,7 @@ Documents solved problems into `docs/solutions/` so the `learnings-researcher` a

- **5 parallel subagents** — Context Analyzer, Solution Extractor, Related-Docs Finder, Prevention Strategist, Category Classifier
- **Frictionless manual / model-proactive** — a deliberate run proceeds directly once a problem/solution pair is identifiable (no confirmation gate); best invoked right after solving a non-trivial, verified problem
- **Ship-time ticket write-back** — after the PR/MR is open (and only on a run that opens it), one append-only comment goes to the origin ticket carrying the shipped PR URL and the deviation-trailer texts, so the ticket the team actually reads learns what the flow discovered. Routed by ref shape: a Linear key over an issue-comment MCP tool, a GitHub issue over `gh issue comment` with an explicit `-R`. It fires at **every** size tier including typo — the one tier where the deviation text reaches no other reader. Interpolated trailer prose is escaped before it is wrapped, so it cannot autolink an unrelated issue, mention a person, or pair a closing keyword with a ref. The receipt's fourth line names the outcome over a closed six-literal set — `posted` with the ticket it went to, `skipped` for no usable ref or no reachable writer, `failed` for a rejected, timed-out or unconfirmable write, or `unavailable` — and the write is never retried: `/ba-propose` writes outside the staged diff here, and a double-post is permanent. The Step 4 preview names the target **and** the sanitized payload before anything is written
- **Ship-time capture offer** — after a successful create, `/ba-propose` may offer to run `/ba-compound` when the change looks like it carried a reusable learning; either way the ship's terminal receipt names the capture disposition on its own line (see the `/ba-propose` entry)
- **Explicit invocation** — `/ba-compound` or `/ba-compound [context hint]` for immediate documentation
- **Structured output** — YAML frontmatter with `category`, `tags`, `module`, and `symptom` for maximum discoverability by `learnings-researcher`
Expand All @@ -193,22 +194,22 @@ Documents solved problems into `docs/solutions/` so the `learnings-researcher` a

Commit, push, and open a PR/MR with a composed title and body.

- Pure-function body composition: orchestrator gathers inputs (diff, branch, Linear, docs/solutions, preserved blocks, proof, risk, focus areas) → composition reads value objects and returns title + body
- Pure-function body composition: orchestrator gathers inputs (diff, branch, issue context from either tracker, docs/solutions, preserved blocks, proof, risk, focus areas) → composition reads value objects and returns title + body
- Host-detected dispatch: GitHub `gh`, GitLab `glab`, graceful fallback for unknown hosts (compose + push only)
- Body composition selects from Michael Lynch's 16-section menu, sized to the diff — the size-tier vocabulary is hidden behind the composition seam (no flag, no preview surface)
- **U-ID preservation** — never strips or rewrites `/ba-execute`'s U-tagged commit subjects (`U<n>` per the convention in `execute.md`); PR/MR title is U-ID-free by design
- **Proof** — always-on one-line signal, auto-detected from the diff (test file touched, visual evidence preserved from the PR body, docs-only, or pending); no blocking question
- **Risk lead-line** — an always-on, un-headed `**Risk:** low/medium/high — <reason>` line at the top of the body, deterministically derived from sensitive paths, size, and breaking-change signals; absent at typo tier
- **Where to look** — an earned `## Where to look` section naming 1–2 hotspot areas on medium+ diffs, omitted when there's no dominant hotspot
- **Deviation fold** — scans `DIFF_BASE..HEAD` commit bodies for `Deviation (U<n>):` trailers and folds genuinely reviewer-relevant substance into the Impact prose (no standalone header, no `U<n>` shown); the commit trailer and Linear ticket rollup (when linked) are unchanged; warns on near-matches at preview
- **Deviation fold** — scans `DIFF_BASE..HEAD` commit bodies for `Deviation (U<n>):` trailers and folds genuinely reviewer-relevant substance into the Impact prose (no standalone header, no `U<n>` shown); the commit trailer is unchanged, and the origin ticket comment carries the same texts when a usable ref resolved and a writer was reachable; warns on near-matches at preview
- **Stacked-branch aware** — on a stacked branch (a feature branch built on another unmerged feature branch), `DIFF_BASE` and the MR/PR target come from `resolve-stack-base`, so the MR targets the parent branch and shows only this plan's commits; `--base`/`--target` override the resolution. `/ba-execute` and `/ba-handoff` resume correctly on stacked branches too — the parent plan's commits fall outside the resume window, so their U-IDs no longer swallow the current plan's units
- Linear MCP optional with diff-derived fallback; clear preview warning when MCP is unavailable
- **Two-tracker issue context** — a Linear key (`TO-1234`) reads over MCP, a GitHub issue (`#123`, or a bare number via `--issue`) reads over `gh issue view`, which doubles as the confirmation that the number names an issue and not a pull request. Either read is optional: a failure keeps the ref, falls back to diff-derived motivation, and warns at preview. A numeric ref is never guessed from a branch name
- `docs/solutions/` auto-detection on current-branch-touched entries; per-entry confirm to splice as "What I learned"
- Cursor BugBot block and existing `## Demo` / `## Screenshots` preserved byte-identical
- Commit message and PR/MR body share the same composed markdown — no separate render path
- `--body-file` discipline (temp file + quoted-sentinel heredoc); no `git add -A`/`.`; no `--no-verify`; `--force-with-lease` only
- **Apply-by-default** — every `ACTION` applies without a confirmation prompt by default; pass `--review` (alias `--interactive`) or set `BA_PROPOSE_REVIEW=1` to restore the Apply / edit / regenerate-with-hint / exit menu and the Step 0b edit-only confirm
- **Ship-time capture offer** — after a successful create (and only then), a best-effort read-only assessment may offer to run `/ba-compound` on the just-shipped learning; the terminal receipt names the capture disposition on its own line (line 3, or line 2 when the ship URL is unresolved) on every route that reaches it — offered, or suppressed as routine, uncertain, already-captured, non-interactive, or URL-unresolved, or reported `unavailable` when the assessment itself failed — while edit/describe-only/unknown-host paths print no receipt at all
- **Ship-time capture offer** — after a successful create (and only then), a best-effort read-only assessment may offer to run `/ba-compound` on the just-shipped learning; the terminal receipt names the capture disposition on its own line (line 3, or line 2 when the ship URL is unresolved — the receipt is four lines, three on that guard) on every route that reaches it — offered, or suppressed as routine, uncertain, already-captured, non-interactive, or URL-unresolved, or reported `unavailable` when the assessment itself failed — while edit/describe-only/unknown-host paths print no receipt at all

### `/ba-handoff [focus]`

Expand Down
Loading