* docs(agents): exempt test headers from the two-line comment limit
The one-or-two-line comment rule rests on "the diff and commit message
carry the rationale". For a test that premise is false. A test outlives
the PR that added it, and the next person to read it is reading it
because it failed - months later, in someone else's change, with the
original discussion out of reach. That reader has one decision to make:
real regression, or an expectation that has gone stale? The assertions
alone cannot answer it, so the justification has to live in the file.
The new "Test comments" section requires three things of a test header -
what is under test by symbol and file, why that behavior is required, and
the specific regression that returns if the assertions are deleted or
relaxed - and grants whatever length they need.
Authoritative statement lives in that section of
.github/copilot-instructions.md, anchored at #test-comments. AGENTS.md
and CLAUDE.md link to it rather than restate it. The test/** entry in
.coderabbit.yaml carries the one permitted copy, since a YAML instruction
cannot follow a link.
This documents existing practice rather than changing it: 57 of the 72
suites with a test_main.cpp already open with three or more comment
lines, test/test_gps_fix_hold/test_main.cpp with eleven. The rule as
written forbade all of them, and automated reviewers acted on it.
Scoped to the single comment bullet, not to the whole "General Style"
section. Unlike "Naming Conventions", that section also holds the logging
tiers and the Throttle rule, which bind test code as hard as src/; a
blanket preamble would have quietly exempted tests from millis()
discipline as well.
The exception is bounded. The CodeRabbit entry still flags narrative that
carries no contract - debugging journey, changelog prose, restating what
the assertions plainly do - and per-case comments that merely repeat the
test name. The documentation-does-not-live-here rule is untouched.
* docs(agents): cut the test-comment rule to its essential statements
A section about comment length had no business running to 373 words.
Canonical section down to 194: dropped the elaboration of why the commit
message is unavailable, the aside about which bullet reviewers most often
cut, the "not licence for narrative" preamble, and the closing flourish.
What remains is what an agent has to act on - the premise that fails for
tests, the three things a header states, the instruction to reject a
shorten-this review comment, and the worked example.
Pointer files carry scope, not argument. The AGENTS.md bullet is one
sentence and a link, matching the Test naming pointer directly above it.
The .coderabbit.yaml copy keeps its imperatives, since a YAML instruction
cannot follow the link to find them, but loses the causal explanation it
did not need in order to act.
* docs(agents): document that test names are snake_case, not camelCase
Automated reviewers repeatedly ask for test suite directories and test_*
functions to be renamed to camelCase to match the src/ convention. That
rename breaks the harness and the rule was never written down.
Authoritative statement lives in the "Test naming" section of
.github/copilot-instructions.md, anchored at #test-naming. AGENTS.md and
CLAUDE.md link to it rather than restate it.
bin/run-tests.sh enumerates suites with -name 'test_*' but matches
PlatformIO verdict lines against test_[a-z0-9_]+, lowercase only, so an
uppercase suite directory is counted missing and the run reports AMBER
instead of GREEN. RUN_TEST in test/TestUtil.h passes #func to Unity and to
the state-checkpoint hooks, making the function name the only attribution a
CI failure carries.
.coderabbit.yaml gains a test/** path_instruction stating the rule inline,
since YAML cannot follow the link.
* docs(agents): separate the suite-directory and test-function naming rules
Review feedback on the previous commit was correct on both points.
The section called the test-function form snake_case while every example used
camelCase segments. The tree holds 743 test functions with an uppercase segment
and 675 without, so snake_case was wrong for more than half of them. Split the
two rules that were conflated: suite directories are strictly test_[a-z0-9_]+,
while test functions require only the test_ prefix and underscore separators,
with segment case free. States what is actually forbidden - dropping the prefix,
or collapsing the segments into one camelCase identifier.
The canonical-copy policy forbade restating the rule anywhere, then restated it
in AGENTS.md and .coderabbit.yaml. Name the YAML entry as the single permitted
copy, since a YAML instruction cannot follow a link, and reduce the AGENTS.md
bullet to a pointer.
* docs(agents): make the AGENTS.md and CLAUDE.md pointers neutral
Both still carried the "snake_case, not camelCase" label that b4fdd9168
corrected in the canonical section, so an agent reading either pointer got the
whole-name rule the canonical section now rejects. Describe the scope instead of
restating the rule: the src/ naming rule does not apply under test/.