#!/usr/bin/env python3 """loss_view.py - render + lint the rated loss-manifest registry. #TAG:loss_view Usage: python loss_view.py card|ladder|role|cell|show|recheck-gauge|lint|html [ARG] [--json PATH] [--min N] [--max N] (verb defaults to 'card') Reads inventory/loss_manifest.json. Stdlib only, no import-time side effects.""" import argparse, collections, html, json, os, sys, zlib FALLBACK_ROOT = "." ROLES = ("PRIMARY", "AUX", "GAUGE", "GAUGE-DISTRUSTED", "RETRACTED", "FORBIDDEN") # BREG (Bregman divergence of a substrate potential) is the FOURTH differencing # primitive, introduced 2026-07-25 by the FAC design - a genuine schema widening, # not a mis-binning: it is neither CE, squared error, nor KL. PRIMS = ("CE", "SQ", "KL", "DET", "BREG", "NONE") COLS = (("CE", "CE"), ("SQ", "SQ"), ("KL", "KL"), ("DET", "DET"), ("BREG", "BREG"), ("NONE", "-")) ACCUMS = tuple("A%d" % i for i in range(11)) + ("NA",) # NA minted 2026-07-25 (A0 audit) # key, display name, lo, hi (names overridable by an optional top-level "sub_names" map) SUB = (("R", "replication", 0, 3), ("P", "potency", 0, 3), ("D", "durability", 0, 2), ("C", "coverage", 0, 2), ("I", "independence", 0, 2), ("L", "lineage", 0, 1)) ABBR = {"PRIMARY": "PRIM", "AUX": "AUX", "GAUGE": "GAUG", "GAUGE-DISTRUSTED": "GDIS", "RETRACTED": "RETR", "FORBIDDEN": "FORB"} # the only four non-ASCII glyphs this tool emits: dagger, heavy-x, perpendicular, warning MARK = (("retraction=1", "\u2020"), ("doctrine<=2", "\u2716"), ("split", "\u27c2"), ("contra", "\u26a0")) LEGEND = ("\u2020 retraction floor-breaker | \u2716 doctrine ceiling | " "\u27c2 split sibling | \u26a0 unreconciled contradiction") BANNER_LAW = "Each row is the EVIDENCE for a standing law. Not a graveyard - cite them." def repo_root(): d = os.path.abspath(os.getcwd()) while True: if os.path.exists(os.path.join(d, "MANIFEST.md")): return d p = os.path.dirname(d) if p == d: return FALLBACK_ROOT d = p def load(path): p = path or os.path.join(repo_root(), "inventory", "loss_manifest.json") if not os.path.isfile(p): print("ERROR: loss manifest not found at %s (pass --json PATH)" % p) sys.exit(2) with open(p, encoding="utf-8") as f: return json.load(f) def cut(s, n): s = "" if s is None else str(s) return s if len(s) <= n else s[:max(1, n - 3)] + "..." def pad(s, n): return "%-*s" % (n, cut(s, n)) def wrap(s, n, ind): out, cur = [], ind for w in str(s).split(): if cur.strip() and len(cur) + len(w) > n: out.append(cur.rstrip()) cur = ind cur += w + " " out.append(cur.rstrip()) return "\n".join(out) def banner(d): print("LOSS MANIFEST - census %s - %d entries - rubric v%s" % (d.get("census_date", "?"), len(d.get("entries") or []), d.get("rubric_version", "?"))) def prim_lbl(e): return "-" if e.get("primitive") == "NONE" else str(e.get("primitive")) def cell_lbl(e): return "%s.%s/%s" % (prim_lbl(e), e.get("accum"), e.get("substrate", "?")) def rate_lbl(e): hi = e.get("rating_hi") return "%s-%s" % (e.get("rating"), hi) if hi is not None else "%s" % e.get("rating") def marks(e): r = e.get("rules_fired") or [] return "".join(g for t, g in MARK if t in r) def rate_col(e): return rate_lbl(e) + marks(e) def rpdcil(e): s = e.get("sub") or {} return "".join(str(s.get(k, "?")) for k, _, _, _ in SUB[:5]) + "+" + str(s.get("L", "?")) def sub_named(d): ov = d.get("sub_names") or {} return [(k, ov.get(k, nm), lo, hi) for k, nm, lo, hi in SUB] def sortkey(e): s = e.get("sub") or {} return (-(e.get("rating") or 0), -(s.get("P") or 0), -(s.get("R") or 0), str(e.get("id"))) def expect(d, e): """rubric-derived rating: lookup[s_raw], minus blind-2, then every '<=N' cap, then retraction.""" lut = d.get("lookup") or [] s = e.get("s_raw") if not isinstance(s, int) or not 0 <= s < len(lut): return None base = lut[s] rules = e.get("rules_fired") or [] if "blind-2" in rules: base -= 2 for t in rules: # canonical order is unrun/single-seed/sub1pct/doctrine; min-caps commute if "<=" in t: try: base = min(base, int(t.split("<=")[1])) except ValueError: pass if "retraction=1" in rules: return 1 return max(1, base) def card(d, arg, a): es = d.get("entries") or [] banner(d) print("") c = collections.Counter((x.get("primitive"), x.get("accum")) for x in es) print("GRID " + "".join("%5s" % l for _, l in COLS) + "%6s" % "row") tot = {} for acc in ACCUMS: v = [c[(p, acc)] for p, _ in COLS] tot[acc] = sum(v) print("%-5s" % acc + "".join("%5s" % (x if x else "-") for x in v) + "%6d" % tot[acc]) emp = [k for k in ACCUMS if not tot[k] and k != "A10"] line = "empty: " + (" ".join(emp) if emp else "(none)") if not tot["A10"]: line += " | A10 EMPTY BY STATUTE" print(line) print("") h = collections.Counter(x.get("rating") for x in es) mx = max([h[r] for r in range(1, 11)] + [1]) print("RATINGS") for r in range(1, 11): n = h.get(r, 0) bar = "#" * max(1, round(22 * n / mx)) if n else "" print("%2d |%-22s %d" % (r, bar, n)) rr = sorted((x.get("rating") or 0) for x in es) mean = sum(rr) / len(rr) if rr else 0.0 med = 0.0 if not rr else (rr[len(rr) // 2] if len(rr) % 2 else (rr[len(rr) // 2 - 1] + rr[len(rr) // 2]) / 2) print("mean %.2f median %.1f (ranges counted at their low end)" % (mean, med)) print("") print("TOP") for x in sorted(es, key=sortkey)[:3]: print(" %s %s %s %s" % (pad(x.get("id"), 6), pad(rate_col(x), 6), pad(x.get("name"), 32), cut(x.get("headline"), 34))) print("") print("BOTTOM %d entries at rating 1" % sum(1 for x in es if x.get("rating") == 1)) print(" these are the DOCTRINE'S PROOF SET, not an appendix - see `role RETRACTED`") print("") print("FLAGS contradictions %d | gauge-distrusted %d | unrun-flagged %d" % (sum(1 for x in es if x.get("rating_hi") is not None or "contra" in (x.get("rules_fired") or [])), sum(1 for x in es if x.get("role") == "GAUGE-DISTRUSTED"), sum(1 for x in es if "UNRUN" in (x.get("flags") or [])))) print("") print(LEGEND) def ladder(d, arg, a): banner(d) print("") es = [x for x in (d.get("entries") or []) if a.min <= (x.get("rating") or 0) <= a.max] print("%-6s %-8s %-7s %-4s %-16s %-24s %s" % ("ID", "RATE", "RPDCIL", "ROLE", "CELL", "NAME", "HEADLINE")) for x in sorted(es, key=sortkey): print("%s %s %-7s %-4s %s %s %s" % (pad(x.get("id"), 6), pad(rate_col(x), 8), rpdcil(x), ABBR.get(x.get("role"), "?"), pad(cell_lbl(x), 16), pad(x.get("name"), 24), cut(x.get("headline"), 24))) print("") print("%d rows (rating %d..%d)" % (len(es), a.min, a.max)) print(LEGEND) def role(d, arg, a): banner(d) print("") want = (arg or "").upper() if want not in ROLES: print("unknown role '%s' - one of: %s" % (arg, " ".join(ROLES))) return es = [x for x in (d.get("entries") or []) if x.get("role") == want] print("ROLE %s - %d entries" % (want, len(es))) print("") if want not in ("RETRACTED", "FORBIDDEN"): for x in sorted(es, key=sortkey): print("%s %s %s %s %s" % (pad(x.get("id"), 6), pad(rate_col(x), 8), pad(cell_lbl(x), 16), pad(x.get("name"), 28), cut(x.get("headline"), 34))) return print(BANNER_LAW) print("") fam = collections.defaultdict(list) for x in es: fam[x.get("family") or "(unfiled)"].append(x) for k, v in sorted(fam.items(), key=lambda kv: (-len(kv[1]), kv[0])): print("[%s] %d" % (k, len(v))) for x in sorted(v, key=sortkey): print(" %s %s %s %s" % (pad(x.get("id"), 6), pad(rate_col(x), 6), pad(x.get("name"), 34), cut(x.get("headline"), 38))) print("") def cell(d, arg, a): banner(d) print("") p, _, acc = (arg or "").partition(".") p, acc = p.strip().upper(), acc.strip().upper() if p == "-": p = "NONE" if p not in PRIMS or acc not in ACCUMS: print("usage: cell ., PRIM in %s, ACCUM in A0..A10" % "/".join(PRIMS)) return meta = (d.get("accum") or {}).get(acc) or {} print("CELL %s.%s" % ("-" if p == "NONE" else p, acc)) print(" %s: %s" % (acc, meta.get("name", "(no name in accum map)"))) print(wrap("law: %s" % meta.get("law", "(no law text)"), 96, " ")) print("") es = [x for x in (d.get("entries") or []) if x.get("primitive") == p and x.get("accum") == acc] if not es: print("(no entries occupy this cell)") return for x in sorted(es, key=sortkey): print("%s %s %-7s %-4s %s %s" % (pad(x.get("id"), 6), pad(rate_col(x), 8), rpdcil(x), ABBR.get(x.get("role"), "?"), pad(x.get("name"), 30), cut(x.get("headline"), 30))) print("") print("%d entries" % len(es)) def show(d, arg, a): banner(d) print("") e = next((x for x in (d.get("entries") or []) if str(x.get("id")) == str(arg)), None) if e is None: print("no entry with id '%s'" % arg) return known = ("id", "name", "role", "primitive", "accum", "substrate", "family", "flags", "s_raw", "rating", "rating_hi", "sub", "rules_fired", "gauge", "headline", "cite", "note") print("id %s" % e.get("id")) print("name %s" % e.get("name")) print("role %s" % e.get("role")) print("primitive %s" % prim_lbl(e)) print("accum %s (%s)" % (e.get("accum"), ((d.get("accum") or {}).get(e.get("accum")) or {}) .get("name", "?"))) print("substrate %s" % e.get("substrate")) print("cell %s" % cell_lbl(e)) print("family %s" % e.get("family")) print("flags %s" % (", ".join(e.get("flags") or []) or "(none)")) print("rating %s%s" % (rate_lbl(e), (" " + marks(e)) if marks(e) else "")) print("rating_hi %s" % ("(none)" if e.get("rating_hi") is None else e.get("rating_hi"))) print("s_raw %s (rubric-derived rating: %s)" % (e.get("s_raw"), expect(d, e))) s = e.get("sub") or {} for k, nm, lo, hi in sub_named(d): print(" %s %-13s %s [%d..%d]" % (k, nm, s.get(k, "?"), lo, hi)) print("rules_fired %s" % (", ".join(e.get("rules_fired") or []) or "(none)")) print("gauge %s" % e.get("gauge")) print("headline %s" % e.get("headline")) print("cite %s" % (("\n ".join(str(c) for c in (e.get("cite") or []))) or "(EMPTY - lint violation)")) print("note %s" % (e.get("note") or "(none)")) for k in sorted(k for k in e if k not in known): print("%-11s %s" % (k, e[k])) def recheck_gauge(d, arg, a): banner(d) print("") q = (arg or "").lower() if not q: print("usage: recheck-gauge (matched against gauge and every cite)") return print("GAUGE BLINDNESS SWEEP - all rows below must be re-rated in the same session.") print("") hits = [x for x in (d.get("entries") or []) if q in str(x.get("gauge") or "").lower() or any(q in str(c).lower() for c in (x.get("cite") or []))] for x in sorted(hits, key=sortkey): print("[ ] %s %s %s gauge=%s" % (pad(x.get("id"), 6), pad(rate_col(x), 8), pad(x.get("name"), 30), cut(x.get("gauge"), 16))) print(wrap("cite: %s" % (", ".join(str(c) for c in (x.get("cite") or [])) or "(none)"), 96, " ")) print("") print("%d rows matched '%s'" % (len(hits), arg)) def lint(d, arg, a): banner(d) print("") es = d.get("entries") or [] v = [] for k, n in sorted(collections.Counter(str(x.get("id")) for x in es).items()): if n > 1: v.append("%s: duplicate id (%d entries share it)" % (k, n)) splits = collections.Counter(str(x.get("family")) for x in es if "split" in (x.get("rules_fired") or [])) for x in es: i, r, s = x.get("id"), x.get("rules_fired") or [], x.get("sub") or {} if not (x.get("cite") or []): v.append("%s: empty cite" % i) for fld in ("formula", "impl"): # roster law 2026-07-25 if not x.get(fld): v.append("%s: missing %s (every entry carries its math + its home)" % (i, fld)) if x.get("role") not in ROLES: v.append("%s: role '%s' outside allowed set" % (i, x.get("role"))) if x.get("primitive") not in PRIMS: v.append("%s: primitive '%s' outside allowed set" % (i, x.get("primitive"))) if x.get("accum") not in ACCUMS: v.append("%s: accum '%s' outside A0..A10" % (i, x.get("accum"))) tot, ok = 0, True for k, nm, lo, hi in sub_named(d): dv = s.get(k) if not isinstance(dv, int) or isinstance(dv, bool) or not lo <= dv <= hi: v.append("%s: sub.%s (%s) = %r outside %d..%d" % (i, k, nm, dv, lo, hi)) ok = False else: tot += dv if ok and x.get("s_raw") != tot: v.append("%s: s_raw %s != R+P+D+C+I+L = %d" % (i, x.get("s_raw"), tot)) exp = expect(d, x) if exp is None: v.append("%s: s_raw %r outside lookup table (len %d)" % (i, x.get("s_raw"), len(d.get("lookup") or []))) elif exp != x.get("rating"): v.append("%s: rating %s != rubric-derived %d" % (i, x.get("rating"), exp)) if x.get("accum") == "A10" and x.get("role") not in ("FORBIDDEN", "RETRACTED"): v.append("%s: accum A10 with role %s (A10 is FORBIDDEN/RETRACTED only)" % (i, x.get("role"))) if "split" in r and splits[str(x.get("family"))] < 2: v.append("%s: split with no split sibling in family '%s'" % (i, x.get("family"))) hi = x.get("rating_hi") if hi is not None: if not isinstance(hi, int) or hi <= (x.get("rating") or 0): v.append("%s: rating_hi %r not greater than rating %s" % (i, hi, x.get("rating"))) if "contra" not in r: v.append("%s: rating_hi set but 'contra' missing from rules_fired" % i) for line in v: print(line) if v: print("LINT: %d violations" % len(v)) sys.exit(1) print("LINT: clean") sys.exit(0) def _shade(t): t = 0.0 if t < 0 else (1.0 if t > 1 else t) return int(238 - 214 * t), int(243 - 196 * t), int(250 - 140 * t) def _td(bg, fg, body, extra=""): return ("%s" % (bg[0], bg[1], bg[2], fg, extra, body)) def write_html(d, arg, a): banner(d) out = os.path.abspath(arg or "loss_manifest.html") es = d.get("entries") or [] esc, buckets = html.escape, collections.defaultdict(list) for x in es: buckets[(x.get("primitive"), x.get("accum"))].append(x.get("rating") or 0) b = ["", "loss manifest %s" % esc(str(d.get("census_date"))), "", "

LOSS MANIFEST - census %s - %d entries - rubric v%s

" % (esc(str(d.get("census_date"))), len(es), esc(str(d.get("rubric_version")))), "

cell shade = mean rating (light low, dark high); " "cell text = count / mean.

", "", _td((225, 228, 232), "#111111", "accum")] for p, l in COLS: b.append(_td((225, 228, 232), "#111111", "%s" % esc(l))) b.append(_td((225, 228, 232), "#111111", "row") + "") for acc in ACCUMS: meta = (d.get("accum") or {}).get(acc) or {} b.append("" + _td((238, 240, 243), "#111111", "%s %s" % (acc, esc(str(meta.get("name", "")))))) n_row = 0 for p, _l in COLS: rs = buckets.get((p, acc)) or [] n_row += len(rs) if not rs: b.append(_td((232, 232, 232), "#777777", "-", "text-align:center")) continue m = sum(rs) / len(rs) bg = _shade((m - 1) / 9.0) fg = "#ffffff" if (299 * bg[0] + 587 * bg[1] + 114 * bg[2]) / 1000 < 140 else "#111111" b.append(_td(bg, fg, "%d
%.1f" % (len(rs), m), "text-align:center")) b.append(_td((238, 240, 243), "#111111", "%d" % n_row, "text-align:center") + "") b.append("

entries

") b.append("") heads = ("ID", "RATE", "RPDCIL", "ROLE", "CELL", "FAMILY", "NAME", "HEADLINE", "RULES", "CITE") for hcol in heads: b.append(_td((225, 228, 232), "#111111", "%s" % hcol)) b.append("") for i, x in enumerate(sorted(es, key=sortkey)): bg = (255, 255, 255) if i % 2 else (246, 247, 249) vals = (x.get("id"), rate_col(x), rpdcil(x), x.get("role"), cell_lbl(x), x.get("family"), x.get("name"), x.get("headline"), " ".join(x.get("rules_fired") or []), "; ".join(str(c) for c in (x.get("cite") or []))) b.append("" + "".join(_td(bg, "#111111", esc(str(t if t is not None else ""))) for t in vals) + "") crc = zlib.crc32(json.dumps(d, sort_keys=True).encode("utf-8")) b.append("

%s
manifest crc32 0x%08x

" % (esc(LEGEND), crc)) b.append("") with open(out, "w", encoding="utf-8") as f: f.write("\n".join(b)) print("wrote %s" % out) if __name__ == "__main__": try: sys.stdout.reconfigure(encoding="utf-8", errors="replace") except Exception: pass VERBS = {"card": card, "ladder": ladder, "role": role, "cell": cell, "show": show, "recheck-gauge": recheck_gauge, "lint": lint, "html": write_html} ap = argparse.ArgumentParser() ap.add_argument("cmd", nargs="?", default="card", choices=sorted(VERBS)) ap.add_argument("arg", nargs="?", default="") ap.add_argument("--json", dest="path", default="") ap.add_argument("--min", type=int, default=1) ap.add_argument("--max", type=int, default=10) a, rest = ap.parse_known_args() if not a.arg and rest: a.arg = rest[0] # argparse rejects a leading '-', e.g. `cell -.A0`; recover it here VERBS[a.cmd](load(a.path), a.arg, a)