diff --git a/scripts/ops/hermes_triage_monitor.py b/scripts/ops/hermes_triage_monitor.py index 1a712e500..bb0e225c1 100755 --- a/scripts/ops/hermes_triage_monitor.py +++ b/scripts/ops/hermes_triage_monitor.py @@ -27,6 +27,7 @@ from __future__ import annotations import json import os +import re import subprocess import sys import time @@ -268,11 +269,29 @@ def incident_history(incident: str) -> None: "sh", "-c", _HISTORY_QUERY.replace("__INCIDENT__", incident)], limit=10) -def diagnosis_event() -> None: - """Show the diagnosis Ariadne stored: what Hermes said, and the verdict.""" +def diagnosis_event() -> str: + """Show the diagnosis Ariadne stored, and return its Hermes run id.""" - run(["kubectl", "-n", NS_ARIADNE, "exec", "deploy/ariadne", "-c", "ariadne", "--", - "sh", "-c", _DIAG_QUERY], limit=26) + out = run(["kubectl", "-n", NS_ARIADNE, "exec", "deploy/ariadne", "-c", "ariadne", "--", + "sh", "-c", _DIAG_QUERY], limit=26) + match = re.search(r'"run_id":\s*"([^"]+)"', out or "") + return match.group(1) if match else "" + + +def hermes_run_link(run_id: str) -> None: + """Print the deep link that reopens this run in the Hermes console. + + The whole point of the stage is showing that a model made the call, and a + run id nobody can open is not that. This is the same route the pull request + links to, so the audience lands on the page the artifact points at. + """ + + if not run_id: + print(f" {DIM}no run id recorded yet for this incident{RESET}\n") + return + print(f" {BOLD}open the decision itself:{RESET} {HERMES_UI}/chat?resume={run_id}") + print(f" {DIM}that page shows the prompt Hermes was given, the evidence bundle it read," + f" the skill it invoked, and the JSON it returned{RESET}\n") def evidence_for(key: str, incident: str = "") -> None: @@ -287,10 +306,9 @@ def evidence_for(key: str, incident: str = "") -> None: f" received:{RESET}") bundle_sample(incident) elif key == "hermes": - print(f" {DIM}what Hermes actually returned, as Ariadne stored it. The run_id below" - f" identifies this run in the Hermes dashboard, where the prompt it was given" - f" and every tool call it made are visible:{RESET}") - diagnosis_event() + print(f" {DIM}what Hermes actually returned, as Ariadne stored it:{RESET}") + run_id = diagnosis_event() + hermes_run_link(run_id) print(f" {DIM}Hermes holds no Git or Kubernetes write access; this JSON is its" f" entire output. When outcome.suggested_remediation is populated, Hermes found" f" no action that fits and is proposing one for a maintainer to build; it is"