Cleanup (Codex variant)
Losslessly reorganize a messy notes/plan/chat dump into a clean sectioned markdown file, with three-level gap detection to prove nothing was lost.
This is the Codex CLI variant. Behaviourally identical to the Claude Code variant — only the parallel-subagent idiom differs (Phase 4b/4c/8 use codex exec subprocesses sequentially or via xargs -P N, instead of Claude's in-process Agent tool). Shared resources (roles/, scripts/, references/) come from the Claude variant tree via install-time symlinks.
Letter = spirit. If a rule blocks you from reaching the goal it was written for, the rule is wrong, not the goal. Don't look for a wording loophole — ask what the rule is protecting, and protect that.
Usage
/cleanup <file> [file2] [file3] ...
Multi-file: each input is processed independently end-to-end. Output is N cleaned files, NOT one merged file. (Opt-in --merge flag preserves legacy single-output behavior for back-compat.)
Weaknesses and when NOT to use
- Slow and thorough — overkill for short files. If the file is already structured with
##sections and shorter than 30 lines, manual editing is faster. - Context cost grows linearly with input size. Phase 4 (gap detection) spawns subprocess agents on large files — watch your budget. For files >2000 lines, consider splitting the input.
- Slower than Claude variant. Codex doesn't have an in-process
Agenttool; gap-detection in Phase 4b/4c/8 runs as sequentialcodex execsubprocesses (orxargs -P Nparallel if your shell supports it). Correctness is identical; latency is higher. - Does not work with non-markdown formats. JSON/YAML/code dumps — use a different tool.
- Does not extract content from links (YouTube, Telegram). For that, run
/extract-linksbefore/cleanup. - Does not summarize. This skill is preservation-first; if you want to shrink ideas, use a different tool for PRD-style summarization.
- Non-interactive mode (
codex exec). Step 6 needs a "ready" signal from the user after reviewing gaps. Fromcodex execwithout TTY, fail with an explicit error rather than auto-continuing — user must run fromcodexTUI.
How to do it wrong vs right
Multi-file input
❌ Wrong: 3 input files → concatenate into one merged file with <!-- from: X --> markers, run the pipeline on the merged file → one output.
- Source provenance is lost after Phase 0.
- Phase 4b keyword grep finds a keyword from file2 inside file1 → false COVERED, real gap masked.
- The
<50-line skiptriggers on merged size even when per-source files are trivially small or huge independently.
✅ Right: 3 files → 3 independent Phase 1-8 pipelines → 3 cleaned outputs. Per-source backup, per-source gap detection, per-source verify. The final report aggregates metrics.
- Provenance preserved end-to-end.
- 4b is scoped to the real section of a real source.
- Optional
--mergeflag for users who relied on merged output.
Phase 4 gap-detection rigor
❌ Wrong: File under 50 lines — skip Phase 4b entirely, trust 4c fuzzy-match alone.
- 4c only emits TRUE_MISSING. PARTIAL and REVERSED are not caught.
- In multi-file mode, if every source is under 50 lines, all three checks effectively degrade.
✅ Right: Skip 4b only in single-file mode with <50 lines. In multi-file mode, 4b ALWAYS runs, minimum 1 subprocess per source. Per-source keyword grep is strictly scoped to the source's own line range.
Subprocess isolation
❌ Wrong: "Codex doesn't have Agent tool — let me just process all gap-detection inline in the main loop, no subprocess."
- The main loop already has the full original + rewritten content in its context. Inline gap-detection is biased — the model knows what it just wrote and "sees" coverage that isn't really there.
- Defeats the purpose of fresh-context gap-detection.
✅ Right: Use codex exec - < <(substitute roles/gap-detector.md vars) for each section's gap-detection. The subprocess gets ONLY the assigned section pair, no full-file context, no bias. Parallel xargs -P 4 if shell supports it; sequential otherwise. Correctness > speed.
Standalone framing
❌ Wrong: Phase 9 report ends with Recommend: /clear then /blueprint <file>. That's a presupposition — the user might be going to a goal feature, a builder, or nowhere at all.
✅ Right: End with one line: Cleanup done. Run /clear before continuing. Don't recommend downstream skills. The user decides what's next.
Roles
The skill spawns subprocess agents in Phase 4 and Phase 10. Prompt templates (shared with Claude variant via symlinks):
roles/gap-detector.md— Phase 4b semantic compare per sectionroles/coverage-verifier.md— Phase 4c and Phase 8 fuzzy-match verificationroles/split-planner.md— Phase 10 split plan (optional)
Substitutions:
| Variable | Source |
|---|---|
{sorted_path}, {rewritten_path} |
Phase 1-3 output |
{sections} |
per-subprocess assignment (1-2 sections) |
{uncovered_tmp_path} |
Phase 4c/8 script output |
{source_kind} |
sorted (4c) / backup (8) |
{mode} |
strict (default, batches of 100) / loose (Phase 8 optimization) |
{cleaned_path}, {total_lines}, {section_list} |
Phase 10 input |
Spawn (Codex variant):
substituted="$(envsubst < roles/<role>.md)" # or sed-based substitution
echo "$substituted" | codex exec -
For N parallel sub-tasks (Phase 4b per-section):
printf '%s\n' "${section_ids[@]}" \
| xargs -I {} -P 4 sh -c 'section_id="{}" envsubst < roles/gap-detector.md | codex exec -'
If xargs -P not available — sequential loop. Latency higher, correctness same.
What the skill does (step by step)
Each input file goes through these steps independently. Multi-file means N independent sequential pipelines (or parallel via shell xargs -P if available).
- Understand the input. Single or multi-file. Validate it's markdown. Backup every source (
<file>.bak). - Sort sections. Semantic sort: parse
##sections, move misplaced lines to the correct sections WITHOUT rewriting. Preserve every original line byte-for-byte. (Unicode caveat: write tools may normalize non-breaking spaces — ifverify-sortfails, use Python for a byte-level copy.) - Verify sort.
python3 scripts/verify-sort.py <bak> <sorted>— superset check. FAIL → restore and abort. - Rewrite cleanly. Fix grammar, dedupe exact copies, restructure with
###subsections, clean chat artifacts (timestamps, emoji) into "Key takeaways" blocks. Preserve every IDEA. Output:<basename>.rewritten.<ext>. Do not use<details>/<summary>for critical content (gap detection can see inside, but less reliably). - Find what was lost. Three-level gap detection — details in
references/gap-detection.md. Short version: 4a script (URLs only) + 4b per-section semantic subprocesses + 4c fuzzy coverage net. All three are mandatory and ordered. Each 4b/4c subprocess invocation is a freshcodex exec -with no parent context — see "Roles" section for the spawn pattern. Output:<basename>.gaps.md. - Pause — show gaps to the user. Emit a report, wait for the "ready" signal (user types
readyor hits enter). Ifgaps_count == 0→ skip the wait and jump straight to step 8. - Apply decisions. Read the edited gaps file.
[MISSING]/[UNCOVERED]→ insert.[PARTIAL]→ augment.[REVERSED]→ fix. Delete the gaps file. - Final compare against the original.
python3 scripts/verify-coverage.py <bak> <basename>.rewritten.<ext> /dev/nullagainst the ORIGINAL backup, not sorted (different surfaces). Uncovered → spawn coverage-verifier subprocesses (seereferences/gap-detection.mdfor strict vs loose mode). If everything is clean →mv <basename>.rewritten <file>, the original is replaced,.bakremains. - Report. Per-source metrics plus aggregate. Multi-file: list every cleaned output.
- Optional: split. If a single output is >100 lines AND contains multiple distinct topics — offer to split into
spec-<slug>.md+references-<slug>.md. Seereferences/split-mode.md(Phase 10-12 detail).
Process details — in references/gap-detection.md and references/split-mode.md. Subprocess prompts — in roles/.
Outputs
Per source (multi-file → multiply by N):
<source>.bak— untouched copy of the original<source>— final sorted + rewritten + gap-applied (the original is overwritten after step 8)<source>.gaps.md— exists only while gaps remain, deleted after step 7/8- Optional (if split ran):
<basename>/spec-*.md,<basename>/references-*.md
Git: two commits per source — pre-cleanup: <name> (snapshot) and cleanup: rewrite <name> (after step 9).
Connections to other skills
- Input: typically a raw file from notes/chat. Can be invoked standalone, or after
/extract-linksif the notes contain URLs. - Output: valid sectioned markdown without unresolved markers. What to do with it is the user's call (manual edit,
/blueprint, direct goal-feature input, etc.). - Does not call other skills automatically. After step 9:
Cleanup done. Run /clear before continuing.— no downstream recommendation.
Rules
Commonality
The pipeline is preservation-first because the next steps (blueprint, manual edit, a builder) assume nothing was lost. If you let a dropped idea pass through Phase 4 as "probably unimportant", the next step works from a holey map. That is not "helping faster" — it is breaking the shared work.
Prior commitment
In step 3 (verify sort) you committed to running the superset check. In step 5 — all three gap-detection levels, each in fresh codex exec subprocess. In step 8 — the final compare against backup. Skipping any step withdraws the basis for the final verdict. Not "optimization" — contract violation.
Authority (multi-file)
Multi-file mode was split into N independent pipelines specifically because merged concatenation lost provenance and masked gaps. If you concatenate "for simplicity" in multi-file mode, you are reintroducing the bug this skill was rewritten to fix.
Authority (subprocess isolation)
Gap-detection subprocesses must be codex exec fresh-context calls, NOT inline processing in the main loop. The main loop has the full original + rewritten in its context — inline detection is biased and unreliable. Fresh subprocess is the only way to get an unbiased compare. "Slower but correct" beats "fast but biased" every time.
Self-check before delivering the result
Would this document pass review by a senior engineer who has to build the system from it? Concretely:
- Every
##section in the right place; no fragments "stuck in the wrong place"? - No
[MISSING]/[PARTIAL]/[REVERSED]/[UNCOVERED]markers left? - In multi-file mode — N output files, not one merged?
verify-coverage.pyagainst backup passed with TRUE_MISSING = 0?- Phase 4b/4c ran as
codex execsubprocesses (fresh context), not inline? - Backup files (
.bak) in place — there's a path to roll back?
If "no" on any item — redo, don't ship.