Two portable agent-judgment skills in data/skills/boocode/, externalizing when/how Opus commits and when it isolates work in a worktree, so weaker agents (opencode build agent, BooCoder) can approximate it. committing-changes: segment by concern, stage explicitly (never git add -A), draft scope-prefix messages, present-and-STOP — commit only on explicit command, never push, identity indifferentketchup. using-worktrees: the when-to-isolate heuristic (just-create-when-clear / propose-when-ambiguous / skip), stable-base mechanics, runtime-isolation caveat — deliberately autonomous vs committing's command-gate. Each has an eval.yaml (matching improving-boocode-guidance) with a negative-trigger task. AGENTS.md gets a parser-safe preamble (the registry throws on bare ## headings) pointing at both skills. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.3 KiB
Commit message style
Freeform scope-prefix messages. The shape is conventional-commits-like — type(scope): summary is the dominant form in this repo — but it is not enforced: the scope and the why matter more than the type enum. Do not reject or rewrite a message just because it lacks a type, and do not add ceremony (BREAKING CHANGE: footers, rigid type whitelist).
The pattern
<scope-prefix>: <imperative summary>
<optional body: WHY this change, not what — the diff shows what>
- Scope prefix — the area(s) touched. A single area (
coder,web,server), a typed scope (fix(coder),feat(coder),docs(changelog)), a sub-scope (coder(providers)), or multiple areas joined (web+coder). Pick whatever names the blast radius honestly. - Imperative summary — "strip dcp tags", not "stripped" / "strips". One line, no trailing period needed.
- Body — only when the why isn't obvious from the summary. Explain the reason, the failure it fixes, or the constraint it satisfies. Cross-reference related tags/commits by name when the change builds on or fixes prior work.
- No emojis. Anywhere — summary, body, or trailers.
Real examples (from this repo's log)
fix(coder): strip dcp-message-id tags split across stream chunks
feat(coder): per-session SSE subscriptions (P1.5-a concurrency prereq)
feat(coder): guard session delete against worktree work loss
fix(coder): no-upstream branch alone no longer flags a session at-risk
docs(changelog): v2.6.2-delete-guard-and-sse
chore(coder): untrack live coder-providers.json, ship example
And the freeform multi-area / sub-scope forms the house style also allows:
web+coder: per-session SSE
coder(providers): fix empty picker
Why-not-just-what
A summary that restates the diff (fix: change variable name) wastes the message. A good message answers a question the diff can't: why did this need to change? Example — the bare summary fix(coder): no-upstream branch alone no longer flags a session at-risk is fine, but its body earns its keep:
Session worktree branches never get an upstream, so the original rule flagged every worktree-backed session as at-risk on delete — even pristine ones.
That sentence is the part a future reader (or git blame) actually needs.