192 of the original 198 violations remain and the work spans more sessions than one context window holds. This is the handoff: paste it into a fresh session. Deliberately points at `check_file_length.sh --all` as the live worklist rather than enumerating files, so it cannot go stale, and records the traps that cost time -- above all that the gate must be wired LAST, because ci-mirror runs `pre-commit --all-files` on pre-push and would otherwise block every push for the rest of the effort. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
6.5 KiB
Resume: enforce the 250-line file cap
Paste this whole file to a fresh Claude session opened in
~/testsAndMisc. It is self-contained. Continuesrefactor_claude_todo.md, which is still the spec — read it too, but the decisions below override it where they differ.
Where things stand
192 files over 250 lines (was 198). All work so far is committed and pushed
to main; git status is clean apart from pre-existing unrelated edits to
README.md, billsplit/analysis_options.yaml, focus_owner/analysis_options.yaml
— leave those three alone, they are not yours.
Done already (do not redo):
| Commit | What |
|---|---|
~/utils |
plans/ + sessions/ exempted from the cap (specs/ still capped) |
17b20e5 |
New no-inline-python pre-commit hook + the one violation fixed |
004b4b0 |
CLAUDE.md 259 → 141 lines |
72a5e28 |
poker-stakes/ tracked in git (58 files) |
73b85f5 |
poker-stakes/ 4 violations → 0 |
The live worklist
Do not work from a list in this file — it goes stale. Run:
bash ~/utils/scripts/check_file_length.sh --all
Current distribution: linux_configuration 84, python_pkg 50,
phone_focus_mode 13, kcd2_dice_solver 12, focus_owner 11, billsplit 6,
reverse_survivors/meta/docs 4 each, .github/bucket_catch 2 each.
48 of them are near-misses at 251–300 lines — highest count-drop per unit
of effort, do these first.
Decisions already made (do not re-ask)
- Full clearance to
--allexit 0. When context runs out, write a fresh handoff like this one rather than stopping mid-way. - CI checks only files in the push/PR range, not
--all. docs/superpowers/plans/**+sessions/**are exempt — already done.poker-stakes/is tracked — already done.- For prose: automate what can be automated, delete the automated lines, keep only HOW, never WHY.
- Shell verification is
bash -n+shellcheck+systemctl catpath checks. Never execute enforcement scripts that mutate the phone or the live system. - One commit per logical unit.
The constraint that will bite you
Wire the file-length gate LAST, only once --all already exits 0.
meta/scripts/ci_mirror.sh:109 runs pre-commit run --all-files as a
pre-push hook, and .github/workflows/pre-commit.yml:105 does the same in
CI. Registering the hook while violations remain makes every git push fail
until the last file is fixed. Do not scope around it with exclude:/files: —
that is the allowlist the spec forbids.
Final commit, once and only once the tree is clean:
- id: file-length
name: file length <= 250 lines
entry: bash /home/kuhy/utils/scripts/check_file_length.sh
language: system
Plus .github/workflows/file-length.yml modelled on
~/todo/.github/workflows/file-length.yml (checks out kuhyx/utils into
.utils), scoped to changed files. Then prove it fails: stage a deliberately
251-line file, confirm git commit aborts, delete it.
Split recipes
- Shell — extract into
lib/*.shsourced by a thin entry script,set -euo pipefailin each. Followphone_focus_mode/lib/andlinux_configuration/scripts/lib/common.sh. - Python — extract cohesive helpers into sibling modules; keep the public API stable by re-exporting.
- TS/Dart — extract components; re-export from the original path so no importer changes.
- Tests — split by describe/test-group. Coverage must not drop.
Never game the cap: no one-lining, no deleting tests, no moving code into an exempt extension, no suppressions.
Traps that cost time in the last session
- Test fixtures and coverage. When splitting a test file, shared helpers
must go where the coverage config already excludes them (in
poker-stakesthat issrc/test/**, matched by path). Putting them beside the source makes the coverage tool count them as production code and the 100% gate fails. Move the file; do not add acoverage.excludeentry. end-of-file-fixeraborts commits. Files built withsed/catoften lack a trailing newline. The hook fixes it and then fails the commit ("files were modified by this hook"). Justgit addagain and re-commit.- Formatters silently revert edits. A PostToolUse formatter stripped an
added import twice. After editing,
grepthe file to confirm the change survived before running anything. - Contracts. Staging ≥4 code files requires a fresh
docs/superpowers/contracts/*.jsonin that same commit, on top of the per-commitdocs/superpowers/evidence/*.json. Required keys:title,objective,acceptance_criteria,out_of_scope,verifier. Validate withpython3 meta/scripts/validate_contract.py <file>. invariants.test.tsin poker-stakes flakes on its 5s timeout under parallel coverage load. It passes standalone in ~2.6s. Not a regression — do not "fix" it by weakening the test.- Long commands: background anything over ~60s rather than blocking.
phone_focus_mode — highest blast radius, do it LAST
Two silent failure modes:
deploy.shhas a hardcoded flat push list (search foradb_cmd push, around lines 374–383) with nolib/subdirectory. Every new split lib must be added there in the same commit, or the phone sources a missing file at runtime — gate green, tests green, device broken.config.sh(556 lines) is sourced by 11 scripts. Keepconfig.shas the entry point that re-sources its own parts, so all 11 callers keep working untouched.
Static check after each split: grep deploy.sh's push list and every
source/. line in phone_focus_mode/*.sh and confirm each new lib appears.
Suggested order
- The 48 near-misses (251–300) — mechanical, biggest count drop.
python_pkg(50) —pytest-coveragegates each changed package on commit.linux_configuration(84) — largest; check systemd unit paths still resolve.kcd2_dice_solver,focus_owner,billsplit, the rest.phone_focus_mode(13) — with the guard above.- Gate wiring + CI workflow — last.
Done condition
cd ~/testsAndMisc && bash ~/utils/scripts/check_file_length.sh --all # exit 0
pre-commit run --all-files # passes
Plus: a staged 251-line file makes git commit fail.