feat(ledger): divergence readout — button B where button A is canon, shape history, and judged-shape recheck (#2793, milestone 294 step 7)
CI & Build / TypeScript typecheck (push) Failing after 2s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / integration (push) Successful in 28s
CI & Build / Python tests (push) Failing after 37s
CI & Build / Build & push image (push) Skipped
CI & Build / TypeScript typecheck (push) Failing after 2s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / integration (push) Successful in 28s
CI & Build / Python tests (push) Failing after 37s
CI & Build / Build & push image (push) Skipped
Every judgment now goes through one helper that remembers the fingerprint judged (classified_sha) and writes a code_shape_events row; the sync writes vanished / reappeared / drifted events and flags recheck_at when a body moves under an instance/variant. The refresh flags diverges_from on shapes new since the previous computation that sit where one canon dominates the judged siblings of their directory+kind and were not proposed as that canon (a first seed flags nothing); the write-path hint asks the same question in-band for the shapes the hook names. list_shapes(flag=divergence|recheck), shape_history(project_id, path, symbol) (read-only), coverage line/payload/ card carry divergent + recheck. Backup v8 carries the history. Plugin 0.1.36. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -507,3 +507,19 @@ def test_coverage_line_names_the_proposers_standing():
|
||||
assert "; 90 unclassified (40 proposed, 2 derive groups), largest: src" in line
|
||||
line = coverage_line({**base, "proposed": 0, "derive_groups": [{"group": "a"}]})
|
||||
assert "(1 derive group)" in line
|
||||
|
||||
|
||||
def test_coverage_line_names_divergence_and_recheck():
|
||||
from scribe.services.coverage import coverage_line
|
||||
|
||||
base = {
|
||||
"total": 100, "accounted": 40, "unclassified": 60,
|
||||
"counts": {"canonical": 10, "instance": 30, "variant": 0, "exempt": 0},
|
||||
"computed_at": "2026-08-21T00:00:00+00:00",
|
||||
"largest_gaps": [{"dir": "src", "unclassified": 60, "total": 60}],
|
||||
}
|
||||
line = coverage_line({**base, "divergent": 2, "recheck": 1, "proposed": 5})
|
||||
assert "; 60 unclassified (5 proposed, 2 DIVERGENT), largest: src" in line
|
||||
assert line.endswith("; 1 judged shape changed since judged — recheck")
|
||||
assert "DIVERGENT" not in coverage_line(base)
|
||||
assert "recheck" not in coverage_line(base)
|
||||
|
||||
Reference in New Issue
Block a user