Jev maintenance tools: shared client, spec coverage audit, voice check, nightly triage
ci / test (3.13) (push) Successful in 4m32s
ci / test (3.12) (push) Successful in 4m36s

This commit is contained in:
kemal committed 2026-10-01 13:21:36 +01:00
1 parent 0ff888e41b
commit 3ed0503bdf
9 files changed
+722 -48

No files matched your search

+28
View File
@@ -175,6 +175,23 @@ def render(night: dict[str, Any]) -> str:
"<table><tr><th>step</th><th>verdict</th><th>seconds</th><th>details</th><th></th></tr>"
+ "".join(rows)
+ "</table>"
+ _triage_html(night.get("triage"))
)
def _triage_html(tri: dict[str, Any] | None) -> str:
if not tri:
return ""
if "error" in tri:
return f"<p>Triage failed: {html.escape(str(tri['error']))}</p>"
rows = "".join(
f"<tr><td>{html.escape(k)}</td><td>{html.escape(str(t['match']))}</td><td>{t['match_confidence']}</td>"
f"<td>{t['regression']}</td><td>{t['severity']}</td><td>{'yes' if t['needs_person'] else 'no'}</td></tr>"
for k, t in tri.items()
)
return (
"<h2>Triage</h2><table><tr><th>step</th><th>explained by</th><th>confidence</th><th>regression p</th>"
f"<th>severity (0 to 3)</th><th>needs a person</th></tr>{rows}</table>"
)
@@ -209,6 +226,17 @@ def main() -> int:
overall = "PASS" if all(s.get("verdict") in ("PASS", "SKIPPED") for s in steps.values()) else "FAIL"
night = {"date": day, "version": version, "overall": overall, "seconds": round(time.time() - t0), "steps": steps}
(base / "summary.json").write_text(json.dumps(night, indent=2) + "\n")
if overall != "PASS": # which known finding explains each failing step (scripts/jev, needs the TypeSafe key)
try:
sys.path.insert(0, str(ROOT / "scripts" / "jev"))
from client import api_key
from nightly_triage import triage
if api_key():
night["triage"] = triage(base)
(base / "summary.json").write_text(json.dumps(night, indent=2) + "\n")
except Exception as e: # triage is advice; it must never break the nightly run
night["triage"] = {"error": f"{type(e).__name__}: {e}"}
(base / "index.html").write_text(render(night))
# large intermediates are not kept (reports and summaries are)
for heavy in ("gsa_gtc/gt/samples", "gsa_vcf/vcf", "omni_gtc/gt/samples"):