feat(3 U2-wiring): render summary card PNG + level badge SVG into run artifact dir (best-effort, R7; not yet served)

This commit is contained in:
autonomic-bot
2026-05-31 07:03:10 +00:00
parent d7e812e96d
commit afe5e51057

View File

@ -44,6 +44,7 @@ sys.path.insert(0, os.path.join(ROOT, "runner"))
from harness import ( # noqa: E402
abra,
canonical,
card as card_mod,
deps as deps_mod,
discovery,
generic,
@ -1212,6 +1213,7 @@ def main() -> int:
# ---- Phase 3 (R1/R3): assemble results.json (per-stage/per-test + computed level). Best-effort:
# a failure here NEVER changes `overall` (R7 — cosmetics never block the pipeline). ----
data: dict | None = None
try:
sso_unverified = sso_dep_unverified(declared, deps_ready, requires_deps_skipped)
clean_teardown = (deploy_count == expected_deploy_count) and not dep_teardown_error
@ -1252,6 +1254,28 @@ def main() -> int:
file=sys.stderr,
)
# ---- Phase 3 U2 (R3/R6): render the summary CARD (HTML→PNG) + level BADGE (SVG) from the
# results dict into the run artifact dir, alongside results.json + screenshot.png. The card
# REPORTS results.json verbatim — it computes nothing, so it can never look greener than the tiers
# (cardinal invariant, plan §6). Separate best-effort block (results.json is already written by
# here) — any failure is swallowed and NEVER changes `overall` (R7); a render failure simply means
# no summary.png, and U3/U4 fall back to text. ----
if data is not None:
try:
html_path = os.path.join(run_artifact_dir, "summary.html")
with open(html_path, "w", encoding="utf-8") as f:
f.write(card_mod.render_card_html(data, screenshot_rel=data.get("screenshot")))
png = card_mod.render_card_png(html_path, os.path.join(run_artifact_dir, "summary.png"))
with open(os.path.join(run_artifact_dir, "badge.svg"), "w", encoding="utf-8") as f:
f.write(card_mod.level_badge_svg(data["level"], data.get("level_cap_reason", "")))
print(
f"summary card {'rendered ' + png if png else '(PNG render unavailable)'} + "
f"badge.svg written into {run_artifact_dir}",
flush=True,
)
except Exception as e: # noqa: BLE001 — card/badge are cosmetic; never fail a run (R7)
print(f"!! summary card/badge render failed (non-fatal): {_scrub(str(e))}", flush=True)
# WC5 promote-on-green-cold: a GREEN COLD run on LATEST (no PR head) of an enrolled
# (WARM_CANONICAL) recipe advances/seeds the canonical. ONLY cold-on-latest advances it (a PR
# `!testme` carries REF and must NOT promote; `--quick` never promotes — handled in run_quick).