feat(repolint): line-cap CI gate with ratchet baseline #193
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab#193
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adopt a per-file line-cap policy, enforced as a hard CI gate with a ratcheting baseline for existing violators. Line count is a gate, not a diagnosis: the underlying pains are merge conflicts between concurrent lab agents, degraded AI edits on huge files, and review load. Churn×size data picked the thresholds; line count is the only PR-local, deterministic metric CI can enforce.
Caps
linguist-generated=trueviagit check-attr, or// Code generated .* DO NOT EDIT\.within the first 10 lines (Go convention)docs/***_test.go,*.test.ts,*.test.tsx*.css*.go,*.ts,*.tsxNumbers are grounded in the repo distribution (2026-07-21): source p95 ≈ 700 (Go 740 / TS 629 — near-identical, hence one shared number), tests p95 ≈ 1037. Caps sit ~1.4–2× above p95 so they only bite genuine outliers.
Deliverables
Checker — a Go test (suggested:
internal/repolint) that:git ls-files(git is on PATH in CI per the D17 bar),lines(f) > max(cap(f), baseline(f)), with a message that names the file, its count, its limit, and the two legal remedies (split the file, or — for a grandfathered file within headroom — nothing; growing past headroom has no remedy but splitting),baseline(f) > max(cap(f), ceil(lines(f) * 1.05)). So shrinking a file forces the baseline down in the same PR, and once a file is at/under its cap the entry must be deleted — files leave the table forever, never re-enter.go test ./internal/repolint -update(or a small cmd) rewrites the baseline file tight (ceil(lines*1.05), entries only for over-cap files) so fixing a stale-baseline failure is one command.Baseline file — checked in (suggested:
internal/repolint/baseline.json), seeded withceil(size*1.05)at implementation time. Reference values from 2026-07-21 (recompute at branch time — these files churn daily):(
web/package-lock.jsonis exempt as generated;docs/reference/lab-v0/handlers.gois exempt underdocs/**.).gitattributes— addweb/package-lock.json linguist-generated=true. Future codegen must carry either the attribute or the Go generated-header.ADR 0051 — document the policy: the caps table, the ratchet semantics, and the split-quality bar: an over-cap file gets a decomposition issue naming one responsibility per proposed file before split code is written; splits named
foo2/part2/single-callerhelpers, or with heavy import fan-out between new siblings, are rejected in review. The gate is a tripwire; cohesion is judged by review.Acceptance
go test ./...is red if any non-exempt tracked file exceedsmax(cap, baseline), and red if any baseline entry is stale per the ratchet rule; green otherwise..forgejo/workflows/needed — the checker rides the existinggo testin both the native and nix gates.-updateregeneration produces a byte-stable file (sorted paths).