#!/usr/bin/env python3
"""Generate evidence.html and decisions.html for the AutoQA leadership site (v2)."""
import json
import html
from pathlib import Path

SITE = Path(__file__).resolve().parent.parent / "site"
DATA = json.load(open(SITE / "assets" / "claims.json"))
CLAIMS = {c["id"]: c for c in DATA["claims"]}
S = DATA["summary"]

E = html.escape


def chip(cid, label=None):
    c = CLAIMS.get(cid)
    if not c:
        raise KeyError(f"unknown claim id {cid}")
    du = c.get("decision_use") or {}
    g = du.get("grade", "?")
    title = E(f'[Decision-use {g} — {du.get("basis","")}] ' + c["claim"][:200])
    return f'<a class="claim-ref g{g}" href="evidence.html#{cid}" title="{title}">{label or cid} · {g}</a>'


def gapchip(gid, label=None):
    return f'<a class="claim-ref gap" href="evidence.html#{gid}" title="Measured gap — no published evidence; in-house measurement required">{label or gid.upper()}</a>'


def expchip(eid):
    return f'<a class="claim-ref gap" href="decisions.html#{eid}" title="Settled by experiment {eid.upper()}">{eid.upper()}</a>'


NAV = '''<nav id="primary-nav" class="primary-nav" aria-label="Primary navigation">
      <a href="index.html" data-nav="home">Thesis</a>
      <a href="research.html" data-nav="research">Research</a>
      <a href="architecture.html" data-nav="architecture">System</a>
      <a href="pilot.html" data-nav="pilot">Pilot</a>
      <a href="decisions.html" data-nav="decisions">Decisions</a>
      <a href="evidence.html" data-nav="evidence">Evidence</a>
      <a href="library.html" data-nav="library">Library</a>
    </nav>'''


def shell(title, description, active, body, extra_script=""):
    return f'''<!doctype html>
<html lang="en" data-theme="light">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="{E(description)}">
  <meta name="theme-color" content="#13243a">
  <title>{E(title)} · AutoQA Foundation</title>
  <link rel="stylesheet" href="assets/site.css">
  <script defer src="assets/site.js"></script>
</head>
<body class="">
<a class="skip-link" href="#main">Skip to content</a>
<header class="site-header">
  <div class="header-inner">
    <a class="brand" href="index.html" aria-label="AutoQA Foundation home">
      <span class="brand-mark" aria-hidden="true">AΩ</span>
      <span><strong>AutoQA</strong><small>Foundation 0.1.0</small></span>
    </a>
    <button class="nav-toggle" type="button" aria-expanded="false" aria-controls="primary-nav">Menu</button>
    {NAV}
    <div class="header-actions">
      <button class="theme-toggle" type="button" aria-label="Toggle dark mode"><span aria-hidden="true">◐</span></button>
      <a class="button button-small button-quiet" href="brief.html">Present</a>
    </div>
  </div>
</header>
<main id="main" class="page">
{body}
</main><script>document.documentElement.dataset.activeNav="{active}";</script>{extra_script}
<footer class="site-footer">
  <div class="footer-grid">
    <div><strong>AutoQA Foundation</strong><p>A measurement and governance framework for human-annotated AI training data.</p></div>
    <div><span class="footer-label">Version</span><p>Foundation 0.1.0<br>Leadership site generated 2026-07-15</p></div>
    <div><span class="footer-label">Primary artifacts</span><p><a href="evidence.html">Evidence ledger</a><br><a href="decisions.html">Decision register</a><br><a href="documents/view/research-atlas.html">Research atlas</a><br><a href="downloads/autoqa-foundation-v0.1.0.zip">Foundation archive</a></p></div>
    <div><span class="footer-label">Important limitation</span><p>Published judge results mostly evaluate model outputs, not human evaluative writeups. Positive-praise verification requires in-house validation.</p></div>
  </div>
</footer>
</body>
</html>'''


# =====================================================================================
# EVIDENCE LEDGER
# =====================================================================================
DOMAIN_LABELS = {
    "academic-judges": "Academic judges",
    "annotation-quality": "Annotation quality",
    "critique-models": "Critique models",
    "grounding-faithfulness": "Grounding & faithfulness",
    "hybrid-statistical": "Hybrid & statistical",
    "rubrics-recent": "Rubrics 2025–26",
    "industry-practice": "Industry practice",
    "contrarian": "Contrarian",
    "frontier-2026": "Frontier 2026",
    "critic-and-gapfill": "Critic & gap-fill",
    "durable-anchors": "Durable anchors — round 2",
}

VERDICT_LABEL = {
    "confirmed": ("v-confirmed", "Confirmed"),
    "partially_confirmed": ("v-partial", "Partially confirmed"),
    "mismatch": ("v-mismatch", "Mismatch"),
    "not_retrievable": ("v-none", "Not retrievable"),
    None: ("v-none", "Not yet re-checked"),
}

GAPS = [
    ("gap-01", "Positive-claim / praise verification", "Precision and recall of “is this praise warranted,” per praise type: the reviewed corpus identifies no published benchmark — treated as unmeasured, not as proven absent. The mission’s core novel requirement is a from-scratch measurement. AbsenceBench predicts empty-praise detection is the hardest lane.", ["e2"]),
    ("gap-02", "Transfer from model outputs to human writeups", "Every published judge number was measured grading model outputs, not human evaluative writeups. Flagged by every domain; no partial-transfer experiment exists.", ["e3"]),
    ("gap-03", "False-agreement rate", "Judge and attempter both wrong versus expert ground truth, in an annotation-QA setting. Nearest proxies: the ≥3.3% gold-label error floor and the CriticGPT flawless-slice result.", ["e2"]),
    ("gap-04", "Attempter adaptation to a deployed AI QA layer", "Feedback-boundary leakage, AutoQA-vs-held-out-gold divergence, monoculture drift: no published study. The divergence sensor must be built, not borrowed.", ["e5"]),
    ("gap-05", "Longitudinal feedback efficacy for paid annotators", "Repeat-error-rate deltas under AI feedback: adjacent literatures transfer with caveats; the direct experiment is unrun.", ["e6"]),
    ("gap-06", "Confidence-proxy shootout", "Verbalized confidence vs k-sample agreement vs conformal width vs ensemble disagreement, scored on predicting human overturn: never benchmarked head-to-head.", ["e4"]),
    ("gap-07", "Our own reviewers’ reliability floor", "No measured Krippendorff’s alpha exists for the population this system is designed around. The variance-attribution pilot is the first experiment for a reason.", ["e1"]),
]


def render_ledger_item(c):
    cid = c["id"]
    lb = " load-bearing" if c["load_bearing"] else ""
    src = c["source"] or {}
    ext = c.get("external_verification")
    inc = c.get("in_corpus_verification")
    ven = c.get("venue") or {}

    du = c.get("decision_use") or {}
    grade = du.get("grade", "?")
    GRADE_LABEL = {"A": ("g-a", "Decision-use A · durable"),
                   "B": ("g-b", "Decision-use B · current-gen, confirm at bakeoff"),
                   "C": ("g-c", "Decision-use C · magnitude superseded — mechanism prior only")}
    g_cls, g_label = GRADE_LABEL.get(grade, ("g-b", f"Decision-use {grade}"))

    ext_cls, ext_label = VERDICT_LABEL.get((ext or {}).get("verdict"), VERDICT_LABEL[None])
    chips = [f'<span class="ledger-id">{cid}</span>',
             f'<span class="badge">{E(DOMAIN_LABELS.get(c["domain"], c["domain"]))}</span>',
             f'<span class="verdict-chip {g_cls}">{E(g_label)}</span>']
    if c["load_bearing"]:
        chips.append('<span class="badge warn">Load-bearing</span>')
    marker = ven.get("marker")
    if ven.get("peer_reviewed"):
        chips.append(f'<span class="badge good">Peer-reviewed · {E(str(marker))}</span>')
    elif marker == "preprint":
        chips.append('<span class="badge open">Preprint</span>')
    elif marker == "regulation/standard":
        chips.append('<span class="badge good">Regulation / standard</span>')
    elif marker in ("practitioner", "community"):
        chips.append(f'<span class="badge">{E(marker.title())}</span>')
    if inc:
        inc_cls = "v-confirmed" if inc.get("verdict") == "confirmed" else "v-partial"
        chips.append(f'<span class="verdict-chip {inc_cls}">Sweep audit · {E(inc.get("verdict") or "")}</span>')
    chips.append(f'<span class="verdict-chip {ext_cls}">Re-check 2026-07-15 · {E(ext_label)}</span>')

    parts = [f'<article class="ledger-item{lb}" id="{cid}" data-domain="{c["domain"]}" data-grade="{grade}" data-verdict="{(ext or {}).get("verdict") or "unchecked"}" data-lb="{int(c["load_bearing"])}" data-used="{int(bool(c["used_on"]))}" data-search="{E((c["claim"] + " " + (src.get("title") or "")).lower())}">']
    parts.append(f'<div class="ledger-head">{"".join(chips)}</div>')
    parts.append(f'<p class="ledger-claim">{E(c["claim"])}</p>')
    url = src.get("url") or "#"
    parts.append(f'<p class="ledger-src"><a href="{E(url)}" target="_blank" rel="noreferrer">{E(src.get("title") or url)}</a> · {E(src.get("date") or "")} · {E(src.get("type") or "")}</p>')

    du_bits = [f'<strong>Decision use:</strong> {E(du.get("basis") or "")} · measured on {E(du.get("measured_on") or "n/a")}']
    if du.get("models_measured"):
        du_bits.append(f'<strong>Models measured:</strong> {E(", ".join(du["models_measured"]))}')
    if du.get("note"):
        du_bits.append(f'<strong>Currency note:</strong> {E(du["note"])}')
    parts.append(f'<p class="ledger-kv">{"<br>".join(du_bits)}</p>')

    if ext:
        det = ['<details><summary>Independent re-check (2026-07-15)</summary>']
        if ext.get("quote"):
            det.append(f'<blockquote class="ledger-quote">“{E(ext["quote"])}”</blockquote>')
        kv = []
        if ext.get("retrieval"):
            kv.append(f'<strong>Retrieved:</strong> {E(ext["retrieval"])}')
        if ext.get("checked"):
            kv.append(f'<strong>Checked &amp; matching:</strong> {E("; ".join(ext["checked"]))}')
        if ext.get("not_visible"):
            kv.append(f'<strong>Asserted but not visible in retrievable text:</strong> {E("; ".join(ext["not_visible"]))}')
        if ext.get("notes"):
            kv.append(f'<strong>Notes:</strong> {E(ext["notes"])}')
        if kv:
            det.append(f'<p class="ledger-kv">{"<br>".join(kv)}</p>')
        det.append('</details>')
        parts.append("".join(det))

    if inc:
        det = ['<details><summary>Research-sweep verification transcript (2026-07-14)</summary>']
        det.append(f'<p class="ledger-kv">{E(inc.get("transcript") or "")}</p>')
        if inc.get("corrected"):
            det.append(f'<p class="ledger-kv"><strong>Corrected statement:</strong> {E(inc["corrected"])}</p>')
        det.append('</details>')
        parts.append("".join(det))

    parts.append(f'<details><summary>Evidence detail &amp; design implication</summary><p class="ledger-kv"><strong>Evidence:</strong> {E(c.get("evidence") or "")}</p><p class="ledger-kv"><strong>Implication:</strong> {E(c.get("implication") or "")}</p></details>')

    extras = []
    if c.get("same_source_claims"):
        sibs = " ".join(f'<a href="#{s}">{s}</a>' for s in c["same_source_claims"])
        extras.append(f'<div class="ledger-used"><span class="ledger-filter-note">Same underlying source as:</span> {sibs} <span class="ledger-filter-note">(repetition across domains is not independent corroboration)</span></div>')
    if c["used_on"]:
        links = " ".join(f'<a href="{E(u["page"])}#{E(u["anchor"])}">{E(u["label"])}</a>' for u in c["used_on"])
        extras.append(f'<div class="ledger-used"><span class="ledger-filter-note">Used on:</span> {links}</div>')
    parts.extend(extras)
    parts.append('</article>')
    return "".join(parts)


def build_evidence():
    v = S["external_verdicts"]
    n_conf = v.get("confirmed", 0)
    n_part = v.get("partially_confirmed", 0)
    n_mis = v.get("mismatch", 0)
    n_nr = v.get("not_retrievable", 0)

    gd = S.get("decision_grades", {})
    deploy = S.get("deployment_tier_measurements", {"count": 0})
    mo = S.get("measured_on", {})
    body = [f'''
  <header class="page-hero"><span class="hero-kicker">Evidence ledger</span><h1>Every load-bearing number: verified twice, then graded for decision use.</h1><p>{S.get("n_corpus_claims", 132)} claims from the research corpus{" plus " + str(S.get("n_da_admitted", 0)) + " round-2 durable anchors (admitted under the “relevant and certain” bar, provenance disclosed on each)" if S.get("n_da_admitted") else ""}, each tied to its primary source — with the research sweep’s own verification transcripts, an independent re-check against the retrievable source text run 2026-07-15, and a decision-use grade answering the question verification alone cannot: <em>is this claim usable for decisions under current capabilities, or is it verified-but-stale signal?</em> The philosophical kernel these decisions are built on is <a href="KERNEL.md">KERNEL.md</a>. Nothing here asks to be trusted; everything can be clicked through.</p></header>

  <section class="stat-strip" aria-label="Ledger summary">
    <div><span class="stat-number">{S["n_claims"]}</span><span class="stat-label">claims, {S["n_sources"]} primary sources</span></div>
    <div><span class="stat-number">{n_conf + n_part}</span><span class="stat-label">re-checks confirmed or confirmed-with-nuance · 0 refuted</span></div>
    <div><span class="stat-number">{gd.get("A", 0)}</span><span class="stat-label">grade-A durable claims safe to decide on now</span></div>
    <div><span class="stat-number">{deploy.get("count", 0)}</span><span class="stat-label">published tests of deployment-tier models on this task</span></div>
  </section>

  <section class="section">
    <div class="section-head"><div><span class="eyebrow">Method</span><h2>Two verification layers, one currency layer — honestly bounded.</h2></div><p>Verification below is layered, dated, and quoted — and its limits are stated rather than smoothed over.</p></div>
    <div class="equation-panel">
      <div class="equation">Layer 1 — sweep audit (2026-07-14)<small>During the research sweep, 27 load-bearing claims were adversarially spot-checked by independent verifiers who fetched the cited sources: 20 confirmed, 7 partially confirmed with corrections applied, 0 refuted. Full transcripts are preserved on each claim below.</small></div>
      <div class="equation">Layer 2 — independent re-check (2026-07-15)<small>Every one of the {S["n_claims"]} claims was re-checked against ONLY the source URL the corpus names (plus served redirects and same-document arXiv variants). Verdicts derive exclusively from retrieved text. Numbers that live only in a full PDF are listed as “not visible” rather than assumed true. {n_nr} sources could not be retrieved (paywalls, scripts) and are labeled as such.</small></div>
      <div class="equation">Layer 3 — decision-use grade (capability currency)<small>Verified is not the same as usable. Grade A ({gd.get("A", 0)} claims) — capability-invariant: law, mathematics, human-rater and feedback science, adversarial and economic floors, documented practice; decide on these now. Grade B ({gd.get("B", 0)}) — measured in the 2025–26 frontier window but not on the deployment tier; strong priors, confirmed at the bakeoff. Grade C ({gd.get("C", 0)}) — magnitudes from 2023–mid-2025 models (GPT-4o / o1 / flash-tier); the mechanism informs design, the number must not set a current threshold in either direction.</small></div>
    </div>
    <div class="callout danger" style="margin-top:18px"><strong>The capability-currency fact that frames everything.</strong> Of {S["n_claims"]} claims, {mo.get("model-outputs", 0)} were measured grading model outputs, {mo.get("human-work", 0)} on human work, {mo.get("adjacent-domain", 0)} in adjacent domains, and {mo.get("structural", 0)} are structural results — law, mathematics, standards, documented practice — that do not depend on model tier. <strong>{deploy.get("count", 0)} test the deployment-tier frontier (Claude Fable / Opus 4.8 class, GPT-5.5 / 5.6 class) on claim-level QA of human evaluative work.</strong> That combination has never been published. Dated evidence must not set current thresholds in either direction: neither the optimistic numbers as promises, nor the pessimistic ones as prohibitions. Capability-dependent anchors are re-measured on the deployment tier at the pilot bakeoff before any threshold is set.</div>
    <div class="callout warning" style="margin-top:14px"><strong>Independence caveat, kept visible.</strong> Several claims across different domains trace to the same underlying paper — repetition across domain reports is not corroboration. Same-source groupings are labeled on every affected claim. The headline kappa-deflation figures trace to one June 2026 preprint; its findings are directionally consistent with peer-reviewed work but the magnitudes should not be treated as settled.</div>
  </section>

  <section class="section" id="ledger">
    <div class="section-head"><div><span class="eyebrow">The ledger</span><h2>Filter, search, and open any claim.</h2></div><p>Claims used on the leadership pages carry links back to exactly where they are used. Load-bearing claims are edge-marked.</p></div>
    <div class="library-tools"><input id="ledger-search" class="search-box" type="search" placeholder="Search claims and sources: kappa, praise, FACTS, directive…" aria-label="Search the evidence ledger"><div id="ledger-count" class="library-summary"></div></div>
    <div class="filter-bar" aria-label="Verdict filters" data-fgroup="verdict">
      <button class="filter-button active" type="button" data-fv="All">All verdicts</button>
      <button class="filter-button" type="button" data-fv="confirmed">Confirmed</button>
      <button class="filter-button" type="button" data-fv="partially_confirmed">Partially confirmed</button>
      <button class="filter-button" type="button" data-fv="mismatch">Mismatch (0)</button>
      <button class="filter-button" type="button" data-fv="not_retrievable">Not retrievable</button>
    </div>
    <div class="filter-bar" aria-label="Decision-use filters" data-fgroup="grade">
      <button class="filter-button active" type="button" data-fg="All">All grades</button>
      <button class="filter-button" type="button" data-fg="A">A · durable</button>
      <button class="filter-button" type="button" data-fg="B">B · current-gen</button>
      <button class="filter-button" type="button" data-fg="C">C · superseded magnitude</button>
    </div>
    <div class="filter-bar" aria-label="Scope filters" data-fgroup="scope">
      <button class="filter-button active" type="button" data-fs="All">Whole corpus</button>
      <button class="filter-button" type="button" data-fs="used">Used on leadership pages</button>
      <button class="filter-button" type="button" data-fs="lb">Load-bearing</button>
    </div>''']

    order = ["durable-anchors", "academic-judges", "annotation-quality", "critique-models",
             "grounding-faithfulness", "hybrid-statistical", "rubrics-recent", "industry-practice",
             "contrarian", "frontier-2026", "critic-and-gapfill"]
    for dom in order:
        items = [c for c in DATA["claims"] if c["domain"] == dom]
        if not items:
            continue
        body.append(f'<div class="section-head ledger-domain-head" data-domain-head="{dom}"><div><span class="eyebrow">Domain</span><h2>{E(DOMAIN_LABELS[dom])}</h2></div><p>{len(items)} claims.</p></div>')
        for c in items:
            body.append(render_ledger_item(c))
    body.append('</section>')

    gap_cards = "".join(
        f'<article class="gap-card" id="{gid}"><h3>{E(t)}</h3><p>{E(d)}</p><div class="chip-row"><span class="ledger-filter-note">Measured by:</span>{"".join(expchip(e) for e in exps)}</div></article>'
        for gid, t, d, exps in GAPS)
    files = S["corpus_meta"]["files"]
    per_domain_gaps = []
    for fname, info in files.items():
        for g in info.get("gaps", []):
            per_domain_gaps.append(f'<li><strong>{E(DOMAIN_LABELS.get(info["domain"], info["domain"]))}:</strong> {E(g)}</li>')
    disagreements = []
    for fname, info in files.items():
        for g in info.get("disagreements", []):
            disagreements.append(f'<li><strong>{E(DOMAIN_LABELS.get(info["domain"], info["domain"]))}:</strong> {E(g)}</li>')

    body.append(f'''
  <section class="section" id="gaps">
    <div class="section-head"><div><span class="eyebrow">Honesty layer</span><h2>Where the reviewed corpus finds no evidence.</h2></div><p>Absence claims are bounded to what was actually reviewed — “not identified in this corpus,” never “proven absent.” These are not weaknesses to hide; they are the measurement plan. Each gap is assigned to the experiment that closes it in the <a href="decisions.html#experiments">decision register</a>.</p></div>
    <div class="gap-grid">{gap_cards}</div>
    {"".join(['<div class="callout" style="margin-top:20px"><strong>Candidate anchors — not admitted.</strong> Proposed as durable anchors but not verifiable against their primary source under this build’s retrieval constraints; they remain quarantined rather than quietly included: ' + "; ".join(E(c["title"]) + " (" + E(str(c["reason"])) + ")" for c in S.get("da_candidates_not_admitted", [])) + '.</div>']) if S.get("da_candidates_not_admitted") else ""}
    <details style="margin-top:26px"><summary class="ledger-filter-note" style="cursor:pointer">Open the full per-domain gap inventory ({len(per_domain_gaps)} entries)</summary><ul style="margin-top:12px; padding-left:20px; color:var(--ink-2); font-size:14px; line-height:1.7">{"".join(per_domain_gaps)}</ul></details>
    <details style="margin-top:14px"><summary class="ledger-filter-note" style="cursor:pointer">Open the recorded disagreements between sources ({len(disagreements)} entries — deliberately not averaged away)</summary><ul style="margin-top:12px; padding-left:20px; color:var(--ink-2); font-size:14px; line-height:1.7">{"".join(disagreements)}</ul></details>
  </section>

  <section class="section" id="integrity">
    <div class="section-head"><div><span class="eyebrow">Package integrity</span><h2>The foundation validates against its own contract.</h2></div><p>Run on this site’s copy of Foundation 0.1.0, 2026-07-15.</p></div>
    <div class="equation">python validation/validate_package.py<small>PASS project-contract.example.json · PASS case-input.example.json · PASS evaluation-output.example.json · PASS benchmark-item.example.json · PASS human-resolution-packet.example.json · PASS cross-document referential integrity · PASS canonical example hashes · PASS positive-proof and failure-proof invariants</small></div>
    <div class="callout" style="margin-top:16px"><strong>Correction applied to this site.</strong> The previously shipped <code>site-manifest.json</code> recorded stale hashes for <code>assets/site.css</code>, <code>assets/site.js</code>, and <code>README.md</code>, and omitted the font and favicon assets. The manifest was regenerated for this build and now covers every shipped file, including this page and the machine-readable ledger.</div>
    <div class="hero-actions" style="margin-top:22px"><a class="button" href="assets/claims.json" download>Download the machine-readable ledger (claims.json)</a><a class="button button-secondary" href="site-manifest.json" download>Download the site manifest</a></div>
  </section>''')

    script = '''<script>
(function(){
  var items=[...document.querySelectorAll('.ledger-item')];
  var heads=[...document.querySelectorAll('[data-domain-head]')];
  var q='';var fv='All';var fs='All';var fg='All';
  var search=document.getElementById('ledger-search');
  var count=document.getElementById('ledger-count');
  function apply(){
    var visible=0;
    items.forEach(function(el){
      var ok=true;
      if(fv!=='All'&&el.dataset.verdict!==fv)ok=false;
      if(fg!=='All'&&el.dataset.grade!==fg)ok=false;
      if(fs==='used'&&el.dataset.used!=='1')ok=false;
      if(fs==='lb'&&el.dataset.lb!=='1')ok=false;
      if(q&&el.dataset.search.indexOf(q)===-1)ok=false;
      el.hidden=!ok;if(ok)visible++;
    });
    heads.forEach(function(h){
      var dom=h.dataset.domainHead;
      h.hidden=!items.some(function(el){return el.dataset.domain===dom&&!el.hidden;});
    });
    if(count)count.textContent=visible+' of '+items.length+' claims';
  }
  if(search)search.addEventListener('input',function(){q=search.value.toLowerCase().trim();apply();});
  document.querySelectorAll('[data-fv]').forEach(function(b){b.addEventListener('click',function(){
    document.querySelectorAll('[data-fv]').forEach(function(x){x.classList.remove('active');});
    b.classList.add('active');fv=b.dataset.fv;apply();});});
  document.querySelectorAll('[data-fs]').forEach(function(b){b.addEventListener('click',function(){
    document.querySelectorAll('[data-fs]').forEach(function(x){x.classList.remove('active');});
    b.classList.add('active');fs=b.dataset.fs;apply();});});
  document.querySelectorAll('[data-fg]').forEach(function(b){b.addEventListener('click',function(){
    document.querySelectorAll('[data-fg]').forEach(function(x){x.classList.remove('active');});
    b.classList.add('active');fg=b.dataset.fg;apply();});});
  apply();
  if(location.hash){var t=document.querySelector(location.hash);if(t&&t.querySelector('details'))t.querySelector('details').open=true;}
})();
</script>'''

    page = shell("Evidence ledger", "Claim-by-claim evidence ledger with two layers of source verification for the AutoQA leadership case.", "evidence", "\n".join(body), script)
    (SITE / "evidence.html").write_text(page, encoding="utf-8")
    print(f"evidence.html: {len(page)} bytes, {len(DATA['claims'])} claims rendered")


# =====================================================================================
# DECISION REGISTER
# =====================================================================================

def ev(cid, why):
    return f'<div class="ev-row">{chip(cid)}<span>{why}</span></div>'


def ev_if(cid, why):
    """Evidence row rendered only if the claim was admitted to the ledger (DA anchors are conditional)."""
    return ev(cid, why) if cid in CLAIMS else ""


def gv(gid, why):
    return f'<div class="ev-row">{gapchip(gid)}<span>{why}</span></div>'


USAGE_RECORD = {}


def record_usage(html_fragment, anchor, title_text, page="decisions.html", prefix="Decisions"):
    import re as _re
    for m in _re.finditer(r'href="evidence\.html#([A-Za-z0-9-]+)"', html_fragment):
        cid = m.group(1)
        if cid.startswith("gap-"):
            continue
        USAGE_RECORD.setdefault(cid, [])
        entry = {"page": page, "anchor": anchor, "label": f"{prefix} · {title_text}"}
        if entry not in USAGE_RECORD[cid]:
            USAGE_RECORD[cid].append(entry)


def decision_block(anchor, kind, kicker, title, why, options_html, evidence_html, flip, deps, status_badges):
    badges = "".join(status_badges)
    deps_html = f'<div class="flip-line deps"><strong>Depends on</strong><span>{deps}</span></div>' if deps else ""
    record_usage(evidence_html + options_html + (flip or ""), anchor, html.unescape(title).rstrip("."))
    return f'''<article class="decision-block {kind}" id="{anchor}">
      <div class="ledger-head"><span class="ledger-id">{anchor.upper()}</span>{badges}</div>
      <span class="eyebrow">{E(kicker)}</span>
      <h3>{title}</h3>
      <p class="decision-why">{why}</p>
      {options_html}
      <div class="decision-evidence"><strong>Evidence (click any tag to audit it)</strong>{evidence_html}</div>
      <div class="flip-line"><strong>What changes this</strong><span>{flip}</span></div>
      {deps_html}
    </article>'''


def build_decisions():
    B = []
    B.append('''
  <header class="page-hero"><span class="hero-kicker">Decision register</span><h1>Every open call, its options, its evidence, and what would change the answer.</h1><p>This page is the working surface between the evidence and the pilot. Every decision links each of its load-bearing inputs to the <a href="evidence.html">evidence ledger</a>, states a recommended position where the evidence supports one, and — because this territory is genuinely uncharted — names the measurement that would flip it. Nothing here moves silently. The philosophical kernel underneath every entry — the permanent constraints, the chosen commitments, the derivations, and the honestly open holes — is <a href="KERNEL.md">KERNEL.md</a>; when a dispute arises, it is resolved by tracing to the kernel, not by re-arguing here.</p></header>

  <section class="stat-strip" aria-label="Register summary">
    <div><span class="stat-number">5</span><span class="stat-label">items</span></div>
    <div><span class="stat-number">6</span><span class="stat-label">open design decisions</span></div>
    <div><span class="stat-number">5</span><span class="stat-label">standing defaults on the record</span></div>
    <div><span class="stat-number">7</span><span class="stat-label">experiments that settle them</span></div>
  </section>

  <section class="section">
    <div class="callout danger"><strong>Capability currency — the rule this register is built under.</strong> The decisions below would be executed with deployment-tier models (Claude Fable / Opus 4.8 class, GPT-5.5 / 5.6 class). No published study tests that tier on claim-level QA of human evaluative work — the evidence base contains <a href="evidence.html">zero such measurements</a>. So this register leans hardest on grade-A evidence (law, mathematics, human-rater and feedback science, adversarial floors that only strengthen as models improve), treats grade-B current-generation results as priors to confirm, and treats grade-C superseded-generation magnitudes as mechanism warnings only. Dated evidence sets no current threshold in either direction: yesterday’s 55% is not today’s ceiling, and yesterday’s 91% is not today’s promise. Every capability-dependent bar is re-measured on the deployment tier at the pilot bakeoff before it binds anything. Every evidence tag below carries its grade. The standing rule, from <a href="KERNEL.md">the kernel</a>: <strong>design for the walls, rent the capability</strong> — the permanent constraints own the architecture; model capability only ever fills declared, re-measurable interface slots.</div>
  </section>''')

    # ---------------- Section A ----------------
    B.append('''
  <section class="section" id="authorize">
    <div class="section-head"><div><span class="eyebrow">Section A</span></div><p>This is a falsifiable pilot, not an automation promise. Each authorization states its own reversibility and failure condition.</p></div>''')

    B.append(decision_block(
        "a1", "leadership", "Authorization", "Approve the construct: instruction satisfaction plus evidence grounding.",
        "Quality is defined as satisfaction of the written project instructions, grounded in the defined evidence record — not imitation of the median reviewer. Consensus-prediction caps the system’s validity at the reviewers’ own unmeasured reliability ceiling; instruction-satisfaction lets the QA layer be more valid than the layer it augments, and makes every verdict traceable to a clause and a span.",
        '',
        "".join([
            ev("AJ-02", "Forced-choice consensus gold labels selected judge systems up to 31% worse when criteria admit multiple valid readings — the consensus construct mis-ranks judges."),
            ev("AQ-03", "Judge validation must stratify by human-label uncertainty; clear and contested items cannot be pooled into one target."),
            ev("AQ-04", "Most annotator disagreement traces to task underspecification and style — signal about the instructions, not error in the people."),
            ev("CT-11", "Disagreement contains recoverable systematic signal; forcing consensus destroys it."),
            ev("F26-08", "Lab-scale practice now preserves conflicting criteria as a record of legitimate disagreement."),
        ]),
        "Nothing in the corpus contradicts this construct. Experiment <a href='#e1'>E1</a> measures how much of OUR population’s disagreement is underspecification, which calibrates how much validity the construct switch buys here.",
        None,
        ['<span class="badge warn">Needs leadership sign-off</span>', '<span class="badge">Reversibility: moderate — gold sets built under one construct do not transfer cheaply</span>'],
    ))

    B.append(decision_block(
        "a2", "leadership", "Authorization", "Choose the first project — and fund its adjudicated gold set.",
        "One project with bounded evidence, meaningful reviewer variance, and enough expert access to adjudicate gold labels. The adjudicated gold set is the one cost that cannot be automated away; its size is computable in closed form before committing.",
        '',
        "".join([
            ev("HS-01", "PPI-family estimation makes a small human gold set go far — but only if it exists; sizing is closed-form from pilot correlation."),
            ev("HS-03", "Required human labels are computable in advance with doubly-robust designs — the budget is knowable before signing."),
            ev("RR-02", "Production-grade rubric practice is built on expert-written per-item criteria — expert access is the scarce input, not engineering."),
            ev("CT-03", "When the judge is no more accurate than what it evaluates, nothing cuts gold-label needs by more than 2× — the gold set is structural."),
        ]),
        "If no candidate project can fund adjudication, shrink the pilot design, not the measurement discipline — <a href='#e1'>E1</a> still runs on dual review alone.",
        "<a href='#d5'>D5</a> (the same choice sets the EU legal posture)",
        ['<span class="badge warn">Needs leadership sign-off</span>', '<span class="badge">Reversibility: moderate — per-project compilation cost is sunk</span>'],
    ))

    B.append(decision_block(
        "a3", "leadership", "Authorization", "Fund the measurement baseline before judging any automation.",
        "Dual-review a representative item set; measure reviewer–reviewer reliability, severity, fail prevalence, and code disagreements as rubric vs expertise vs attention vs legitimate ambiguity. This is Experiment E1 and it decides the build order.",
        '',
        "".join([
            ev("CG-02", "The canonical rater-science result: training improves rater self-consistency but does NOT equalize severity — calibration meetings cannot fix this."),
            ev("CG-04", "Rater main effects are minor; rater×item×criterion interactions dominate — only per-claim, per-item verification attacks the dominant variance."),
            gv("gap-07", "Our own reviewers’ reliability floor has never been measured — every downstream threshold depends on it."),
        ]),
        "Nothing — this purchase is valuable under every downstream outcome, including a decision not to build.",
        None,
        ['<span class="badge warn">Needs leadership sign-off</span>', '<span class="badge good">Reversibility: total — the data is useful regardless</span>'],
    ))

    B.append(decision_block(
        "a4", "leadership", "Authorization", "Set authority boundaries: measurement broadly, enforcement narrowly.",
        "No autonomous enforcement below calibrated Level B (the package’s own conformance rule). Consequential adverse actions retain a meaningful human decision-maker, plain-language explanation, and appeal — which is both what the complementarity evidence recommends and what EU platform-work law will require for EU workers.",
        '',
        "".join([
            ev("CT-02", "Across 370 effect sizes, naive human-verifies-AI teams underperform the best party alone; deference to AI recommendations reached ~90% in a 2025 hiring study."),
            ev("CM-03", "Evidence-only assistance is the only tested format that helps when the AI is right without hurting when it is wrong."),
            ev("CM-10", "The closest production analog (Toloka) ships pass / fail / unable-to-verify with human escalation — not autonomous enforcement."),
            ev("IP-01", "Vendor practice: the LLM judge flags for human review; it does not sanction."),
            ev("CG-07", "Platform Work Directive Art 10(5): decisions of significant detriment must be taken by a human — no consent exception."),
            ev("CG-11", "SCHUFA doctrine: a score with a determining role is itself an automated decision, and rubber-stamp review counts as zero-touch."),
            ev_if("DA-02", "US side: consequential verdicts over US workers are selection-procedure-shaped — validity evidence and adverse-impact monitoring are compliance duties under the Uniform Guidelines, independent of EU law."),
        ]),
        "Per-lane graduation is earned by the ship gate under a precommitted statistical rule: for every critical error class, the one-sided 95% upper confidence bound must sit below its approved ceiling on an untouched, adjudicated test set — ceilings, minimum effective sample, multiplicity treatment, and stop rules locked before the test is opened (the corpus's certification machinery and the benchmark protocol's rare-critical-error sizing exist for exactly this). Seeded fail-class recall and robustness probes (<a href='#e2'>E2</a>, <a href='#e3'>E3</a>) feed the operating-point curve. Capability currency cuts both ways: lane boundaries derive from deployment-tier bakeoff data — not from the pessimism of 2024-era numbers, nor the optimism of adjacent-domain studies.",
        None,
        ['<span class="badge warn">Needs leadership sign-off</span>', '<span class="badge">Reversibility: ratchet — authority is easy to grant later, hard to claw back</span>'],
    ))

    B.append(decision_block(
        "a5", "leadership", "Authorization", "Accept the permanent expert-audit channel as an operating cost.",
        "Blind seeded gold, randomized deep audits of confident passes, and rubric revision never sunset. This is not conservatism; it is arithmetic.",
        '',
        "".join([
            ev("CT-03", "The 2× theorem: when judge accuracy ≤ attempter accuracy, no statistical method can substitute for expert gold."),
            ev("AQ-10", "Gold labels themselves run ≥3.3% wrong — even the audit layer needs auditing."),
            ev("CM-02", "Critic-assisted second looks found 4× the rating-changing problems on the “flawless” slice — confident passes are exactly where audits pay."),
            ev("CG-13", "A decade of content-moderation practice: ~3–4% random audit plus QA-of-QA layers was the deployed baseline at Facebook/Cognizant scale."),
            ev("CG-14", "Industry codification: blind golden-set seeding works only if seeded items are indistinguishable — a standing design constraint."),
            ev_if("DA-04", "The audit-rate and escalate/relax machinery is a solved national standard (acceptance sampling: AQL-indexed plans with normal/tightened/reduced switching rules) — imported, not invented; deviations from the standard are what require justification."),
        ]),
        "Nothing — structural. The only tunable is the audit rate, which is set from measured drift and divergence (<a href='#e5'>E5</a>) — with the acceptance-sampling switching-rule template as the starting point.",
        None,
        ['<span class="badge warn">Needs leadership sign-off</span>', '<span class="badge">Reversibility: n/a — removing it removes the certificate</span>'],
    ))
    B.append('</section>')

    # ---------------- Section B ----------------
    B.append('''
  <section class="section" id="design-decisions">
    <div class="section-head"><div><span class="eyebrow">Section B</span><h2>Open design decisions on the program owner’s desk.</h2></div><p>Six calls the evidence narrows but does not make. Each carries a recommended position and the measurement that would overturn it.</p></div>''')

    B.append(decision_block(
        "d1", "owner", "Open decision", "Enforcement weight at launch: advisory or consequential?",
        "Whether verdicts carry consequences (pay, standing) from day one, or launch as coaching-only and attach consequences per-lane. This choice sets the precision floor, the legal posture, and the adversarial pressure the system faces on day one.",
        '''<div class="opt-grid">
          <div class="opt recommended"><strong>Launch advisory; attach consequences per-lane after seeded-recall numbers exist</strong>Preserves trust, tolerates the unmeasured praise-verification lane, keeps the legal floor forward-looking, and converts enforcement into an earned per-lane graduation.</div>
          <div class="opt"><strong>Consequential from day one</strong>Real deterrence immediately — but the precision floor for the weakest lanes is currently unmeasurable, false fails burn trust and pay, and EU-touching deployments immediately bind the Article 10(5) human-decision floor.</div>
        </div>
        <div class="equation" style="margin-top:16px">The arithmetic of consequences — no capability exemption exists<small>Worked example, checkable by hand (this is derivation, not literature): at a 3% true-fail prevalence, a judge with 95% fail-recall and 99% specificity produces fail-verdicts of which ≈25% are false accusations (0.95×0.03 true fails vs 0.01×0.97 false fails). Reaching 95% precision on fail-verdicts at that prevalence requires ≈99.8% specificity — and <em>demonstrating</em> 99.8% specificity to the person it binds requires thousands of adjudicated true-pass items. Consequential auto-fail is therefore gated by prevalence arithmetic and gold-set economics, not by model quality — which is why advisory-first is what the math licenses, not caution.</small></div>''',
        "".join([
            gv("gap-01", "Praise-verification precision — the lane most likely to generate false fails — has no published measurement identified in the reviewed corpus; a consequence-bearing launch would price this lane blind."),
            ev("CM-05", "Advisory feedback moves behavior at scale: 27% of reviewers revised after model feedback in a >20k-review RCT."),
            ev("CG-19", "More than a third of feedback interventions reduce performance — the channel needs instrumentation before it needs teeth."),
            ev("CG-07", "Consequential adverse decisions for EU workers require a human decision-maker — enforcement weight and the legal floor arrive together."),
            ev_if("DA-03", "The multitask incentive theorem: strong incentives on measured dimensions divert effort from unmeasured ones — enforcement weight on partially-measured quality is bounded by theorem, not prudence."),
        ]),
        "Per-lane seeded fail-class recall and false-flag rates from <a href='#e2'>E2</a>/<a href='#e3'>E3</a> at the contract’s error prices — the ship gate’s operating-point curve prices each lane’s consequences before they attach.",
        "<a href='#a4'>A4</a>, <a href='#d5'>D5</a>, <a href='#c5'>C5</a>",
        ['<span class="badge open">Open — owner call</span>', '<span class="badge">Reversibility: advisory→consequential is a ratchet; go slow</span>'],
    ))

    B.append(decision_block(
        "d2", "owner", "Open decision", "Construct authority: rubric-as-law, or standing owner overrides?",
        "When the project owner’s case-by-case intuition contradicts their own compiled rubric, which wins? The system’s premise is that unexplained variance is the disease — standing overrides quietly re-import it.",
        '''<div class="opt-grid">
          <div class="opt recommended"><strong>Rubric-as-law with forced amendment</strong>Owner disagreement triggers a versioned rubric amendment (with an explicit retroactive re-scoring policy), never a silent per-item exception. Every verdict stays traceable to a written clause.</div>
          <div class="opt"><strong>Standing owner overrides</strong>Faster in the moment; but overrides become unversioned criteria, verdicts stop being reproducible, and the override stream contaminates calibration data.</div>
        </div>''',
        "".join([
            ev("RR-05", "Criteria drift is structural: graders’ criteria change as they grade — amendments WILL happen; the design question is only whether they are versioned."),
            ev("CT-04", "Human evaluation criteria are output-dependent and unstable even when defined in advance — ad-hoc authority cannot be the arbiter."),
        ]),
        "If <a href='#e1'>E1</a> shows amendment latency is operationally intolerable for the pilot project, add a bounded fast-amendment path — still versioned, never silent.",
        None,
        ['<span class="badge open">Open — owner call</span>', '<span class="badge good">Reversibility: high — this is process, not infrastructure</span>'],
    ))

    B.append(decision_block(
        "d3", "owner", "Open decision", "LLM-assistance provenance: content validity only, or provenance-gated?",
        "Is a correct, well-grounded, heavily-LLM-assisted annotation a pass, a fail, or per-project policy? Roughly a third of text workers already use LLMs; detection is economically beaten; and process telemetry has legal limits.",
        '''<div class="opt-grid">
          <div class="opt recommended"><strong>Content-validity-only default, per-project override</strong>Judge the work, not the workflow. Defend integrity with economics and provenance signals at the worker level (throttling, work-history consistency, randomized deep audits), not per-item text detection.</div>
          <div class="opt"><strong>Provenance-gated</strong>Only defensible where a buyer contractually requires human-only process — and even then enforcement rests on telemetry that Article 7 constrains and on detection that a $0.05 agent already beats.</div>
        </div>''',
        "".join([
            ev("AQ-01", "~33–35% of crowdworkers used LLMs on an LLM-advantaged task; best mitigations halve it, never eliminate it, and cost quality."),
            ev("AQ-02", "An autonomous agent passes 99.8% of standard checks at ~$0.05/task — content-based detection is economically and technically beaten."),
            ev("AQ-08", "Worker-level statistical contamination auditing exists without per-item detection — the defensible instrument if provenance matters."),
            ev("CG-10", "Telemetry is allowlist-only for EU workers: no emotional-state inference, no off-task collection, DPIA required."),
        ]),
        "A buyer contract that pays for human-only provenance — in which case the gate is economic and worker-level, and the policy flips per-project, not globally.",
        "<a href='#d6'>D6</a> (disclosure posture)",
        ['<span class="badge open">Open — owner call</span>', '<span class="badge good">Reversibility: high — policy toggle per project contract</span>'],
    ))

    B.append(decision_block(
        "d4", "owner", "Open decision", "Judge sourcing: rent everything, or own the screening tier?",
        "The evidence supports a two-tier judge economy — cheap specialists screening every claim, frontier reasoners issuing verdicts, cross-family routing as the bias defense. The open question is only whether to eventually own the bottom tier.",
        '''<div class="opt-grid">
          <div class="opt recommended"><strong>Two-tier, both rented, cross-family — revisit at volume</strong>Frontier API reasoners for verdicts; commodity specialist checkers for screening at ~1/100 cost. No training program until measured volume crosses the fine-tune breakeven.</div>
          <div class="opt"><strong>Own a fine-tuned screening tier now</strong>Cost control and stack ownership — but trained judges win mainly on preference-style benchmarks, and the training data (adjudicated in-domain labels) does not exist until the pilot produces it.</div>
        </div>''',
        "".join([
            ev("AJ-01", "On judging tasks with verifiable ground truth, frontier reasoning models dominate fine-tuned judges and reward models. (2024-tier measurement — direction only; the bakeoff re-ranks on the deployment tier.)"),
            ev("GF-01", "Sub-1B–7B specialist checkers land within ~2.5 points of frontier models at ~1/100 cost — the screening tier is already commoditized."),
            ev("AJ-09", "2025’s trained judges (J1, CompassJudger-2, Skywork-V2) win on preference-style benchmarks — the wrong regime for criteria-based QA verdicts."),
            ev("GF-02", "The measured-best grounding architecture is exemplar anchoring on a frontier judge — it needs compiled exemplars, not a custom model."),
            ev("IP-08", "Published cost arithmetic: judge ~$5–15 per 10k outputs vs expert review ~$800–1,800 per 500 — routing, not model ownership, is the economic lever."),
        ]),
        "Screening volume × unit cost crossing the fine-tune breakeven, measured in the pilot’s bakeoff gate — plus adjudicated data sufficient to train on.",
        None,
        ['<span class="badge open">Open — owner call</span>', '<span class="badge good">Reversibility: high — tiers are swappable by design</span>'],
    ))

    B.append(decision_block(
        "d5", "owner", "Open decision", "Where the first pilot runs — and which legal floors bind at launch.",
        "The pilot project choice is simultaneously the legal-posture choice, and the gate is two-sided. EU side: if the attempter population includes EU-resident workers, the Platform Work Directive floor (human decision-maker on significant detriment, explanations, two-week substantiated review, telemetry limits, DPIA) becomes a launch constraint on 2026-12-02. US side: where verdicts influence pay, standing, or continued engagement of US workers, automated-employment-decision-tool and selection-procedure law attaches in enacted jurisdictions — bias-audit and notice obligations, and validation requirements under adverse impact. Neither side is a preference; both are facts to census per candidate project.",
        '''<div class="opt-grid">
          <div class="opt"><strong>US-only pilot population</strong>The EU floor stays forward-looking (design to it anyway — it is the same design K12 independently demands). The US side is live: AEDT/bias-audit exposure in enacted jurisdictions and selection-procedure validation duties are counsel questions before consequences attach, not after.</div>
          <div class="opt"><strong>EU-touching pilot population</strong>The PWD floor binds: consequential auto-fail is out at launch, appeal SLAs are mandatory, telemetry is allowlist-only, and counsel review precedes go-live.</div>
        </div>''',
        "".join([
            ev("CG-09", "The directive explicitly covers online-performed platform work — location of the platform does not exempt it; location of the worker decides."),
            ev("CG-07", "Art 10(5): restriction, suspension, or termination decisions must be taken by a human — no consent exception."),
            ev("CG-08", "Art 11: plain-language explanations, a competent human contact, and substantiated written review within two weeks — the evidence dossier and feedback tuple ARE this explanation if designed to that bar."),
            ev_if("DA-01", "NYC Local Law 144: independent bias audit and public summary before using an automated employment decision tool, plus candidate/employee notice — enforced since July 2023."),
            ev_if("DA-02", "The Uniform Guidelines (29 CFR 1607): selection procedures with adverse impact require validity evidence; the four-fifths rule is the practical adverse-impact test."),
            ev("CG-12", "ISO/IEC 5259 is the neutral vocabulary to map quality dimensions onto now (cheap) rather than retrofit later (expensive)."),
        ]),
        "A two-sided workforce census of the candidate projects (EU-resident and US-jurisdiction exposure) — facts to look up, not preferences; then counsel on the single-item pay-denial question (<a href='#c5'>C5</a>) and on US AEDT/selection-procedure applicability.",
        "<a href='#a2'>A2</a>, <a href='#d1'>D1</a>, <a href='#c5'>C5</a>",
        ['<span class="badge open">Open — owner call + counsel (both jurisdictions)</span>', '<span class="badge">Reversibility: low once live — population choice is the binding switch</span>'],
    ))

    B.append(decision_block(
        "d6", "owner", "Open decision", "Dial governance: who moves the operating profile, and is the residual error disclosed?",
        "Contractual pace sometimes demands a looser operating point. The system supports that honestly: the dial moves thresholds, routing, verification depth, and disposition — never the judge’s perception — and every batch ships stamped with its profile and corrected residual-error estimate. Two governance questions remain: who may move the dial, and whether the stamp is disclosed to the data buyer.",
        '''<div class="opt-grid">
          <div class="opt recommended"><strong>Owner + client sign-off; disclose the stamped estimate</strong>A priced error rate converts deadline pressure from hidden liability into a contractual artifact — and is the posture consistent with the ISO 5259 mapping. Attempter-facing bar changes are prospective-only and announced.</div>
          <div class="opt"><strong>Owner-only, undisclosed</strong>Operationally lighter — but re-creates exactly the off-the-books loosening the dial exists to prevent, and leaves the buyer pricing risk they do not know they hold.</div>
        </div>''',
        "".join([
            ev("F26-03", "Consequence framing measurably corrupts judge verdicts with zero chain-of-thought trace — which is WHY the dial must move thresholds downstream, never judge prompts."),
            ev("F26-09", "Corrected pass-rate reporting under an imperfect judge is a solved statistical problem — the stamp is computable, not aspirational."),
            ev("HS-08", "Plug-in corrected estimators exist precisely for reporting rates measured through a noisy judge."),
            ev("CG-12", "Buyer-side data-quality contracting is standardizing (ISO/IEC 5259) — disclosure aligns with where procurement is going."),
        ]),
        "Nothing on the mechanism — measurement persists under every profile by construction. The disclosure posture is the one genuinely commercial call on this page; it is flagged as such rather than dressed up as a technical conclusion.",
        None,
        ['<span class="badge open">Open — owner call</span>', '<span class="badge good">Reversibility: high — disclosure can begin with the first stamped batch</span>'],
    ))
    B.append('</section>')

    # ---------------- Section C ----------------
    B.append('''
  <section class="section" id="defaults">
    <div class="section-head"><div><span class="eyebrow">Section C</span><h2>Standing defaults, on the record.</h2></div><p>Positions the evidence does not fully settle, adopted explicitly and reversibly — each with the falsifier that retires or confirms it. This is what “uncharted territory” looks like when it is governed rather than guessed.</p></div>''')

    B.append(decision_block(
        "c1", "default-adopted", "Standing default", "Entailment standard: reasonable-expert support, three-way verdicts.",
        "Attempter statements are checked to a reasonable-expert-support standard, not strict logical entailment (which fails nearly all competent human prose). Output is supported / contradicted / unsupported — only “contradicted” is a high-confidence fail trigger; “unsupported” alone triggers an evidence request or escalation.",
        '',
        "".join([
            ev("GF-05", "Verifiability triage before entailment is field-standard machinery — opinions and undecidables never reach truth-scoring."),
            ev("GF-07", "The positive-class asymmetry is measured and large — fail-class behavior must be measured directly, not assumed from pass-class performance. (Measured on flash-tier graders; the deployment-tier asymmetry is E2’s first number.)"),
            ev("GF-03", "Strict atomic decomposition measurably degrades strong verifiers — context-preserving claim units are the default for the same reason."),
        ]),
        "The ship gate measures the false-flag rate under this standard per project; if it exceeds the contract’s error prices, the standard tightens per-lane — as a measured output, not an assumption.",
        None,
        ['<span class="badge good">Default adopted — reversible</span>'],
    ))

    B.append(decision_block(
        "c2", "default-adopted", "Standing default", "Read-checkable vs recompute-checkable routing is provisional.",
        "Judges silently re-solve tasks instead of checking evidence when checks exceed their own solving ability — so checks are routed by whether they can be verified by reading versus by recomputing. Flagged honestly: the quantified collapse comes from a single under-review 2026 study.",
        '',
        "".join([
            ev("F26-01", "Wrong-reference detection collapses (68%→9%) and false positives explode (44%→88%) beyond the judge’s solving ability, while read-checkable detection holds at 80% — one study, under review, replicated internally before this hard-gates routing."),
        ]),
        "Experiment <a href='#e3'>E3</a> includes an internal replication probe. If it fails to replicate on our workload, the hard routing gate is dropped; the routing config surface stays either way.",
        None,
        ['<span class="badge good">Default adopted — provisional</span>', '<span class="badge open">Rests on one under-review study — said out loud</span>'],
    ))

    B.append(decision_block(
        "c3", "default-adopted", "Standing default", "Evidence-only to adjudicators; full critiques to attempters.",
        "Escalated humans see the claim, the criterion clause, and the judge’s collected evidence spans — never its verdict or rationale. Attempters receive the full 4-tuple feedback (quoted claim, evidence span, criterion clause, concrete fix). The two halves are each evidence-backed; their combination is an inferred split no single study has tested.",
        '',
        "".join([
            ev("CM-03", "Verdict-visible review produces measured over-reliance; evidence-only is the sole format that helps when the AI is right without hurting when it is wrong."),
            ev("CM-05", "Full critiques delivered to authors changed behavior at deployment scale — the attempter side of the split."),
            ev("CM-01", "Critic-assisted humans strictly beat either alone on critique tasks — the assistance itself is not in question; only the format split is."),
        ]),
        "Experiment <a href='#e6'>E6</a> A/Bs the assistance-format split directly, alongside verdict-only vs 4-tuple feedback.",
        None,
        ['<span class="badge good">Default adopted — reversible</span>', '<span class="badge open">Combination inferred, untested in any single study</span>'],
    ))

    B.append(decision_block(
        "c4", "default-adopted", "Standing default", "Statistics staging: chance-corrected + PPI at v1; MFRM, e-processes, conformal at phase 2.",
        "Version 1 ships chance-corrected agreement, PPI-corrected population estimates with dual-uncertainty intervals, and k-sample entropy routing. Full psychometric enrollment of the judge as a rater facet, anytime-valid drift statistics, and conformal routing are phase-2 refinements — the full stack is the target, not the launch gate.",
        '',
        "".join([
            ev("AQ-06", "Chance-corrected coefficients can be near zero despite high raw agreement under extreme base rates — raw percent-agreement is banned from reporting at v1, not phase 2."),
            ev("HS-01", "PPI-corrected estimates stay valid under a bad judge — the v1 statistical floor is already sound."),
            ev("CG-06", "MFRM now applies symmetrically to LLM judges — the phase-2 enrollment has precedent, not speculation."),
            ev("CG-01", "MFRM adjustment flipped model rankings on real RLHF ratings — worth staging in, too consequential to improvise at launch."),
            ev("HS-10", "Frozen anchor sets with anytime-valid statistics attribute drift (judge moved vs population moved) — the phase-2 drift design is specified now."),
        ]),
        "Nothing — this is sequencing, not selection. Phase-2 components activate when the pilot’s rater-item overlap and volume make them estimable.",
        None,
        ['<span class="badge good">Default adopted — staging</span>'],
    ))

    B.append(decision_block(
        "c5", "default-adopted", "Standing default", "A consequential single-item pay denial is treated as “significant detriment” until counsel says otherwise.",
        "Whether one item’s pay denial qualifies as a decision of “equivalent detriment” under Article 10(5) is legally untested. Until counsel or transposition texts settle it, consequential item fails route through the human lane for EU workers.",
        '',
        "".join([
            ev("CG-07", "The Article 10(5) floor and its untested single-item boundary — the conservative reading is adopted, and labeled as a reading."),
            ev("CG-11", "Active enforcement exists (SCHUFA doctrine; €490k Hamburg fine) — the cost of guessing wrong is not hypothetical."),
        ]),
        "A counsel opinion or the national transposition texts (deadline 2026-12-02). This is the one default on this page that law, not measurement, will flip.",
        "<a href='#d5'>D5</a>",
        ['<span class="badge good">Default adopted — conservative</span>', '<span class="badge open">Legally untested boundary</span>'],
    ))
    B.append('</section>')

    # ---------------- Section D ----------------
    exps = [
        ("e1", "E1 — Variance-attribution pilot", "Dual review + disagreement coding on one live project. Measures the human floor and splits variance into rubric vs expertise vs attention vs legitimate ambiguity.",
         "Calibrates <a href='#a1'>A1</a> · funds <a href='#a3'>A3</a> · informs <a href='#d2'>D2</a> and per-project build order · closes <a href='evidence.html#gap-07'>GAP-07</a>"),
        ("e2", "E2 — Positive-claim seeded set", "Warranted vs empty praise pairs per praise type; judge precision/recall per type, plus absence-claim recall behind “no errors” writeups. The first measurement of the moat.",
         "Prices <a href='#d1'>D1</a>’s per-lane consequences · closes <a href='evidence.html#gap-01'>GAP-01</a> and <a href='evidence.html#gap-03'>GAP-03</a>"),
        ("e3", "E3 — Transfer check", "Compiled-config judge vs adjudicated labels on HUMAN evaluative writeups — the number every published anchor is missing. Includes the re-solving replication probe.",
         "Tests <a href='#c2'>C2</a> · closes <a href='evidence.html#gap-02'>GAP-02</a> · gates every borrowed benchmark number"),
        ("e4", "E4 — Confidence-proxy shootout", "Verbalized confidence vs k-sample entropy vs conformal width vs cross-family disagreement, scored on predicting human overturn — with a uniform-sampling baseline.",
         "Picks the routing statistic behind <a href='#a4'>A4</a> · closes <a href='evidence.html#gap-06'>GAP-06</a>"),
        ("e5", "E5 — Divergence sensor dry run", "Held-out human-graded goldens + AutoQA score tracking from the first live week, so Goodhart is measurable before it is a problem.",
         "Arms the standing alarm behind <a href='#a5'>A5</a> and <a href='#d6'>D6</a> · closes <a href='evidence.html#gap-04'>GAP-04</a>"),
        ("e6", "E6 — Feedback tier A/B", "Verdict-only vs 4-tuple high-information feedback; repeat-error rate per criterion as the outcome, attrition separated; includes the assistance-format split.",
         "Tests <a href='#c3'>C3</a> · decides whether the feedback channel is instrument or decoration · closes <a href='evidence.html#gap-05'>GAP-05</a>"),
        ("e7", "E7 — Agnosticism falsification", "Onboard a second project through config alone. Any edit to the core judge prompts falsifies the project-agnostic claim; the fix is widening the config schema, never patching the core.",
         "Guards the architecture’s central product claim"),
    ]
    rows = "".join(
        f'<tr id="{eid}"><td><strong>{E(name)}</strong></td><td>{E(what)}</td><td>{feeds}</td></tr>'
        for eid, name, what, feeds in exps)
    B.append(f'''
  <section class="section" id="experiments">
    <div class="section-head"><div><span class="eyebrow">Section D</span><h2>The experiments that settle them.</h2></div><p>Ordered; each kills or funds a component. This is the machinery that turns the defaults above from opinions into measurements. Four outcomes are legitimate by construction — <strong>stop</strong>, <strong>narrow</strong> (fewer lanes or projects), <strong>assisted-only</strong> (no autonomous authority), or <strong>selective graduation</strong> (named criterion families and actions only) — and the register is written so a credible “stop” is a success of the process, not a failure of it.</p></div>
    <table class="metric-table"><thead><tr><th>Experiment</th><th>What it measures</th><th>What it settles</th></tr></thead><tbody>{rows}</tbody></table>
    <div class="callout" style="margin-top:22px"><strong>Sequencing note (recommendation only — nothing operational is authorized by this paragraph).</strong> The highest-information-per-dollar measurement in the program is a stripped E2 probe: a seeded warranted/empty-praise and planted-defect set, scored by the deployment-tier models, buildable from existing expert-annotated flawed-solution material. It can run first and in parallel with A2/A3, and its result moves more decisions per dollar than anything else here — it prices the moat, D1’s consequence timeline, and the lane map simultaneously, in either direction. Foundation before implementation stands: this note changes the <em>order</em> of the already-defined experiments, not the authorization to build anything.</div>
    <div class="callout danger" style="margin-top:22px"><strong>Bakeoff scope (pilot gate 4) — the capability-currency requirement.</strong> Every capability-dependent anchor in the <a href="evidence.html">evidence ledger</a> (grades B and C) is re-measured at the bakeoff on the deployment-tier set — Claude Fable / Opus 4.8 class and GPT-5.5 / 5.6 class, cross-family — on OUR adjudicated human-writeup data, before any threshold, lane assignment, or human-only designation is fixed. Published numbers inform the design of the measurement; they never substitute for it. This cuts both ways by construction: lanes the 2024–25 literature says are near-chance may clear the bar at the deployment tier, and lanes the optimistic studies favor may not survive contact with human evaluative writeups.</div>
  </section>''')

    # ---------------- Section E ----------------
    B.append(f'''
  <section class="section" id="invariants">
    <div class="section-head"><div><span class="eyebrow">Section E</span><h2>Not open for re-litigation.</h2></div><p>Constraints already encoded in the foundation — listed so decision meetings spend no time on them.</p></div>
    <div class="concept-grid">
      <article class="concept-card"><span class="concept-index">01</span><h3>Reporting</h3><strong>No raw percent-agreement, anywhere.</strong><p>Chance-corrected statistics, per-class recall at fixed prevalence, corrected population estimates with intervals. {chip("AJ-03")} {chip("AQ-06")}</p></article>
      <article class="concept-card"><span class="concept-index">02</span><h3>Judge prompts</h3><strong>Stakes-sterile and dial-sterile, always.</strong><p>Consequence framing measurably corrupts verdicts with no chain-of-thought trace; leniency moves thresholds downstream, never perception. {chip("F26-03")}</p></article>
      <article class="concept-card"><span class="concept-index">03</span><h3>Human scoring</h3><strong>Never score anyone on agreement with the final verdict.</strong><p>Consensus-rewarded auditing trains the best dissenters to conform exactly where independent judgment matters most. {chip("CG-16")}</p></article>
      <article class="concept-card"><span class="concept-index">04</span><h3>Absence claims</h3><strong>“Not contradicted,” never “verified,” without seeded recall.</strong><p>Omission detection is the judge’s structurally weakest lane. {chip("CM-06")}</p></article>
      <article class="concept-card"><span class="concept-index">05</span><h3>Spam defense</h3><strong>Economics and provenance, not content detection.</strong><p>An autonomous agent passes 99.8% of content checks at $0.05/task; the defense is identity, throttling, history, and randomized audits. {chip("AQ-02")}</p></article>
      <article class="concept-card"><span class="concept-index">06</span><h3>Calibration data</h3><strong>No judge calibration from unadjudicated override streams.</strong><p>Single-touch overrides are logged as claims, not truth; only panel-adjudicated or owner-signed artifacts calibrate. {chip("CG-16")} {chip("AQ-10")}</p></article>
    </div>
    <div class="callout danger" style="margin-top:26px"><strong>And one meta-invariant.</strong> The bar attempters are judged against never moves silently or retroactively. Profile changes are owner-authorized, logged, prospective-only, and announced. This is simultaneously the trust posture, the legal posture, and the Goodhart defense.</div>
    <div class="hero-actions" style="margin-top:28px"><a class="button" href="evidence.html">Audit the evidence behind this page</a><a class="button button-secondary" href="pilot.html">See the pilot that runs these experiments</a><a class="button button-secondary" href="assets/decision-record.json" download>Download the machine-readable decision record</a></div>
  </section>''')

    # record invariants-section usage too
    record_usage(B[-1], "invariants", "Not open for re-litigation")

    page = shell("Decision register", "Every open AutoQA decision with options, linked evidence, recommended defaults, and the experiments that would change each answer.", "decisions", "\n".join(B))
    (SITE / "decisions.html").write_text(page, encoding="utf-8")
    print(f"decisions.html: {len(page)} bytes")


build_decisions()
import json as _json
(Path(__file__).resolve().parent / "decisions_usage.json").write_text(
    _json.dumps(USAGE_RECORD, indent=2, ensure_ascii=False), encoding="utf-8")
print(f"decisions_usage.json: {len(USAGE_RECORD)} claims referenced from decision register")
build_evidence()


# =====================================================================================
# MACHINE-READABLE DECISION RECORD
# =====================================================================================
def evidence_ids_for(anchor):
    return sorted({cid for cid, uses in USAGE_RECORD.items()
                   if any(u["anchor"] == anchor for u in uses)})


record = {
    "record_version": "1.1.0",
    "date": "2026-07-15",
    "status": "proposed — pending leadership sign-off (A1–A5) and owner calls (D1–D6)",
    "register_page": "decisions.html",
    "evidence_page": "evidence.html",
    "kernel": {
        "path": "KERNEL.md",
        "version": "0.1",
        "discipline": "A design element is legitimate only if derived from the kernel, an operationalization filling a declared interface slot with a measured-error obligation, or an explicit versioned kernel amendment. Disputes resolve by tracing to the kernel.",
        "standing_rule": "Design for the walls, rent the capability: permanent constraints own the architecture; model capability only fills declared, re-measurable interface slots and is re-derived every model generation.",
    },
    "sequencing_note": "Recommendation only, nothing operational authorized: a stripped E2 probe (seeded praise/planted-defect set on deployment-tier models) is the highest-information-per-dollar measurement and can run first, in parallel with A2/A3.",
    "legal_gate": "Two-sided workforce census: EU (Platform Work Directive scope; binding from 2026-12-02 transposition) AND US (AEDT/bias-audit exposure in enacted jurisdictions; selection-procedure validation under adverse impact). Counsel review on both sides precedes any consequential authority.",
    "recommendation": {
        "authorization_to_learn": "GO — one-project falsifiable pilot: baseline measurement, contract compilation, adjudicated gold, deployment-tier bakeoff, shadow scoring, selective-human-loop experiment",
        "authorization_to_act": "NO — no autonomous enforcement below calibrated Level B; consequential adverse actions retain a meaningful human decision-maker, explanation, and appeal",
    },
    "capability_currency": {
        "deployment_tier": "Claude Fable / Opus 4.8 class; GPT-5.5 / 5.6 class",
        "published_deployment_tier_measurements_on_this_task": 0,
        "grade_distribution": S.get("decision_grades", {}),
        "rule": "Dated evidence sets no current threshold in either direction; every capability-dependent anchor (grades B and C) re-measures at the pilot bakeoff on the deployment tier before it binds anything.",
    },
    "valid_outcomes": ["stop", "narrow", "assisted_only", "selective_graduation"],
    "graduation_rule": {
        "statistical_rule": "For every critical error class, the one-sided 95% upper confidence bound must be below its approved ceiling on an untouched, adjudicated test set.",
        "precommit_before_test": ["error-class ceilings", "minimum effective sample", "multiplicity treatment", "clustering assumptions", "stop rules"],
        "scope": "named criterion family and action only; material change requires requalification",
        "grounding": ["HS-07", "F26-09", "HS-03", "foundation BENCHMARK_PROTOCOL §9 (rare critical errors)"],
    },
    "authorizations": [
        {"id": a, "title": t, "status": "needs leadership sign-off", "evidence_ids": evidence_ids_for(a)}
        for a, t in [
            ("a1", "Approve the construct: instruction satisfaction plus evidence grounding"),
            ("a2", "Choose the first project and fund its adjudicated gold set"),
            ("a3", "Fund the measurement baseline (variance-attribution pilot)"),
            ("a4", "Set authority boundaries: measurement broadly, enforcement narrowly"),
            ("a5", "Accept the permanent expert-audit channel"),
        ]
    ],
    "open_decisions": [
        {"id": d, "title": t, "status": "open — owner call", "recommended": r, "evidence_ids": evidence_ids_for(d)}
        for d, t, r in [
            ("d1", "Enforcement weight at launch", "launch advisory; attach consequences per-lane after seeded-recall numbers exist"),
            ("d2", "Construct authority", "rubric-as-law with forced, versioned amendment"),
            ("d3", "LLM-assistance provenance policy", "content-validity-only default with per-project override"),
            ("d4", "Judge sourcing", "two-tier, both rented, cross-family; revisit owning the screening tier at volume"),
            ("d5", "First pilot locale and EU exposure gate", "decide by workforce census + counsel; the choice switches the legal floor from forward-looking to binding"),
            ("d6", "Dial governance and disclosure", "owner + client sign-off; disclose the stamped residual-error estimate"),
        ]
    ],
    "standing_defaults": [
        {"id": c, "title": t, "falsifier": f, "evidence_ids": evidence_ids_for(c)}
        for c, t, f in [
            ("c1", "Entailment standard: reasonable-expert support, three-way verdicts", "ship-gate false-flag rate vs contract error prices"),
            ("c2", "Read-checkable vs recompute-checkable routing (provisional; single under-review study)", "E3 internal replication"),
            ("c3", "Evidence-only to adjudicators; full critiques to attempters (combination untested)", "E6 A/B"),
            ("c4", "Statistics staging: chance-corrected + PPI at v1; MFRM/e-process/conformal at phase 2", "staging, not selection"),
            ("c5", "Single-item pay denial treated as significant detriment until counsel says otherwise", "counsel opinion / national transposition texts (2026-12-02)"),
        ]
    ],
    "experiments": [
        {"id": e, "title": t} for e, t in [
            ("e1", "Variance-attribution pilot"), ("e2", "Positive-claim seeded set"),
            ("e3", "Transfer check + re-solving replication"), ("e4", "Confidence-proxy shootout"),
            ("e5", "Divergence sensor dry run"), ("e6", "Feedback tier A/B"),
            ("e7", "Agnosticism falsification"),
        ]
    ],
    "not_authorized_under_any_profile": [
        "silent or retroactive changes to the bar attempters are judged against",
        "judge calibration from unadjudicated override streams",
        "scoring any human on agreement-with-final-verdict",
        "consequence language in judge prompts (stakes/dial-sterile always)",
        "raw percent-agreement or single-number accuracy in reporting",
        "'verified' labels on absence claims without seeded-recall evidence",
    ],
}
(SITE / "assets" / "decision-record.json").write_text(_json.dumps(record, indent=2, ensure_ascii=False), encoding="utf-8")
print(f"decision-record.json written ({len(record['authorizations'])} authorizations, {len(record['open_decisions'])} open decisions)")
