@andresmassello/uscha 1.75.0 → 1.76.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -40,7 +40,7 @@ Requires **Python 3.8+** on the machine (the engine is Python stdlib — no pip
40
40
  runtime dependencies). The npm package is a thin router; the canonical installer is
41
41
  `uscha-kit/install-uscha.py`.
42
42
 
43
- **Kit v1.75.0** <!-- uscha:version --> · [uscha.dev](https://uscha.dev) ·
43
+ **Kit v1.76.0** <!-- uscha:version --> · [uscha.dev](https://uscha.dev) ·
44
44
  [changelog](https://github.com/andresmassello/uscha/blob/main/uscha-kit/CHANGELOG.md)
45
45
  (the per-release changelogs live in the repo, not in the npm tarball)
46
46
 
@@ -76,7 +76,7 @@ and see which file, which test, and when.
76
76
  | `/uscha-mirador` | Bird's-eye HTML dashboard: readiness, trail, acceptance, loops |
77
77
  | `/uscha-status` | One-line progress readout, in chat |
78
78
 
79
- **A measurement engine** (`qa_ledger.py`, 47 subcommands, Python stdlib) that ingests
79
+ **A measurement engine** (`qa_ledger.py`, 48 subcommands, Python stdlib) that ingests
80
80
  evidence from **11 language stacks** — maven, gradle, ant, python, node, go, rust, dotnet,
81
81
  cpp, swift, flutter — and computes a readiness score with hard caps and visible provenance.
82
82
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andresmassello/uscha",
3
- "version": "1.75.0",
3
+ "version": "1.76.0",
4
4
  "description": "Spec-driven development for LLM coding agents: 9 skills + a stdlib evidence engine. Facts block, guesses advise; the human approves.",
5
5
  "author": {
6
6
  "name": "Andres Massello",
@@ -5551,7 +5551,9 @@ def _bench_entry(entry_dir, name):
5551
5551
  greens = sum(1 for i in impls if i["oracle"]["green"])
5552
5552
  min_rate = min((i["oracle"]["passed"] / i["oracle"]["total"]) if i["oracle"]["total"]
5553
5553
  else 0.0 for i in impls)
5554
- distinct = rec["variance"]["all_distinct"] if rec["variance"] else (n == 1)
5554
+ # distinct is None when variance could not be computed (fewer than 2 resolvable impl files),
5555
+ # which is NOT the same as a byte-identical convergence -- keep the two reasons apart.
5556
+ distinct = rec["variance"]["all_distinct"] if rec["variance"] else None
5555
5557
  if stub_green:
5556
5558
  rec["verdict"], rec["reason"] = "FAIL", ("oracle satisfied by a degenerate stub -- not "
5557
5559
  "discriminating; the entry proves nothing")
@@ -5559,6 +5561,9 @@ def _bench_entry(entry_dir, name):
5559
5561
  rec["verdict"], rec["reason"] = "FAIL", "a compilation does not validate against the pinned IR"
5560
5562
  elif n < 3:
5561
5563
  rec["verdict"], rec["reason"] = "PENDING", "fewer than 3 compilations (have %d)" % n
5564
+ elif distinct is None:
5565
+ rec["verdict"], rec["reason"] = "FAIL", ("cannot assess distinctness -- fewer than 2 "
5566
+ "resolvable implementation files on disk")
5562
5567
  elif not distinct:
5563
5568
  rec["verdict"], rec["reason"] = "FAIL", ("implementations converged to a byte-identical "
5564
5569
  "pair -- a disguised implementation")
@@ -5654,6 +5659,209 @@ def cmd_bench(args):
5654
5659
  sys.exit(0)
5655
5660
 
5656
5661
 
5662
+ # --------------------------------------------------------------------------- #
5663
+ # lang-compare (Diamond controlled-language arm: the SAME canonical package in
5664
+ # free prose vs EARS+STE, judged by the SAME withheld oracle, compiled by the
5665
+ # same models. Measures whether controlled authoring reduces inter-compiler
5666
+ # variance and/or unresolved_intent. The language is demonstrated or discarded
5667
+ # by the delta, never decreed. Deterministic, no LLM. ADR-019.)
5668
+ # --------------------------------------------------------------------------- #
5669
+ _LANG_MARGIN = 0.05 # variance delta below this is NO EFFECT
5670
+ _LANG_PR_MARGIN = 0.02 # mean oracle pass-rate drop counted a regression
5671
+
5672
+
5673
+ def _lang_arm_metrics(arm_dir):
5674
+ """Measure ONE arm: per-compiler oracle green + unresolved_intent, and inter-compiler
5675
+ variance over the arm's compilations. Reuses the M4/M5 organs unchanged."""
5676
+ ir_graph, ir_errors = _load_ir_at(os.path.join(arm_dir, IR_FILE))
5677
+ try:
5678
+ with open(os.path.join(arm_dir, "oracle", "ORACLE.json"), encoding="utf-8-sig") as fh:
5679
+ cases = (json.load(fh) or {}).get("cases") or []
5680
+ except (OSError, ValueError):
5681
+ cases = []
5682
+ rec = {"arm": os.path.basename(arm_dir), "ir_ok": ir_graph is not None and not ir_errors,
5683
+ "compilations": [], "greens": 0, "n": 0, "variance_score": None,
5684
+ "mean_passrate": None, "ui_count": 0.0, "ui_distinct_regions": 0.0,
5685
+ "ui_rationale_len": 0.0}
5686
+ if ir_graph is None or ir_errors or not cases:
5687
+ return rec, ["arm incomplete (missing/invalid IR or oracle)"]
5688
+ comp_dirs = sorted(d for d in os.listdir(arm_dir)
5689
+ if d.startswith("c-") and
5690
+ os.path.isfile(os.path.join(arm_dir, d, "COMPILATION.json")))
5691
+ impl_paths, ui_counts, ui_regions, ui_lens = [], [], [], []
5692
+ for d in comp_dirs:
5693
+ cd = os.path.join(arm_dir, d)
5694
+ cj = os.path.join(cd, "COMPILATION.json")
5695
+ errors, _adv = _validate_compilation(cj, ir_graph)
5696
+ unit, model, uis = None, None, []
5697
+ try:
5698
+ with open(cj, encoding="utf-8-sig") as fh:
5699
+ c = json.load(fh)
5700
+ src = c.get("source") or []
5701
+ unit = src[0].get("unit") if src else None
5702
+ model = (c.get("compilation_report") or {}).get("model")
5703
+ uis = c.get("unresolved_intent") or []
5704
+ except (OSError, ValueError, AttributeError, IndexError):
5705
+ pass
5706
+ impl = os.path.join(cd, unit.replace("/", os.sep)) if unit else None
5707
+ ores = (_bench_oracle_all(impl, cases) if impl and os.path.isfile(impl)
5708
+ else {"passed": 0, "total": len(cases), "green": False})
5709
+ if impl and os.path.isfile(impl):
5710
+ impl_paths.append(impl)
5711
+ ui_counts.append(len(uis))
5712
+ ui_regions.append(len({(u.get("ir_region") or "") for u in uis}))
5713
+ ui_lens.append((sum(len(u.get("rationale") or "") for u in uis) / len(uis))
5714
+ if uis else 0.0)
5715
+ rec["compilations"].append({"dir": d, "model": model, "compile_valid": not errors,
5716
+ "oracle": ores, "ui_count": len(uis)})
5717
+ rec["n"] = len(rec["compilations"])
5718
+ rec["greens"] = sum(1 for i in rec["compilations"] if i["oracle"]["green"])
5719
+ # mean oracle pass-RATE (not just the binary all-green flag): a per-compiler regression that
5720
+ # never reaches all-green is invisible in `greens` but real in the pass-rate, and lower
5721
+ # variance toward a WORSE behaviour must not read as a clean win (the M4 convergence lesson).
5722
+ rates = [(i["oracle"]["passed"] / i["oracle"]["total"]) if i["oracle"]["total"] else 0.0
5723
+ for i in rec["compilations"]]
5724
+ rec["mean_passrate"] = round(sum(rates) / len(rates), 4) if rates else None
5725
+ rec["ui_count"] = round(sum(ui_counts) / len(ui_counts), 3) if ui_counts else 0.0
5726
+ rec["ui_distinct_regions"] = round(sum(ui_regions) / len(ui_regions), 3) if ui_regions else 0.0
5727
+ rec["ui_rationale_len"] = round(sum(ui_lens) / len(ui_lens), 1) if ui_lens else 0.0
5728
+ # inter-compiler variance: mean pairwise normalized structural distance (0 = identical)
5729
+ metrics = [_impl_metrics(p) for p in impl_paths]
5730
+ good = [m for m in metrics if "error" not in m]
5731
+ dists = []
5732
+ for i in range(len(good)):
5733
+ for j in range(i + 1, len(good)):
5734
+ a, b = good[i], good[j]
5735
+ ia, ib = set(a["imports"]), set(b["imports"])
5736
+ jac = (len(ia & ib) / len(ia | ib)) if (ia or ib) else 1.0
5737
+ dloc = abs(a["loc"] - b["loc"]) / max(a["loc"], b["loc"], 1)
5738
+ dast = abs(a["ast_nodes"] - b["ast_nodes"]) / max(a["ast_nodes"], b["ast_nodes"], 1)
5739
+ dists.append((dloc + dast + (1.0 - jac)) / 3.0)
5740
+ rec["variance_score"] = round(sum(dists) / len(dists), 4) if dists else None
5741
+ return rec, []
5742
+
5743
+
5744
+ def _oracle_hash(arm_dir):
5745
+ try:
5746
+ with open(os.path.join(arm_dir, "oracle", "ORACLE.json"), "rb") as fh:
5747
+ return hashlib.sha256(fh.read()).hexdigest()
5748
+ except OSError:
5749
+ return None
5750
+
5751
+
5752
+ def cmd_lang_compare(args):
5753
+ """Compare a FREE-prose arm and a CONTROLLED (EARS+STE) arm of the same canonical package
5754
+ (ADR-019). The two arms MUST share one withheld oracle -- a differing oracle is a mechanical
5755
+ refusal, because the whole comparison rests on the arms targeting the same behaviour. Emits
5756
+ the per-arm metrics, the delta, and a COMPUTED verdict (REDUCED / NO EFFECT / WORSE); a null
5757
+ is a first-class result. Consults no model."""
5758
+ hf, hc = _oracle_hash(args.free), _oracle_hash(args.controlled)
5759
+ if hf is None or hc is None:
5760
+ print("[qa_ledger] lang-compare: an arm has no oracle/ORACLE.json", file=sys.stderr)
5761
+ sys.exit(2)
5762
+ if hf != hc:
5763
+ print("[qa_ledger] lang-compare: the two arms have DIFFERENT oracles (%s.. vs %s..) -- "
5764
+ "the comparison requires the SAME withheld oracle; behaviour must be held fixed "
5765
+ "while only the authoring changes." % (hf[:12], hc[:12]), file=sys.stderr)
5766
+ sys.exit(2)
5767
+ free, ef = _lang_arm_metrics(args.free)
5768
+ ctrl, ec = _lang_arm_metrics(args.controlled)
5769
+ if ef or ec:
5770
+ for e in ef + ec:
5771
+ print("[qa_ledger] lang-compare: %s" % e, file=sys.stderr)
5772
+ sys.exit(2)
5773
+ vf, vc = free["variance_score"], ctrl["variance_score"]
5774
+ d_var = (vc - vf) if (vf is not None and vc is not None) else None
5775
+ d_ui = ctrl["ui_count"] - free["ui_count"]
5776
+ d_green = ctrl["greens"] - free["greens"]
5777
+ pf, pc = free["mean_passrate"], ctrl["mean_passrate"]
5778
+ d_pass = (pc - pf) if (pf is not None and pc is not None) else None
5779
+ # Verdict is BEHAVIOUR-FIRST (the M4 lesson: lower variance toward a WORSE answer is not a
5780
+ # win). A regression is a lost all-green OR a mean pass-rate drop beyond the pass-rate margin.
5781
+ variance_reduced = d_var is not None and d_var <= -_LANG_MARGIN
5782
+ variance_worse = d_var is not None and d_var >= _LANG_MARGIN
5783
+ regressed = (d_green < 0) or (d_pass is not None and d_pass <= -_LANG_PR_MARGIN)
5784
+ if variance_reduced and regressed:
5785
+ verdict = "MIXED" # variance down but behaviour regressed
5786
+ elif variance_reduced:
5787
+ verdict = "REDUCED" # variance down, behaviour held
5788
+ elif variance_worse or regressed:
5789
+ verdict = "WORSE"
5790
+ else:
5791
+ verdict = "NO EFFECT"
5792
+ delta = {"variance_score": round(d_var, 4) if d_var is not None else None,
5793
+ "unresolved_intent_count": round(d_ui, 3), "oracle_green": d_green,
5794
+ "mean_passrate": round(d_pass, 4) if d_pass is not None else None}
5795
+ report = {"free": free, "controlled": ctrl, "delta": delta, "verdict": verdict,
5796
+ "margin": _LANG_MARGIN, "passrate_margin": _LANG_PR_MARGIN, "oracle_shared": True}
5797
+ if args.out:
5798
+ with open(args.out, "w", encoding="utf-8", newline="\n") as fh:
5799
+ fh.write(_render_lang_md(report))
5800
+ if args.json:
5801
+ print(json.dumps(report, indent=2, ensure_ascii=False))
5802
+ else:
5803
+ for a in (free, ctrl):
5804
+ print("LANG %-11s: oracle-green %d/%d · pass-rate %s · variance %s · "
5805
+ "unresolved_intent %.2f (regions %.2f, rationale %.0f chars)"
5806
+ % (a["arm"], a["greens"], a["n"],
5807
+ "%.3f" % a["mean_passrate"] if a["mean_passrate"] is not None else "n/a",
5808
+ "%.4f" % a["variance_score"] if a["variance_score"] is not None else "n/a",
5809
+ a["ui_count"], a["ui_distinct_regions"], a["ui_rationale_len"]))
5810
+ print("DELTA (controlled - free): variance %s · pass-rate %s · unresolved_intent %+.2f "
5811
+ "· green %+d"
5812
+ % ("%+.4f" % delta["variance_score"] if delta["variance_score"] is not None
5813
+ else "n/a",
5814
+ "%+.4f" % delta["mean_passrate"] if delta["mean_passrate"] is not None else "n/a",
5815
+ delta["unresolved_intent_count"], delta["oracle_green"]))
5816
+ print("VERDICT: %s (variance margin %.2f, pass-rate margin %.2f) -- behaviour-first, "
5817
+ "computed from the delta, never decreed" % (verdict, _LANG_MARGIN, _LANG_PR_MARGIN))
5818
+ if args.out:
5819
+ print(" -> %s" % args.out)
5820
+ sys.exit(0)
5821
+
5822
+
5823
+ def _render_lang_md(r):
5824
+ d = r["delta"]
5825
+ lines = ["<!-- GENERATED by qa_ledger.py lang-compare (ADR-019) -- measured run; do not "
5826
+ "hand-edit. -->", "", "# CONTROLLED-LANGUAGE-REPORT", "",
5827
+ "The same canonical package compiled by the same models from **free prose** (arm A) "
5828
+ "and an **EARS+STE rewrite** (arm B), judged by one **shared withheld oracle** "
5829
+ "(behaviour held fixed; only the authoring changes). The verdict is computed from "
5830
+ "the delta.", "",
5831
+ "| Arm | Oracle-green | Mean pass-rate | Inter-compiler variance | unresolved_intent (count · regions · rationale chars) |",
5832
+ "|-----|--------------|----------------|-------------------------|-------------------------------------------------------|"]
5833
+ for a in (r["free"], r["controlled"]):
5834
+ vs = "%.4f" % a["variance_score"] if a["variance_score"] is not None else "n/a"
5835
+ pr = "%.3f" % a["mean_passrate"] if a["mean_passrate"] is not None else "n/a"
5836
+ lines.append("| %s | %d/%d | %s | %s | %.2f · %.2f · %.0f |"
5837
+ % (a["arm"], a["greens"], a["n"], pr, vs, a["ui_count"],
5838
+ a["ui_distinct_regions"], a["ui_rationale_len"]))
5839
+ dv = "%+.4f" % d["variance_score"] if d["variance_score"] is not None else "n/a"
5840
+ dp = "%+.4f" % d["mean_passrate"] if d.get("mean_passrate") is not None else "n/a"
5841
+ lines += ["", "**Delta (controlled − free):** variance %s · mean pass-rate %s · "
5842
+ "unresolved_intent %+.2f · oracle-green %+d."
5843
+ % (dv, dp, d["unresolved_intent_count"], d["oracle_green"]), "",
5844
+ "## Verdict: %s" % r["verdict"], "",
5845
+ {"REDUCED": "Controlled authoring reduced inter-compiler variance beyond the %.2f "
5846
+ "margin WITHOUT a behavioural regression — for this subsystem, at this "
5847
+ "sample size." % r["margin"],
5848
+ "MIXED": "Controlled authoring reduced inter-compiler variance beyond the %.2f "
5849
+ "margin, BUT mean oracle pass-rate regressed beyond the %.2f pass-rate "
5850
+ "margin (or an all-green was lost): the compilers agreed MORE, on a "
5851
+ "marginally WORSE behaviour. Lower variance is not a win when it converges "
5852
+ "toward a worse answer — the honest, two-part finding."
5853
+ % (r["margin"], r.get("passrate_margin", 0.02)),
5854
+ "NO EFFECT": "Within the margins: controlled authoring did not measurably change "
5855
+ "the delta here. A null result, reported as a null — not a failure.",
5856
+ "WORSE": "Controlled authoring increased variance, or regressed behaviour (lost an "
5857
+ "all-green or dropped mean pass-rate) beyond the margins — reported "
5858
+ "honestly."}[r["verdict"]],
5859
+ "", "*The oracle is byte-identical across both arms, so behaviour is held fixed; "
5860
+ "the only variable is the authoring discipline. The judgement of \"same semantic "
5861
+ "content\" between the two canonical packages is human — a stated limitation.*", ""]
5862
+ return "\n".join(lines)
5863
+
5864
+
5657
5865
  # --------------------------------------------------------------------------- #
5658
5866
  # facts (T0 / SYSTEM-FACTS: public claims become compiled artifacts of repo
5659
5867
  # facts -- Diamond applied to Diamond. ADR-012.)
@@ -9777,6 +9985,17 @@ def build_parser():
9777
9985
  pbn.add_argument("--json", action="store_true")
9778
9986
  pbn.set_defaults(func=cmd_bench)
9779
9987
 
9988
+ plc = sub.add_parser(
9989
+ "lang-compare",
9990
+ help="controlled-language arm (ADR-019): compare a FREE-prose arm and an EARS+STE arm of "
9991
+ "the same canonical package, judged by the SAME withheld oracle; the delta on "
9992
+ "variance/unresolved_intent gives a computed REDUCED/NO EFFECT/WORSE verdict")
9993
+ plc.add_argument("--free", required=True, help="the free-prose arm directory")
9994
+ plc.add_argument("--controlled", required=True, help="the EARS+STE arm directory")
9995
+ plc.add_argument("--out", default=None, help="write CONTROLLED-LANGUAGE-REPORT.md here")
9996
+ plc.add_argument("--json", action="store_true")
9997
+ plc.set_defaults(func=cmd_lang_compare)
9998
+
9780
9999
  pcr = sub.add_parser("cleanroom",
9781
10000
  help="run a command against a CLEAN checkout of one commit in a throwaway worktree (ADR-008)")
9782
10001
  pcr.add_argument("--ledger", default="QA-LEDGER.json")
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "uscha",
4
- "version": "1.75.0",
4
+ "version": "1.76.0",
5
5
  "displayName": "Uscha",
6
- "description": "Spec-driven development for LLM coding agents: 9 skills (discovery, adr-refine, reverse-discovery, characterize, devloop, sysdoc, rubric, mirador, status) + a stdlib measurement engine (qa_ledger.py, 47 subcommands + universal installer + npm/npx router). Facts block, guesses advise; the human approves.",
6
+ "description": "Spec-driven development for LLM coding agents: 9 skills (discovery, adr-refine, reverse-discovery, characterize, devloop, sysdoc, rubric, mirador, status) + a stdlib measurement engine (qa_ledger.py, 48 subcommands + universal installer + npm/npx router). Facts block, guesses advise; the human approves.",
7
7
  "author": {
8
8
  "name": "Andres Massello",
9
9
  "url": "https://github.com/andresmassello"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uscha",
3
- "version": "1.75.0",
3
+ "version": "1.76.0",
4
4
  "description": "Uscha spec-driven development methodology for coding agents. Includes npm/npx router.",
5
5
  "author": {
6
6
  "name": "Andres Massello",
@@ -1,6 +1,6 @@
1
1
  # uscha-kit
2
2
 
3
- **Kit version:** v1.75.0 <!-- uscha:version --> · **[uscha.dev](https://uscha.dev)**
3
+ **Kit version:** v1.76.0 <!-- uscha:version --> · **[uscha.dev](https://uscha.dev)**
4
4
 
5
5
  Spec-driven orchestrator + multi-repo QA for Claude Code, with a deterministic ledger.
6
6
  **Nine skills** (`uscha-discovery`, `uscha-adr-refine`, `uscha-devloop`, `uscha-sysdoc`, `uscha-reverse-discovery`,
package/uscha-kit/VERSION CHANGED
@@ -1 +1 @@
1
- uscha-kit 1.75.0
1
+ uscha-kit 1.76.0
@@ -0,0 +1 @@
1
+ {"AC-CL-01": true, "AC-CL-02": true, "AC-CL-03": true, "AC-CL-04": true, "AC-CL-05": true, "AC-CL-06": true}
@@ -5551,7 +5551,9 @@ def _bench_entry(entry_dir, name):
5551
5551
  greens = sum(1 for i in impls if i["oracle"]["green"])
5552
5552
  min_rate = min((i["oracle"]["passed"] / i["oracle"]["total"]) if i["oracle"]["total"]
5553
5553
  else 0.0 for i in impls)
5554
- distinct = rec["variance"]["all_distinct"] if rec["variance"] else (n == 1)
5554
+ # distinct is None when variance could not be computed (fewer than 2 resolvable impl files),
5555
+ # which is NOT the same as a byte-identical convergence -- keep the two reasons apart.
5556
+ distinct = rec["variance"]["all_distinct"] if rec["variance"] else None
5555
5557
  if stub_green:
5556
5558
  rec["verdict"], rec["reason"] = "FAIL", ("oracle satisfied by a degenerate stub -- not "
5557
5559
  "discriminating; the entry proves nothing")
@@ -5559,6 +5561,9 @@ def _bench_entry(entry_dir, name):
5559
5561
  rec["verdict"], rec["reason"] = "FAIL", "a compilation does not validate against the pinned IR"
5560
5562
  elif n < 3:
5561
5563
  rec["verdict"], rec["reason"] = "PENDING", "fewer than 3 compilations (have %d)" % n
5564
+ elif distinct is None:
5565
+ rec["verdict"], rec["reason"] = "FAIL", ("cannot assess distinctness -- fewer than 2 "
5566
+ "resolvable implementation files on disk")
5562
5567
  elif not distinct:
5563
5568
  rec["verdict"], rec["reason"] = "FAIL", ("implementations converged to a byte-identical "
5564
5569
  "pair -- a disguised implementation")
@@ -5654,6 +5659,209 @@ def cmd_bench(args):
5654
5659
  sys.exit(0)
5655
5660
 
5656
5661
 
5662
+ # --------------------------------------------------------------------------- #
5663
+ # lang-compare (Diamond controlled-language arm: the SAME canonical package in
5664
+ # free prose vs EARS+STE, judged by the SAME withheld oracle, compiled by the
5665
+ # same models. Measures whether controlled authoring reduces inter-compiler
5666
+ # variance and/or unresolved_intent. The language is demonstrated or discarded
5667
+ # by the delta, never decreed. Deterministic, no LLM. ADR-019.)
5668
+ # --------------------------------------------------------------------------- #
5669
+ _LANG_MARGIN = 0.05 # variance delta below this is NO EFFECT
5670
+ _LANG_PR_MARGIN = 0.02 # mean oracle pass-rate drop counted a regression
5671
+
5672
+
5673
+ def _lang_arm_metrics(arm_dir):
5674
+ """Measure ONE arm: per-compiler oracle green + unresolved_intent, and inter-compiler
5675
+ variance over the arm's compilations. Reuses the M4/M5 organs unchanged."""
5676
+ ir_graph, ir_errors = _load_ir_at(os.path.join(arm_dir, IR_FILE))
5677
+ try:
5678
+ with open(os.path.join(arm_dir, "oracle", "ORACLE.json"), encoding="utf-8-sig") as fh:
5679
+ cases = (json.load(fh) or {}).get("cases") or []
5680
+ except (OSError, ValueError):
5681
+ cases = []
5682
+ rec = {"arm": os.path.basename(arm_dir), "ir_ok": ir_graph is not None and not ir_errors,
5683
+ "compilations": [], "greens": 0, "n": 0, "variance_score": None,
5684
+ "mean_passrate": None, "ui_count": 0.0, "ui_distinct_regions": 0.0,
5685
+ "ui_rationale_len": 0.0}
5686
+ if ir_graph is None or ir_errors or not cases:
5687
+ return rec, ["arm incomplete (missing/invalid IR or oracle)"]
5688
+ comp_dirs = sorted(d for d in os.listdir(arm_dir)
5689
+ if d.startswith("c-") and
5690
+ os.path.isfile(os.path.join(arm_dir, d, "COMPILATION.json")))
5691
+ impl_paths, ui_counts, ui_regions, ui_lens = [], [], [], []
5692
+ for d in comp_dirs:
5693
+ cd = os.path.join(arm_dir, d)
5694
+ cj = os.path.join(cd, "COMPILATION.json")
5695
+ errors, _adv = _validate_compilation(cj, ir_graph)
5696
+ unit, model, uis = None, None, []
5697
+ try:
5698
+ with open(cj, encoding="utf-8-sig") as fh:
5699
+ c = json.load(fh)
5700
+ src = c.get("source") or []
5701
+ unit = src[0].get("unit") if src else None
5702
+ model = (c.get("compilation_report") or {}).get("model")
5703
+ uis = c.get("unresolved_intent") or []
5704
+ except (OSError, ValueError, AttributeError, IndexError):
5705
+ pass
5706
+ impl = os.path.join(cd, unit.replace("/", os.sep)) if unit else None
5707
+ ores = (_bench_oracle_all(impl, cases) if impl and os.path.isfile(impl)
5708
+ else {"passed": 0, "total": len(cases), "green": False})
5709
+ if impl and os.path.isfile(impl):
5710
+ impl_paths.append(impl)
5711
+ ui_counts.append(len(uis))
5712
+ ui_regions.append(len({(u.get("ir_region") or "") for u in uis}))
5713
+ ui_lens.append((sum(len(u.get("rationale") or "") for u in uis) / len(uis))
5714
+ if uis else 0.0)
5715
+ rec["compilations"].append({"dir": d, "model": model, "compile_valid": not errors,
5716
+ "oracle": ores, "ui_count": len(uis)})
5717
+ rec["n"] = len(rec["compilations"])
5718
+ rec["greens"] = sum(1 for i in rec["compilations"] if i["oracle"]["green"])
5719
+ # mean oracle pass-RATE (not just the binary all-green flag): a per-compiler regression that
5720
+ # never reaches all-green is invisible in `greens` but real in the pass-rate, and lower
5721
+ # variance toward a WORSE behaviour must not read as a clean win (the M4 convergence lesson).
5722
+ rates = [(i["oracle"]["passed"] / i["oracle"]["total"]) if i["oracle"]["total"] else 0.0
5723
+ for i in rec["compilations"]]
5724
+ rec["mean_passrate"] = round(sum(rates) / len(rates), 4) if rates else None
5725
+ rec["ui_count"] = round(sum(ui_counts) / len(ui_counts), 3) if ui_counts else 0.0
5726
+ rec["ui_distinct_regions"] = round(sum(ui_regions) / len(ui_regions), 3) if ui_regions else 0.0
5727
+ rec["ui_rationale_len"] = round(sum(ui_lens) / len(ui_lens), 1) if ui_lens else 0.0
5728
+ # inter-compiler variance: mean pairwise normalized structural distance (0 = identical)
5729
+ metrics = [_impl_metrics(p) for p in impl_paths]
5730
+ good = [m for m in metrics if "error" not in m]
5731
+ dists = []
5732
+ for i in range(len(good)):
5733
+ for j in range(i + 1, len(good)):
5734
+ a, b = good[i], good[j]
5735
+ ia, ib = set(a["imports"]), set(b["imports"])
5736
+ jac = (len(ia & ib) / len(ia | ib)) if (ia or ib) else 1.0
5737
+ dloc = abs(a["loc"] - b["loc"]) / max(a["loc"], b["loc"], 1)
5738
+ dast = abs(a["ast_nodes"] - b["ast_nodes"]) / max(a["ast_nodes"], b["ast_nodes"], 1)
5739
+ dists.append((dloc + dast + (1.0 - jac)) / 3.0)
5740
+ rec["variance_score"] = round(sum(dists) / len(dists), 4) if dists else None
5741
+ return rec, []
5742
+
5743
+
5744
+ def _oracle_hash(arm_dir):
5745
+ try:
5746
+ with open(os.path.join(arm_dir, "oracle", "ORACLE.json"), "rb") as fh:
5747
+ return hashlib.sha256(fh.read()).hexdigest()
5748
+ except OSError:
5749
+ return None
5750
+
5751
+
5752
+ def cmd_lang_compare(args):
5753
+ """Compare a FREE-prose arm and a CONTROLLED (EARS+STE) arm of the same canonical package
5754
+ (ADR-019). The two arms MUST share one withheld oracle -- a differing oracle is a mechanical
5755
+ refusal, because the whole comparison rests on the arms targeting the same behaviour. Emits
5756
+ the per-arm metrics, the delta, and a COMPUTED verdict (REDUCED / NO EFFECT / WORSE); a null
5757
+ is a first-class result. Consults no model."""
5758
+ hf, hc = _oracle_hash(args.free), _oracle_hash(args.controlled)
5759
+ if hf is None or hc is None:
5760
+ print("[qa_ledger] lang-compare: an arm has no oracle/ORACLE.json", file=sys.stderr)
5761
+ sys.exit(2)
5762
+ if hf != hc:
5763
+ print("[qa_ledger] lang-compare: the two arms have DIFFERENT oracles (%s.. vs %s..) -- "
5764
+ "the comparison requires the SAME withheld oracle; behaviour must be held fixed "
5765
+ "while only the authoring changes." % (hf[:12], hc[:12]), file=sys.stderr)
5766
+ sys.exit(2)
5767
+ free, ef = _lang_arm_metrics(args.free)
5768
+ ctrl, ec = _lang_arm_metrics(args.controlled)
5769
+ if ef or ec:
5770
+ for e in ef + ec:
5771
+ print("[qa_ledger] lang-compare: %s" % e, file=sys.stderr)
5772
+ sys.exit(2)
5773
+ vf, vc = free["variance_score"], ctrl["variance_score"]
5774
+ d_var = (vc - vf) if (vf is not None and vc is not None) else None
5775
+ d_ui = ctrl["ui_count"] - free["ui_count"]
5776
+ d_green = ctrl["greens"] - free["greens"]
5777
+ pf, pc = free["mean_passrate"], ctrl["mean_passrate"]
5778
+ d_pass = (pc - pf) if (pf is not None and pc is not None) else None
5779
+ # Verdict is BEHAVIOUR-FIRST (the M4 lesson: lower variance toward a WORSE answer is not a
5780
+ # win). A regression is a lost all-green OR a mean pass-rate drop beyond the pass-rate margin.
5781
+ variance_reduced = d_var is not None and d_var <= -_LANG_MARGIN
5782
+ variance_worse = d_var is not None and d_var >= _LANG_MARGIN
5783
+ regressed = (d_green < 0) or (d_pass is not None and d_pass <= -_LANG_PR_MARGIN)
5784
+ if variance_reduced and regressed:
5785
+ verdict = "MIXED" # variance down but behaviour regressed
5786
+ elif variance_reduced:
5787
+ verdict = "REDUCED" # variance down, behaviour held
5788
+ elif variance_worse or regressed:
5789
+ verdict = "WORSE"
5790
+ else:
5791
+ verdict = "NO EFFECT"
5792
+ delta = {"variance_score": round(d_var, 4) if d_var is not None else None,
5793
+ "unresolved_intent_count": round(d_ui, 3), "oracle_green": d_green,
5794
+ "mean_passrate": round(d_pass, 4) if d_pass is not None else None}
5795
+ report = {"free": free, "controlled": ctrl, "delta": delta, "verdict": verdict,
5796
+ "margin": _LANG_MARGIN, "passrate_margin": _LANG_PR_MARGIN, "oracle_shared": True}
5797
+ if args.out:
5798
+ with open(args.out, "w", encoding="utf-8", newline="\n") as fh:
5799
+ fh.write(_render_lang_md(report))
5800
+ if args.json:
5801
+ print(json.dumps(report, indent=2, ensure_ascii=False))
5802
+ else:
5803
+ for a in (free, ctrl):
5804
+ print("LANG %-11s: oracle-green %d/%d · pass-rate %s · variance %s · "
5805
+ "unresolved_intent %.2f (regions %.2f, rationale %.0f chars)"
5806
+ % (a["arm"], a["greens"], a["n"],
5807
+ "%.3f" % a["mean_passrate"] if a["mean_passrate"] is not None else "n/a",
5808
+ "%.4f" % a["variance_score"] if a["variance_score"] is not None else "n/a",
5809
+ a["ui_count"], a["ui_distinct_regions"], a["ui_rationale_len"]))
5810
+ print("DELTA (controlled - free): variance %s · pass-rate %s · unresolved_intent %+.2f "
5811
+ "· green %+d"
5812
+ % ("%+.4f" % delta["variance_score"] if delta["variance_score"] is not None
5813
+ else "n/a",
5814
+ "%+.4f" % delta["mean_passrate"] if delta["mean_passrate"] is not None else "n/a",
5815
+ delta["unresolved_intent_count"], delta["oracle_green"]))
5816
+ print("VERDICT: %s (variance margin %.2f, pass-rate margin %.2f) -- behaviour-first, "
5817
+ "computed from the delta, never decreed" % (verdict, _LANG_MARGIN, _LANG_PR_MARGIN))
5818
+ if args.out:
5819
+ print(" -> %s" % args.out)
5820
+ sys.exit(0)
5821
+
5822
+
5823
+ def _render_lang_md(r):
5824
+ d = r["delta"]
5825
+ lines = ["<!-- GENERATED by qa_ledger.py lang-compare (ADR-019) -- measured run; do not "
5826
+ "hand-edit. -->", "", "# CONTROLLED-LANGUAGE-REPORT", "",
5827
+ "The same canonical package compiled by the same models from **free prose** (arm A) "
5828
+ "and an **EARS+STE rewrite** (arm B), judged by one **shared withheld oracle** "
5829
+ "(behaviour held fixed; only the authoring changes). The verdict is computed from "
5830
+ "the delta.", "",
5831
+ "| Arm | Oracle-green | Mean pass-rate | Inter-compiler variance | unresolved_intent (count · regions · rationale chars) |",
5832
+ "|-----|--------------|----------------|-------------------------|-------------------------------------------------------|"]
5833
+ for a in (r["free"], r["controlled"]):
5834
+ vs = "%.4f" % a["variance_score"] if a["variance_score"] is not None else "n/a"
5835
+ pr = "%.3f" % a["mean_passrate"] if a["mean_passrate"] is not None else "n/a"
5836
+ lines.append("| %s | %d/%d | %s | %s | %.2f · %.2f · %.0f |"
5837
+ % (a["arm"], a["greens"], a["n"], pr, vs, a["ui_count"],
5838
+ a["ui_distinct_regions"], a["ui_rationale_len"]))
5839
+ dv = "%+.4f" % d["variance_score"] if d["variance_score"] is not None else "n/a"
5840
+ dp = "%+.4f" % d["mean_passrate"] if d.get("mean_passrate") is not None else "n/a"
5841
+ lines += ["", "**Delta (controlled − free):** variance %s · mean pass-rate %s · "
5842
+ "unresolved_intent %+.2f · oracle-green %+d."
5843
+ % (dv, dp, d["unresolved_intent_count"], d["oracle_green"]), "",
5844
+ "## Verdict: %s" % r["verdict"], "",
5845
+ {"REDUCED": "Controlled authoring reduced inter-compiler variance beyond the %.2f "
5846
+ "margin WITHOUT a behavioural regression — for this subsystem, at this "
5847
+ "sample size." % r["margin"],
5848
+ "MIXED": "Controlled authoring reduced inter-compiler variance beyond the %.2f "
5849
+ "margin, BUT mean oracle pass-rate regressed beyond the %.2f pass-rate "
5850
+ "margin (or an all-green was lost): the compilers agreed MORE, on a "
5851
+ "marginally WORSE behaviour. Lower variance is not a win when it converges "
5852
+ "toward a worse answer — the honest, two-part finding."
5853
+ % (r["margin"], r.get("passrate_margin", 0.02)),
5854
+ "NO EFFECT": "Within the margins: controlled authoring did not measurably change "
5855
+ "the delta here. A null result, reported as a null — not a failure.",
5856
+ "WORSE": "Controlled authoring increased variance, or regressed behaviour (lost an "
5857
+ "all-green or dropped mean pass-rate) beyond the margins — reported "
5858
+ "honestly."}[r["verdict"]],
5859
+ "", "*The oracle is byte-identical across both arms, so behaviour is held fixed; "
5860
+ "the only variable is the authoring discipline. The judgement of \"same semantic "
5861
+ "content\" between the two canonical packages is human — a stated limitation.*", ""]
5862
+ return "\n".join(lines)
5863
+
5864
+
5657
5865
  # --------------------------------------------------------------------------- #
5658
5866
  # facts (T0 / SYSTEM-FACTS: public claims become compiled artifacts of repo
5659
5867
  # facts -- Diamond applied to Diamond. ADR-012.)
@@ -9777,6 +9985,17 @@ def build_parser():
9777
9985
  pbn.add_argument("--json", action="store_true")
9778
9986
  pbn.set_defaults(func=cmd_bench)
9779
9987
 
9988
+ plc = sub.add_parser(
9989
+ "lang-compare",
9990
+ help="controlled-language arm (ADR-019): compare a FREE-prose arm and an EARS+STE arm of "
9991
+ "the same canonical package, judged by the SAME withheld oracle; the delta on "
9992
+ "variance/unresolved_intent gives a computed REDUCED/NO EFFECT/WORSE verdict")
9993
+ plc.add_argument("--free", required=True, help="the free-prose arm directory")
9994
+ plc.add_argument("--controlled", required=True, help="the EARS+STE arm directory")
9995
+ plc.add_argument("--out", default=None, help="write CONTROLLED-LANGUAGE-REPORT.md here")
9996
+ plc.add_argument("--json", action="store_true")
9997
+ plc.set_defaults(func=cmd_lang_compare)
9998
+
9780
9999
  pcr = sub.add_parser("cleanroom",
9781
10000
  help="run a command against a CLEAN checkout of one commit in a throwaway worktree (ADR-008)")
9782
10001
  pcr.add_argument("--ledger", default="QA-LEDGER.json")
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.75.0",
2
+ "version": "1.76.0",
3
3
  "project": null,
4
4
  "defaults": {
5
5
  "coverage_threshold": 60,