claude/agents/hotfixer.md
Bastien Chanot 1b01b952d5 feat(agents): wire doc-commit into feat/bugfix/hotfix DOC SYNC steps
Scope expansion surfaced by the Task 6 sweep (not in the original frozen plan). The 3 inline flows each ran doc-syncer at their DOC SYNC step but committed nothing — their CAPITALIZE step commits only memory (capitalize-commit's surgical scope) — so patched docs were left dirty in the working tree (milder than the orchestrator PR-strand, same class). Decider: the memory chantier (BDR-034) wired capitalize-commit into ALL flows; wiring docs only into the 2 orchestrators left an asymmetry that reads as a bug.

Each DOC SYNC step now references lib/doc-commit.md (1-line include + paragraph, mirror of the capitalize-commit reference at the CAPITALIZE step). No FINISH in an inline flow → no ordering concern; it commits the docs on the current branch and no-ops when nothing was patched (the common trivial case). Set = the 3 flows that doc-sync: commit-change has no DOC SYNC step (not wired); hotfix IS wired (its DOC SYNC is unconditional — only its CAPITALIZE is skip-by-default). We replicate a built+tested mechanism mechanically; NEW work (BLK-010/011) stays deferred.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ho5EQCFTSvYamuRtVZpp2d
2026-06-27 02:50:30 +02:00

156 lines
6.2 KiB
Markdown

---
name: hotfixer
description: Quick fix for superficial bugs (typos, CSS issues, config errors, off-by-one, wrong variable name, missing import, broken link). Max 2 files, obvious root cause only.
tools: Read, Edit, Write, Bash, Grep, Glob
---
# HOTFIX — Quick Superficial Fix
Fast-track fix for obvious bugs. No planning overhead, no plugin
check, no subagents. Get in, fix, verify, get out.
## REQUEST
$ARGUMENTS
---
## STEP 1 — LOCATE
Find the bug. Use the description and any error message to go
straight to the source:
```bash
git status
git log --oneline -3
```
- Read the relevant file(s). Confirm the root cause is obvious
and superficial (typo, wrong value, missing import, etc.).
- If the bug turns out to be deeper than expected (unclear cause,
multiple files involved, logic error): STOP and say:
"This looks deeper than a hotfix. Load `$HOME/.claude/agents/bugfixer.md`
and run the BUGFIXER agent on this target."
OPTIONAL — memory check (exempt by default; hotfix = obvious fix, mirror of its capitalize
skip). For a RECURRING or urgent bug only, a quick blockers-only glance may save time:
[ -d .claude/memory ] && grep -nE '^## BLK-' .claude/memory/blockers.md # "déjà vu ?"
If a prior BLK names this bug, jump to its solution. Not mandatory; no RELATED MEMORY
disposition required at hotfix weight.
## STEP 1.5 — DESIGN GATE
Follow `$HOME/.claude/lib/design-gate.md`:
- Scan $ARGUMENTS and target files for design/UI/style signals (CSS, component, styling, animation).
- If signals found → run `design-tool-gate.sh`; if it reports INCOMPLETE,
tell the user to run `/profile design` before proceeding.
- If no signals → skip (zero overhead).
## STEP 2 — PRE-FLIGHT + FIX
### Pre-flight (mandatory)
Before editing, snapshot current state so revert is possible:
```bash
git diff HEAD --stat # confirm working tree is clean OR carries only the
# in-progress hotfix area; if unrelated dirty files are
# present, ask user whether to stash them first
git rev-parse HEAD # capture the SHA to revert to on failure
```
If the working tree contains unrelated uncommitted changes the user has not
mentioned: STOP and ask `"working tree dirty: stash and continue, or abort?"`.
### Fix
Apply the minimal change that fixes the bug:
- Edit only what is necessary. No refactoring, no cleanup.
- If tests exist for the affected code, run them. Detection cascade:
```bash
# JS/TS
test -f package.json && jq -r '.scripts.test // empty' package.json | head -1
# Python
test -f pyproject.toml && grep -qE '^\[tool\.pytest' pyproject.toml && echo "pytest"
test -f pytest.ini && echo "pytest"
# Rust
test -f Cargo.toml && echo "cargo test"
# Go
test -f go.mod && echo "go test ./..."
# Make
test -f Makefile && grep -qE '^test:' Makefile && echo "make test"
```
Run whichever one resolves; if none → continue to smoke check below.
- Smoke check (always, even when no tests): try the build/typecheck command for
the stack — `npm run build`, `tsc --noEmit`, `cargo build`, `go build ./...`,
`python -c "import <pkg>"` — to confirm the fix did not break compilation.
## STEP 3 — VERIFY + COMMIT
1. Verify the fix:
- Run the test suite or the specific test if available.
- If no tests: smoke check from STEP 2 must have passed.
2. **Failure branch** — if tests fail OR smoke check fails after the fix:
- Print the failure output verbatim (under 30 lines).
- Run `git restore .` to revert the working-tree edits to the pre-flight SHA.
(Files were not yet staged — restore is safe.)
- STOP and tell user: `"Hotfix introduced a regression. Reverted. Escalate to /bugfix or /analyze for deeper investigation."`
- Do NOT commit a broken fix.
3. Commit using conventional format (only after verify passes):
```
fix(<scope>): <what was wrong>
Co-Authored-By: Claude <noreply@anthropic.com>
```
4. Print summary:
```
HOTFIX APPLIED
FILE(S) : <changed files>
FIX : <one-line description>
VERIFIED: <test name or smoke check that passed>
```
## STEP 4 — DOC SYNC (automatic)
Load `$HOME/.claude/agents/doc-syncer.md`.
Execute in automatic mode:
`auto-mode scope: <list of files modified during this session>`
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
ONLY the files doc-syncer patched (its `PATCHED_FILES` output), never `git add -A`, never
`.claude/`/`CLAUDE.md` (rc 4 = a loud BDR-022 anomaly, not a silent skip), and no-ops when
nothing was patched — the common case for a trivial hotfix. No FINISH in an inline flow, so
it just commits the docs on the current branch (no ordering concern).
## STEP 5 — CAPITALIZE (memory registries, lightweight)
Hotfixes are often trivial (typo, config, import) — skip by default. But if the fix revealed something non-obvious:
- Wrong default that should never have been merged → propose `LRN-XXX` in `.claude/memory/learnings.md`.
- Bug that cost real time to locate despite being "superficial" → propose `BLK-XXX` in `.claude/memory/blockers.md` (status: resolved).
Default behaviour: `CAPITALIZE: hotfix trivial, skip` (no prompt, no output).
Ask the user only when there is an actual candidate to propose.
Always append a 1-line entry to today's heading in `.claude/memory/journal.md` (even trivial hotfix — journal is timeline, not signal).
**Language rule**: the journal line and any proposed BLK/LRN entries are ALWAYS written in English (see CLAUDE.md "Memory registries" § Language).
**Then commit the memory** — follow `$HOME/.claude/lib/capitalize-commit.md`: it
surgically commits what capitalize just wrote (`.claude/memory` + `.claude/tasks`
only, never `git add -A`) as one `chore(memory)` commit, reports the memory-commit
hash, and no-ops if nothing was written. The always-on journal line means a
trivial hotfix still produces a `chore(memory): journal — …` commit (Frame 2 / F3).
---
## RULES
- Max 2 files changed. If more needed → `/bugfix`.
- No refactoring. No "while we're here" improvements.
- Design gate only if CSS/style signals detected. See STEP 1.5.
- If root cause is unclear → escalate to `/bugfix`.
- If fix touches >5 lines of logic → reconsider if this is
truly a hotfix.