post-change-refactor · git:20260905.db253c7 · 2026-09-05 · sha256 7445d0a0c644d04c
post-change-refactor git:20260905.db253c7A
Immutable. This exact content is served forever at /api/v1/blob/7445d0a0c644d04c.
--- name: post-change-refactor description: >- Refactor concepts implicated by the current uncommitted change before commit. Use concept-bounded scope even when completion requires untouched code, but Jidoka-stop before unapproved cross-subsystem refactoring. Remove duplication, unclear naming, shotgun surgery, dead / test-only / redundant code, and oversized files; run related tests only when the refactor edits. Local slice wrap-up overlay (execute-plan / gsd-execute-phase). Use after a slice, before commit, or on: refactor change, clean up change, post-change refactor, before commit cleanup, tidy current change. --- <objective> Clean concepts implicated by the **current uncommitted change** so they are cohesive, capability-named, and non-speculative, then return control for commit. Purpose: Local wrap-up gate required by `execute-plan` / `/gsd-execute-phase` (see `.cursor/rules/gsd-coexistence.mdc`). Structure-only: no new behavior. Output: Refactored tree + `## REFACTOR COMPLETE`, or an impact report + `## REFACTOR JIDOKA STOP`. **Do not commit** — the caller commits after success (and pushes when closing a slice). </objective> <context> **Mandatory first read:** `.cursor/agent-map.md` (navigation + focused test commands). **Scope is concept-bounded, not file-bounded.** A candidate must be triggered by an issue introduced, exposed, or materially aggravated by the current change or highly related code. Such code represents the same concept, duplicates the same knowledge, or must change to leave it coherent. Dependency adjacency alone is neither required nor sufficient. Find the smallest complete set of representations, callers, tests, fixtures, and configuration needed for coherence, including untouched code when needed. Every edit must serve that candidate; do not initiate nearby cleanup. Discover scope: ```bash git status git diff git diff --cached ``` Whitespace hygiene: `scripts/check_diff_whitespace.sh` (not raw `git diff --check`) — excludes generated API artifacts under `packages/generated/donut-backend-api/**` and `open_api_docs.yaml`. **Git does not use the Nix prefix.** All other repo tooling does: `CURSOR_DEV=true nix develop -c …` **Plan justification (decision boundary):** Keep code justified by the **current change** or the **immediate next** slice in the active plan (`.planning/phases/*/`, `.planning/quick/*/`). Anything justified only by a later slice, or by "we might need it later", is speculative — remove it. No plan → justification comes only from the current change. The immediate next slice may justify retaining code, but does not independently trigger unrelated refactoring. **Subsystem boundary:** Backend production code, frontend production code, CLI, MCP server, and database schema are separate subsystems. Tests, E2E, fixtures, generated artifacts, and configuration following one production seam do not alone create a crossing. Existing behavior work spanning subsystems also does not trigger the gate; the **refactoring itself** must require coordinated production edits across boundaries. Optional caller context (when spawned from execute-plan): - Plan path and current slice text (for the immediate-next-slice justification boundary) - Implementer's compact `proof:` block(s), including each exact focused command and the behavior or paths it covers **Invokers:** `execute-plan` (fresh sub-agent before commit), `bug-fixing`, `test-optimization`, or on-demand developer request. </context> <process> <preflight_gate name="discover_scope"> Run the git discovery commands above. If there is no uncommitted change, report empty scope and emit `## REFACTOR COMPLETE` with no edits. </preflight_gate> <preflight_gate name="map_concept_impact"> Before editing, read [the refactor checks](references/refactor-checks.md) and perform a fast read-only pass over every check. For each candidate, record: 1. The triggering issue and its connection to the current change. 2. The minimum concept-bounded edit set needed for coherent completion. 3. The production subsystems that edit set would touch. Use references as navigation, not automatic scope. Do not inventory general repository cleanup. </preflight_gate> <preflight_gate name="cross_subsystem_jidoka"> If a candidate requires production refactoring in more than one subsystem, stop before editing unless the human explicitly authorized that named concept and those subsystems. Generic "clean up" or "refactor" requests do not qualify. Return the `<output>` Jidoka report; do not enter the edit/test pass or substitute a partial refactoring. If discovered while editing, stop before the first cross-subsystem edit and leave no partial candidate: reverse only this agent's edits for that candidate, never pre-existing user changes. </preflight_gate> After the gates, **decide first**: if `map_concept_impact` recorded no edit candidates (and the cross-subsystem gate did not stop), skip the edit steps and `confirm_related_tests`; report "none — already clean" and emit `## REFACTOR COMPLETE`. Do not run related tests as a pre-triage gate. If there are edit candidates, execute them **in refactor-check order**, then `confirm_related_tests`. Do not repeat broad discovery. After all checks pass, return to the caller — **do not commit** from inside this skill. <step name="confirm_related_tests"> Skip this step when triage recorded no refactor edits. When the caller provided compact proof, rerun only the handed-off command(s) whose covered behavior or paths the refactor edits invalidated — not the whole suite, and not before deciding to edit. If an edit moved the covered boundary so a handed-off command is no longer the right focused proof, state why and run a focused replacement. Do not rerun unaffected handed-off proof. Without a proof handoff, run related focused tests for the files this refactor changed. Use `CURSOR_DEV=true nix develop -c …` for all commands except `git`. | Area touched | Focused command | |--------------|-----------------| | Backend Java | `CURSOR_DEV=true nix develop -c backend/gradlew -p backend test -Dspring.profiles.active=test --tests "com.odde.donut....ClassName"` per affected class (or package pattern). If `backend/src/main/resources/db/migration/` changed → `CURSOR_DEV=true nix develop -c pnpm backend:test` | | Frontend Vue/TS | `CURSOR_DEV=true nix develop -c pnpm frontend:test tests/path/to/File.spec.ts` | | E2E (only if behavior under test changed) | `CURSOR_DEV=true nix develop -c pnpm cypress run --spec e2e_test/features/<name>.feature` | | CLI | `CURSOR_DEV=true nix develop -c pnpm cli:test` (or narrower path under `cli/`) | | MCP server | `CURSOR_DEV=true nix develop -c pnpm mcp-server:test` | Prefer controller-level backend tests and mounted-component / E2E tests over tests that only exercise internal helpers (`unit-testing.mdc`). All related tests must pass before returning. If a test breaks because of the refactor (not the original change), fix it now. </step> </process> <success_criteria> - Every candidate is triggered by the current change or highly related code - Edits are the smallest coherent concept-bounded set, including untouched files - No cross-subsystem refactoring without concept-specific human authorization - No speculative structure beyond current change / immediate next slice - Duplication, naming, shotgun, dead-code, and file-size checks applied (500 lines for seed and plan files; 250 lines for other files) - Invalidated handed-off proof (or related focused tests without a handoff) green when this skill edited; skipped when triage made no edits - Successful and Jidoka handoffs report approximate active elapsed time - No commit created by this skill - Final output includes `## REFACTOR COMPLETE` </success_criteria> <output> On successful completion, report a short summary to the caller: 1. Which checks led to changes — duplication / naming / shotgun / dead code / file size (or "none — already clean"). 2. Files renamed, extracted, split, or deleted. 3. Which related tests were run and confirmed passing — or `skipped — no refactor edits`. 4. Approximate active elapsed time spent on the refactor pass. ``` ## REFACTOR COMPLETE ``` Hand control back. **Do not commit** — the caller commits (and pushes when closing a slice). On a cross-subsystem gate, report only decision-relevant facts: 1. Triggering issue and its connection to the current change. 2. Concept requiring refactoring. 3. Affected subsystems and representative files. 4. Why a single-subsystem edit would be partial or misleading. 5. Expected risk and focused validation. 6. Choices: authorize it, defer it, or approve a described narrow exception. 7. Approximate active elapsed time spent before the stop. End with: ``` ## REFACTOR JIDOKA STOP ``` Do not emit `## REFACTOR COMPLETE`. The caller must surface the decision and must not consider refactoring complete or commit until the human decides. </output> <out_of_scope> - Do not initiate unrelated refactoring discovered during concept tracing. - Do not apply cross-subsystem refactoring without explicit, concept-specific human authorization. - Do not start a new slice or add new behavior — Structure only. - Do not run the entire test suite or trigger CI. - Do not run related tests when triage recorded no refactor edits. - Do not regenerate the OpenAPI client unless controller/DTO signatures changed as part of this refactor (use `generate-api-client` when needed). - Do not commit, push, or amend from inside this skill. - Do not prefix `git` with `nix develop -c` — git runs directly; other tooling uses nix (`CURSOR_DEV=true nix develop -c`). </out_of_scope>