chore: a count in a sentence is checked, or it stops being a count - #222
Conversation
The architecture answer to a question worth asking: why does an audit keep finding gaps, and how does it stop. Measured first. This workspace is a third prose by line — 10,939 of 31,615 non-blank source lines are doc comments, before CLAUDE.md, the changelog, the register and the skills — and the compiler has an opinion about none of it. Of twelve defects found in one day's own work, eight were prose and three were code. All three code defects were caught within minutes, by the compiler, by an existing test, and by a new one. None of the eight was caught by anything but somebody reading. And corrections rot faster than original writing. Every long-standing count in this repository verified; the three wrong ones were written the day before, by the changes that were correcting something else. A small local edit gets less scrutiny than new code. So: scripts/counts.py reads the source for a fact and the prose for the claim, and CI runs it. It is deliberately small. The three facts in it are the ones with a history of rotting, and it caught three stale citations while it was being written — including one in a role file the change that fixed CLAUDE.md had not reached. Its `--self-test` calls the production comparison rather than a copy of it, which is the mistake coverage.py's makes: recomputing the two set differences inline proves the copy works and says nothing about the original. The larger half is that most of these should not be numbers. "A change here reaches every adapter" carries what "five adapters" carried and cannot go stale. Four such counts became words, including conformance.rs's "all six clients", which now says "every client in the roster" — and the roster is latched. Why the list is hand-kept, measured rather than assumed: 112 (number + countable noun) pairs live in this repository's prose, and almost all are rhetorical — "four ways of reaching green", "six currencies iyzico settles in", "one provider". A check over all of them is ninety false positives, which is a check people learn to route around. So the list is small, every entry has a reason, and it may only shrink. money-safety §5 gains the marker the other four carry. It named two shipped defects — #168's inverted refund-key rule and #187's refunds summing to nothing — without saying so in the form the rest use, which is why the count disagreed with the file rather than the file disagreeing with itself. CLAUDE.md gains the rule the whole thing is for: one claim, one home; a checkable claim becomes a check; a number is a word or it is in counts.py; an unverifiable claim goes in UNVERIFIED.md; and measure a rule before writing it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 6 minutes Limit details: You’ve used all 10 included reviews currently available. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?Wait for the limit to reset, then comment An organization admin can change what happens after included review limits in Billing. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
Comment |
The architecture answer to "why does this keep finding gaps, and how do we get ahead of it". Measured before it was built.
What the measurement said
This workspace is a third prose by line: 10,939 of 31,615 non-blank source lines are doc comments — before
CLAUDE.md, the changelog, the register and the skills. The compiler has an opinion about none of it.Of twelve defects found in one day's own work: eight were prose, three were code, one was process. All three code defects were caught within minutes — by the compiler, by an existing test, by a new one. None of the eight was caught by anything but somebody reading.
And corrections rot faster than original writing. Every long-standing count in this repository verified; the three wrong ones were written the day before, by the changes that were correcting something else. A small local edit gets less scrutiny than new code.
scripts/counts.pyReads the source for a fact and the prose for the claim. CI runs it.
It is deliberately small — three facts, each with a history of rotting — and it earned its place while it was being written, catching three stale citations in sequence, including one in a role file that the change fixing
CLAUDE.mdhad not reached.Its
--self-testcalls the production comparison rather than a copy. That is the mistakecoverage.py's self-test makes: recomputing the two set differences inline proves the copy works and says nothing about the original.The larger half: stop writing the number
Most of these should not be numbers at all. "A change here reaches every adapter" carries what "five adapters" carried and cannot go stale. Four became words — including
conformance.rs's "all six clients", now "every client in the roster", and the roster is latched.Why the list is hand-kept, and why that is the right call here
Measured, not assumed: 112 (number + countable noun) pairs live in this repository's prose, and almost all are rhetorical — "four ways of reaching green", "six currencies iyzico settles in", "one provider". A check over all of them is ninety false positives, which is a check people learn to route around.
So the list is small, every entry has a reason, and per
ratchetsit may only shrink: a count that becomes a word, or a command, leaves it and does not come back.money-safety §5
Gains the marker the other four carry. It named two shipped defects — #168's inverted refund-key rule and #187's refunds summing to nothing — without saying so in the form the rest use. That is why the count disagreed with the file rather than the file disagreeing with itself.
The rule, in CLAUDE.md
One claim, one home. A checkable claim becomes a check. A number is a word or it is in
counts.py. An unverifiable claim goes inUNVERIFIED.md. And measure a rule before you write it — twice in one day a fix that sounded right was refused by its own measurement, the sharpest being that widening the doc-seam detector to skip a blank///matches 380 comments, because that is the correct shape for one.CI decides.