|
| 1 | +--- |
| 2 | +name: desloppify |
| 3 | +description: > |
| 4 | + Codebase health scanner and technical debt tracker. Use when the user asks |
| 5 | + about code quality, technical debt, dead code, large files, god classes, |
| 6 | + duplicate functions, code smells, naming issues, import cycles, or coupling |
| 7 | + problems. Also use when asked for a health score, what to fix next, or to |
| 8 | + create a cleanup plan. Supports 29 languages. |
| 9 | +--- |
| 10 | + |
| 11 | +<!-- desloppify-begin --> |
| 12 | +<!-- desloppify-skill-version: 6 --> |
| 13 | + |
| 14 | +# Desloppify |
| 15 | + |
| 16 | +## 1. Your Job |
| 17 | + |
| 18 | +Maximise the **strict score** honestly. Your main cycle: **scan → plan → execute → rescan**. Follow the scan output's **INSTRUCTIONS FOR AGENTS** — don't substitute your own analysis. |
| 19 | + |
| 20 | +**Don't be lazy.** Do large refactors and small detailed fixes with equal energy. If it takes touching 20 files, touch 20 files. If it's a one-line change, make it. No task is too big or too small — fix things properly, not minimally. |
| 21 | + |
| 22 | +## 2. The Workflow |
| 23 | + |
| 24 | +Three phases, repeated as a cycle. |
| 25 | + |
| 26 | +### Phase 1: Scan and review — understand the codebase |
| 27 | + |
| 28 | +```bash |
| 29 | +desloppify scan --path . # analyse the codebase |
| 30 | +desloppify status # check scores — are we at target? |
| 31 | +``` |
| 32 | + |
| 33 | +The scan will tell you if subjective dimensions need review. Follow its instructions. To trigger a review manually: |
| 34 | +```bash |
| 35 | +desloppify review --prepare # then follow your runner's review workflow |
| 36 | +``` |
| 37 | + |
| 38 | +### Phase 2: Plan — decide what to work on |
| 39 | + |
| 40 | +After reviews, triage stages and plan creation appear in the execution queue surfaced by `next`. Complete them in order — `next` tells you what each stage expects in the `--report`: |
| 41 | +```bash |
| 42 | +desloppify next # shows the next execution workflow step |
| 43 | +desloppify plan triage --stage observe --report "themes and root causes..." |
| 44 | +desloppify plan triage --stage reflect --report "comparison against completed work..." |
| 45 | +desloppify plan triage --stage organize --report "summary of priorities..." |
| 46 | +desloppify plan triage --complete --strategy "execution plan..." |
| 47 | +``` |
| 48 | + |
| 49 | +For automated triage: `desloppify plan triage --run-stages --runner codex` (Codex) or `--runner claude` (Claude). Options: `--only-stages`, `--dry-run`, `--stage-timeout-seconds`. |
| 50 | + |
| 51 | +Then shape the queue. **The plan shapes everything `next` gives you** — `next` is the execution queue, not the full backlog. Don't skip this step. |
| 52 | + |
| 53 | +```bash |
| 54 | +desloppify plan # see the living plan details |
| 55 | +desloppify plan queue # compact execution queue view |
| 56 | +desloppify plan reorder <pat> top # reorder — what unblocks the most? |
| 57 | +desloppify plan cluster create <name> # group related issues to batch-fix |
| 58 | +desloppify plan focus <cluster> # scope next to one cluster |
| 59 | +desloppify plan skip <pat> # defer — hide from next |
| 60 | +``` |
| 61 | + |
| 62 | +### Phase 3: Execute — grind the queue to completion |
| 63 | + |
| 64 | +Trust the plan and execute. Don't rescan mid-queue — finish the queue first. |
| 65 | + |
| 66 | +**Branch first.** Create a dedicated branch — never commit health work directly to main: |
| 67 | +```bash |
| 68 | +git checkout -b desloppify/code-health # or desloppify/<focus-area> |
| 69 | +desloppify config set commit_pr 42 # link a PR for auto-updated descriptions |
| 70 | +``` |
| 71 | + |
| 72 | +**The loop:** |
| 73 | +```bash |
| 74 | +# 1. Get the next item from the execution queue |
| 75 | +desloppify next |
| 76 | + |
| 77 | +# 2. Fix the issue in code |
| 78 | + |
| 79 | +# 3. Resolve it (next shows the exact command including required attestation) |
| 80 | + |
| 81 | +# 4. When you have a logical batch, commit and record |
| 82 | +git add <files> && git commit -m "desloppify: fix 3 deferred_import findings" |
| 83 | +desloppify plan commit-log record # moves findings uncommitted → committed, updates PR |
| 84 | + |
| 85 | +# 5. Push periodically |
| 86 | +git push -u origin desloppify/code-health |
| 87 | + |
| 88 | +# 6. Repeat until the queue is empty |
| 89 | +``` |
| 90 | + |
| 91 | +Score may temporarily drop after fixes — cascade effects are normal, keep going. |
| 92 | +If `next` suggests an auto-fixer, run `desloppify autofix <fixer> --dry-run` to preview, then apply. |
| 93 | + |
| 94 | +**When the queue is clear, go back to Phase 1.** New issues will surface, cascades will have resolved, priorities will have shifted. This is the cycle. |
| 95 | + |
| 96 | +## 3. Reference |
| 97 | + |
| 98 | +### Key concepts |
| 99 | + |
| 100 | +- **Tiers**: T1 auto-fix → T2 quick manual → T3 judgment call → T4 major refactor. |
| 101 | +- **Auto-clusters**: related findings are auto-grouped in `next`. Drill in with `next --cluster <name>`. |
| 102 | +- **Zones**: production/script (scored), test/config/generated/vendor (not scored). Fix with `zone set`. |
| 103 | +- **Wontfix cost**: widens the lenient↔strict gap. Challenge past decisions when the gap grows. |
| 104 | + |
| 105 | +### Scoring |
| 106 | + |
| 107 | +Overall score = **25% mechanical** + **75% subjective**. |
| 108 | + |
| 109 | +- **Mechanical (25%)**: auto-detected issues — duplication, dead code, smells, unused imports, security. Fixed by changing code and rescanning. |
| 110 | +- **Subjective (75%)**: design quality review — naming, error handling, abstractions, clarity. Starts at **0%** until reviewed. The scan will prompt you when a review is needed. |
| 111 | +- **Strict score** is the north star: wontfix items count as open. The gap between overall and strict is your wontfix debt. |
| 112 | +- **Score types**: overall (lenient), strict (wontfix counts), objective (mechanical only), verified (confirmed fixes only). |
| 113 | + |
| 114 | +### Reviews |
| 115 | + |
| 116 | +Four paths to get subjective scores: |
| 117 | + |
| 118 | +- **Local runner (Codex)**: `desloppify review --run-batches --runner codex --parallel --scan-after-import` — automated end-to-end. |
| 119 | +- **Local runner (Claude)**: `desloppify review --prepare` → launch parallel subagents → `desloppify review --import merged.json` — see skill doc overlay for details. |
| 120 | +- **Cloud/external**: `desloppify review --external-start --external-runner claude` → follow session template → `--external-submit`. |
| 121 | +- **Manual path**: `desloppify review --prepare` → review per dimension → `desloppify review --import file.json`. |
| 122 | + |
| 123 | +**Batch output vs import filenames:** Individual batch outputs from subagents must be named `batch-N.raw.txt` (plain text/JSON content, `.raw.txt` extension). The `.json` filenames in `--import merged.json` or `--import findings.json` refer to the final merged import file, not individual batch outputs. Do not name batch outputs with a `.json` extension. |
| 124 | + |
| 125 | +- Import first, fix after — import creates tracked state entries for correlation. |
| 126 | +- Target-matching scores trigger auto-reset to prevent gaming. Use the blind-review workflow described in your agent overlay doc (e.g. `docs/CLAUDE.md`, `docs/HERMES.md`). |
| 127 | +- Even moderate scores (60-80) dramatically improve overall health. |
| 128 | +- Stale dimensions auto-surface in `next` — just follow the queue. |
| 129 | + |
| 130 | +**Integrity rules:** Score from evidence only — no prior chat context, score history, or target-threshold anchoring. When evidence is mixed, score lower and explain uncertainty. Assess every requested dimension; never drop one. |
| 131 | + |
| 132 | +#### Review output format |
| 133 | + |
| 134 | +Return machine-readable JSON for review imports. For `--external-submit`, include `session` from the generated template: |
| 135 | + |
| 136 | +```json |
| 137 | +{ |
| 138 | + "session": { |
| 139 | + "id": "<session_id_from_template>", |
| 140 | + "token": "<session_hmac_from_template>" |
| 141 | + }, |
| 142 | + "assessments": { |
| 143 | + "<dimension_from_query>": 0 |
| 144 | + }, |
| 145 | + "findings": [ |
| 146 | + { |
| 147 | + "dimension": "<dimension_from_query>", |
| 148 | + "identifier": "short_id", |
| 149 | + "summary": "one-line defect summary", |
| 150 | + "related_files": ["relative/path/to/file.py"], |
| 151 | + "evidence": ["specific code observation"], |
| 152 | + "suggestion": "concrete fix recommendation", |
| 153 | + "confidence": "high|medium|low" |
| 154 | + } |
| 155 | + ] |
| 156 | +} |
| 157 | +``` |
| 158 | + |
| 159 | +`findings` MUST match `query.system_prompt` exactly (including `related_files`, `evidence`, and `suggestion`). Use `"findings": []` when no defects found. Import is fail-closed: invalid findings abort unless `--allow-partial` is passed. Assessment scores are auto-applied from trusted internal or cloud session imports. Legacy `--attested-external` remains supported. |
| 160 | + |
| 161 | +#### Import paths |
| 162 | + |
| 163 | +- Robust session flow (recommended): `desloppify review --external-start --external-runner claude` → use generated prompt/template → run printed `--external-submit` command. |
| 164 | +- Durable scored import (legacy): `desloppify review --import findings.json --attested-external --attest "I validated this review was completed without awareness of overall score and is unbiased."` |
| 165 | +- Findings-only fallback: `desloppify review --import findings.json` |
| 166 | + |
| 167 | +#### Reviewer agent prompt |
| 168 | + |
| 169 | +Runners that support agent definitions (Cursor, Copilot, Gemini) can create a dedicated reviewer agent. Use this system prompt: |
| 170 | + |
| 171 | +``` |
| 172 | +You are a code quality reviewer. You will be given a codebase path, a set of |
| 173 | +dimensions to score, and what each dimension means. Read the code, score each |
| 174 | +dimension 0-100 from evidence only, and return JSON in the required format. |
| 175 | +Do not anchor to target thresholds. When evidence is mixed, score lower and |
| 176 | +explain uncertainty. |
| 177 | +``` |
| 178 | + |
| 179 | +See your editor's overlay section below for the agent config format. |
| 180 | + |
| 181 | +### Plan commands |
| 182 | + |
| 183 | +```bash |
| 184 | +desloppify plan reorder <cluster> top # move all cluster members at once |
| 185 | +desloppify plan reorder <a> <b> top # mix clusters + findings in one reorder |
| 186 | +desloppify plan reorder <pat> before -t X # position relative to another item/cluster |
| 187 | +desloppify plan cluster reorder a,b top # reorder multiple clusters as one block |
| 188 | +desloppify plan resolve <pat> # mark complete |
| 189 | +desloppify plan reopen <pat> # reopen |
| 190 | +desloppify backlog # broader non-execution backlog |
| 191 | +``` |
| 192 | + |
| 193 | +### Commit tracking |
| 194 | + |
| 195 | +```bash |
| 196 | +desloppify plan commit-log # see uncommitted + committed status |
| 197 | +desloppify plan commit-log record # record HEAD commit, update PR description |
| 198 | +desloppify plan commit-log record --note "why" # with rationale |
| 199 | +desloppify plan commit-log record --only "smells::*" # record specific findings only |
| 200 | +desloppify plan commit-log history # show commit records |
| 201 | +desloppify plan commit-log pr # preview PR body markdown |
| 202 | +desloppify config set commit_tracking_enabled false # disable guidance |
| 203 | +``` |
| 204 | + |
| 205 | +After resolving findings as `fixed`, the tool shows uncommitted work, committed history, and a suggested commit message. After committing externally, run `record` to move findings from uncommitted to committed and auto-update the linked PR description. |
| 206 | + |
| 207 | +### Agent directives |
| 208 | + |
| 209 | +Directives are messages shown to agents at lifecycle phase transitions — use them to switch models, set constraints, or give context-specific instructions. |
| 210 | + |
| 211 | +```bash |
| 212 | +desloppify directives # show all configured directives |
| 213 | +desloppify directives set execute "Switch to claude-sonnet-4-6. Focus on speed." |
| 214 | +desloppify directives set triage "Switch to claude-opus-4-6. Read carefully." |
| 215 | +desloppify directives set review "Use blind packet. Do not anchor on previous scores." |
| 216 | +desloppify directives unset execute # remove a directive |
| 217 | +``` |
| 218 | + |
| 219 | +Available phases: `execute`, `review`, `triage`, `workflow`, `scan` (and fine-grained variants like `review_initial`, `triage_postflight`, etc.). |
| 220 | + |
| 221 | +### Quick reference |
| 222 | + |
| 223 | +```bash |
| 224 | +desloppify next --count 5 # top 5 execution items |
| 225 | +desloppify next --cluster <name> # drill into a cluster |
| 226 | +desloppify backlog --count 5 # top 5 backlog items outside execution |
| 227 | +desloppify show <pattern> # filter by file/detector/ID |
| 228 | +desloppify show --status open # all open findings |
| 229 | +desloppify plan skip --permanent "<id>" --note "reason" --attest "..." # accept debt |
| 230 | +desloppify exclude <path> # exclude a directory from scanning |
| 231 | +desloppify config show # show all config including excludes |
| 232 | +desloppify scan --path . --reset-subjective # reset subjective baseline to 0 |
| 233 | +``` |
| 234 | + |
| 235 | +## 4. Fix Tool Issues Upstream |
| 236 | + |
| 237 | +When desloppify itself appears wrong or inconsistent — a bug, a bad detection, a crash, confusing output — **fix it and open a PR**. If you can't confidently fix it, file an issue instead. |
| 238 | + |
| 239 | +### Fix and PR (preferred) |
| 240 | + |
| 241 | +Clone the tool repo to a temp directory, make the fix there, and verify it works against the project you're scanning before pushing. |
| 242 | + |
| 243 | +```bash |
| 244 | +git clone https://github.com/peteromallet/desloppify.git /tmp/desloppify-fix |
| 245 | +cd /tmp/desloppify-fix |
| 246 | +git checkout -b fix/<short-description> |
| 247 | +``` |
| 248 | + |
| 249 | +Make your changes, then run the test suite and verify the fix against the original project: |
| 250 | + |
| 251 | +```bash |
| 252 | +python -m pytest desloppify/tests/ -q |
| 253 | +python -m desloppify scan --path <project-root> # the project you were scanning |
| 254 | +``` |
| 255 | + |
| 256 | +Once it looks good, push and open a PR: |
| 257 | + |
| 258 | +```bash |
| 259 | +git add <files> && git commit -m "fix: <what and why>" |
| 260 | +git push -u origin fix/<short-description> |
| 261 | +gh pr create --title "fix: <short description>" --body "$(cat <<'EOF' |
| 262 | +## Problem |
| 263 | +<what went wrong — include the command and output> |
| 264 | +
|
| 265 | +## Fix |
| 266 | +<what you changed and why> |
| 267 | +EOF |
| 268 | +)" |
| 269 | +``` |
| 270 | + |
| 271 | +Clean up after: `rm -rf /tmp/desloppify-fix` |
| 272 | + |
| 273 | +### File an issue (fallback) |
| 274 | + |
| 275 | +If the fix is unclear or the change needs discussion, open an issue at `https://github.com/peteromallet/desloppify/issues` with a minimal repro: command, path, expected output, actual output. |
| 276 | + |
| 277 | +## Prerequisite |
| 278 | + |
| 279 | +`command -v desloppify >/dev/null 2>&1 && echo "desloppify: installed" || echo "NOT INSTALLED — run: uvx --from git+https://github.com/peteromallet/desloppify.git desloppify"` |
| 280 | + |
| 281 | +If `uvx` is not available: `pip install desloppify[full]` |
| 282 | + |
| 283 | +<!-- desloppify-end --> |
| 284 | + |
| 285 | +## Claude Code Overlay |
| 286 | + |
| 287 | +Use Claude subagents for subjective scoring work. **Do not use `--runner codex`** — use Claude subagents exclusively. |
| 288 | + |
| 289 | +### Review workflow |
| 290 | + |
| 291 | +Run `desloppify review --prepare` first to generate review data, then use Claude subagents: |
| 292 | + |
| 293 | +1. **Prepare**: `desloppify review --prepare` — writes `query.json` and `.desloppify/review_packet_blind.json`. |
| 294 | +2. **Launch subagents**: Split the review across N parallel Claude subagents (one message, multiple Task calls). Each agent reviews a subset of dimensions. |
| 295 | +3. **Merge & import**: Merge agent outputs, then `desloppify review --import merged.json --manual-override --attest "Claude subagents ran blind reviews against review_packet_blind.json" --scan-after-import`. |
| 296 | + |
| 297 | +#### How to split dimensions across subagents |
| 298 | + |
| 299 | +- Read `dimension_prompts` from `query.json` for dimensions with definitions and seed files. |
| 300 | +- Read `.desloppify/review_packet_blind.json` for the blind packet (no score targets, no anchoring data). |
| 301 | +- Group dimensions into 3-4 batches by theme (e.g., architecture, code quality, testing, conventions). |
| 302 | +- Launch one Task agent per batch with `subagent_type: "general-purpose"`. Each agent gets: |
| 303 | + - The codebase path and list of dimensions to score |
| 304 | + - The blind packet path to read |
| 305 | + - Instruction to score from code evidence only, not from targets |
| 306 | +- Each agent writes output to `results/batch-N.raw.txt` (matching the batch index). Merge assessments (average overlapping dimension scores) and concatenate findings. |
| 307 | + |
| 308 | +### Subagent rules |
| 309 | + |
| 310 | +1. Each agent must be context-isolated — do not pass conversation history or score targets. |
| 311 | +2. Agents must consume `.desloppify/review_packet_blind.json` (not full `query.json`) to avoid score anchoring. |
| 312 | + |
| 313 | +### Triage workflow |
| 314 | + |
| 315 | +Orchestrate triage with per-stage subagents: |
| 316 | +1. `desloppify plan triage --run-stages --runner claude` — prints orchestrator instructions |
| 317 | +2. For each stage (observe → reflect → organize → enrich): |
| 318 | + - Get prompt: `desloppify plan triage --stage-prompt <stage>` |
| 319 | + - Launch a subagent with that prompt |
| 320 | + - Verify: `desloppify plan triage` (check dashboard) |
| 321 | + - Confirm: `desloppify plan triage --confirm <stage> --attestation "..."` |
| 322 | +3. Complete: `desloppify plan triage --complete --strategy "..." --attestation "..."` |
| 323 | + |
| 324 | +<!-- desloppify-overlay: claude --> |
| 325 | +<!-- desloppify-end --> |
0 commit comments