feat(demo): name the chart branch the monitor is taking
Some checks failed
Tests / Declarative: Post Actions testing.tests.test_repo_structure.test_knowledge_service_mirror_matches_source failed

An audience following mermaid/TestAutomation.mmd needs to know which edge off
the route diamond was taken, which was the one thing the output left them to
infer. It now quotes the chart's own labels - authorized action, human
required, and the optional code path - and the docstring states where the
reporting is coarser than the diagram.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
jenkins 2026-08-06 16:25:39 -03:00
parent e93dc7b8a8
commit db14a9d6a8

View File

@ -1,16 +1,22 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Stream the triage flow as it happens, in the stages of the flow chart. """Stream the triage flow as it happens, in the stages of the flow chart.
Run in a second terminal alongside the demo. Each stage below is a subgraph in Run in a second terminal alongside the demo. Every stage name below is a
`mermaid/TestAutomation.mmd`, so what prints here can be followed on the chart: subgraph in `mermaid/TestAutomation.mmd`, and the route line quotes that
chart's own edge labels, so an audience can follow along on the diagram:
Detect and gather -> Hermes analysis -> Ariadne policy gates Detect and gather -> Hermes analysis -> Ariadne policy gates
-> Ariadne response -> Inspectable outputs -> Ariadne response -> Inspectable outputs
Every stage prints the evidence that moved it, because the point of the chart Each stage prints the evidence that moved it, because the claim the chart
is that each step is answerable from data rather than asserted. makes is that every step is answerable from data rather than asserted.
Read-only: it polls Kubernetes, Jenkins and Gitea and changes nothing. Two honest limits. The chart draws finer nodes inside each subgraph - the
collector, the response check, the marker check, the authorizer - and this
reports at subgraph granularity, not per node. And it follows one incident on
one job at a time, whereas the chart describes the system as a whole.
Read-only: it polls Kubernetes and changes nothing.
""" """
from __future__ import annotations from __future__ import annotations
@ -32,6 +38,7 @@ STAGES = [
("evidence", "Detect and gather", "Ariadne collects the bounded evidence bundle"), ("evidence", "Detect and gather", "Ariadne collects the bounded evidence bundle"),
("hermes", "Hermes analysis", "Hermes returns a classification it cannot act on"), ("hermes", "Hermes analysis", "Hermes returns a classification it cannot act on"),
("gates", "Ariadne policy gates", "Ariadne authorizes or refuses, on its own reading"), ("gates", "Ariadne policy gates", "Ariadne authorizes or refuses, on its own reading"),
("route", "Ariadne response", "Which branch off the route diamond was taken"),
("response", "Ariadne response", "Ariadne executes, proposes, or escalates"), ("response", "Ariadne response", "Ariadne executes, proposes, or escalates"),
("verify", "Ariadne response", "One rebuild decides whether the repair worked"), ("verify", "Ariadne response", "One rebuild decides whether the repair worked"),
("outputs", "Inspectable outputs", "Incident closed; artifacts left behind"), ("outputs", "Inspectable outputs", "Incident closed; artifacts left behind"),
@ -150,12 +157,16 @@ def main() -> None:
if "run_triage" in msg or "hermes run" in msg.lower(): if "run_triage" in msg or "hermes run" in msg.lower():
monitor.mark("hermes", msg[:110]) monitor.mark("hermes", msg[:110])
if record.get("event") == "hermes_code_flow": if record.get("event") == "hermes_code_flow":
monitor.mark("response", f"code proposal: {record.get('status')}") monitor.mark("route", "code_path (optional source proposal) also taken")
monitor.mark("response", f"code proposal: {record.get('status')} -> gitea_pr")
if status == "awaiting_rebuild": if status == "awaiting_rebuild":
monitor.mark("evidence", "bundle collected; console regions, tests and logs attached") monitor.mark("evidence", "bundle collected; console regions, tests and logs attached")
monitor.mark("hermes", "diagnosis returned and parsed against the frozen schema") monitor.mark("hermes", "diagnosis returned and parsed against the frozen schema")
monitor.mark("gates", "every gate passed; Ariadne authorized the predefined action") monitor.mark("gates", "every gate passed; Ariadne authorized the predefined action")
# The chart labels this edge "authorized action"; naming it lets a
# viewer point at the branch being taken rather than infer it.
monitor.mark("route", "route --|authorized action|--> registry -> operational_result")
monitor.mark( monitor.mark(
"response", "response",
f"{state.get('repair', 'action')} on {state.get('target', 'target')}", f"{state.get('repair', 'action')} on {state.get('target', 'target')}",
@ -168,6 +179,7 @@ def main() -> None:
"gates", "gates",
f"Ariadne refused: {state.get('reason', 'human_required')} — no action taken", f"Ariadne refused: {state.get('reason', 'human_required')} — no action taken",
) )
monitor.mark("route", "route --|human required|--> human_required -> gitea_issue")
monitor.mark("response", "escalated to a human; issue filed in the service repository") monitor.mark("response", "escalated to a human; issue filed in the service repository")
if status == "healthy" and state.get("resolved") and not monitor.summarised: if status == "healthy" and state.get("resolved") and not monitor.summarised:
monitor.mark("verify", "rebuild finished green") monitor.mark("verify", "rebuild finished green")