feat(ledger): the consumer map surfaces — every css row carries used_by on list_shapes, flag="unused-css" (the map's negative space, surfaced never deleted), derive groups and the write-path family carry consumers, the derive line says "used by N template(s)", coverage payload unused_css + the standing block; docs, SKILL, plugin 0.1.44; the two step-2 tests expected 5 edges where fan-out makes 6 (milestone 302 step 3, #2936)
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / Python lint (push) Successful in 4s
CI & Build / TypeScript typecheck (push) Successful in 38s
CI & Build / integration (push) Failing after 44s
CI & Build / Python tests (push) Successful in 1m26s
CI & Build / Build & push image (push) Successful in 31s

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 14:03:35 -04:00
co-authored by Claude Fable 5
parent ffbdf19116
commit 8664d8ad14
11 changed files with 181 additions and 28 deletions
+30 -2
View File
@@ -629,7 +629,23 @@ async def compute_coverage(
agg["accounted"] += row.status != "unclassified"
unclassified = counts.pop("unclassified")
proposals = shape_ledger.proposal_summary(rows)
# The CSS consumer map's readout (milestone 302): which files render each
# css row — on the derive groups (a shared recipe vs a scoped one is a
# count), and the negative space: css rules no template names. "Unused"
# is measured only where the map has evidence of templates at all (one
# edge somewhere); a repo of bare stylesheets is "not measured", not
# "all unused".
css_rows = [r for r in rows if r.kind == "css"]
consumer_paths: dict[int, list[str]] = {}
unused_css = None
try:
edges = await shape_ledger.consumers_of([r.id for r in css_rows])
consumer_paths = {sid: [e.path for e in es] for sid, es in edges.items()}
if consumer_paths:
unused_css = sum(1 for r in css_rows if r.id not in consumer_paths)
except Exception:
logger.warning("consumer map read failed", exc_info=True)
proposals = shape_ledger.proposal_summary(rows, consumer_paths=consumer_paths)
divergence = shape_ledger.divergence_summary(rows)
derive_new = shape_ledger.derive_new_summary(rows, since=since)
return {
@@ -646,6 +662,9 @@ async def compute_coverage(
# duplicate family — what the arrival line names so drift is noticed
# on entering, not found by an audit.
"derive_new": derive_new,
# The consumer map's negative space (milestone 302): live css rules
# no template names — None when the map has no evidence of templates.
"unused_css": unused_css,
"proposer": proposer_stats,
# The divergence readout (#2793): button B where button A is canon,
# and judged shapes whose bodies moved since they were judged.
@@ -823,7 +842,16 @@ def coverage_line(coverage: dict) -> str:
standing.append(f"top canon #{top['snippet_id']} ×{top.get('count', 0)}")
first = (coverage.get("derive_groups") or [{}])[0]
if first.get("label") and first.get("files"):
standing.append(f"top copy {first['label']} ×{first['files']} files")
top_copy = f"top copy {first['label']} ×{first['files']} files"
# A css family says what renders it (milestone 302): the count that
# tells a shared recipe from a scoped convention.
if "consumers" in first:
n_t = (first.get("consumers") or {}).get("count", 0)
top_copy += f" · used by {n_t} template{'s' if n_t != 1 else ''}"
standing.append(top_copy)
if coverage.get("unused_css"):
n_u = coverage["unused_css"]
standing.append(f"{n_u} unused class{'es' if n_u != 1 else ''}")
if unclassified:
line += f"; {unclassified} unclassified"
if standing: