tools (volt): reply_check's two spelled class counts were both wrong, and four cells now grade them (37 -> 41 cells)
The control plane measured them at 16:52Z: the docstring said 'Five classes
are graded' over a seven-row enumeration and 'Three more are counted and
printed' over four, while FAULTS holds 7 and ADVISORIES holds 4. Prose is not
executed and doc_census_check.py reads only '<digits> <unit>', so a spelled
count has no reader at all.
Fix: Seven classes are graded; Four more are reported and printed, with the
HOLE/ line split stated (three of the four reach 'advisories: N').
Instrument: doc_counts() parses the two spelled counts; four selftest cells
grade them against len(FAULTS)/len(ADVISORIES), assert every graded class is
named in the docstring, and pin the pre-fix words on a fixture. RED measured on
the same file with only the words reverted: 39/41, 2 failed ('says 5; FAULTS
holds 7', 'says 3; ADVISORIES holds 4'), rc 1. GREEN: 41/41 rc 0.
Live archive unchanged: 194 files, 1 known-faulting under the baseline, 0 new;
bare run still rc 1 with the one fault printed. verify.py 5/5 rc 0 (sweep 15
tools, 15 OK). doc_census_check --fail: 0 STALE, rc 0. ruff F,E9 clean.
This commit is contained in:
1 parent
a3766c60d2
commit
8bee8257d9
1 file changed
+61
-6
+61
-6
@@ -19,7 +19,7 @@ WHY THIS EXISTS
|
|||||||
WHAT IT MEASURES (read-only; the only write path is --json)
|
WHAT IT MEASURES (read-only; the only write path is --json)
|
||||||
Every `*.md` under --dir except `README.md` is one ROW. The filename gives
|
Every `*.md` under --dir except `README.md` is one ROW. The filename gives
|
||||||
(date, recipient, number); the first `# ` heading in the file gives what the
|
(date, recipient, number); the first `# ` heading in the file gives what the
|
||||||
file says about itself. Five classes are graded:
|
file says about itself. Seven classes are graded:
|
||||||
|
|
||||||
NAME_MALFORMED the filename is neither the numbered contract form nor
|
NAME_MALFORMED the filename is neither the numbered contract form nor
|
||||||
the one unnumbered legacy form -- the row is skipped
|
the one unnumbered legacy form -- the row is skipped
|
||||||
@@ -39,9 +39,11 @@ WHAT IT MEASURES (read-only; the only write path is --json)
|
|||||||
FAULT: "the next free integer in that recipient's own
|
FAULT: "the next free integer in that recipient's own
|
||||||
series" cannot produce the same integer twice.
|
series" cannot produce the same integer twice.
|
||||||
|
|
||||||
Three more are counted and printed, and are ADVISORY by construction -- each
|
Four more are reported and printed, and are ADVISORY by construction -- each
|
||||||
is a stated consequence of history that predates the naming rule, not a
|
is a stated consequence of history that predates the naming rule, not a
|
||||||
defect this tool can attribute to a writer:
|
defect this tool can attribute to a writer. Three of the four reach the
|
||||||
|
`advisories: N` count; HOLE rides the `series:` line instead, because a hole
|
||||||
|
belongs to a recipient's series and not to any one file:
|
||||||
|
|
||||||
LEGACY_UNNUMBERED the one legacy form (no `-<N>`). Its number is implicit
|
LEGACY_UNNUMBERED the one legacy form (no `-<N>`). Its number is implicit
|
||||||
in its position, so numbering rules skip it.
|
in its position, so numbering rules skip it.
|
||||||
@@ -86,15 +88,17 @@ BASELINE -- the archive's one fault, stated instead of hidden
|
|||||||
The ledger names the tolerance, and the row stays visible in every report.
|
The ledger names the tolerance, and the row stays visible in every report.
|
||||||
|
|
||||||
SELFTEST
|
SELFTEST
|
||||||
`--selftest` grades 37 cells, building every fixture in a fresh temporary
|
`--selftest` grades 41 cells, building every fixture in a fresh temporary
|
||||||
directory: each fault class fires on a fixture that carries it and only the
|
directory: each fault class fires on a fixture that carries it and only the
|
||||||
classes that belong there (a wrong addressee, a wrong number, a duplicate
|
classes that belong there (a wrong addressee, a wrong number, a duplicate
|
||||||
number, an impossible date, a missing heading, a malformed name, non-UTF-8
|
number, an impossible date, a missing heading, a malformed name, non-UTF-8
|
||||||
bytes), the advisory classes stay advisory and exit 0 (legacy form, hole,
|
bytes), the advisory classes stay advisory and exit 0 (legacy form, hole,
|
||||||
heading that names nobody), the prefix match accepts a hyphenated handle,
|
heading that names nobody), the prefix match accepts a hyphenated handle,
|
||||||
README.md is not a row, and both rc 2 paths (missing directory, file where a
|
README.md is not a row, and both rc 2 paths (missing directory, file where a
|
||||||
directory belongs) answer 2. A rule that stops firing and a rule that fires
|
directory belongs) answer 2. Four cells grade this docstring's own census --
|
||||||
everywhere both fail a cell.
|
the two spelled class counts against FAULTS/ADVISORIES, every graded class
|
||||||
|
named here, and the pre-fix words refused on a fixture. A rule that stops
|
||||||
|
firing and a rule that fires everywhere both fail a cell.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -119,6 +123,35 @@ FAULTS = ("NAME_MALFORMED", "BAD_DATE", "NO_HEADER", "UNREADABLE",
|
|||||||
ADVISORIES = ("LEGACY_UNNUMBERED", "NO_RECIPIENT_IN_HEADING",
|
ADVISORIES = ("LEGACY_UNNUMBERED", "NO_RECIPIENT_IN_HEADING",
|
||||||
"NO_NUMBER_IN_HEADING", "HOLE")
|
"NO_NUMBER_IN_HEADING", "HOLE")
|
||||||
|
|
||||||
|
WORD_NUMBERS = {"one": 1, "two": 2, "three": 3, "four": 4, "five": 5, "six": 6,
|
||||||
|
"seven": 7, "eight": 8, "nine": 9, "ten": 10, "eleven": 11,
|
||||||
|
"twelve": 12}
|
||||||
|
|
||||||
|
# The docstring's two spelled counts, and the sentence each lives in. A spelled
|
||||||
|
# count is invisible to doc_census_check.py, which reads `<digits> <unit>` only,
|
||||||
|
# so these are the claims that drift with no instrument watching them: on
|
||||||
|
# 2026-10-19 the control plane measured `Five` over a seven-row table and
|
||||||
|
# `Three` over four rows, and carried the class to this lane.
|
||||||
|
DOC_GRADED_RE = re.compile(r"\b([A-Z][a-z]+) classes are graded\b")
|
||||||
|
DOC_ADVISORY_RE = re.compile(r"\b([A-Z][a-z]+) more are (?:counted|reported)\b")
|
||||||
|
|
||||||
|
|
||||||
|
def doc_counts(doc=None):
|
||||||
|
"""The docstring's two spelled counts -> (graded, advisory); None if absent.
|
||||||
|
|
||||||
|
`doc` is a parameter rather than `__doc__` read inside the function so the
|
||||||
|
selftest can grade a fixture docstring -- including the pre-fix `Five` /
|
||||||
|
`Three` pair -- through the same code path the live docstring takes.
|
||||||
|
"""
|
||||||
|
text = __doc__ if doc is None else doc
|
||||||
|
|
||||||
|
def word(rx):
|
||||||
|
m = rx.search(text or "")
|
||||||
|
return WORD_NUMBERS.get(m.group(1).lower()) if m else None
|
||||||
|
|
||||||
|
return word(DOC_GRADED_RE), word(DOC_ADVISORY_RE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _real_date(y, m, d):
|
def _real_date(y, m, d):
|
||||||
try:
|
try:
|
||||||
@@ -695,6 +728,28 @@ def selftest():
|
|||||||
cell("a ledger naming an unknown class exits 2",
|
cell("a ledger naming an unknown class exits 2",
|
||||||
rc(["--dir", ds, "--baseline", bad2]) == 2)
|
rc(["--dir", ds, "--baseline", bad2]) == 2)
|
||||||
|
|
||||||
|
# 38-41: the docstring's own census. The two spelled counts live only in
|
||||||
|
# prose, so nothing graded them until this cell; the enumeration beside each
|
||||||
|
# one is the copy a reader follows, and FAULTS/ADVISORIES are what the code
|
||||||
|
# grades. A class added to either table without its docstring row, or a
|
||||||
|
# count word left behind, fails here rather than in the next reader's quote.
|
||||||
|
graded_w, advisory_w = doc_counts()
|
||||||
|
cell("docstring graded-count word matches FAULTS",
|
||||||
|
graded_w == len(FAULTS),
|
||||||
|
"docstring says %r; FAULTS holds %d" % (graded_w, len(FAULTS)))
|
||||||
|
cell("docstring advisory-count word matches ADVISORIES",
|
||||||
|
advisory_w == len(ADVISORIES),
|
||||||
|
"docstring says %r; ADVISORIES holds %d" % (advisory_w, len(ADVISORIES)))
|
||||||
|
unnamed = [c for c in FAULTS + ADVISORIES if c not in (__doc__ or "")]
|
||||||
|
cell("every class the code grades is named in the docstring",
|
||||||
|
not unnamed, unnamed)
|
||||||
|
# the instrument itself, against the words this file carried before the fix
|
||||||
|
prefix_doc = (" file says about itself. Five classes are graded:\n"
|
||||||
|
" Three more are counted and printed, and are ADVISORY.\n")
|
||||||
|
cell("the pre-fix count words are refused",
|
||||||
|
doc_counts(prefix_doc) != (len(FAULTS), len(ADVISORIES)),
|
||||||
|
doc_counts(prefix_doc))
|
||||||
|
|
||||||
failed = [(label, detail) for label, ok, detail in cells if not ok]
|
failed = [(label, detail) for label, ok, detail in cells if not ok]
|
||||||
print("selftest: %d cells, %d passed, %d failed" %
|
print("selftest: %d cells, %d passed, %d failed" %
|
||||||
(len(cells), len(cells) - len(failed), len(failed)))
|
(len(cells), len(cells) - len(failed), len(failed)))
|
||||||
|
|||||||
Reference in new issue
Block a user