本文へ移動
cccskills
無料GitHub で公開

debt-sweep

Autonomous themed tech-debt cleanup. Reads docs/architecture/debt-ledger.yml, rotates to the least-recently-served debt theme, works it for a time budget (default 2h) or until drained, opens one PR, and asks judgment questions inline at the end. Use for daily debt burndown without Peter pointing at a target: grandfathered analyzer rules, architecture-test baselines, obsolete-field reads, cross-section stitching.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md17.0 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Debt Sweep

See docs/superpowers/specs/2026-06-12-debt-sweep-design.md for full design.

Invocation

FlagBehavior
(none)rotation picks the theme; ~2h budget
--budget=<duration>override budget (30m, 4h). Wall-clock guidance, checked between items, never mid-item
--theme=<id>skip rotation, work this theme
--inventoryfull re-scan: re-run every theme's detect, merge new classes, refresh counts, evict gone entries. Combinable with a normal sweep or standalone (standalone still PRs the ledger update)

Phase 0: Setup

REPO_ROOT=$(git rev-parse --show-toplevel). Parse --budget (default 2h); record start time.

Phase 1: Workspace

Per always-use-worktree — a worktree locally, the repo root in a cloud run. $WORKTREE is the sweep's workspace either way; the rest of the skill doesn't care which it is.

git fetch origin main
TS=$(date -u +%Y-%m-%dT%H%M%SZ)
if [ "$CLAUDE_CODE_REMOTE" = "true" ]; then  # ephemeral single-session container — no worktree
  git checkout -b debt-sweep/$TS origin/main
  WORKTREE=$REPO_ROOT
else
  git worktree add $REPO_ROOT/.claude/worktrees/debt-sweep-$TS -b debt-sweep/$TS origin/main
  WORKTREE=$REPO_ROOT/.claude/worktrees/debt-sweep-$TS  # EnterWorktree here; all commands run inside
fi

Scope is frozen here. Never re-fetch, re-resolve, or reconcile against origin/main mid-run — a parallel session merging a PR while the sweep runs is expected and irrelevant. Anything landing after the branch point is the next sweep's input. Path/branch collision → error; instruct git worktree list / git worktree remove.

Locally, scope every Glob/Grep to $WORKTREE paths — never the repo root (it holds other worktrees). In a cloud run $WORKTREE is the repo root and there is nothing to scope away.

Phase 2: Ledger + staleness check

  1. Read docs/architecture/debt-ledger.yml. Validate: version: 1; every theme has id, title, detect, review (light|panel; the inbox theme alone uses per-item — each inbox entry carries its own tier), last_swept, remaining. Optional: parked: "<reason>" (see Phase 3). Parse error → abort (no partial run), report to Peter. 1b. Read every section ledger too — src/Sections/*/Docs/debt.yml, each version: 1 plus an inbox: of the same entry shape (memory/process/debt-ledger-additions.md). Section-owned one-offs live there so the central ledger stays rotation state; the sweep pools them into one inbox and does not care where an item was written. A section file that fails to parse aborts the run like the central one. themes: exists only centrally — a section file declaring one is a parse error.
ls $WORKTREE/src/Sections/*/Docs/debt.yml 2>/dev/null   # absent is normal — most sections have none
  1. Staleness check (every run, cheap):
    • Distinct HUM#### ids in real [Grandfathered( attribute usages vs. ledger theme ids → each missing rule becomes a new theme (last_swept: never, review: light unless it is plainly a structural/judgment rule — then panel). Anchor the grep to attribute syntax — an unanchored [Grandfathered( also matches analyzer doc-comments and message strings, which seeds phantom themes:
      grep -rn -A3 --include='*.cs' '^[[:space:]]*\[Grandfathered(' $WORKTREE/src | grep -oE '"HUM[0-9]{4}"' | sort -u
      
    • Files in tests/Humans.Web.Tests/Architecture/Baselines/ with >0 non-comment entries vs. ledger → same.
    • New themes are committed in the ledger update (Phase 5) even when not worked this run.
  2. --inventory only: re-run every theme's detect, refresh all remaining, evict themes whose debt is gone (note each eviction in the report), and look for debt classes the ledger misses (new [Obsolete] clusters, new custom warning ids in a fresh build, new ratchet analyzers). Never evict a parked: theme — refresh its remaining and leave the entry in place, remaining: 0 included. Evicting it would drop the park, and the staleness check would later re-create the theme unparked.

Build-derived counts

Warning-backed themes (detect: build:<CODE>) are counted from one build log instead of per-theme commands:

dotnet build Humans.slnx -v quiet --no-incremental 2>&1 | tee /tmp/debt-sweep-build.log >/dev/null
grep -E "warning <CODE>" /tmp/debt-sweep-build.log | sed 's/ \[.*//' | sort -u | wc -l   # distinct sites

Run this build once in Phase 3 (it doubles as the baseline build) and reuse the log for every build: detect this run.

Phase 3: Pick theme

  1. --theme if given; else: order themes by last_swept ascending (never first), skip remaining: 0 and skip any theme carrying a parked: value. The inbox theme is exempt from the zero-skip — re-run its detect first and use that count. Its contents are appended between sweeps by processes that never touch the central remaining field (a /section-doctor run writing a section ledger, anyone adding a one-off), so a stale 0 there would retire the inbox permanently while real debt piled up in the files it pools. The detect is a grep -c; running it every time is free.
  2. Run the candidate's detect to confirm remaining > 0. If 0 → apply the drain rule (below), update the entry, take the next candidate.
  3. Enumerate the theme's concrete items (file list from grep, baseline lines, distinct warning sites). Order items so anything in a recent_sections section is worked last.
  4. Fold in inbox items that match the chosen theme — from the central ledger and every section file, one pool. An item's file decides who edits it in Phase 5, never whether it is eligible here.

Parked themes: a theme with a parked: "<reason>" value is off the table — Peter has decided the work must not happen yet. Rotation skips it, and --theme=<parked-id> refuses: report the parked reason and stop, never work it. Only Peter removes the field. Parking is orthogonal to remaining — a parked theme keeps its real count so --inventory stays honest, and it is never retired or evicted, at remaining: 0 or otherwise: the entry is the park, and deleting it would let the staleness check re-create the theme unparked the moment the debt reappears.

Drain rule: when a theme hits 0 and a structural enforcer guards regression (analyzer at Error with no remaining grandfathers; architecture test whose baseline is empty), retire the entry — delete it from the ledger and note it in the report. The Phase 2 staleness check re-creates it if the debt ever reappears. Themes without an enforcer stay listed at remaining: 0 and are only re-checked by --inventory. Parked themes are exempt — set remaining: 0 and leave the entry (and its parked: value) alone.

Phase 4: Work loop

Until budget exhausted or theme drained, per item (one item or one tight cluster per commit):

Budget checks are real clock reads, never estimates. Between items run date -u +%H:%M and compare against the Phase 0 start time. Narrative time-feel drifts badly (first run stopped at 27 real minutes while "estimating" 85); the only valid stop-on-budget is one backed by a date call in the transcript.

  1. Fix it right — no surgical fixes (constitution). Reuse-first; match existing patterns (the theme's notes often names the reference implementation).
  2. dotnet build Humans.slnx -v quiet.
  3. Targeted tests: the touched section's tests + --filter the Architecture tests. Full dotnet test Humans.slnx -v quiet at minimum before each push.
  4. EF verification (items changing the persistent model): follow section-migrations-in-maintenance. Generate the owning context's migration with dotnet ef, inspect its snapshot diff, run has-pending-model-changes with that context and project, and pass the EF migration review gate before commit. Use memory/process/ef-multi-context-commands.md for the context/project pair. A migration is allowed only when the item set out to change the schema. Drift the item did not intend → revert the item, record it (Phase 7 question or inbox), continue; the unattended loop never generates a migration to absorb a surprise. Code-only changes that cannot alter the schema need no EF tooling.
  5. Forbidden-move grep on the item diff: #pragma warning disable HUM, [SuppressMessage, new [Grandfathered], // ReSharper disable, visibility narrowing that dodges a rule rather than fixes it. Any hit → revert the item, record in report. Exception (debt-sweep-standing-policy D12): a new [Grandfathered] that makes already-existing debt visible to an analyzer is allowed — say so in the commit message. Also forbidden (judgment, not grep): splitting a controller method into controller-local helpers (private methods, static helpers, local functions, VM factories) to satisfy a per-method metric. The metric is a proxy for "no business logic in controllers" — the fix is a service move, or an honest "this is presentation; the threshold is miscalibrated" finding (grandfather stays, record it). Rejected and reverted wholesale on 2026-06-12.
  6. review: panel themes only: dispatch a second-opinion reviewer subagent — opus-tier, read-only, score-blind, default-reject (refactor-swarm posture): "is this fix a good idea, not merely green — name the concept that improved in one sentence." Name it debt-review-<item>-opus, description tagged (opus). Reject → rework once; persistent reject → revert, skip item, record.
  7. Commit with a one-line debt(<theme-id>): <what> message. Push every 3–5 items.

Rules of the loop:

  • Standing policy first: debt-sweep-standing-policy (D1–D13) decides what is pre-approved, what closes outright and what is not debt. Rule-prescribed contract changes (D1) are done and listed in the PR under Pre-approved contract changes; internal types are never public surface (D2). No category-bin skips (D4): every skipped item gets a one-line code check first; a failed check means close it.
  • Stop-and-ask classes are skip-and-ask classes here: a NEW interface, service or endpoint (interface-method-additions-are-debt, minus the D1 shapes), required columns, privilege changes → skip the item, queue a Phase 7 question in D3 format. A storage drop is never a Phase 7 item: no-drops-until-prod-verified gives every destructive migration its own PR, so an item whose migration would drop storage is skipped and recorded as separately scoped work, never bundled into the sweep PR on a Phase 7 yes. Substantial architecture transitions also go to explicit planning and dedicated PRs. Never block the loop waiting.
  • Off-theme debt discovered while working → append to an inbox: the owning section's file when one section owns the fix (any section — writing another's ledger is intended), the central ledger otherwise. Never chased.
  • Mechanical edit fan-out is allowed via edit-only subagent workers (sonnet, named <task>-sonnet, absolute $WORKTREE paths, no git/build); the orchestrator owns all git and build commands.
  • An item that can't be made green after a genuine attempt → revert it cleanly, record, continue. Never leave the branch red between commits.

Phase 5: Ledger update + report

In the worktree:

  1. Theme entry: last_swept: <today>, remaining: from re-running detect, apply drain/retire rule.
  2. recent_sections: ← dominant sections of the last ~3 sweeps (this one included).
  3. Add Phase 2 staleness discoveries; append work-loop inbox items; remove inbox items completed this run — from whichever file holds each one, central or section; apply --inventory evictions. A section file drained to its last entry keeps an empty inbox: [] — never delete the file; deleting it is a destructive action needing Peter's per-instance approval (memory/process/no-destructive-actions-without-approval.md), and an empty ledger costs three lines.
  4. Overwrite docs/debt/last-report.md: timestamp, theme, budget used; items fixed (one line each: what + commit sha); items skipped + why (schema, interface-addition, panel-reject, budget); forbidden-move reverts; inbox additions; ledger changes (new themes, retirements, evictions).

Commit ledger + report with the work (same PR).

Phase 6: PR

git push -u origin debt-sweep/$TS
gh pr create --repo peterdrier/Humans --base main \
  --title "debt: <theme title> — N items" \
  --body "$(cat <<'EOF'
## Theme
<theme id — one-line description>

## Fixed
<per-item bullets>

## Pre-approved contract changes
<D1 change — signature before → after — prescribing rule>

## Skipped
<item — reason>

## Ledger
<delta: counts, new themes, retirements>

Report: `docs/debt/last-report.md` (committed in this PR).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"

One PR per sweep. Print the PR URL.

Phase 7: Resolve review items inline (no homework)

After the PR is open and before teardown, present every item that needs Peter's judgment inline in chat — numbered, each answerable cold by someone who has NOT read the ledger (D3): what the code does today, what would change, why it matters, then a yes/no proposal with a concrete signature. A row id alone is never enough. Items: skipped schema/interface items, panel rejects worth debating, uncertain classifications, anything queued during the loop. The report is the record, not the delivery channel — assume Peter never opens it. Inline prose, never the AskUserQuestion tool (project rule).

Wait for answers. Apply resulting edits in the worktree, git add + new git commit (a bare push after editing sends nothing), update the report's skipped/questions sections with each resolution, git push.

Zero judgment calls → say so in one line and proceed.

Phase 8: Teardown

Only after Phase 7 resolves: cd $REPO_ROOT && git worktree remove $WORKTREE (--force only if Phase 6 errored). Never rm -rf. Branch stays on origin until the PR closes. Nothing to tear down in a cloud run — there is no worktree, and the container is reclaimed anyway.

Adding debt to the ledger (any session, any time)

  • Recurring class → append a themes: entry with last_swept: never (rotation serves it next automatically). Pick review: honestly: light only when the fix is rule-prescribed and the verifier is mechanical.
  • One-off item → append to an inbox: with added: <date>, an id: allocated from that file's next_id: header (bump next_id: in the same edit), and a one-line what: — src/Sections/Humans.<X>/Docs/debt.yml when the fix lives in one section, docs/architecture/debt-ledger.yml otherwise. Match the entry shape and id format in memory/process/debt-ledger-additions.md exactly — read it before writing the row.
  • Ledger-only changes ride the discovery PR or go direct to origin/main per no-direct-to-main.

Standing constraints

  • Section-owned migrations are allowed when the item needs them, under section-migrations-in-maintenance. Migrations and snapshots are generated; existing review and approval requirements remain. Substantial architecture transitions are explicitly scoped tasks, not sweep items.
  • Never touch [DontFix] — Peter-applied permanent exceptions; skip those sites entirely.
  • No analyzer suppressions in any form (no-analyzer-suppressions).
  • No data migrations / backfills (no-data-backfills).
  • Explicit subagent models, tagged in name + description (sonnet workers, opus-tier panel reviewers).
  • The sweep touches only: the theme's item files and their required section-owned migrations/snapshots, docs/architecture/debt-ledger.yml, the src/Sections/*/Docs/debt.yml files whose items it worked, and docs/debt/last-report.md.
  • After the run, update docs/architecture/maintenance-log.md per maintenance-log-update (separate from the sweep PR if needed).

Failure modes

FailureBehavior
Ledger YAML parse errorAbort before any work; report
detect command failsSkip theme, pick next; record
Item breaks build/tests, can't right itRevert item, record, continue
Panel rejects twiceRevert, skip, record
Unintended EF model driftRevert item, record, continue (intended schema changes carry their generated migration through the review gate)
Budget hit mid-themeNormal: commit what's done; ledger carries the remainder
Push / PR failsWorktree retained; fix manually

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

check-pr

無料

Check an externally created PR for coding rule violations against memory/INDEX.md atoms and docs/architecture/code-review-rules.md.

日本語の概要は準備中です。原文の説明を表示しています。

nobodies-collective/Humans32026年10月7日 更新

Two-phase memory hygiene. Phase 1: scan external Claude Code memory (~/.claude/projects/<slug>/memory/) for durable rules to migrate into the repo and entries already duplicated by repo atoms. Phase 2: audit in-repo memory/, CLAUDE.md, docs/architecture/, and docs/sections/ for dead links, duplication, drift, and bloat.

日本語の概要は準備中です。原文の説明を表示しています。

nobodies-collective/Humans32026年10月7日 更新

Review, repair and steward the nightly Codex debt-sweep PR (branch codex/daily-debt/<date>). Judges every commit GOOD / REPAIR / REVERT, triages the bot review findings through /fix, lands one round-1 commit, files follow-up issues, then stewards the PR itself with a 3-round ceiling. Run by the 08:00 UTC cloud routine; also '/debt-review', '/debt-review 1789'.

日本語の概要は準備中です。原文の説明を表示しています。

nobodies-collective/Humans32026年10月7日 更新

ef-regen

無料

Scrap and regenerate the in-flight EF migrations on the current branch as one consolidated migration. Use when migrations have accumulated mid-development cruft (added/removed columns, stacked add-column-to-existing-table fixes, hand-edited SQL that needs to come out, schema changes that should have been one migration but ended up as five), or when the branch has merged main and its migrations are now stuck mid-chain so `dotnet ef migrations remove` is unsafe. Triggers on phrases like 'regen the migrations', 'redo these migrations', 'scrap and regen migrations', 'consolidate the in-flight migrations', 'redo the migration stack', or any time an agent hits the mid-chain situation in `memory/architecture/migration-regen-after-rebase.md`.

日本語の概要は準備中です。原文の説明を表示しています。

nobodies-collective/Humans32026年10月7日 更新

Use when a sprint tracking issue (label `sprint`) on peterdrier/Humans needs working — routine-fired cloud runs, or any unattended session told to execute the sprint queue.

日本語の概要は準備中です。原文の説明を表示しています。

nobodies-collective/Humans32026年10月7日 更新

finish

無料

End-of-session cleanup for coding and project work. Use when the user says "finish", "wrap up", "done for now", or any variation of ending a work session.

日本語の概要は準備中です。原文の説明を表示しています。

nobodies-collective/Humans32026年10月7日 更新

nobodies-collective のスキルをすべて見る

このスキルの問題を報告する