Skip to content

feat(skills): add /issue_cleanup — issue-tracker reconciliation door - #175

Merged
Jammy2211 merged 2 commits into
mainfrom
feature/issue-cleanup
Jul 28, 2026
Merged

feat(skills): add /issue_cleanup — issue-tracker reconciliation door#175
Jammy2211 merged 2 commits into
mainfrom
feature/issue-cleanup

Conversation

@Jammy2211

Copy link
Copy Markdown
Contributor

Closes #174.

Adds /issue_cleanup, the missing door for reconciling the GitHub issue trackers — the issue-tracker counterpart to /repo_cleanup's git-debris sweep. Same proven shape: audit → bucketed dashboard → per-bucket human confirmation → execute → recap.

Why

Nothing owned this. /repo_cleanup sweeps branches, refs, stashes and worktrees and stops there; /community handles external users' issues awaiting a reply; /create_issue and /update_issue are single-issue primitives. The trackers had drifted to 82 open issues across 18 repos, of which 35 were closable. An ad-hoc sweep on 2026-07-28 cleared those (29 shipped-but-still-open + 6 obsolete 2018–2019 PyAutoCTI), leaving 47.

The reasoning is the deliverable

A naive "a complete/ record references this issue, so close it" rule is wrong five ways, each found by verification rather than inspection:

  1. Body mentions are not claims — only header lines are evidence, and only for a known set of keys. Records use - notes: for long prose that cites issue URLs freely, so "any - word: line" re-admits exactly the prose the rule exists to exclude.
  2. The header key carries the meaningissue: (630 uses) completes; followup-issue: / library-followup-issue: / parent-issue: / upstream-issues-filed: / plan: (13 uses) mean the record spawned a still-open issue. Completing keys are an allowlist, so a new spawn-style key fails closed.
  3. Annotations and status override(open — …), (STAYS OPEN — …), and Status: issued. A record can sit in complete/ having merely filed its issue (ep-hierarchical-scale-collapse.mdPyAutoFit#1405, a live bug).
  4. A phase-scoped claim does not complete an umbrella — four records each claim a Phase 5 item of PyAutoBrain#130; none establishes it is done.
  5. Age is not evidence of obsolescence — probe whether the named API still exists. Six PyAutoCTI issues (2693–2785 days) closed on a zero-hit grep of autocti/; PyAutoHands#16/#17 are the same ~1337-day vintage but stayed open as still-valid unimplemented asks.

Closing requires two independent evidence legs (record header + merged PR) and always a human confirmation. The PR leg checks both the GitHub timeline and a PR named in the record body — timeline alone under-reports (12 of the 29 had only the latter).

Regression bar

Rules 1 and 4 were caught by the skill's own bar, not by inspection — which is why the bar ships with it. It pins the post-sweep state (47 open · A=0 · B=1 · C=7 · spawn-held=3 · D=6 · E=8 · F=22) and names the two traps explicitly: PyAutoGalaxy#417 must land in the backlog rather than a held bucket (or the header allowlist has regressed), and PyAutoBrain#130 must land in B rather than A (or umbrellas are being closed on partial evidence). Verified passing at the tip of this branch.

Also in this PR

  • COMMANDS.md gains a maintenance doors tier documenting /repo_cleanup and /issue_cleanup as complements — neither was previously listed there.
  • /wake_up gains a read-only issue-drift step, so drift surfaces daily instead of at 82-issue depth. The audit half is safe unattended; every close stays human-gated.

Notes for review

  • Docs/skill-only change — no source, no tests to run. The behavioural check is the regression bar above.
  • gh issue close is broken in this environment; the skill uses the comment + gh api -X PATCH pair, with state_reason completed vs not_planned.
  • The two ~/.claude symlinks are intentionally not created here — bin/install.sh run from a worktree repoints ~/.claude at that worktree. Run it from the canonical checkout after merge.

🤖 Generated with Claude Code

No skill owned the GitHub issue trackers: /repo_cleanup sweeps git debris
only, /community handles external users' issues, and /create_issue and
/update_issue are single-issue primitives. The trackers had drifted to 82
open across 18 repos, 35 of them closable.

Adds /issue_cleanup as the issue-tracker counterpart to /repo_cleanup,
following the same audit-first shape: audit -> bucketed dashboard ->
per-bucket human confirmation -> execute -> recap. Closing requires two
independent evidence legs (a PyAutoMind record header plus a merged PR)
and always a human confirmation.

The reasoning is the deliverable. A naive "record references the issue ->
close it" rule is wrong five ways, each found by verification:

1. Body mentions are not claims — only header lines are evidence, and only
   for a known set of keys (`- notes:` prose cites issue URLs freely).
2. The header KEY carries the meaning: `issue:` completes, but
   `followup-issue:`/`parent-issue:`/`plan:` mean the record SPAWNED a
   still-open issue. Completing keys are an allowlist so new spawn-style
   keys fail closed.
3. Inline `(open …)`/`(STAYS OPEN …)` annotations and `Status: issued`
   override — a record in complete/ can have merely FILED its issue.
4. A phase-scoped claim ("(Phase 5 item 4)") does not complete an umbrella.
5. Age is not evidence of obsolescence — probe whether the named API still
   exists. Six 2018-19 PyAutoCTI issues closed on a zero-hit grep; two
   PyAutoHands issues of the same vintage stayed open as still-valid asks.

Rules 1 and 4 were caught by the skill's own regression bar rather than by
inspection, which is why the bar is part of the skill: it pins the
post-sweep state (47 open / A=0 / B=1 / C=7 / F=22) and names the two
traps — PyAutoGalaxy#417 must land in the backlog, not a held bucket, and
PyAutoBrain#130 must land in B, not A.

Also wires the door into COMMANDS.md as a new "maintenance doors" tier
alongside /repo_cleanup, and adds a read-only issue-drift step to /wake_up
so drift surfaces daily instead of at 82-issue depth. The audit half is
safe to run unattended; every close stays human-gated.

Refs #174

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… as Claude

The body referenced sibling doors in Claude-only /verb notation. Switch to
the established $verb form used elsewhere ($repo-cleanup, $community,
$create-issue, $update-issue, $hygiene, $wake-up), keeping one explicit
dual-notation line so the Claude spelling is still discoverable.

Also records why this skill is the harness-portable half of the cleanup
pair: it needs only an authenticated gh and a readable PyAutoMind/, so it
runs on Codex and mobile where /repo_cleanup cannot. Adds the constraint
that no step may depend on a local checkout, a Claude-only tool or a
~/.claude path, and notes that SKILL.md's `name:` must stay hyphenated
because Codex takes its skill name from it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: /issue_cleanup — GitHub issue-tracker reconciliation door

1 participant