Record UX review, propose spec v0.2, add workplan RBT-WP-0007 and UI tasks
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 5s
Work Records / validate (push) Has been cancelled

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 295952@bnt-lap001
Assistant-Session: e93f64ad-516c-46eb-9666-aad8d300c477
This commit is contained in:
tegwick 2026-09-29 10:31:17 +02:00
parent 6ed772052f
commit cb517b613a
6 changed files with 402 additions and 12 deletions

View file

@ -0,0 +1,163 @@
# Runbook pack specification v0.2 - proposal
Status: **proposed** (review with Bernd; RBT-WP-0002-T04). Derived from
`docs/ux-review-2026-09-29.md`. v0.1 stays valid; v0.2 is a superset.
## Principle
The spec describes *what the procedure is*: structure, data, actors, gates and
order. It carries no presentation. Rendering (layout, theme, dark mode, the
questionnaire and the dimension view) is the renderer's job and must follow from
the semantics alone. If a UI feature needs a new spec field, that field has to be
justified as meaning, not appearance.
## The model
```text
pack
|- framing what to keep in mind (shown first)
|- actors who does or approves what, with privileges
|- datapoints the non-secret facts collected and applied -> state nil/set/err/ok
|- stages hierarchy of the procedure
| |- steps the work -> state todo/running/done/failed
| |- gates QA checks tied to the stage and to goals -> state open/passed/failed/waived
|- artefacts what a run produces and where it lives (non-secret references)
```
### Two states, two things
| Thing | States | Meaning |
| --- | --- | --- |
| **Datapoint** (parameter, role assignment, artefact location, custody reference) | `nil` no value, `set` value given, `err` invalid or rejected, `ok` confirmed in the real system | Is the data known and right? |
| **Step** | `todo`, `running`, `done`, `failed` (`skipped` for read-only) | Has it been applied? |
| **Gate** | `open`, `passed`, `failed`, `waived` | Is the quality condition met? |
A v0.1 `parameter` is a datapoint that has a value type and is asked as a
question. Steps `uses:` datapoints; steps may `produces:` datapoints
(for example an artefact location).
### Hierarchy and order
- `stages` nest to at most three levels. A stage has `title`, `goal`, `steps`, and
optional child `stages`.
- Every step and stage may declare `requires:` (ids of steps, stages, gates,
or datapoints in state `ok`). This forms a dependency graph, so alternatives and
parallel work are expressible. `one_of:` groups declare alternatives: any one
satisfies the group.
- **Canonical serialization.** The order in which the pack lists things is the
recommended order. The engine computes: *ready* = every requirement met;
*recommended next* = the first ready item in canonical order. Operators may take
any other ready item. A pack that lists no `requires` behaves as a linear
sequence, which is exactly a v0.1 pack.
### Gates
A gate is a QA condition, not a step.
```yaml
gates:
- id: custody-approved
title: Custody strategy approved
stage: custody # exit gate of this stage
goal: platform-root-custody # quality objective; canon standard id where one exists
blocking: true # blocks dependents and the stage exit
checks: # same check shape as step verify
- {done_when: "signed roster verifies", command: "...", expect: exit-0}
- {datapoints_ok: [custody_mode, roster_location]}
waivable: {by: king, needs_reason: true} # omit if never waivable
```
- A gate is tied to exactly one stage (its exit or entry) and names the quality
goal it protects, so gates are traceable to standards instead of floating.
- `requires: [gate:custody-approved]` makes a step wait for a gate.
- A waiver records who, when and why, and appears in the overview.
### Actors, roles and privileges
```yaml
actors:
- id: king
role: Platform-root custodian
description: Holds platform-root recovery authority.
privileges: [approve-custody, revoke-root-token]
```
Steps and gates name an `actor` (who acts or approves). `owner` stays the
repository or tool that does the work. The pack thereby explains what is relevant
and who is responsible; the overview can group by actor.
### Datapoints and dimensions
```yaml
datapoints:
- id: custody_mode
label: Custody mode
type: enum
values: [temporary-single-king, two-of-three-ready]
dimensions: {actor: king, subsystem: openbao, kind: decision}
ask_in: custody # stage in which the questionnaire asks for it
```
`dimensions` are free key/value tags, using canon vocabulary where it exists
(actor, role, privilege, subsystem, kind, assurance goal). They drive the
**dimension view**: a random-access table of all datapoints grouped or filtered by
any dimension, editable independently of the flow. Secrets are never datapoints;
only references ("stored in the platform-root safe entry") are.
### Artefacts
`artefacts:` lists what a run yields, each with a `location` datapoint (a
reference, never a value) and the `produced_by` step. The artefacts view is what
makes a run more than a script.
### Confirmation
Each step declares `reversible: true|false` (default `true`).
- reversible: a confirm button;
- not reversible: the operator types the pack's `confirm_phrase` (default
`I understand this cannot be undone`; a step may set its own).
This replaces v0.1's `risk` for the purpose of confirmation. v0.1 `risk` values map
as: `destructive` gives `reversible: false`, all others `true`.
### Framing
`threat_checks` becomes `framing:` (list of statements, optionally per stage):
things to keep in mind, shown before the work starts. They are not gates. v0.1
`threat_checks` load as pack-level framing.
## Compatibility
- The engine loads `runbook-pack/v0.1` and `v0.2`. A v0.1 pack is interpreted as one
stage, a linear `requires` chain, no gates, no actors, its parameters as datapoints.
- `engine: legacy-command` is unchanged.
- The run record gains `datapoints`, `gates` and `waivers` sections (`runbook-run/v0.2`);
v0.1 records still load.
## What this is not
- No layout, color, icon or copy-text fields.
- No embedded scripting, and no execution mode (still RBT-WP-0006).
- No secret values anywhere.
## Recommendation
Keep `runbook-pack/v0.1` as shipped (three NetKingdom packs use it). Adopt this
proposal as v0.2 and port the four in-repo packs, then use the console's seven
runbooks and 14 gates as the first real v0.2 test: if the model can express them
without special cases, it is expressive enough.
## Open questions
1. **Waivers:** allowed at all, and by whom? Proposal: only where the pack declares
`waivable`, always with a recorded reason.
2. **Gate checks against live systems:** may a gate run a command (as steps' verify
do, operator-confirmed), or only read datapoint states and step results?
Proposal: both, with the same confirmation rule.
3. **Dimension vocabulary:** free tags first, or start from a canon list? Proposal:
free tags, with a `dimensions` registry file that packs may reference, promoted
to canon later.
4. **Nesting depth:** three levels enough?
5. **Datapoint `ok`:** who confirms it, the operator or a check? Proposal: either;
a check makes it `ok`, a manual confirmation is recorded as such.

View file

@ -0,0 +1,44 @@
# UX review: old console vs first native UI (2026-09-29)
Reviewer: Bernd. Recorded by Claude. Compared `security-bootstrap-console`
(NetKingdom, `:8876`) with the first `rtut ui` (`:8877`) on the NetKingdom packs.
## The comparison is unequal
The old console is more accessible and more professional on first impression, and
it models a far more complicated procedure. Each of its stages is about the size
of one of the new example runbooks. The new UI was built for flat sequences and
looks like a config form with comments as content. Design polish (spacing, dark
mode, visual guidance) is a renderer job. **The specification must not be
complicated to enable eye-candy**; a clear specification should render well.
## Findings
| # | Finding | Consequence |
| --- | --- | --- |
| 1 | The new flows are the basic element only: simple sequences with no hierarchy, no alternatives. The old console's stages give progress feedback and structure | The spec needs stages, hierarchy, alternatives and parallelism |
| 2 | Two different states are needed: `nil/set/err/ok` is about **setting the parameter** (a datapoint); `todo/running/done/failed` is about **applying** it (a step) | Datapoints get their own state, separate from step state |
| 3 | Next-action guidance is necessary. Several actions may be available once their prerequisites are met, but exactly one is *recommended* | The pack captures parallelism; a canonical, optional serialization gives a single operator one path |
| 4 | An overview with very clear state transparency, in several views by dimension (from canon standards where available), is a core feature. Hierarchical organization of complex runbooks is how orientation and learning happen | Overview and hierarchy are first-class |
| 5 | The pack must define and explain actors, roles, privileges; otherwise nothing says what is relevant | Actors and roles are part of the pack |
| 6 | Showing what a run produced and where it lives is what makes the UI more valuable than a wizard, script or config files | Artefacts (non-secret references) are part of the pack |
| 7 | Both confirmation styles are needed: a confirm button for reversible actions, a typed phrase for irreversible ones | Derive the style from reversibility; default confirm |
| 8 | Layout: the new UI is unpolished and gives too little visual guidance | Renderer work, after the spec |
| 9 | **Two views, two use cases.** A serial guided questionnaire is the main interface. A dimension/tag organized, random-access view of the collected datapoints is a second interface, independent of the flow. In the old console the two are intermingled | Separate the flow from the data view |
| 10 | Gates are not clearly tied to stages or to quality-assurance goals in the old console, and gates are missing from the new UI entirely | QA gates become a first-class concept, attached to stages and goals |
| 11 | Threat checks in the footer are misplaced: they are framing to keep in mind, not a final gate to pass | Show framing at the start; keep gates separate |
## Usability defects in the first UI (to fix in the renderer)
- Ticking the manual confirm box shows "passed" but the step stays `running`
until "Mark done" is pressed. Unticking then changes nothing. The
check, record and lock-in cycle is not visible.
- Steps after the first show no Start button and no reason. A blocked step must
say what it is waiting for.
- The good part, to keep: parameter form, then a run view with copy command,
run in terminal, feedback, confirm.
## Later extension (noted, not scheduled)
Operator feedback on a step feeds a runbook-aware assistant that may diagnose
the deployment, giving a feedback, retry, feedback, confirm loop.

View file

@ -57,20 +57,42 @@ semantic checks the schema cannot express (placeholders, duplicates, rollback,
secret markers, parameter defaults) and 16 tests. Parameter rendering rejects secret markers, parameter defaults) and 16 tests. Parameter rendering rejects
unsafe characters. unsafe characters.
## Review the specification with the operator and freeze v0.1 ## Review the v0.2 proposal and decide
```task ```task
id: RBT-WP-0002-T04 id: RBT-WP-0002-T04
status: todo status: progress
priority: high priority: high
state_hub_task_id: "1e1bdfdd-2482-5280-a870-5d823dfa1d34"
``` ```
Walk through the spec with Bernd against the real NetKingdom packs and the `docs/pack-spec-v0.2-proposal.md` (stages and hierarchy, dependency graph with a
legacy console. Open questions: step branching and conditional steps; whether recommended serialization, datapoints with `nil/set/err/ok`, QA gates tied to stages
`verify` may run a command automatically; how packs declare dependencies on and goals, actors and roles, artefacts, reversibility-based confirmation, framing).
other packs; signed packs. Record decisions and freeze `runbook-pack/v0.1`, or Review with Bernd, resolve the five open questions, and decide: freeze v0.1 as
raise v0.2 with a migration note. shipped and adopt v0.2. Supersedes the earlier plan to freeze v0.1 alone.
## Write the v0.2 schema and validator
```task
id: RBT-WP-0002-T05
status: wait
priority: high
```
After T04: `schema/runbook-pack-v0.2.schema.json`, semantic checks (acyclic
requires, gate and datapoint references resolve, one stage per gate, no secret
datapoints), v0.1 packs still load, tests.
## Port the in-repo and NetKingdom packs
```task
id: RBT-WP-0002-T06
status: wait
priority: medium
```
Port the four validating packs to v0.2 where it helps, and add v0.2 test packs with
alternatives, gates and actors.
## Acceptance Criteria ## Acceptance Criteria

View file

@ -24,14 +24,12 @@ what you have proven.
```task ```task
id: RBT-WP-0004-T01 id: RBT-WP-0004-T01
status: todo status: done
priority: high priority: high
state_hub_task_id: "8309d778-3688-5cb3-bb34-18f87b66dbf3" state_hub_task_id: "8309d778-3688-5cb3-bb34-18f87b66dbf3"
``` ```
Run `make security-bootstrap-ui` in `net-kingdom` with Bernd and record what to keep Done 2026-09-29 with Bernd. Findings and consequences are in `docs/ux-review-2026-09-29.md`; the model they imply is proposed in `docs/pack-spec-v0.2-proposal.md`.
(state chips `nil/set/err/ok`, next safe action, copyable command blocks,
approval phrase) and what to change. Output: a short UX note in `docs/`.
## Build the step view ## Build the step view
@ -71,7 +69,79 @@ state_hub_task_id: "616255c2-091c-5948-8160-abd9dc69907f"
Show the run record, export it as non-secret JSON, and produce the exercise-status Show the run record, export it as non-secret JSON, and produce the exercise-status
diff from RBT-WP-0003-T04. diff from RBT-WP-0003-T04.
## Fix the check, record and lock-in cycle
```task
id: RBT-WP-0004-T05
status: todo
priority: high
```
Defects found in review: a ticked manual check shows "passed" while the step stays
`running`, and unticking changes nothing; blocked steps show no Start button and no
reason. Make the cycle explicit (check, record, mark done), and show what a blocked
step is waiting for.
## Questionnaire flow on the v0.2 model
```task
id: RBT-WP-0004-T06
status: wait
priority: high
```
Depends on RBT-WP-0007. The serial guided flow is the main interface: stages with
progress, the recommended next action, other ready actions, framing shown at the
start of each stage, and gates shown at stage exit.
## Dimension view
```task
id: RBT-WP-0004-T07
status: wait
priority: high
```
Depends on RBT-WP-0007. A random-access table of datapoints (with `nil/set/err/ok`
state) grouped or filtered by dimension (actor, role, privilege, subsystem, kind),
editable independently of the flow, plus the artefacts view.
## Overview
```task
id: RBT-WP-0004-T08
status: wait
priority: high
```
Depends on RBT-WP-0007. State transparency at a glance: stage progress, gate states
and waivers, datapoint completeness by dimension.
## Visual design
```task
id: RBT-WP-0004-T09
status: wait
priority: medium
```
Theme and layout at the quality of the old console or better: spacing, hierarchy,
dark mode, visual guidance. Implemented in the renderer only; no presentation fields
in the pack spec.
## Typed-phrase confirmation
```task
id: RBT-WP-0004-T10
status: wait
priority: medium
```
Confirm button for reversible steps, typed phrase for irreversible ones, per the v0.2
`reversible` field.
## Acceptance Criteria ## Acceptance Criteria
- Bernd can complete the SSH tutorial pack in the UI without pasting outputs to an agent. - Bernd can complete the SSH tutorial pack in the UI without pasting outputs to an agent.
- The old console's seven runbooks can be walked in the new UI at equal or better clarity.
- The UI refuses to display or store anything matching the secret markers. - The UI refuses to display or store anything matching the secret markers.

View file

@ -43,3 +43,15 @@ state_hub_task_id: "0cfb69bc-dc7e-5960-8359-64c49a742a6e"
`rtut list --estate` scans registered repos for `runbooks/*/pack.yaml` and publishes `rtut list --estate` scans registered repos for `runbooks/*/pack.yaml` and publishes
a capability entry in the registry. Needs a decision on scan scope. a capability entry in the registry. Needs a decision on scan scope.
## Runbook-aware feedback assistant
```task
id: RBT-WP-0006-T03
status: wait
priority: low
```
Operator feedback on a step feeds an assistant that knows the runbook and may
diagnose the deployment (read-only access first), giving a feedback, retry,
feedback, confirm loop. Needs decisions on access, identity and what is sent where.

View file

@ -0,0 +1,79 @@
---
id: RBT-WP-0007
type: workplan
title: "Engine v0.2: graph, datapoint states and gates"
domain: infotech
repo: runbook-tutorials
status: backlog
flavor: implementation
owner: claude
topic_slug: stack
created: "2026-09-29"
updated: "2026-09-29"
depends_on: [RBT-WP-0002]
---
## Goal
Make the engine understand the v0.2 model so a renderer can show a questionnaire flow,
a dimension view and an overview from the same run data.
## Dependency graph and recommended next action
```task
id: RBT-WP-0007-T01
status: wait
priority: high
```
Compute ready items from `requires` and `one_of`; recommended next = first ready in
canonical order; explain what a blocked item waits for.
## Datapoint states
```task
id: RBT-WP-0007-T02
status: wait
priority: high
```
`nil/set/err/ok` per datapoint in the run record, with validation, dimension tags, and
how `ok` is reached (check or recorded manual confirmation).
## Gates and waivers
```task
id: RBT-WP-0007-T03
status: wait
priority: high
```
Evaluate gate checks (same confirmation rule as step verify), block dependents and stage
exit, record waivers with who, when and why.
## Run record v0.2
```task
id: RBT-WP-0007-T04
status: wait
priority: medium
```
`runbook-run/v0.2` with datapoints, gates, waivers; v0.1 records still load.
## Confirmation policy
```task
id: RBT-WP-0007-T05
status: wait
priority: medium
```
Derive confirm button versus typed phrase from `reversible`; enforce the phrase in the
engine so no renderer can skip it.
## Acceptance Criteria
- The old console's stages, gates and datapoints can be expressed and computed
without special cases.
- A v0.1 pack behaves exactly as before.