Skip to main content

cleanup-completed-issues

Guide for archiving closed issue specification files from docs/issues/open/ to docs/issues/closed/. Covers verifying closure on GitHub, moving files, updating frontmatter, auditing and repairing affected documentation links, creating a branch, and opening a PR. Permanent deletion of closed specs is not automated — the user must explicitly request it. Use when cleaning up closed issue specs, archiving issue docs, or maintaining the docs/issues/ folder. Triggers on "cleanup issue", "archive issue", "move closed issue", "clean completed issues", or "maintain issue docs".

Informações da origem

Repositório
torrust/torrust-tracker
Última atividade na origem
7 de outubro de 2026 às 14:46
Idioma detectado do SKILL.md
inglês
Estrelas
532
Forks
56

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
cleanup-completed-issues
description
Guide for archiving closed issue specification files from docs/issues/open/ to docs/issues/closed/. Covers verifying closure on GitHub, moving files, updating frontmatter, auditing and repairing affected documentation links, creating a branch, and opening a PR. Permanent deletion of closed specs is not automated — the user must explicitly request it. Use when cleaning up closed issue specs, archiving issue docs, or maintaining the docs/issues/ folder. Triggers on "cleanup issue", "archive issue", "move closed issue", "clean completed issues", or "maintain issue docs".
metadata
{"author":"torrust","version":"1.11"}
# Cleaning Up Completed Issues ## Lifecycle Closed issue specs follow this lifecycle: 1. **Archive** (automated by this skill): When an issue is closed, move its spec file from `docs/issues/open/` to `docs/issues/closed/`. The file stays in the closed buffer as a reference for ongoing and upcoming work. 2. **Permanent deletion** (user-driven): If the user wants specs permanently deleted, they will explicitly ask for it. This skill does not automate deletion. See [`docs/issues/closed/README.md`](../../../../../docs/issues/closed/README.md) for the purpose of the closed buffer folder. Related lifecycle docs: - Open issue specs: [`docs/issues/open/README.md`](../../../../../docs/issues/open/README.md) - Closed issue buffer: [`docs/issues/closed/README.md`](../../../../../docs/issues/closed/README.md) - Reopening an archived issue or EPIC: [reopen-issue](../reopen-issue/SKILL.md) <!-- skill-link: reopen-issue --> ## When to Archive - **After PR merge**: Move the issue file when its PR is merged and the issue is closed on GitHub. - **Batch archive**: Periodically move multiple closed issue files during maintenance. - **Before releases**: Tidy `docs/issues/` before major releases. ## Prerequisites - GitHub CLI (`gh`) must be authenticated and have access to the `torrust/torrust-tracker` repository. ## Step-by-Step Process ### Step 0: Create a Working Branch (Mandatory) Always create a new branch for this work. Never commit directly to `develop`. Start from an up-to-date `develop`: ```bash UPSTREAM_REMOTE="${UPSTREAM_REMOTE:-torrust}" git checkout develop git pull --ff-only "$UPSTREAM_REMOTE" develop git checkout -b chore/cleanup-completed-issues ``` > **Edge case — branch already exists**: If a branch named `chore/cleanup-completed-issues` > already exists (e.g., from a previous aborted run), first delete it, then recreate: > > ```bash > git branch -D chore/cleanup-completed-issues > git checkout develop > git pull --ff-only "$UPSTREAM_REMOTE" develop > git checkout -b chore/cleanup-completed-issues > ``` > > This ensures the branch is based on the latest `develop` and carries no stale commits > from the prior attempt. If the branch has already been pushed to a remote, you may also > need to delete it there: > > ```bash > git push "$FORK_REMOTE" --delete chore/cleanup-completed-issues > ``` ### Step 0.5: Discover Archive Candidates (Mandatory) All new issue specifications use directories. Scan directory specs under `docs/issues/open/` and include legacy single-file specs while they remain: ```bash echo "[open issue folders]" find docs/issues/open -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | sort echo "[legacy open single-file specs]" find docs/issues/open -maxdepth 1 -type f -name '*.md' \ ! -name 'README.md' ! -name 'AGENTS.md' -exec basename {} \; | sort ``` Optional unified number extraction for batch state verification: ```bash { find docs/issues/open -maxdepth 1 -mindepth 1 -type d -exec basename {} \; find docs/issues/open -maxdepth 1 -type f -name '*.md' \ ! -name 'README.md' ! -name 'AGENTS.md' -exec basename {} \; } | sed -E 's/^([0-9]+).*/\1/' | sort -n | uniq ``` ### Step 0.6: Reconcile Drafts That Already Have a GitHub Issue (Mandatory) During issue-document maintenance, inspect `docs/issues/drafts/` for specifications whose frontmatter has a non-null `github-issue`. A draft must not remain in `drafts/` once it is linked to a GitHub issue: - if the GitHub issue is open, move the spec to `docs/issues/open/` using the assigned issue number; - if the GitHub issue is closed, include the spec in this archive operation and move it directly to `docs/issues/closed/`; and - update `status`, `spec-path`, `related-pr`, and workflow checkpoints to match the recorded state. Use the GitHub state check in Step 1 before choosing either destination. Do not assume a draft is unopened merely because it is still filed below `docs/issues/drafts/`. ### Step 0.7: Block EPIC Closure While Draft Subissues Remain (Mandatory) Do not close or archive an EPIC merely because all currently created GitHub child issues are closed. Before treating an EPIC as a closure candidate, run this check after reconciling linked drafts in Step 0.6. It detects both the EPIC-number-prefixed draft-directory convention and explicit parent declarations or links: ```bash EPIC_NUMBER=1669 { find docs/issues/drafts -maxdepth 1 -mindepth 1 -type d -printf '%p\n' | rg "/${EPIC_NUMBER}(-|$)" rg -l -i "(^epic: ${EPIC_NUMBER}$|epic.*\\[#${EPIC_NUMBER}\\]|\\[#${EPIC_NUMBER}\\].*epic)" \ docs/issues/drafts --glob '*.md' } | sort -u ``` If it finds any draft specifications, the EPIC remains open. Do not close its GitHub issue or move its specification to `docs/issues/closed/` until every listed draft has been resolved: create or link its GitHub issue and move the draft according to Step 0.6, or explicitly remove its parent EPIC relationship because it no longer belongs there. Record that resolution in the affected documents before rerunning this check. ### Step 1: Verify Issue is Closed on GitHub **Single issue:** ```bash gh issue view {issue-number} --repo torrust/torrust-tracker --json state --jq .state ``` Expected: `CLOSED` **Batch:** ```bash for issue in 21 22 23 24; do state=$(gh issue view "$issue" --repo torrust/torrust-tracker --json state --jq .state 2>/dev/null || echo "NOT_FOUND") echo "$issue: $state" done ``` ### Step 2: Move Issue Specification to `docs/issues/closed/` **Directory specification:** ```bash git mv docs/issues/open/42-my-subissue-folder/ docs/issues/closed/ ``` **Legacy single-file specification:** ```bash git mv docs/issues/open/42-add-peer-expiry-grace-period.md docs/issues/closed/ ``` **Batch files:** ```bash git mv docs/issues/open/21-some-old-issue.md \ docs/issues/open/22-another-old-issue.md \ docs/issues/closed/ ``` Note: `git mv` on a directory moves all files inside it atomically. ### Step 3: Update Frontmatter of Moved Files After moving, update the spec's YAML frontmatter to reflect the closed state: | Field | Before | After | | ------------------ | ----------------------- | ------------------------ | | `status` | `open`, `planned`, etc. | `done` | | `spec-path` | `docs/issues/open/...` | `docs/issues/closed/...` | | `last-updated-utc` | previous date | current date | For directories with multiple files, update at minimum the main `ISSUE.md` or `EPIC.md` plus any supplementary files whose frontmatter references the `docs/issues/open/` path (e.g., `related-artifacts` links to the open spec). For supplementary docs without existing frontmatter, add a minimal block with `spec-path`, `last-updated-utc`, and a `semantic-links` section linking back to the parent issue spec. Also check the spec's **Workflow Checkpoints** section and tick any checkboxes that reflect completed work (manual verification, acceptance criteria review, etc.) based on the actual content of the spec body. Add a progress log entry documenting the archival action. ### Step 4: Audit and Repair Documentation References (Mandatory) An archive move invalidates every live reference to the old `docs/issues/open/...` path. After updating the moved documents' own frontmatter, search the repository for each old path and update all **current** documentation links and references to the new `docs/issues/closed/...` location. This includes: - parent EPIC subissue tables and their frontmatter `semantic-links`; - active issue specs that name the archived issue as a prerequisite, dependency, or related artifact; - ADR frontmatter and body links; and - frontmatter in moved supplementary artifacts (`evidence.md`, manual-verification records, and similar documents) that references the moved primary spec. When modifying an affected document that has YAML frontmatter, keep its metadata current: - preserve its existing `status` unless its actual lifecycle state changed; - update any changed `spec-path` or `semantic-links.related-artifacts` value; and - set `last-updated-utc` to the current date when that field exists. Do not rewrite immutable historical records (for example, past PR review summaries) merely because they accurately record the path that existed at the time. Update them only when they function as a live navigational reference. For each archived issue, search for the old path before finishing. For a single-file spec: ```bash rg 'docs/issues/open/42-add-peer-expiry-grace-period\.md' \ --glob '!target/**' --glob '!storage/**' ``` For a folder spec, search its folder name alone, not the full `docs/issues/open/...` path, so relative links such as `../../open/42-my-subissue-folder/evidence.md` are found too: ```bash rg '42-my-subissue-folder' \ --glob '!target/**' --glob '!storage/**' ``` The local link checker excludes `docs/issues/closed/`, so a stale link in an already archived spec is not reported by `linter all`; this search is the only check for it. The remaining results must be either corrected or deliberately retained historical records. ### Step 5: Update Any Parent Epic Spec If the closed issue was a subissue of an EPIC, update the epic's spec to reflect the new `docs/issues/closed/` path and `DONE` status in its subissue table. Example: if a parent `docs/issues/open/<epic-slug>/EPIC.md` has a table row referencing a subissue at `docs/issues/open/...` with `TODO` status, update both the path and status after archiving. The parent EPIC is also an affected document under Step 4: update its frontmatter `semantic-links` and `last-updated-utc` when applicable. ### Step 6: Validate and Commit Before committing, confirm that every changed Markdown frontmatter block is valid YAML and that each archived primary issue spec has `status: done`, a `spec-path` below `docs/issues/closed/`, and a current `last-updated-utc`. Also run `git diff --cached --check` after staging. ```bash # Single issue git commit -S -m "chore(issues): archive closed issue #42 spec to docs/issues/closed" # Batch git commit -S -m "chore(issues): archive closed issue specs #21, #22, #23 to docs/issues/closed" ``` Run the pre-commit hooks before finishing: ```bash ./contrib/dev-tools/git/hooks/pre-commit.sh ``` ### Step 7: Push and Open a Pull Request ```bash FORK_REMOTE="${FORK_REMOTE:-josecelano}" git push "$FORK_REMOTE" chore/cleanup-completed-issues ``` Open a PR targeting `develop`: ```bash gh pr create \ --repo torrust/torrust-tracker \ --base develop \ --head "${FORK_REMOTE}:chore/cleanup-completed-issues" \ --title "chore(issues): archive closed issue #${N} spec to docs/issues/closed" \ --body "Archives the spec for issue #${N} (closed on GitHub) from \`docs/issues/open/\` to \`docs/issues/closed/\`. - Verified issue #${N} is \`CLOSED\` on GitHub - Updated frontmatter (\`status: done\`, \`spec-path\`, \`last-updated-utc\`) - Updated workflow checkboxes where applicable - Pre-commit hooks passed" ```
Ver no GitHub