Skip to content

P2: sweep one-off committed debris from the repo root and add a root-allowlist guard #2277

Description

@stranske

Why

The system-of-record repo root holds one-off, agent/developer-generated files that are committed, ungitignored, and referenced by nothing — pollution that every automation scanning the repo root has to wade through. All anchors verified against the current checkout (origin/main, HEAD 2fb8e8b3).

  • Six one-off YAML-fixer scripts, zero workflow/script references (each grep -rln '<name>' .github scripts tools → empty): comprehensive_fix.py, fix_duplicate_with.py, fix_duplicates.py, fix_indentation.py, fix_token_placement.py, remove_duplicate_token_lines.py.
  • Committed CI/coverage outputs at root, none gitignored: coverage-local.json, coverage-local.xml, coverage-output.txt, pytest-junit.xml, pytest-junit-local.xml.
  • Five .patch files at root, all stale one-offs with no owner: 0001-fix-Auto-format-files-to-meet-lint-standards.patch, manager-database-pr327-fix.patch, pa-sweep-fixes.patch, template-repo-readme-updates.patch, verifier-pr-diff.patch.
  • artifacts/coverage-auth.txt is a verbatim committed pytest run with zero workflow references (grep -rln coverage-auth .github scripts → empty); artifacts/ is not in .gitignore and no workflow writes there.
  • .gitignore gap (verified): verifier-diff-summary.md is listed at .gitignore:89 and coverage.xml at :117, but there is no rule for *.patch, coverage-local.*, or pytest-junit*.xml.
  • Tracked-despite-ignored file: verifier-diff-summary.md is tracked (git ls-files verifier-diff-summary.md returns it) even though it is listed in .gitignore — because git does not ignore already-tracked files (git check-ignore verifier-diff-summary.md → not-ignored, rc=1). It therefore needs an explicit git rm --cached.

This is latent context-pollution, not a current break: nothing fails, but per this workspace's own guidance, stray root files are exactly the "one local file drawn into a system conclusion" hazard, and they bloat every agent's working context. Source: q-other-dirs.md F-12/F-11/F-01, map-overview.md F6.

Scope

  • git rm the listed root debris (6 fixer scripts, 5 coverage/junit outputs, 5 .patch files) and git rm --cached verifier-diff-summary.md (already ignored, still tracked).
  • git rm artifacts/coverage-auth.txt and gitignore the artifacts/ directory.
  • Extend .gitignore with *.patch, coverage-local.*, pytest-junit*.xml, and artifacts/.
  • Add a root-allowlist guard to .github/workflows/health-40-repo-selfcheck.yml (the existing repo-health workflow) that FAILS when a file not on an explicit allowlist appears at the repo root.

Non-Goals

  • Do NOT delete topics.json or input.txt — both are intentional ChatGPT-sync surfaces (agents-63-issue-intake.yml writes/uploads topics.json; input.txt is the raw ChatGPT message). They are tracked on purpose and MUST be on the root allowlist.
  • Do NOT delete verifier-diff-summary.md from working copies of users who regenerate it; only git rm --cached so it stops being tracked while staying ignored.
  • Do NOT touch the agents/ bootstrap-stub accumulation (137 files) — its GC is a separate concern; this issue does not add a stub reaper.
  • Do NOT add the root-allowlist guard to the required Gate (pr-00-gate.yml); wire it into health-40-repo-selfcheck.yml so a future stray file is flagged without blocking unrelated PRs (unless the team explicitly wants it gating).
  • Do NOT broaden .gitignore so aggressively that it would ignore legitimate root config (e.g. pyproject.toml, sitecustomize.py, topics.json, input.txt); the new patterns must be scoped to the debris classes named above.
  • Scaffold-only completion does NOT count: adding the allowlist check but leaving the debris files tracked (so the very check would fail on a clean checkout) is a failure of this issue; conversely, deleting the files without the guard leaves the door open for recurrence and is also incomplete.

Tasks

  • git rm from the repo root: comprehensive_fix.py, fix_duplicate_with.py, fix_duplicates.py, fix_indentation.py, fix_token_placement.py, remove_duplicate_token_lines.py, coverage-local.json, coverage-local.xml, coverage-output.txt, pytest-junit.xml, pytest-junit-local.xml, and the 5 root .patch files (0001-fix-Auto-format-files-to-meet-lint-standards.patch, manager-database-pr327-fix.patch, pa-sweep-fixes.patch, template-repo-readme-updates.patch, verifier-pr-diff.patch); then git rm --cached verifier-diff-summary.md and git rm artifacts/coverage-auth.txt.
  • Extend .gitignore (currently has verifier-diff-summary.md:89, coverage.xml:117) with *.patch, coverage-local.*, pytest-junit*.xml, and artifacts/.
  • Add a root-allowlist check to .github/workflows/health-40-repo-selfcheck.yml (slot it into the repo-health job after the existing "Collect repository signals" step at :141): enumerate the allowed root entries (must include topics.json, input.txt, README.md, AGENTS.md, CLAUDE.md, pyproject.toml, sitecustomize.py, .gitignore, and the known top-level dirs) and fail with a clear message when git ls-files shows an unlisted file at depth 0. Store the allowlist as a checked-in file (e.g. config/root-allowlist.txt or inline in the workflow) so it is reviewable.
  • Capture, in the PR, a grep proving zero references to each deleted file against the post-change tree (commands in Implementation Notes).

Acceptance Criteria

  • Zero-reference verification (captured in PR): for each deleted file, grep -rn '<filename>' .github scripts tools docs returns empty (excluding the deleted file). E.g. grep -rn comprehensive_fix .github scripts tools → empty; grep -rln coverage-auth .github scripts → empty.
  • verifier-diff-summary.md is no longer tracked (git ls-files verifier-diff-summary.md → empty) but remains ignored (git check-ignore verifier-diff-summary.md → exits 0), and git check-ignore foo.patch coverage-local.json pytest-junit-local.xml artifacts/x all exit 0.
  • The root-allowlist check passes on the cleaned tree (gh workflow run health-40-repo-selfcheck.yml → the new step is green, no unlisted root file).
  • Deliberate-break gate: add a stray file at the repo root (e.g. echo x > stray_debris.tmp && git add -f stray_debris.tmp) and confirm the root-allowlist step in health-40-repo-selfcheck.yml FAILS naming stray_debris.tmp. Then confirm that adding an explicitly-allowed file does NOT fail (e.g. re-touching topics.json keeps the step green). Remove the stray file before requesting review; capture both the FAIL and the green-on-allowed output in the PR.

Implementation Notes

  • Confirmed-from-checkout reproduction (origin/main, HEAD 2fb8e8b3):
    • Debris present: ls comprehensive_fix.py fix_*.py remove_duplicate_token_lines.py coverage-local.* coverage-output.txt pytest-junit*.xml *.patch → all present (5 .patch files).
    • Unreferenced: for f in comprehensive_fix fix_duplicate_with fix_duplicates fix_indentation fix_token_placement remove_duplicate_token_lines; do grep -rln "$f" .github scripts tools; done → all empty.
    • .gitignore gap: grep -n '\.patch\|coverage-local\|pytest-junit\|^artifacts' .gitignore → only verifier-diff-summary.md:89 and coverage.xml:117 (no patch/coverage-local/pytest-junit/artifacts rules).
    • Tracked-but-ignored: git check-ignore verifier-diff-summary.md → rc=1 (not ignored, because tracked); git ls-files verifier-diff-summary.md → returns it.
    • Intentional keepers: git ls-files topics.json input.txt → both tracked (do NOT delete; add to allowlist).
    • Wire-in point: .github/workflows/health-40-repo-selfcheck.yml job repo-health (:24), last signal step "Collect repository signals" at :141.
  • A minimal allowlist check can be a shell step: git ls-files | awk -F/ 'NF==1' | grep -vxF -f config/root-allowlist.txt and fail (exit 1) if the result is non-empty.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions