diff --git a/TODO-file-length-250.md b/TODO-file-length-250.md deleted file mode 100644 index faf1364..0000000 --- a/TODO-file-length-250.md +++ /dev/null @@ -1,112 +0,0 @@ -# Refactor TODO — enforce the 250-line file cap - -> **This file is a ready-to-use prompt.** Paste it to Claude, or open this repo -> and say "do refactor_claude_todo". It is self-contained: everything needed to -> execute is below. Generated 2026-08-14 from a measured survey of every repo. - -## Goal - -Every file in this repo must be **at most 250 lines** — source, tests, and -prose (`.md`/`.txt`/`.rst`/`.tex`) alike — and must **stay** that way forever, -enforced by a gate that fails the commit, not by a note anyone can ignore. - -Why: a file that cannot be read in one piece forces re-reads and partial edits, -which is the single largest avoidable cost in an LLM-assisted workflow. Aim by -churn, not size alone — refactoring pays where code is read and changed often -(Fowler, _refactoring economic benefit_). - -## Scope in this repo - -- **18 files** currently exceed 250 lines (of 73 eligible files). -- **6,553 lines** sit in violation; longest file is **478 lines**. - -Exempt (do NOT split these): - -- generated files — `*.g.dart`, `*.freezed.dart`, `*.gr.dart`, `**/l10n/generated/**`, - anything with a `GENERATED` header -- markup — `.html`, `.css`, `.scss` -- data files — `.json`, `.yaml`, `.csv`, wordlists and other data-ish `.txt` - (mean line length under 25 chars) - -## Violations, highest ROI first - -ROI = lines x commits in the last year. Work top-down; a long file nobody edits -has near-zero payoff and should not be first. - -| lines | commits/yr | kind | file | -| ----: | ---------: | :--- | :------------------------------------- | -| 478 | 15 | code | `wake_alarm/_alarm.py` | -| 438 | 12 | code | `wake_alarm/tests/test_alarm_part2.py` | -| 435 | 12 | code | `wake_alarm/tests/test_alarm.py` | -| 358 | 8 | code | `wake_alarm/tests/test_alarm_part3.py` | -| 457 | 4 | code | `wake_alarm/tests/test_alarm_sinks.py` | -| 283 | 6 | code | `wake_alarm/tests/test_alarm_part4.py` | -| 329 | 4 | code | `wake_alarm/_alarm_view.py` | -| 405 | 3 | code | `wake_alarm/_audio.py` | -| 386 | 3 | code | `wake_alarm/tests/test_sync.py` | -| 371 | 3 | code | `wake_alarm/_sync.py` | -| 317 | 3 | code | `wake_alarm/_escape_flow.py` | -| 314 | 3 | code | `wake_alarm/tests/test_state.py` | -| 420 | 2 | code | `wake_alarm/tests/test_alarm_audio.py` | -| 351 | 2 | code | `wake_alarm/tests/test_smart_plug.py` | -| 341 | 2 | code | `wake_alarm/_sinks.py` | - -_(3 further files over 250 lines not listed — re-run the survey for the full set.)_ - -## How to split - -- **Python** — extract cohesive helpers into sibling modules; keep the public - API and imports stable. -- **Shell** — split into `lib/*.sh` sourced by a thin entry script. Keep - `set -euo pipefail` in each. -- **Dart / TypeScript** — extract widgets/components into their own files. -- **Tests** — split by test-group into sibling files - (`foo.test.ts` -> `foo.parsing.test.ts`, `foo.render.test.ts`). Coverage must - not drop. -- **Docs** — split into topic files under `docs/` with an index. For an - oversized `CLAUDE.md`, move detail into referenced docs so the - always-loaded part shrinks. - -**Do not** game the cap: no one-lining, no deleting tests, no moving code into -an exempt extension, no `# noqa`-style suppressions. - -## Make it permanent (required — this is the point) - -A refactor without a gate silently regrows. Before this task is done: - -1. Wire the shared gate `~/src/utils/scripts/check_file_length.sh` into this repo's - `.pre-commit-config.yaml` as a local hook. If the repo has no pre-commit - config, add a minimal one. -2. The hook checks **files in the commit** (not the whole tree), so unrelated - commits never break, and it **fails** — exit 1, not a warning. -3. No baseline file and no allowlist. Those are suppressions. -4. If this repo has CI (`.github/workflows`), add the same check there so it - also fails on push. - -## Done condition - -- `bash ~/src/utils/scripts/check_file_length.sh --all` from this repo root exits 0. -- The repo's own test suite and coverage bar are still green. -- `pre-commit run --files ` passes. -- A deliberately over-250-line test file, staged, makes `git commit` **fail**. -- For a deployed daemon/app: the entry point still actually runs. - -## Verify - -Run the suite, then the alarm entry point. The phone_app companion needs `phone-deploy` verification if touched. - -## Why this sat untouched (added 2026-08-24) - -This repo ran a LOCAL `scripts/check_file_length.py` with `MAX_LINES = 500`, -under a hook named "Max file length (500 lines)". It reported "gated" while -permitting files every other repo rejects -- so the cap looked enforced and -nothing ever failed. The hook now delegates to the shared 250-line gate in -`~/src/utils`, which reports 17 real violations. - -Done condition is now an exit code, not a count: - -``` -bash scripts/check_file_length.sh --all # must exit 0 -``` - -REMOVE ME AFTER FINISH