From 48f6c7420f70f6444d2ed0b8c495b73da14a079f Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Sat, 22 Aug 2026 14:31:35 +0200 Subject: [PATCH] Gate the 250-line cap on every commit, repo-wide A refactor without a gate silently regrows, so this is the part that makes the cap stick. Until now the repo had no root .pre-commit-config.yaml at all -- `git commit` ran zero hooks, and the five subproject configs only covered their own directories. Adds a root config wiring scripts/check_file_length.sh as a local hook, and carries the same hook in each of the five subproject configs so committing with one of those is gated too. Staged files only, so an unrelated commit never breaks on a violation it did not introduce; exit 1, not a warning; no baseline and no allowlist, since those are suppressions. Verified in a throwaway worktree, both directions: - a staged 261-line file fails the commit (exit 1, HEAD unchanged, no commit object created) - a staged 200-line file commits normally (exit 0) The 44 files still over the cap cannot block this: the hook only ever sees what a commit touches. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01CFSGeWxHPY5rHUGrPqhcmG --- .pre-commit-config.yaml | 27 ++++++++++++++++++++++++ crdt-sync/.pre-commit-config.yaml | 5 +++++ design_system/.pre-commit-config.yaml | 5 +++++ gatelock/.pre-commit-config.yaml | 5 +++++ sync_settings_ui/.pre-commit-config.yaml | 5 +++++ web_ui/.pre-commit-config.yaml | 5 +++++ 6 files changed, 52 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..4de83cf --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,27 @@ +# Repo-wide gate for the shared 250-line file cap (refactor_claude_todo.md). +# +# A file that cannot be read in one piece forces re-reads and partial edits, +# which is the largest avoidable cost in an LLM-assisted workflow. A refactor +# without a gate silently regrows, so this is the part that makes it stick. +# +# Checks only the files in the commit, so an unrelated commit never breaks on +# a violation it did not introduce, and it FAILS (exit 1) rather than warning. +# No baseline and no allowlist -- those are suppressions. +# +# The subprojects (gatelock/, crdt-sync/, web_ui/, design_system/, +# sync_settings_ui/) each keep their own .pre-commit-config.yaml for their own +# linters, and carry this same hook so committing with one of those configs is +# gated too. This root config is what `pre-commit install` wires up, and it is +# the only one that covers the subprojects without a config of their own +# (aur-publish/, guard-lib/, crdt_sync_dart/, file_length/, ...). +# +# `entry` is not run through a shell, so `~` would not expand: the absolute +# path is deliberate. +repos: + - repo: local + hooks: + - id: file-length-cap + name: file length <= 250 lines + entry: bash /home/kuhy/utils/scripts/check_file_length.sh + language: system + pass_filenames: true diff --git a/crdt-sync/.pre-commit-config.yaml b/crdt-sync/.pre-commit-config.yaml index 372daac..0ca5217 100644 --- a/crdt-sync/.pre-commit-config.yaml +++ b/crdt-sync/.pre-commit-config.yaml @@ -40,6 +40,11 @@ repos: - repo: local hooks: + - id: file-length-cap + name: file length <= 250 lines + entry: bash /home/kuhy/utils/scripts/check_file_length.sh + language: system + pass_filenames: true - id: subproject-scope name: subproject scope regex still matches entry: scripts/check_subproject_scope.sh crdt-sync diff --git a/design_system/.pre-commit-config.yaml b/design_system/.pre-commit-config.yaml index 5cab55b..9d9a9c8 100644 --- a/design_system/.pre-commit-config.yaml +++ b/design_system/.pre-commit-config.yaml @@ -27,6 +27,11 @@ repos: - repo: local hooks: + - id: file-length-cap + name: file length <= 250 lines + entry: bash /home/kuhy/utils/scripts/check_file_length.sh + language: system + pass_filenames: true - id: subproject-scope name: subproject scope regex still matches entry: scripts/check_subproject_scope.sh design_system diff --git a/gatelock/.pre-commit-config.yaml b/gatelock/.pre-commit-config.yaml index c28e2ea..cd43c59 100644 --- a/gatelock/.pre-commit-config.yaml +++ b/gatelock/.pre-commit-config.yaml @@ -40,6 +40,11 @@ repos: - repo: local hooks: + - id: file-length-cap + name: file length <= 250 lines + entry: bash /home/kuhy/utils/scripts/check_file_length.sh + language: system + pass_filenames: true - id: subproject-scope name: subproject scope regex still matches entry: scripts/check_subproject_scope.sh gatelock diff --git a/sync_settings_ui/.pre-commit-config.yaml b/sync_settings_ui/.pre-commit-config.yaml index fea87f1..05830f0 100644 --- a/sync_settings_ui/.pre-commit-config.yaml +++ b/sync_settings_ui/.pre-commit-config.yaml @@ -27,6 +27,11 @@ repos: - repo: local hooks: + - id: file-length-cap + name: file length <= 250 lines + entry: bash /home/kuhy/utils/scripts/check_file_length.sh + language: system + pass_filenames: true - id: subproject-scope name: subproject scope regex still matches entry: scripts/check_subproject_scope.sh sync_settings_ui diff --git a/web_ui/.pre-commit-config.yaml b/web_ui/.pre-commit-config.yaml index 30facf6..7f4b6ef 100644 --- a/web_ui/.pre-commit-config.yaml +++ b/web_ui/.pre-commit-config.yaml @@ -35,6 +35,11 @@ repos: - repo: local hooks: + - id: file-length-cap + name: file length <= 250 lines + entry: bash /home/kuhy/utils/scripts/check_file_length.sh + language: system + pass_filenames: true - id: subproject-scope name: subproject scope regex still matches entry: scripts/check_subproject_scope.sh web_ui