Add a resume prompt for the file-length refactor
Some checks failed
Pre-commit checks / pre-commit (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
poker-stakes CI / check (push) Has been cancelled

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
This commit is contained in:
Krzysztof Rudnicki 2026-08-16 15:29:27 +02:00
parent 73b85f5326
commit d6b376effb

View File

@ -0,0 +1,143 @@
# Resume: enforce the 250-line file cap
> **Paste this whole file to a fresh Claude session opened in `~/testsAndMisc`.**
> It is self-contained. Continues `refactor_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
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)
1. **Full clearance** to `--all` exit 0. When context runs out, write a fresh
handoff like this one rather than stopping mid-way.
2. **CI checks only files in the push/PR range**, not `--all`.
3. `docs/superpowers/plans/**` + `sessions/**` are exempt — already done.
4. `poker-stakes/` is tracked — already done.
5. For prose: automate what can be automated, delete the automated lines, keep
only HOW, never WHY.
6. Shell verification is `bash -n` + `shellcheck` + `systemctl cat` path checks.
**Never execute enforcement scripts that mutate the phone or the live system.**
7. 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:
```yaml
- 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/*.sh` sourced by a thin entry script,
`set -euo pipefail` in each. Follow `phone_focus_mode/lib/` and
`linux_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-stakes`
that is `src/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 a `coverage.exclude` entry.
- **`end-of-file-fixer` aborts commits.** Files built with `sed`/`cat` often
lack a trailing newline. The hook fixes it and then fails the commit
("files were modified by this hook"). Just `git add` again and re-commit.
- **Formatters silently revert edits.** A PostToolUse formatter stripped an
added import twice. After editing, `grep` the file to confirm the change
survived before running anything.
- **Contracts.** Staging **≥4 code files** requires a _fresh_
`docs/superpowers/contracts/*.json` in that same commit, on top of the
per-commit `docs/superpowers/evidence/*.json`. Required keys: `title`,
`objective`, `acceptance_criteria`, `out_of_scope`, `verifier`. Validate with
`python3 meta/scripts/validate_contract.py <file>`.
- **`invariants.test.ts` in 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:
1. **`deploy.sh` has a hardcoded flat push list** (search for `adb_cmd push`,
around lines 374–383) with **no `lib/` 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.
2. **`config.sh` (556 lines) is sourced by 11 scripts.** Keep `config.sh` as
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
1. The 48 near-misses (251–300) — mechanical, biggest count drop.
2. `python_pkg` (50) — `pytest-coverage` gates each changed package on commit.
3. `linux_configuration` (84) — largest; check systemd unit paths still resolve.
4. `kcd2_dice_solver`, `focus_owner`, `billsplit`, the rest.
5. `phone_focus_mode` (13) — with the guard above.
6. Gate wiring + CI workflow — last.
## Done condition
```bash
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.