Use when user says "purge aped", "clean docs", "tidy aped", "audit docs/aped", "what is in docs/aped", "regenerate aped index", "find orphan docs", "aped doc hygiene", or invokes aped-purge. Walks docs/aped/ (or the configured output_path), classifies every entry as canonical / unknown / archived, regenerates the INDEX.md entry point, and surfaces orphan files (docs Claude wrote outside the APED canon) with a per-file triage menu. Read-only by default — moves and deletes only happen on user c...
Scanned 5/27/2026
Install via CLI
openskills install yabafre/aped-claude---
name: aped-purge
keep-coding-instructions: true
description: 'Use when user says "purge aped", "clean docs", "tidy aped", "audit docs/aped", "what is in docs/aped", "regenerate aped index", "find orphan docs", "aped doc hygiene", or invokes aped-purge. Walks docs/aped/ (or the configured output_path), classifies every entry as canonical / unknown / archived, regenerates the INDEX.md entry point, and surfaces orphan files (docs Claude wrote outside the APED canon) with a per-file triage menu. Read-only by default — moves and deletes only happen on user choice. Not for compaction of historical artefacts (deferred to a future skill); not for state.yaml edits (use aped-status).'
allowed-tools: "Read Edit Write Glob Grep Bash"
allowed-paths:
write: ["{{OUTPUT_DIR}}/**", "{{APED_DIR}}/**"]
read-only: ["src/**", "tests/**", "package.json"]
disable-model-invocation: true
license: MIT
metadata:
author: yabafre
version: {{CLI_VERSION}}
---
<!-- AUTO-GENERATED from SKILL.md.tmpl. Edits will be overwritten. Run: npm run gen:skill-docs -->
**Activation guard (6.2.0):** Before any other action, run `bash {{APED_DIR}}/scripts/check-enabled.sh`. If it exits non-zero, print "APED disabled — run aped-method enable" and HALT.
# APED Purge — Doc Hygiene + Index
Walk the APED output directory. For each entry: canonical / unknown / archived. Regenerate the INDEX entry point. Triage orphans interactively. **Read-only by default** — moves and deletes need explicit user choice per file.
## Activation
Read `{{APED_DIR}}/config.yaml` and resolve `{user_name}` / `{communication_language}` / `{document_output_language}`. ✅ YOU MUST speak in `{communication_language}` and write `INDEX.md` in `{document_output_language}`. HALT if config is missing.
## The canon
These paths under `{{OUTPUT_DIR}}/` are produced by APED skills and considered canonical. Anything else is **unknown** until the user allowlists it.
| Path / glob | Producer skill | Notes |
|---|---|---|
| `state.yaml` | runtime / scaffolder | Pipeline state. |
| `state-corrections.yaml` | `aped-course` / scripts | Append-only correction log (schema v2+). |
| `product-brief.md` | `aped-analyze` | One-shot brief. |
| `prd.md` | `aped-prd` | One-shot PRD. |
| `ux/**` | `aped-ux` | Sharded UX spec (design-spec, screen-inventory, components, flows). |
| `architecture.md` | `aped-arch` | Rolling architecture doc. |
| `adr/000N-*.md` | `aped-arch` | Sharded ADRs (since 6.0.0). |
| `epics.md` | `aped-epics` | Epic + story plan. |
| `epics-context/epic-{N}-context.md` | `aped-story` (compiler) | Cache (since 6.2.0). |
| `stories/*.md` | `aped-story` | One file per story. |
| `retros/*.md` | `aped-retro` | One file per retrospective. |
| `glossary.md` | `aped-glossary` | Canonical domain glossary. |
| `lessons.md` | `aped-retro` | Append-only lessons log. |
| `project-context.md` | `aped-context` | Brownfield project map. |
| `grill-summary.md` | `aped-grill` | Latest alignment grilling summary (overwrite-each-run). |
| `INDEX.md` | `aped-purge` | This skill's entry point output. |
| `.archive/**` | `aped-purge` | Files archived by user choice via this skill. |
| `archive/**` | various | Pre-existing manual archives — left as-is. |
If a project legitimately ships extra docs alongside APED (a project-specific reference, a glossary supplement), surface them once, get user `[K]eep+allowlist`, and they're added to `INDEX.md`'s allowlist section so future runs don't re-flag them.
## Workflow
### 1. Walk
Glob `{{OUTPUT_DIR}}/**` (single pass, exclude `.git`, `node_modules`). For each file, classify:
- **canonical** — matches a path/glob in the canon table.
- **archived** — under `{{OUTPUT_DIR}}/.archive/` or `{{OUTPUT_DIR}}/archive/`.
- **allowlisted** — listed under `## Project-specific allowlist` in the existing `INDEX.md` (if any).
- **unknown** — anything else.
### 2. Regenerate INDEX.md
Write `{{OUTPUT_DIR}}/INDEX.md` with this exact shape (template strict — readable by humans + downstream tooling):
```markdown
# APED Index
_Generated by aped-purge at {ISO 8601}. Re-run aped-purge to refresh._
## Canonical artefacts
| Artefact | Path | Status |
|---|---|---|
| Product brief | `product-brief.md` | ✓ present (last edited {ISO}) | (none) |
| PRD | `prd.md` | … |
| UX spec | `ux/` ({K} files) | … |
| Architecture | `architecture.md` | … |
| ADRs | `adr/` ({M} entries) | … |
| Epics | `epics.md` | … |
| Epic-context cache | `epics-context/` ({N} files) | … |
| Stories | `stories/` ({S} files: {pending}/{ready}/{in-progress}/{review}/{done}) | … |
| Retros | `retros/` ({R} files) | … |
| Glossary | `glossary.md` | … |
| Lessons | `lessons.md` ({L} entries) | … |
| Project context | `project-context.md` | … |
| Grill summary | `grill-summary.md` | … |
| State | `state.yaml` (schema_version: {V}) | … |
| Corrections | `state-corrections.yaml` ({C} entries) | … |
## Sprint snapshot
- Active epic: {sprint.active_epic | none}
- Umbrella branch: {sprint.umbrella_branch | none}
- Stories in-flight: {list}
## Project-specific allowlist
_(Files outside the APED canon that the user has explicitly approved. Re-run aped-purge to add or remove.)_
- {path} — {one-line rationale}
## Archived
_(Files moved to `.archive/` via aped-purge.)_
- {path} (archived {ISO})
```
For "Status" of each row, use:
- ✓ present — file exists, list mtime
- ⚠ stale — file exists but its mtime is older than the most recent canonical input that should have refreshed it (e.g. PRD edited but epics-context not refreshed)
- ⚠ schema-violation — file exists and a structural validator is shipped for it (`{{APED_DIR}}/scripts/validate-{artefact}.sh`), but exits non-zero (drift caught at audit time). Surface advisory; aped-purge is read-only — re-run the producing skill to fix. Validators present in 6.3.0: `validate-story.sh` for `stories/*.md`, `validate-epics.sh` for `epics.md`, `validate-epic-context.sh` for `epics-context/*.md`. If the validator is absent (older scaffold or stripped install), the row stays `✓ present` — no false negatives.
- — absent — phase hasn't run yet (don't flag as a problem; many projects don't use every phase)
### 3. Triage unknowns
For each **unknown** file, present:
```
docs/aped/migration-pattern-modules.md — UNKNOWN
Size: 4.2 KB
Mtime: 2026-04-22T10:14:33Z
Preview: {first 5 non-empty lines}
[A] Archive — move to docs/aped/.archive/migration-pattern-modules.md (recoverable)
[I] Inline into a canonical artefact (you pick which)
[K] Keep + allowlist — add to INDEX.md's allowlist with a one-line rationale
[D] Delete — remove from disk (irrecoverable; require typed confirmation)
[S] Skip — leave the file in place, decide next run
```
⏸ **HALT — wait per file.**
#### `[A]rchive`
Create `{{OUTPUT_DIR}}/.archive/` if absent (gitignored is up to the user — surface a hint). Move the file there preserving relative path. Append to `INDEX.md`'s `## Archived` section.
#### `[I]nline`
Ask which canonical target:
- `architecture.md` — the file gets appended as a new `## {filename-as-section}` section.
- `epics-context/epic-{N}-context.md` — ask for N. Content becomes a `### From {filename}` block under the cache's `## Architecture references` section (or appropriate section based on user choice).
- `lessons.md` — extract Rule + Mistake + Scope, append in lessons format.
- `project-context.md` — append under `## Notes for Development` (brownfield only).
After inlining, delete the source file. Surface the diff to the user before saving.
#### `[K]eep + allowlist`
Prompt for a one-line rationale (non-empty). Append to `INDEX.md`'s `## Project-specific allowlist` section:
```
- {path} — {rationale}
```
Future `aped-purge` runs treat this file as allowlisted, not unknown.
#### `[D]elete`
Surface the full path + size + the first 10 lines of the file. Require the user to type `delete {filename}` exactly. Anything else → cancel and re-prompt with `[A]/[I]/[K]/[S]` as the safer options.
#### `[S]kip`
Leave as unknown. The next `aped-purge` run will flag it again.
### 4. Stale flag triage *(advisory, no auto-action)*
For each ⚠ stale row in INDEX, surface to the user:
```
prd.md is stale — last edited 2026-03-04. epics-context/epic-1-context.md
hasn't been refreshed since (mtime 2026-02-28).
Suggested: run aped-story (it recompiles the cache).
```
This is informational only — `aped-purge` does NOT auto-run other skills.
### 5. Report
After all triage, summarise:
> Purged docs/aped/. {N} canonical, {M} archived, {O} allowlisted, {U} unknown remaining.
> INDEX.md regenerated at {{OUTPUT_DIR}}/INDEX.md.
> Stale artefacts: {comma-separated list, or "none"}.
## Critical rules
- **Read-only by default.** Moves and deletes happen only on explicit per-file user choice.
- **Never auto-archive** — even files that look obviously orphan need user confirmation.
- **Never re-create** archived files automatically — `.archive/` is one-way until the user manually restores.
- **Never delete `state.yaml`, `state-corrections.yaml`, or anything matching the canon.** If the user types `delete state.yaml`, refuse and explain why.
- **The INDEX.md regeneration is always-on** — every run rewrites it from the live walk. Hand-edits to INDEX.md outside the `## Project-specific allowlist` and `## Archived` sections will be overwritten. Surface this once at the start of the run.
## Writing discipline
The INDEX.md and the triage prompts are user-facing — read `{{APED_DIR}}/aped-skills/writing-discipline.md` first. Short status lines, concrete file:line citations, no padding. The INDEX is a map, not a narrative.
## What this skill is NOT
- Not a state.yaml editor — use `aped-status` to inspect, `aped-course` to mutate at a sprint level.
- Not a compactor (yet) — moving done-epic caches to `.archive/` automatically is deferred to a future skill.
- Not a hook — runs only when the user explicitly invokes it.
- Not a code linter — it audits docs, not source.
## Common Issues
- **`.archive/` keeps growing** — that's expected; the skill never auto-prunes. Add a `git clean -fX` or manual `rm` if archives have piled up.
- **A canonical file is flagged as unknown** — the canon table didn't match (typo in the path, or the file lives outside `{{OUTPUT_DIR}}/`). Surface to the user; they update the canon (PR back upstream).
- **The user keeps `[K]eep+allowlist`-ing the same file** — propose adding a comment in the file pointing at why it's kept, or moving its content into the closest canonical artefact instead.
## Output
- `{{OUTPUT_DIR}}/INDEX.md` — always rewritten.
- Files moved to `{{OUTPUT_DIR}}/.archive/<original-relative-path>` on `[A]rchive`.
- Files inlined into a canonical artefact + source deleted on `[I]nline`.
- INDEX's `## Project-specific allowlist` extended on `[K]eep+allowlist`.
- No state.yaml writes — `aped-purge` is doc hygiene, not pipeline state.
## Next step
Manual. The user runs `aped-purge` when they sense doc drift, or after a long sprint, or when an epic ships and they want a clean baseline before the next one.
No comments yet. Be the first to comment!