Why
general.md's Line wrapping rule 1 reads:
A comment standing alone on its own line never passes column 80, no matter where in the file it sits.
It never says what the 80 is measured on. Two readings are available and nothing in the standard picks one:
- the whole physical line, counted from column 1 with indentation included; or
- the comment's own text, after the indent and the
// / * marker.
And in a tab-indented project a third variable is open: what a tab counts as.
This is not academic. Measured across classes/ in kntnt-extractor (6,540 comment lines):
| measure |
lines over the limit |
share |
| whole line, tab = 4 |
2,482 |
38% |
| whole line, tab = 2 |
1,975 |
30% |
| whole line, tab = 1 |
1,650 |
25% |
| prose only, marker stripped |
~240 |
4% |
An 832-line spread between two readings of the same sentence, in one plugin.
The failure has already been paid for downstream. Kntnt/kntnt-extractor#48 derived an acceptance criterion from this rule — "No comment line in classes/Rest/Extractions_Controller.php exceeds 80 columns" — that no implementation could satisfy, because it applied reading 1 to a whole file while the same ticket's Out-of-scope clause forbade touching the rest of the file. The ticket failed independent verification on that criterion alone. The build was correct; the rule it was measured against was ambiguous.
Separately, wordpress.md already declares the tab width in its Indentation row — Tabs (display as 4 cols) — but rule 1 never referenced it, so the one fact that makes the rule measurable sat in a different module with no link.
Changes
Rule 1 keeps its wording. Two paragraphs are added beneath the three rules:
- The measure. The count spans the whole physical line: from column 1, through the indentation and the
//, #, /* or * marker, to the last character written; nothing appears in column 81 or beyond. Indentation is spent from the same budget as the prose. Where a module declares tab indentation, a tab advances to the next multiple of its declared display width — deferring to wordpress.md's row rather than restating a second, independently-driftable number.
- The one exemption. A docblock tag line (
@param, @return, @throws) is exempt where its type cannot be broken without changing what a static analyser reads — a wide array shape or union has no continuation syntax to wrap into. Framed as a last resort, not a licence: shorten the description, drop vertical padding between the tag's columns, or extract the type into a named alias first.
Acceptance criteria
Why
general.md's Line wrapping rule 1 reads:It never says what the 80 is measured on. Two readings are available and nothing in the standard picks one:
///*marker.And in a tab-indented project a third variable is open: what a tab counts as.
This is not academic. Measured across
classes/inkntnt-extractor(6,540 comment lines):An 832-line spread between two readings of the same sentence, in one plugin.
The failure has already been paid for downstream.
Kntnt/kntnt-extractor#48derived an acceptance criterion from this rule — "No comment line inclasses/Rest/Extractions_Controller.phpexceeds 80 columns" — that no implementation could satisfy, because it applied reading 1 to a whole file while the same ticket's Out-of-scope clause forbade touching the rest of the file. The ticket failed independent verification on that criterion alone. The build was correct; the rule it was measured against was ambiguous.Separately,
wordpress.mdalready declares the tab width in its Indentation row — Tabs (display as 4 cols) — but rule 1 never referenced it, so the one fact that makes the rule measurable sat in a different module with no link.Changes
Rule 1 keeps its wording. Two paragraphs are added beneath the three rules:
//,#,/*or*marker, to the last character written; nothing appears in column 81 or beyond. Indentation is spent from the same budget as the prose. Where a module declares tab indentation, a tab advances to the next multiple of its declared display width — deferring towordpress.md's row rather than restating a second, independently-driftable number.@param,@return,@throws) is exempt where its type cannot be broken without changing what a static analyser reads — a wide array shape or union has no continuation syntax to wrap into. Framed as a last resort, not a licence: shorten the description, drop vertical padding between the tag's columns, or extract the type into a named alias first.Acceptance criteria
general.mdstates the measure: column 1, indentation counted, nothing in column 81+tests/test_coding_standard_line_width.pyguards all of the above, red-first