fix(ledger): a canon may hold a class and the to_dict beside it (#4220)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 11s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / integration (push) Successful in 1m1s
CI & Build / Python tests (push) Successful in 1m41s
CI & Build / Build & push image (push) Successful in 28s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 11s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / integration (push) Successful in 1m1s
CI & Build / Python tests (push) Successful in 1m41s
CI & Build / Build & push image (push) Successful in 28s
The review surface shipped yesterday reported two canons on its first live day and both were sound. Coherence was "do all judged rows share a form", which #2844 failed at 37/62 = 0.597 for containing a model class and the to_dict the canon's own text says the class must carry, and #2849 failed at 4/7 for pairing sync loop-starters with the async ticks they schedule. A review surface whose whole output is noise is one that stops being read. The obvious repair is a trap, and there is now a test standing in front of it. Grouping by family and keeping a majority test makes the check BLIND: before #2844 was cleaned by hand it held 37 classes and 56 callables, which as families is 56/93 = 0.602 — a clean pass, and the 31 rows that had no business being there (Vue functions, route handlers, a dozen tests) would never have been reported at all. A looser bar in the same shape is worse than the bug. So the verdict is inverted. Instead of asking whether most rows agree, it asks how many rows the canon CANNOT ACCOUNT FOR: a row in the majority family is accounted for; a callable defined in a file that also holds a majority-family `type` row is a method of a member, not a foreign body; and strangers above a fifth of the readable rows make the canon incoherent. The majority vote abstains those methods, so a class's own serialisers cannot outvote the classes and turn the members into the strangers. Measured on the real ledger before it was written, which is why it is this rule and not a nudge to the share: clean #2844 has 0 strangers in 62, #2849 has 0 in 7, and polluted #2844 had 31 in 93 — the same 31 withdrawn by hand this morning, named exactly. The entry now carries `families`, the majority `family`, `attached`, `stranger_count`, `unattended`, and `strangers` — THE ROWS THAT DO NOT FIT, replacing a sample of the first twelve members. The reader's question is which rows are wrong, and a sample of the agreeing majority cannot answer it. `unattended` is the discriminator between a check that is too strict and a ledger full of junk: both canons flagged on day one were entirely audit-judged, and nothing showed that without opening each one. Scoped to the review surface. `canon_form` still answers at the precise form level for stamping and divergence, where a sync helper beside an async canon is a fair question; nothing here changes what the ledger writes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01821k5B3Ysecp9fNYs92Kuy
This commit is contained in:
@@ -267,13 +267,23 @@ async def stamps_to_review(project_id: int, top: int = 10) -> dict:
|
||||
score, signature and derived form so you can judge rather than trust the
|
||||
threshold.
|
||||
|
||||
`incoherent` — canons whose judged rows do not agree on a form: the
|
||||
`forms` histogram, how many members were hook-stamped weakly, and a
|
||||
sample. A canon asserts that some shapes are the same sort of thing; when
|
||||
its members are a class, three getters and a dozen tests, that assertion
|
||||
has stopped being true and every base-rate reading built on it — the
|
||||
`incoherent` — canons whose membership no longer agrees what the canon
|
||||
is. A canon asserts that some shapes are the same sort of thing; when its
|
||||
members are a class, three getters and a dozen tests, that assertion has
|
||||
stopped being true and every base-rate reading built on it — the
|
||||
divergence prompt included — is reading noise.
|
||||
|
||||
Disagreement is judged by FAMILY (a sync helper and an async one are one
|
||||
family), and a method defined beside a member class counts as part of the
|
||||
shape rather than against it — so a model convention that covers both the
|
||||
class and its `to_dict` reads as coherent, which it is (#4220). Each
|
||||
entry carries `families` and `forms`, the majority `family`, `attached`
|
||||
(minority rows excused as methods of a member), `strangers` — THE ROWS
|
||||
THAT DO NOT FIT, which is what you judge — and `unattended` / `weak_rows`,
|
||||
the count written by the hook with nobody reading. An incoherence whose
|
||||
rows are all judged is likelier this check being strict than a bad
|
||||
ledger; one made of unattended rows is the real thing.
|
||||
|
||||
A row listed here is a question, not a verdict. Some will be correct.
|
||||
|
||||
Read-only; requires read access to the project.
|
||||
|
||||
Reference in New Issue
Block a user