ci: remove the banner carve-out from the comment caps gate

Why

The gate joins blank-separated comment segments so a 2+gap+2 squirm stack answers to one cap, but the banner carve-out undid the join at any multiplicity: every gap-separated // --- or // ── segment kept its own free 2-line row, so a run of banners carried unlimited prose the gate never charged. That is the squirm shape in uniform, and it is the compliant edit authors actually reach for: feat(oci): revalidate a stale tag against the u... (!1875 - merged) • Radamanthus Batnag • 19.4 went from 62 to 166 banners with every gate green (measured on chore(skills): teach write-readable-go the comm... (!2015 - merged) • Radamanthus Batnag • 19.4), and that MR counters the hole with guidance prose that nothing enforces.

We remove the carve-out entirely rather than bounding it. A bounded row still hands every run one free block a prose preamble does not get, and any exemption is a shape to farm. A banner is decoration: it now counts like prose and spends the budget of whatever its run lands on. A lone banner detached above undocumented code survives as a block of at most 2 lines, and a banner plus a short doc fits an exported name's or the package clause's cap of 3. Outside a _test.go file and outside a grouped declaration, a banner above a documented unexported top-level name never fits, and the conforming rewrite depends on the pair: deleting the banner when the doc alone fits, detaching when the pair fits the detached cap of 2, and compressing otherwise.

What (non-obvious)

The ratchet is unchanged: only touched segments count, so a legacy banner header stays mergeable one segment at a time and charges when one edit reaches a second segment. split_run and body_run collapse into one sum_run, and the divider-detection state goes with the carve-out.

A multi-segment finding now names the touched segments (3-4,9-10) rather than their start-end hull: the hull bracketed the untouched lines between touched segments, which an author could cut without clearing the gate. Single-segment findings keep the bare start line. Same findings, same counts, new location text only (all-touched over every Go file: +1007/−1007 raw, 0 gained, 0 lost by range intersection).

One deliberate reversal: the documented squirm remediation was to open a test-file preamble with a // --- rule, so the fleet's test files carry many such banners. They stay grandfathered until touched, and the remediation on touch is deletion or compression, per go-style.md's updated paragraph.

Blast radius, measured at this rebase (base 1df2de91) with the all-touched harness over every Go file and normalized by range intersection because joining re-keys spans: 349 sites gain enforcement (296 test-file, 34 unexported, 8 other, 7 exported, 4 merged doc-and-body-head) and none lose it. The five apparent losses in the raw diff are merged-class findings whose start line moved up into short banner segments that were free before and now join the doc under them, each verified against its replacement. The raw finding-text diff is +1188/−878, re-keyed by both the join and the touched-segment location format. The same measurement at the round-two tree read 152 gained, 0 lost.

Interplay: the ratchet skill landed first, in chore(skills): teach write-readable-go the comm... (!2015 - merged) • Radamanthus Batnag • 19.4. This MR rebased onto it and reconciles the write-readable-go evals it added. Their cap helper and self-test probe carried the carve-out, the self-test regex read a bare line or one range where the gate now names touched segments, and the eval prose and go-style.md's banner-run paragraph called the gate silent on a run. Every train run since round two failed lint:skill-scripts:write-readable-go on the merged result. The new commit counts every segment in the helper, accepts the segment list in the regex, and restates the prose in ratchet terms. The file-header fixture's prompt carries the report this gate produces, one 14-line block against the detached cap of 2, and the other four prompts' reports match the gate unchanged. This MR leaves the citation-only-fix question with npm remote test comments cite moved harness hel... (#915) • Unassigned.

Test plan

  • bash scripts/ci/check-comment-caps_test.sh green under mawk and busybox awk, 205 assertions. Scenario 16 keeps its fixtures with joined verdicts (five findings: funcorder banner plus doc at 2 over cap 1, three-line banner joining at 4, one-line divider joining at 4, adjacent divider unchanged, box banner in a test file at 3 over cap 2) plus a fitting one-line banner and doc pair in a test file. Scenario 21 pins the ratchet and every landing class: one touched banner joins alone and passes, touching a second segment fails from either end of the run, a fresh three-banner run fails whole, a single banner above a doc fails (the explicit reversal), and each cap-3 landing (exported, the package clause, and a grouped member) is pinned in both directions, a banner over a two-line doc failing at 4 against cap 3 and a fitting three-line pair passing. Re-adding a divider carve-out gated on capfor(c) == 3 fails four assertions, where all 198 passed before the cap-3 fixtures existed.
  • python3 .claude/skills/write-readable-go/evals/grade.py --selftest: the four probes agree with the gate (3, 4, 2, 2). The five eval fixtures run through the gate in a throwaway repository match the prompts' reports.
  • Tree-wide all-touched measurement as above, 349 gained, 0 lost.
  • scripts/ci/check-comment-caps.sh --base origin/main on this branch: OK.
  • shellcheck and shfmt clean, and the pre-commit chain (markdownlint, Vale, gitlint) green on the commits. Vale's one new hit is the file's standard "unexported" spelling suggestion, present eight times on main.
Context for LLM agents

Rejected alternatives: bounding the carve-out to one free row per run (built and measured first, +18/-0 all-touched, rejected by the operator because any exemption is a shape agents farm), and guidance-only enforcement (what chore(skills): teach write-readable-go the comm... (!2015 - merged) • Radamanthus Batnag • 19.4 adds, which the measurement above shows gets routed around).

Non-goals: the citation-only-fix ratchet (npm remote test comments cite moved harness hel... (#915) • Unassigned owns it), retroactive cleanup of grandfathered banner runs (the ratchet cleans them on touch), any change to directive or bare-// handling, and a redesign of the file-header-banner-run eval around a grandfathered run the gate stays silent on (its fixture and grader are unchanged, only its prompt's gate paragraph and the surrounding prose moved to what this gate reports).

Edited by Hayley Swimelar

Merge request reports

Loading
Loading