Private
Public Access
0
0

chore(scripts): plan unused scripts cleanup track (5 phases)

5 phases, one per deletion category from the spec:

Phase 1: Remove one-shot indent fixers (10 files)
Phase 2: Remove one-shot transform scripts (6 files)
Phase 3: Remove superseded entropy and code-stat audits (4 files)
Phase 4: Remove one-shot migrators and repros (6 files)
Phase 5: Remove tool-call aliases and legacy tool discovery (4 files)
Phase 6: Final verification + tracks.md update

Each phase = one git rm + one commit + one git note + one
state.toml update. Phase 0 adds the state.toml scaffold. Phase 6
runs the full test suite in 4-at-a-time batches per workflow.md
Phase Completion protocol, re-runs the 2 active audit scripts
(main_thread_imports, weak_types) for regression check, and
commits the tracks.md update.

TDD pattern adapted for deletion: pre-deletion baseline (Phase 0)
+ per-phase git rm + post-deletion test suite pass (Phase 6).
No new code, no new tests, no new CI gate.
This commit is contained in:
2026-06-07 10:26:49 -04:00
parent 11a9c4f705
commit eae5b0a22b
@@ -0,0 +1,540 @@
# Unused Scripts Cleanup Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Remove 30 confirmed-unused scripts from `scripts/` via 5 atomic per-category commits, shrinking the directory from 56 → 26 files (54% reduction).
**Architecture:** Hard deletes via `git rm`. Each deletion category is one phase → one commit. The git log is the restore path; per-category commits give surgical rollback granularity. The "test" for each phase is the existing test suite (4-at-a-time batches per `conductor/workflow.md` Phase Completion protocol). No new code, no new tests, no new CI gate.
**Tech Stack:** PowerShell (Windows), git, pytest, `uv run` (per project convention).
---
## Phase 0: Pre-deletion baseline
**Files:** `conductor/tracks/unused_scripts_cleanup_20260607/state.toml` (create).
- [ ] **Step 0.0: Create `state.toml`**
The `state.toml` is the implementer's "where am I in this track" source of truth. Write `conductor/tracks/unused_scripts_cleanup_20260607/state.toml` with the initial structure (per `conductor/workflow.md` "State.toml Template"):
```toml
# Track state for unused_scripts_cleanup_20260607
# Updated by Tier 2 Tech Lead as tasks complete
[meta]
track_id = "unused_scripts_cleanup_20260607"
name = "Unused Scripts Cleanup"
status = "active"
current_phase = 0
last_updated = "2026-06-07"
[phases]
phase_1 = { status = "pending", checkpointsha = "", name = "Remove one-shot indent fixers" }
phase_2 = { status = "pending", checkpointsha = "", name = "Remove one-shot transform scripts" }
phase_3 = { status = "pending", checkpointsha = "", name = "Remove superseded entropy and code-stat audits" }
phase_4 = { status = "pending", checkpointsha = "", name = "Remove one-shot migrators and repros" }
phase_5 = { status = "pending", checkpointsha = "", name = "Remove tool_call aliases and legacy tool discovery" }
phase_6 = { status = "pending", checkpointsha = "", name = "Final verification + tracks.md update" }
[verification]
scripts_count_baseline = 56
scripts_count_target = 26
tests_passing_at_baseline = true
```
- [ ] **Step 0.0a: Update `state.toml` after each phase**
After each of Phase 1-5 lands, update `state.toml`:
- Set the phase's `status = "completed"` and `checkpointsha = "<the commit SHA>"`.
- Bump `[meta].current_phase` to the next phase number.
- Update `[meta].last_updated` to the current date.
- Commit the `state.toml` change with message: `conductor(plan): mark phase N complete [short-sha]`.
(Step 6 of `conductor/workflow.md` Task Workflow.)
- [ ] **Step 0.1: Capture baseline test state**
Run: `git log -1 --format="%H"` (record: `___________`)
Run: `(Get-ChildItem -LiteralPath scripts -File).Count` (record: `___________`, expect 56)
- [ ] **Step 0.2: Re-verify the 30 deletions have no external references**
Run the following to confirm the audit is still valid (the project has not gained new references to any of the 30 files since the spec was written):
```powershell
$files = @(
"audit_indentation.py","check_hints_v2.py","correct_indentation.py","extract_symbols.py",
"fix_gaps.py","fix_indent.py","fix_indent_ast.py","fix_indent_v3.py","standardize_indent.py",
"type_hint_scanner.py",
"apply_startup_timeline.py","apply_type_hints.py","gut_oop_final.py","restore_regions_final.py",
"transform_render_methods.py","transform_render_methods_safe.py",
"audit_entropy.py","comprehensive_entropy_audit.py","focused_entropy_audit.py","code_stats.py",
"migrate_cruft.ps1","profile_baseline.py","repro_history.py","sdm_injector.py","sdm_mapper.py",
"update_paths.py",
"scan_all_hints.py","tool_call.bat","tool_call.cmd","tool_discovery.py"
)
$bad = @()
foreach ($f in $files) {
$hits = git grep -lF "scripts/$f" -- ':!scripts/'"$f" 2>$null
if ($hits) { $bad += "$f -> $hits" }
}
if ($bad) { $bad | ForEach-Object { Write-Host $_ }; exit 1 } else { Write-Host "OK: 0 external references" }
```
Expected output: `OK: 0 external references`. Exit code 0.
If any file shows hits, STOP and report to the Tier 2 Tech Lead. The spec is stale.
- [ ] **Step 0.3: Confirm `slice_tools.py` and `validate_types.ps1` still exist (they are KEEPS)**
```powershell
Test-Path scripts/slice_tools.py
Test-Path scripts/validate_types.ps1
```
Expected: both `True`.
- [ ] **Step 0.4: Stage nothing, do not commit. Move to Phase 1.**
---
## Phase 1: Remove one-shot indent fixers (10 files, 1 commit)
**Files:** `git rm` 10 files in `scripts/`.
- [ ] **Step 1.1: `git rm` the 10 files**
```bash
git rm scripts/audit_indentation.py scripts/check_hints_v2.py scripts/correct_indentation.py scripts/extract_symbols.py scripts/fix_gaps.py scripts/fix_indent.py scripts/fix_indent_ast.py scripts/fix_indent_v3.py scripts/standardize_indent.py scripts/type_hint_scanner.py
```
- [ ] **Step 1.2: Run a quick test sanity check (one batch, ~30s)**
Run: `uv run pytest tests/test_main_thread_purity.py tests/test_mcp_client_whitelist_enforcement.py -q 2>&1 | Select-Object -Last 20`
Expected: tests pass (these tests import a few scripts modules; if they fail to import, something else was referencing the removed files — STOP and report).
- [ ] **Step 1.3: Commit**
```bash
git commit -m "chore(scripts): remove one-shot indentation fixers
The 1-space indentation convention is now enforced project-wide
(per fix_indentation_1space_20260516). These 10 scripts are
overlapping one-shot fixers and auditors from that era; their
purpose has been served.
Removed (10 files, ~30 KB):
- audit_indentation.py (4.6 KB) - indentation auditor
- check_hints_v2.py (1.0 KB) - crude regex hint checker
- correct_indentation.py (6.4 KB) - one-shot corrector
- extract_symbols.py (547 B) - crude symbol printer
- fix_gaps.py (704 B) - whitespace gap fixer
- fix_indent.py (9.6 KB) - indent fixer v1
- fix_indent_ast.py (3.4 KB) - indent fixer v2 (AST-based)
- fix_indent_v3.py (2.2 KB) - indent fixer v3 (render-method-specific)
- standardize_indent.py (1.0 KB) - indent standardizer
- type_hint_scanner.py (718 B) - CLI hint scanner
Audit (per spec §Gaps to Fill) confirms zero external references
in active code, docs, CI, or planned tracks."
```
- [ ] **Step 1.4: Attach git note to this commit**
Get commit hash: `git log -1 --format="%H"`
```bash
git notes add -m "chore(scripts) Phase 1: remove one-shot indent fixers (10 files)
The 1-space indentation convention is enforced project-wide as of
fix_indentation_1space_20260516. These 10 scripts were overlapping
auditors and fixers from that era; their purpose has been served.
The kept indent-related code is:
- check_imgui_scopes.py (active ImGui linter; not indent-related)
- The 1-space rule is enforced via project workflow + code review,
not a script.
Files removed: audit_indentation.py, check_hints_v2.py,
correct_indentation.py, extract_symbols.py, fix_gaps.py,
fix_indent.py, fix_indent_ast.py, fix_indent_v3.py,
standardize_indent.py, type_hint_scanner.py.
Total: 10 files, ~30 KB. scripts/ now has 46 files." <commit_hash>
```
- [ ] **Step 1.5: Verify scripts/ count = 46**
Run: `(Get-ChildItem -LiteralPath scripts -File).Count`
Expected: 46.
- [ ] **Step 1.6: Conductor - User Manual Verification (per workflow.md)**
Ask the user to confirm Phase 1 looks right before proceeding to Phase 2.
---
## Phase 2: Remove one-shot transform scripts (6 files, 1 commit)
**Files:** `git rm` 6 files in `scripts/`.
- [ ] **Step 2.1: `git rm` the 6 files**
```bash
git rm scripts/apply_startup_timeline.py scripts/apply_type_hints.py scripts/gut_oop_final.py scripts/restore_regions_final.py scripts/transform_render_methods.py scripts/transform_render_methods_safe.py
```
- [ ] **Step 2.2: Run a quick test sanity check**
Run: `uv run pytest tests/test_main_thread_purity.py tests/test_mcp_client_whitelist_enforcement.py -q 2>&1 | Select-Object -Last 20`
Expected: tests pass.
- [ ] **Step 2.3: Commit**
```bash
git commit -m "chore(scripts): remove one-shot transform scripts
These 6 scripts were one-shot AST/code transformations from past
tracks. The transforms they perform are already applied; the
scripts serve no further purpose.
Removed (6 files, ~30 KB):
- apply_startup_timeline.py (8.3 KB) - startup timeline edit
(applied in startup_speedup_20260606 / commit 229559ca)
- apply_type_hints.py (10.5 KB) - type-hint applicator
(applied in gui_2_cleanup_20260513)
- gut_oop_final.py (1.7 KB) - OOP culling
(done in hot_reload_python_20260516)
- restore_regions_final.py (4.8 KB) - region restoration
(done in hot_reload_python_20260516)
- transform_render_methods.py (3.0 KB) - render-method transformer
(delegation done in hot_reload_python_20260516)
- transform_render_methods_safe.py (2.4 KB) - safer variant
Audit (per spec §Gaps to Fill) confirms zero external references."
```
- [ ] **Step 2.4: Attach git note**
```bash
git notes add -m "chore(scripts) Phase 2: remove one-shot transform scripts (6 files)
The 6 transform scripts performed AST/code rewrites that have
already been applied. The kept transform machinery is in
py_struct_tools.py (8.6 KB), which is shared AST/regex logic
actively dispatched by src/mcp_client.py.
Files removed: apply_startup_timeline.py, apply_type_hints.py,
gut_oop_final.py, restore_regions_final.py, transform_render_methods.py,
transform_render_methods_safe.py.
Total: 6 files, ~30 KB. scripts/ now has 40 files." <commit_hash>
```
- [ ] **Step 2.5: Verify scripts/ count = 40**
Run: `(Get-ChildItem -LiteralPath scripts -File).Count`
Expected: 40.
- [ ] **Step 2.6: Conductor - User Manual Verification**
---
## Phase 3: Remove superseded entropy/code audits (4 files, 1 commit)
**Files:** `git rm` 4 files in `scripts/`.
- [ ] **Step 3.1: `git rm` the 4 files**
```bash
git rm scripts/audit_entropy.py scripts/comprehensive_entropy_audit.py scripts/focused_entropy_audit.py scripts/code_stats.py
```
- [ ] **Step 3.2: Run a quick test sanity check**
Run: `uv run pytest tests/test_main_thread_purity.py tests/test_audit_weak_types.py -q 2>&1 | Select-Object -Last 20`
Expected: tests pass. (The `test_audit_weak_types.py` test imports the active CI gate, not the removed scripts.)
- [ ] **Step 3.3: Commit**
```bash
git commit -m "chore(scripts): remove superseded entropy and code-stat audits
These 4 scripts are superseded by the 2 active CI audit gates
(audit_main_thread_imports.py, audit_weak_types.py). The
entropy-era project tracking is no longer used.
Removed (4 files, ~28 KB):
- audit_entropy.py (3.1 KB) - early entropy auditor
- comprehensive_entropy_audit.py (10.5 KB) - one-off audit
- focused_entropy_audit.py (6.8 KB) - Muratori-style audit
- code_stats.py (7.8 KB) - stats gatherer (no consumer)
Active audit infrastructure kept: audit_main_thread_imports.py
(CI gate), audit_weak_types.py (CI gate), check_test_toml_paths.py
(CI gate), check_imgui_scopes.py (linter)."
```
- [ ] **Step 3.4: Attach git note**
```bash
git notes add -m "chore(scripts) Phase 3: remove superseded entropy and code audits (4 files)
The 3 active audit scripts (audit_main_thread_imports.py,
audit_weak_types.py, check_test_toml_paths.py) are permanent CI
gates. The removed scripts were from the entropy-tracking era
(March 2026) and have been superseded.
code_stats.py had no consumer; it was added in commit bd7f8e17
and never wired into any workflow.
Files removed: audit_entropy.py, comprehensive_entropy_audit.py,
focused_entropy_audit.py, code_stats.py.
Total: 4 files, ~28 KB. scripts/ now has 36 files." <commit_hash>
```
- [ ] **Step 3.5: Verify scripts/ count = 36**
Run: `(Get-ChildItem -LiteralPath scripts -File).Count`
Expected: 36.
- [ ] **Step 3.6: Conductor - User Manual Verification**
---
## Phase 4: Remove one-shot migrators and repros (6 files, 1 commit)
**Files:** `git rm` 6 files in `scripts/`.
- [ ] **Step 4.1: `git rm` the 6 files**
```bash
git rm scripts/migrate_cruft.ps1 scripts/profile_baseline.py scripts/repro_history.py scripts/sdm_injector.py scripts/sdm_mapper.py scripts/update_paths.py
```
- [ ] **Step 4.2: Run a quick test sanity check**
Run: `uv run pytest tests/test_main_thread_purity.py tests/test_audit_weak_types.py -q 2>&1 | Select-Object -Last 20`
Expected: tests pass.
- [ ] **Step 4.3: Commit**
```bash
git commit -m "chore(scripts): remove one-shot migrators and repros
These 6 scripts were one-shot migration tools and repros from
past tracks. The migrations are done; the bugs are fixed; the
SDM tags are in place.
Removed (6 files, ~22 KB):
- migrate_cruft.ps1 (2.6 KB) - filesystem cruft migration
(done in consolidate_cruft_and_log_taxonomy_20260228)
- profile_baseline.py (2.4 KB) - profiling baseline
(baselines live in docs/reports/)
- repro_history.py (2.3 KB) - repro for fixed history bug
(bug fixed in hot_reload_python_20260516)
- sdm_injector.py (6.8 KB) - SDM tag injector
(tags in place since sdm_docstrings_20260509)
- sdm_mapper.py (7.3 KB) - SDM tag mapper (pilot)
(tags in place)
- update_paths.py (789 B) - sys.path patcher
(src/ layout is now standard)"
```
- [ ] **Step 4.4: Attach git note**
```bash
git notes add -m "chore(scripts) Phase 4: remove one-shot migrators and repros (6 files)
The migrations and repros are done; the SDM tags are in place
(as documented in src/ via [C: ...] / [M: ...] tags in docstrings);
the src/ layout is standard across the project.
Files removed: migrate_cruft.ps1, profile_baseline.py,
repro_history.py, sdm_injector.py, sdm_mapper.py, update_paths.py.
Total: 6 files, ~22 KB. scripts/ now has 30 files." <commit_hash>
```
- [ ] **Step 4.5: Verify scripts/ count = 30**
Run: `(Get-ChildItem -LiteralPath scripts -File).Count`
Expected: 30.
- [ ] **Step 4.6: Conductor - User Manual Verification**
---
## Phase 5: Remove tool-call aliases and legacy tool discovery (4 files, 1 commit)
**Files:** `git rm` 4 files in `scripts/`.
- [ ] **Step 5.1: `git rm` the 4 files**
```bash
git rm scripts/scan_all_hints.py scripts/tool_call.bat scripts/tool_call.cmd scripts/tool_discovery.py
```
- [ ] **Step 5.2: Run a quick test sanity check**
Run: `uv run pytest tests/test_main_thread_purity.py tests/test_cli_tool_bridge.py tests/test_cli_tool_bridge_mapping.py -q 2>&1 | Select-Object -Last 20`
Expected: tests pass. (These bridge tests use the active `cli_tool_bridge.py` and `claude_tool_bridge.py`, not `tool_discovery.py`.)
- [ ] **Step 5.3: Commit**
```bash
git commit -m "chore(scripts): remove tool_call aliases and legacy tool discovery
These 4 scripts are redundant aliases and a tool that uses a
non-canonical MCP API path.
Removed (4 files, ~3.5 KB):
- scan_all_hints.py (2.0 KB) - only referenced in
.claude/commands/mma-tier2-tech-lead.md (local AI tool config,
not the project). The MMA workflow uses audit_weak_types.py.
- tool_call.bat (49 B) - cmd wrapper for tool_call.py
(redundant with tool_call.ps1)
- tool_call.cmd (50 B) - cmd wrapper for tool_call.py
(redundant with tool_call.ps1)
- tool_discovery.py (1.4 KB) - tool spec discovery using the
legacy mcp_client.MCP_TOOL_SPECS API path (will be refactored
by mcp_architecture_refactor_20260606)
Kept tool-call bridge: tool_call.cpp (source), tool_call.exe
(binary), tool_call.py (Python bridge), tool_call.ps1 (PowerShell)."
```
- [ ] **Step 5.4: Attach git note**
```bash
git notes add -m "chore(scripts) Phase 5: remove tool_call aliases and legacy tool discovery (4 files)
The kept tool-call bridge (tool_call.cpp/.exe/.py/.ps1) is
referenced by the inter-domain system per docs/guide_meta_boundary.md.
The .bat and .cmd aliases are redundant with the .ps1 wrapper.
tool_discovery.py used the legacy mcp_client.MCP_TOOL_SPECS API
path; the upcoming mcp_architecture_refactor_20260606 will
introduce a new sub-MCP-based discovery path.
Files removed: scan_all_hints.py, tool_call.bat, tool_call.cmd,
tool_discovery.py.
Total: 4 files, ~3.5 KB. scripts/ now has 26 files (target met)." <commit_hash>
```
- [ ] **Step 5.5: Verify scripts/ count = 26**
Run: `(Get-ChildItem -LiteralPath scripts -File).Count`
Expected: 26. (Target met.)
- [ ] **Step 5.6: Conductor - User Manual Verification**
---
## Phase 6: Final verification
**Files:** `conductor/tracks.md`.
- [ ] **Step 6.1: Run the full test suite in 4-at-a-time batches per `conductor/workflow.md` Phase Completion protocol**
Run the following 9 batches (one at a time, watching for failures):
```bash
uv run pytest tests/test_audit_weak_types.py tests/test_main_thread_purity.py tests/test_mcp_client_whitelist_enforcement.py tests/test_cli_tool_bridge.py -q 2>&1 | Select-Object -Last 10
uv run pytest tests/test_cli_tool_bridge_mapping.py tests/test_workspace_profile_serialization.py tests/test_hot_reload.py tests/test_log_management.py -q 2>&1 | Select-Object -Last 10
uv run pytest tests/test_app_controller.py tests/test_gui_2.py tests/test_gui_2_no_top_level_heavy_imports.py tests/test_theme_nerv_fx.py -q 2>&1 | Select-Object -Last 10
uv run pytest tests/test_rag_engine.py tests/test_minimax_provider.py tests/test_cost_tracker.py tests/test_external_editor.py -q 2>&1 | Select-Object -Last 10
uv run pytest tests/test_mcp_perf_tool.py tests/test_mcp_config.py tests/test_mcp_client_ts_integration.py tests/test_mcp_client_beads.py -q 2>&1 | Select-Object -Last 10
uv run pytest tests/test_models.py tests/test_personas.py tests/test_presets.py tests/test_tool_presets.py -q 2>&1 | Select-Object -Last 10
uv run pytest tests/test_context_presets.py tests/test_history_manager.py tests/test_log_pruner.py tests/test_log_registry.py -q 2>&1 | Select-Object -Last 10
uv run pytest tests/test_discussion_compression.py tests/test_discussion_metrics.py tests/test_take_management.py tests/test_session_insights.py -q 2>&1 | Select-Object -Last 10
uv run pytest tests/test_multi_agent_conductor.py tests/test_dag_engine.py tests/test_worker_pool.py tests/test_track_state.py -q 2>&1 | Select-Object -Last 10
```
Expected: all batches pass. If any batch fails with a reference to a removed file, STOP — the audit was incomplete. Roll back the affected commit (e.g., `git revert <commit-hash>`) and report to the Tier 2 Tech Lead.
- [ ] **Step 6.2: Re-run the audit script `audit_main_thread_imports.py`**
Run: `uv run python scripts/audit_main_thread_imports.py; echo "exit: $?"`
Expected: exit 0 (or the same exit code as the baseline before this track; no new violations introduced).
- [ ] **Step 6.3: Re-run the audit script `audit_weak_types.py`**
Run: `uv run python scripts/audit_weak_types.py --strict; echo "exit: $?"`
Expected: exit 0 (the baseline count is unchanged; no new weak types introduced).
- [ ] **Step 6.4: Re-run the ImGui linter (sanity check, src/ is untouched)**
Run: `uv run python scripts/check_imgui_scopes.py 2>&1 | Select-Object -Last 5`
Expected: 0 errors.
- [ ] **Step 6.5: Add the track entry to `conductor/tracks.md`**
Open `conductor/tracks.md` and add a new entry under the appropriate section (chronologically under the most recent track). Suggested location: just below the "Test Batching Refactor" entry (the most recent active track) or in a new "Phase 9: Chore Tracks" section if you prefer.
Suggested text:
```markdown
- [x] **Track: Unused Scripts Cleanup** `[checkpoint: <last_commit_sha>]`
*Link: [./tracks/unused_scripts_cleanup_20260607/](./tracks/unused_scripts_cleanup_20260607/), Spec: [./tracks/unused_scripts_cleanup_20260607/spec.md](./tracks/unused_scripts_cleanup_20260607/spec.md), Plan: [./tracks/unused_scripts_cleanup_20260607/plan.md](./tracks/unused_scripts_cleanup_20260607/plan.md)*
*Goal: Remove 30 confirmed-unused one-off scripts from `scripts/` (56 → 26 files, 54% reduction). 5 atomic per-category commits; no new CI gate; follow-up `unused_scripts_audit_20260607` recorded. All 360+ tests still pass.*
```
Replace `<last_commit_sha>` with the SHA from Step 5.3's commit.
- [ ] **Step 6.6: Commit the tracks.md update**
```bash
git add conductor/tracks.md
git commit -m "conductor(tracks): mark Unused Scripts Cleanup track as complete
Phase 6 verification complete: 5 atomic per-category commits landed,
full test suite passes, 2 audit scripts (main_thread_imports,
weak_types) report no new violations, ImGui linter clean. scripts/
shrinks from 56 to 26 files (54% reduction)."
```
- [ ] **Step 6.7: Attach git note to the tracks.md commit**
```bash
git notes add -m "conductor(plan) Phase 6: track complete
Track shipped. 30 files removed across 5 atomic per-category commits.
scripts/ now has 26 files: 24 active infrastructure + 2 borderline
utility (slice_tools.py, validate_types.ps1).
Follow-up: unused_scripts_audit_20260607 (NOT in this track). Trigger
to start: scripts/ grows back to 35+ files.
Final test suite state: all batches pass; no new audit violations;
Imgui linter clean.
The 5 deletion commits are:
1. (Phase 1) one-shot indent fixers
2. (Phase 2) one-shot transform scripts
3. (Phase 3) superseded entropy and code audits
4. (Phase 4) one-shot migrators and repros
5. (Phase 5) tool_call aliases and legacy tool discovery" <commit_hash>
```
- [ ] **Step 6.8: Conductor - User Manual Verification (final)**
Ask the user to confirm the track is complete.
---
## Summary
- **6 phases**, **5 deletion commits**, **1 track-marking commit**, **~30 git operations** total.
- **30 files removed**, **~115 KB deleted**, **scripts/ shrinks from 56 → 26 files**.
- **No new code, no new tests, no new CI gate.** The existing test suite is the regression net.
- **Restore path:** `git log -- scripts/<file>` for any of the 30 files; per-category commits make rollback surgical.
- **Follow-up:** `unused_scripts_audit_20260607` (deferred; trigger at 35+ files in `scripts/`).