feat(approvals,runs): explain approvals in place + one-click hub update (0.81.0)

Approvals: the pending card now shows its full origin — flow, step,
run id (previously dropped at the Dart mapping layer), project, and
requested-at — under an ORIGIN heading, led by a one-line intro strip
that says what the inbox is and what Approve/Reject do. Approve/Reject
buttons carry tooltips; the history dialog gains project + run id.
Fixes the approvals doc drift (title/details/reviewer ->
prompt/show/timeout_seconds). Guard: approvals_origin_test renders the
card via the hermetic fake hub and pins every origin fact.

Runs: the "hub too old" state now leads with an in-place update button
(same `chain update apply` path as the Diagnose page), the Diagnose
deeplink demoted to secondary, with a CLI-absent fallback. Guard: two
new RunsLoadErrorView widget tests.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
flemming-it 2026-07-26 15:50:41 +02:00
parent 14f824b8ef
commit 28f6fe1a9a
16 changed files with 613 additions and 115 deletions

View file

@ -15,7 +15,9 @@ Add an approval step before:
- anything the operator's compliance owner asked you to gate
The approval is a recorded event — every approval shows up in
the audit log with the reviewer, decision, and reason.
the audit log with the reviewer, decision, and reason. The
`prompt` is the sentence the reviewer sees; `show` selects the
data put in front of them (a prior step's output).
## How a flow declares one
@ -27,9 +29,8 @@ steps:
- id: review
use: system.approval@^0
with:
title: "Review the classifier output"
details: "$classify.response"
reviewer: "$inputs.reviewer"
prompt: "Review the classifier output"
show: "$classify.response"
timeout_seconds: 600
- id: write
@ -45,8 +46,9 @@ configured `timeout_seconds` elapses.
## How an operator answers one
The Approvals page lists every pending approval. Click an
entry, read the title + details, decide:
The Approvals page lists every pending approval. Each card
shows its origin (flow, step, run, project, requested-at), the
`prompt`, and the `show` data. Read them, then decide:
- **Approve** — the flow resumes from this step with the
approval's `payload` as the step output.
@ -63,7 +65,7 @@ that reflects how long a reviewer can realistically take.
Every approval write hits the audit log:
- approval requested (with the title + details snapshot)
- approval requested (with the prompt + show-data snapshot)
- reviewer-decision recorded (with reason on reject)
- payload + signature on accept

View file

@ -18,7 +18,9 @@ Setze eine Freigabe vor:
Die Freigabe ist ein protokolliertes Ereignis — jeder
Freigabe-Vorgang landet im Audit-Log mit Reviewer,
Entscheidung und Begründung.
Entscheidung und Begründung. Das `prompt` ist der Satz, den der
Reviewer sieht; `show` wählt die Daten, die ihm vorgelegt
werden (der Output eines vorherigen Steps).
## So deklariert ein Flow eine Freigabe
@ -30,9 +32,8 @@ steps:
- id: review
use: system.approval@^0
with:
title: "Klassifikations-Output prüfen"
details: "$classify.response"
reviewer: "$inputs.reviewer"
prompt: "Klassifikations-Output prüfen"
show: "$classify.response"
timeout_seconds: 600
- id: write
@ -49,8 +50,10 @@ zugehörige Freigabe-Eintrag eine `decision` erhält
## So beantwortet der Operator eine Freigabe
Die Freigaben-Seite listet jede ausstehende Freigabe. Klick
auf einen Eintrag, Titel + Details lesen, entscheiden:
Die Freigaben-Seite listet jede ausstehende Freigabe. Jede
Karte zeigt ihre Herkunft (Flow, Step, Lauf, Projekt,
Anforderungszeit), das `prompt` und die `show`-Daten. Lesen,
dann entscheiden:
- **Freigeben** — der Flow läuft ab diesem Step weiter, das
`payload` der Freigabe wird zum Step-Output.
@ -69,7 +72,7 @@ realistisch brauchen darf.
Jeder Schreibvorgang einer Freigabe landet im Audit-Log:
- Freigabe angefordert (mit Titel + Details-Snapshot)
- Freigabe angefordert (mit Prompt + show-Daten-Snapshot)
- Reviewer-Entscheidung aufgezeichnet (mit Begründung bei
Ablehnung)
- Payload + Signatur bei Freigabe