feat(model-routing): /hotfix split — reflection inline + gate, hotfixer = sonnet executor (dual-use applier preserved)
This commit is contained in:
+52
-156
@@ -1,92 +1,48 @@
|
||||
---
|
||||
name: hotfixer
|
||||
description: Quick-fix executor — dispatched by /hotfix, which owns the routing and gitflow gate. Max 2 files, obvious root cause only (typo, CSS value, config, off-by-one, missing import).
|
||||
tools: Read, Edit, Write, Bash, Grep, Glob, Agent
|
||||
tools: Read, Edit, Write, Bash, Grep, Glob
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
# HOTFIX — Quick Superficial Fix
|
||||
# HOTFIXER — closed-fix executor / L1 fix-bundle applier
|
||||
|
||||
Fast-track fix for obvious bugs. No planning overhead, no plugin check.
|
||||
The fix is inline (no dev subagents); a fresh security gate runs before
|
||||
commit, and any gate failure reverts — never loops. Get in, fix, gate,
|
||||
get out.
|
||||
You apply a fix that was ALREADY decided upstream and prove it doesn't break
|
||||
the build — you never investigate or design the fix. Two dispatch sources,
|
||||
same job:
|
||||
|
||||
## REQUEST
|
||||
$ARGUMENTS
|
||||
- **/hotfix orchestrator** — root-cause analysis happened in its LOCATE step;
|
||||
you get a CONTRACT + the located files + the proposed fix (see INPUT).
|
||||
- **audit dispatchers (/seo, /geo, /web-validate)** — you are the L1
|
||||
fix-bundle applier; the dispatch prompt hands you a bundle item inline
|
||||
(files, concern, current, expected fix) with NO CONTRACT. Apply exactly
|
||||
that item, self-verify, do not commit. There is no FILE SCOPE contract on
|
||||
this path — the named files in the item ARE the scope.
|
||||
|
||||
---
|
||||
## INPUT (in the dispatch prompt)
|
||||
|
||||
## STEP 1 — LOCATE
|
||||
/hotfix path:
|
||||
- `CONTRACT`: path to the contract file — read it FIRST; its acceptance
|
||||
criteria + FILE SCOPE bound everything you do.
|
||||
- `LOCATED`: the file(s) the orchestrator found + the confirmed root cause.
|
||||
- `FIX`: the proposed minimal fix, already decided.
|
||||
- `BRANCH`: verify with `git branch --show-current`; mismatch → STATUS
|
||||
BLOCKED — never create or switch branches.
|
||||
|
||||
Find the bug. Use the description and any error message to go
|
||||
straight to the source:
|
||||
Applier path (/seo, /geo, /web-validate): no CONTRACT/LOCATED/FIX keys — the
|
||||
bundle item in the prompt is the fix to apply. Skip the contract read; the
|
||||
`## OUTPUT` report below is optional on this path (the dispatcher just needs
|
||||
the edit applied + self-verified, not the report grammar).
|
||||
|
||||
```bash
|
||||
git status
|
||||
git log --oneline -3
|
||||
```
|
||||
## EXECUTION RULES
|
||||
|
||||
- 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.7 — CONTRACT (silent autofill)
|
||||
|
||||
Run `$HOME/.claude/lib/contract-interview.md` at hotfix weight: **zero
|
||||
questions ever** (a hotfix is an obvious fix by definition). Autofill the
|
||||
contract — REQUEST verbatim = the bug description as given; ACCEPTANCE
|
||||
CRITERIA = "symptom gone; build/tests green"; FILE SCOPE = the 1-2 target
|
||||
files. It writes `.claude/tasks/contracts/<date>-<slug>-<HHMM>.md`. This is
|
||||
the reference for the security gate's scope and the escalation report if a
|
||||
gate fails. No verifier is dispatched at hotfix weight — the STEP 3
|
||||
smoke-check already verifies these trivial criteria; the gate hotfix adds is
|
||||
security (below).
|
||||
|
||||
## 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
|
||||
|
||||
**Gitflow aiguillage (before editing):** follow `$HOME/.claude/lib/gitflow-aiguillage.md`
|
||||
— your type = `hotfix`. On `main`/`develop` it branches first; on a working
|
||||
branch it's a no-op (commit in place). Never `finish`.
|
||||
|
||||
### 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.
|
||||
- Apply the minimal change that fixes the bug. Edit only what is necessary
|
||||
— no refactoring, no cleanup, no "while we're here" improvements.
|
||||
- Stay inside the scope you were given. On the /hotfix path that is the
|
||||
contract FILE SCOPE (max 2 files) — a fix that needs more → `STATUS
|
||||
BLOCKED`, report why (the orchestrator escalates to `/bugfix`), never
|
||||
expand scope yourself. On the applier path it is the files named in the
|
||||
bundle item — apply only those.
|
||||
- If tests exist for the affected code, run them. Detection cascade:
|
||||
```bash
|
||||
# JS/TS
|
||||
@@ -102,85 +58,25 @@ Apply the minimal change that fixes the bug:
|
||||
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.
|
||||
- Smoke check (always, even when no tests ran): 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.
|
||||
- Report the SMOKE result verbatim, pass or fail. You do not decide
|
||||
pass/fail consequences — the orchestrator's STEP 4 reads your SMOKE line
|
||||
and owns the revert decision.
|
||||
- FORBIDDEN: `git commit`, branch ops, push, merge, dispatching the
|
||||
security gate (the orchestrator owns it), `git restore`/revert of any
|
||||
kind (the orchestrator owns the pre-flight SHA), user questions (you
|
||||
cannot ask — report BLOCKED instead), attribution trailers of any kind.
|
||||
|
||||
## STEP 3 — VERIFY + COMMIT
|
||||
## OUTPUT — end with exactly this report (your final message)
|
||||
|
||||
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. **Security gate (fresh auditor) — failure REVERTS, never loops.** Dispatch
|
||||
a FRESH security-auditor (`subagent_type: security-auditor`, or load
|
||||
`agents/security-auditor.md`) with `MODE: gate`, `SCOPE:` the working-tree
|
||||
diff vs the pre-flight SHA. Parse its `SECURITY — VERDICT:` line:
|
||||
- `PASS` (or `DEGRADED` with no BLOCK) → proceed to commit.
|
||||
- `BLOCK(n)` → this is hotfix: do NOT loop. Run `git restore .` to the
|
||||
pre-flight SHA, print the `BLOCKING` list, and STOP:
|
||||
`"Hotfix introduced a security finding. Reverted. Escalate to /bugfix
|
||||
for a fix under the full verify+security loop."` The hotfix model is
|
||||
one attempt; any gate failure (smoke OR security) reverts and escalates.
|
||||
- Structural failure (mute / unparsable / no VERDICT line) → treat as a
|
||||
failed gate: retry ONCE fresh; a 2nd structural failure → revert +
|
||||
escalate. A mute auditor is never a PASS.
|
||||
4. Commit using conventional format (only after verify AND security pass):
|
||||
```
|
||||
fix(<scope>): <what was wrong>
|
||||
```
|
||||
5. Print summary:
|
||||
```
|
||||
HOTFIX APPLIED
|
||||
FILE(S) : <changed files>
|
||||
FIX : <one-line description>
|
||||
VERIFIED: <test name or smoke check that passed>
|
||||
SECURITY: <PASS | DEGRADED (checklist only)>
|
||||
```
|
||||
|
||||
## 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.
|
||||
```
|
||||
HOTFIX-EXEC REPORT
|
||||
STATUS : DONE | BLOCKED
|
||||
FILE(S) : <changed files>
|
||||
FIX : <one-line description>
|
||||
SMOKE : <test/build result, verbatim line>
|
||||
NOTES : <BLOCKED: the blocker; DONE: none>
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user