AI-Generated Junk Files
Impact: HIGH (Agents create transient plan/summary files that masquerade as documentation)
When you let coding agents work on a project, they tend to leave behind plan files, status summaries, and "next steps" notes that look like documentation but are actually transient working memory. After a few sprints, these accumulate as dozens of PLAN.md/SUMMARY.md files that nobody owns and nobody reads.
How to recognize AI junk
1. By filename
Common patterns generated by AI agents:
PLAN.md IMPLEMENTATION-PLAN.md
TODO.md IMPLEMENTATION-SUMMARY.md
NEXT-STEPS.md REFACTOR-PLAN.md
COMPLETED.md REFACTOR-NOTES.md
PROGRESS.md CHANGES.md (when CHANGELOG.md already exists)
TASK-LIST.md SESSION-NOTES.md
CONTEXT.md DECISIONS.md (when docs/adr/ exists)
WORK-LOG.md DEBUG-NOTES.md2. By content fingerprint
AI-generated docs often have telltale signatures:
- Trailing line: "🤖 Generated with Claude Code" / "Generated by GitHub Copilot" / "Created by Codex"
- Phrases like "I have completed the following tasks" or "Here is a summary of the changes"
- Bullet lists in past tense describing what was just done
- "Next steps:" sections that were never actioned
- Repeated boilerplate intros ("This document describes...")
3. By context
- File has 1 commit (created by the agent, never edited by a human)
- Last commit message:
"Add PLAN.md"/"Update progress"/"Add session summary" - Located at root of the repo (instead of properly organized under
docs/) - Date in the filename:
notes-2025-09-14.md,plan-q3-2025.md
Incorrect — what they look like
❌ PLAN.md (committed by an agent, 8 months ago, never edited since)
# Implementation Plan
I'll be implementing the new user export feature in the following steps:
## Phase 1: Schema (Day 1)
- [x] Add export_jobs table
- [x] Add foreign key to users
- [x] Write migration
## Phase 2: Service layer (Day 2-3)
- [x] Create UserExportService
- [ ] Add streaming support
## Next steps
- Discuss approach with team
- Get sign-off before deployment
🤖 Generated with Claude CodeProblems:
- This was tracking work-in-progress; the work shipped 8 months ago
- The unchecked item is either obsolete (already done in a later PR) or forgotten
- File pollutes the repo's root and gets indexed by GitHub search
- Future agents read it and treat it as authoritative current state
Correct — how to triage
For each candidate junk file, ask:
- Is the work in this file complete? → Delete. Work history is in git/PRs.
- Is the work abandoned? → Delete. (If you want to remember it, open an issue.)
- Is the work ongoing? → Move it to the issue tracker, not a markdown file in the repo.
- Does it contain unique knowledge (architecture decision, gotcha, runbook)? → Refactor into a proper doc:
- Architecture decision →
docs/adr/NNNN-...md - Gotcha / how-to →
docs/guides/...md - Ops procedure →
docs/runbooks/...md
- Architecture decision →
Never auto-delete. Always surface for the user's approval first.
Detection
# Filename patterns
find . -maxdepth 3 -type f -name '*.md' \
-not -path './node_modules/*' -not -path './vendor/*' \
| grep -Ei \
'(PLAN|TODO|SUMMARY|PROGRESS|NEXT-STEPS|COMPLETED|TASK-LIST|SESSION-NOTES|WORK-LOG|REFACTOR-NOTES|DEBUG-NOTES|CONTEXT|CHANGES)\.md$'
# Content fingerprints — AI footer signatures
grep -rln -E '🤖 (Generated|Created) with|Co-Authored-By: Claude|Generated by (Copilot|Codex|Cursor)' \
--include='*.md' .
# Markdown files committed by an agent and never edited by a human (single commit on the file).
# Useful for catching transient plan/summary files that landed and were forgotten.
find . -name '*.md' -not -path './node_modules/*' -not -path './vendor/*' | while read f; do
COMMITS=$(git log --oneline -- "$f" | wc -l | tr -d ' ')
[ "$COMMITS" = "1" ] && echo "SINGLE-COMMIT (likely auto-generated): $f"
donePrevention
- Tell agents not to create plan files: in your
CLAUDE.md/AGENTS.md/cursor.json, instruct: "Do not create PLAN.md, TODO.md, or progress-tracking markdown files in the repo. Use the conversation context or the issue tracker." - CI gate: block PRs that add
PLAN.md/TODO.md/SUMMARY.md/ etc. at root - Periodic audit: every quarter, run the detection above
# .github/workflows/no-agent-junk.yml
- name: Block AI-junk filenames
run: |
NEW=$(git diff --name-only --diff-filter=A origin/main...HEAD)
BAD=$(echo "$NEW" | grep -Ei '^(PLAN|TODO|SUMMARY|PROGRESS|NEXT-STEPS)\.md$')
test -z "$BAD" || { echo "Don't commit transient plan/summary files: $BAD"; exit 1; }Reference: Diátaxis — "what documentation is not" · [Internal: cleanup-orphans, cleanup-empty-stubs]