Skip to content
Development
Command

/dotnet-refactor

Phase-gated refactoring/design loop - session-blind subagents build the map and traces, empirical probes precede the design, an approval gate guards implementation, and a conformance audit re-checks the whole branch after any design change. State persists in

From plugin
dotnet-episteme-skills
123 skills13 agents3 commands3 hooks
+1
Install
> /plugin marketplace add Metalnib/dotnet-episteme-skills
> /plugin install dotnet-episteme-skills@dotnet-episteme-marketplace

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/dotnet-refactor

Context preview

What this command does when you run it.

Phase-gated refactoring/design loop - session-blind subagents build the map and traces, empirical probes precede the design, an approval gate guards implementation, and a conformance audit re-checks the whole branch after any design change. State persists in

Command definition

dotnet-refactor.md
description: Phase-gated refactoring/design loop - session-blind subagents build the map and traces, empirical probes precede the design, an approval gate guards implementation, and a conformance audit re-checks the whole branch after any design change. State persists in .episteme/DESIGN-<slug>.md so the loop survives compaction and fresh sessions.
argument-hint: "<ticket|area> [--design-file <path>] [--lite] e.g. YB-1234 or 'error handling in OrderService'"

/dotnet-refactor - orchestrated design loop

You are the orchestrator. Do not enumerate or trace code yourself - dispatch session-blind workers, persist their artifacts, and hold the gates. **No code is written or edited until the design is approved at the Phase D gate.**

Arguments given: `$ARGUMENTS`

Step 0 - Resolve target and state

  • Target: a ticket id or an area description. Slug it (e.g. `yb-1234` or `orderservice-errors`).
  • State file: `--design-file` if given, else `.episteme/DESIGN-<slug>.md` at the repository root

(create `.episteme/` if missing; whether the host repo gitignores it is the user's call).

  • **If the file exists**, route on its frontmatter - the file is the source of truth, never

conversation memory. This is the context-compaction contract: after `/clear`, compaction, or a fresh session, the loop continues losslessly from the file (a plugin hook re-injects it).

| frontmatter | resume at | |---|---| | `status: done` | nothing to resume - say so and stop | | `status: blocked` | restate the recorded blocker, ask the user | | `status: awaiting-approval` | re-present the design, hold the Phase D gate | | `status: active` | the phase in `phase:` |

  • **If not**, create it:
  ---
  target: <ticket id or area, one line>
  sources: <where the request came from - ticket, MR/PR review thread, QA doc, incident, probe>
  phase: R
  status: active
  design_revision: 0
  ---
  ## Why
  ## References
  ## Map
  ## Traces
  ## Probes
  ## Design (approved)
  ## Decision log
  ## Deferred
  ## Todo
  ## Review findings

Fill `Why` and `References` before Phase R, while the request is still fresh. They are the only sections a later reader cannot reconstruct from the code, and a `target` line is not a problem statement. `Why` is prose, not a list: the defect or goal in the reader's terms, what triggered the loop, why it is worth doing now rather than later, and what breaks if nothing changes. A loop that cannot state its problem in a paragraph should not be spending a worker fan-out on a map. `References` is a provenance table: ticket and sibling ticket ids, the review or PR threads, prior QA or design files, the contract/spec source, vendor docs or live schema fetched, probe artifacts, and the host-repo rule sections applied. Cite them as ids and paths, not as bare claims - "the reviewer asked" is unusable six weeks later.

Keep the frontmatter current: advance `phase` (R, E, T, P, D, I, V, F) the moment a phase completes, and flush worker artifacts to the file the moment they return - unpersisted state does not survive compaction. `Decision log` and `Deferred` are append-only. `Why` and `References` are stable: revise them only when the problem itself changes, and never to make the design that emerged look like the one that was intended.

  • Invariant pack: if the host repository has project-specific design invariants (a local

`/redesign`-style command, a CLAUDE.md section, or architecture docs), extract the 5-15 lines relevant to the target. Workers receive this pack and artifact data only - never conversation narration; the state file is the sole hand-off medium.

Step 1 - Phase R: recall

State to the user, in 3-5 bullets, the problem from `Why` in one line, the standing rules that apply, and anything in the state file's Decision log. The standing rules:

  • Fix the **invariant, not the instance**: a found defect names a rule; sweep for every

violation of the rule before fixing anything.

  • **Dataflow over references**: "who uses this type" is not "what value reaches this branch

during an outage / on duplicates / on empty input".

  • **Distrust names after changing behavior**: doc labels, class names, log texts, annotations,

guard-looking code - re-read every artifact on a changed path.

  • **Empirical before architectural**: never design on assumed external/vendor behavior.

Step 2 - Phases E+T: enumerate and trace

Mode first: **lighter mode** for a small target - one service, a handful of paths (`--lite`, or your own judgment; when unsure run the full pipeline). One `refactor:surveyor` worker maps and traces in a single pass, and reports `ESCALATE: <reason>` when the area turns out bigger than one pass should carry - then rerun in full mode.

Preferred - the bundled workflow (this command is your opt-in):

Workflow({
  scriptPath: "${CLAUDE_PLUGIN_ROOT}/workflows/dotnet-refactor.js",
  args: {
    phase: "map",
    lite: <true for lighter mode>,
    target: "<target>",
    repoRoot: "<absolute repo root>",
    services: ["<service dir>", ...],   // full mode; omit for single-service targets
    invariantPack: "<pack or omit>",
    scopeHints: "<hints or omit>"
  }
})

Full mode fans out one cartographer per service, then pipelines one tracer per path group the cartographers propose; lighter mode runs the single surveyor. Raw worker output never enters this conversation - you receive `{map, traces, anomalies, uncertainties}` (plus `escalate` when the surveyor bailed out; rerun with `lite: false`).

Fallback (Workflow tool unavailable): lighter mode is one `dotnet-episteme-skills:refactor:surveyor` Task call; full mode launches `dotnet-episteme-skills:refactor:cartographer` Task calls - one per service, all **in one message** - with repository root, target, invariant pack, and scope hints, then `dotnet-episteme-skills:refactor:tracer` per path group with the map rows in scope.

Either way: write the map into `Map` and the

Read more
Ships withdotnet-episteme-skills

DotNet Episteme Skills - a curated, manual-first .NET AI skills library rooted in systematic knowledge (episteme) and shaped by disciplined craft (techne), designed for engineers who prioritise precision over hype.

Get the whole plugin

Other commands on dotnet-episteme-skills.