wake-alarm/TODO-file-length-250.md
Krzysztof kuhy Rudnicki 21a989ce21 Adopt the four markdown namespaces and gate them
Renames this repo's markdown onto README.md / CLAUDE*.md / DOCS*.md /
TODO*.md so a future session can tell a live task from a finished
record without reading the file to find out.

TODO files carry the literal "REMOVE ME AFTER FINISH" and are deleted
when the work lands. Enforced by the md-naming pre-commit hook and CI
workflow, both delegating to the shared gate in kuhyx/utils so this
repo's idea of a valid name cannot drift from every other repo's.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A47aX5DJwmA3QFn3pkEWi7
2026-08-24 15:53:51 +02:00

4.5 KiB

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 ~/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 ~/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 <changed 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.