Archive the finished runbook-tutorials workplans
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s
Tests / tests (push) Failing after 35s
Work Records / validate (push) Successful in 12s

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 21:48:05 +02:00
parent f73c35c798
commit 8eaf0c77b0
8 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,59 @@
---
id: RBT-WP-0001
type: workplan
title: "Bootstrap State Hub integration"
domain: infotech
repo: runbook-tutorials
status: finished
owner: codex
topic_slug: stack
created: "2026-09-29"
updated: "2026-09-29"
state_hub_workstream_id: "6e7852c6-04b2-5801-8c41-827ab3371954"
---
# Bootstrap State Hub integration
Runbook-tutorial engine and UI that guides operators through parameterized IT administration runbooks; packs live in the repos that own them.
## Review Generated Integration Files
```task
id: RBT-WP-0001-T01
status: done
priority: high
state_hub_task_id: "bab9969b-008d-569a-aea9-4bfabd5be7f0"
```
Review `INTENT.md`, `SCOPE.md`, `AGENTS.md`, and `.custodian-brief.md`.
Replace generated placeholders with repo-specific facts where needed.
## Verify Local Developer Workflow
```task
id: RBT-WP-0001-T02
status: done
priority: high
state_hub_task_id: "58661155-4185-530e-aa81-044ef1f16c34"
```
Identify the repo's install, test, lint, build, and run commands. Add or refine
those commands in the agent instructions so future coding sessions can verify
changes confidently.
## Seed First Real Workplan
```task
id: RBT-WP-0001-T03
status: done
priority: medium
state_hub_task_id: "fafa64cc-968a-5a4b-bb08-264b51451ce7"
```
Create the first implementation workplan for the repository's most important
next change. After workplan file updates, run the sync locally from this repo
checkout:
```bash
statehub fix-consistency
```

View file

@ -0,0 +1,116 @@
---
id: RBT-WP-0002
type: workplan
title: "Runbook pack specification and validator"
domain: infotech
repo: runbook-tutorials
status: finished
flavor: implementation
owner: claude
topic_slug: stack
created: "2026-09-29"
updated: "2026-09-29"
state_hub_workstream_id: "f72323f4-4ef8-5bcd-9662-09df1c20290e"
---
## Goal
Define what a runbook pack is, so packs can live in the repos that own them and
the engine can load, validate and present them. The pack spec is the contract
between this repo and every pack owner.
## Publish the pack specification
```task
id: RBT-WP-0002-T01
status: done
priority: high
state_hub_task_id: "f9e466d2-9fd1-502e-b2b8-e737068c12d2"
```
`docs/pack-spec.md` v0.1: manifest fields, parameters (never secret), steps with
mandatory verification, rollback for state-changing steps, exercise status per the
attended-procedure standard, and the legacy-command engine.
## Encode the specification as a JSON Schema
```task
id: RBT-WP-0002-T02
status: done
priority: high
state_hub_task_id: "84c0496f-57c1-547a-b831-f4a20b75c0e9"
```
`schema/runbook-pack.schema.json` with conditional requirements per engine.
## Implement discovery, validation and rendering
```task
id: RBT-WP-0002-T03
status: done
priority: high
state_hub_task_id: "2760f95a-5016-5a2e-b25c-b8b67847061c"
```
`rtut/pack.py` and the CLI (`python -m rtut list|validate|show|render`), with
semantic checks the schema cannot express (placeholders, duplicates, rollback,
secret markers, parameter defaults) and 16 tests. Parameter rendering rejects
unsafe characters.
## Review the v0.2 proposal and decide
```task
id: RBT-WP-0002-T04
status: done
priority: high
```
`docs/pack-spec-v0.2.md` (stages and hierarchy, dependency graph with a
recommended serialization, datapoints with `nil/set/err/ok`, QA gates tied to stages
and goals, actors and roles, artefacts, reversibility-based confirmation, framing).
Done 2026-09-29: Bernd answered the five questions; v0.2 adopted as `docs/pack-spec-v0.2.md` (with operating modes, overrides, deviations); v0.1 stays as shipped. Supersedes the earlier plan to freeze v0.1 alone.
## Write the v0.2 schema and validator
```task
id: RBT-WP-0002-T05
status: done
priority: high
```
Done 2026-09-29: `schema/runbook-pack-v0.2.schema.json` and `rtut/v2.py` (acyclic requires, references resolve, nesting depth 3, irreversible steps need a confirm phrase, no secret datapoints). v0.1 packs still load. 61 tests including one negative test per rule.
## Port the in-repo and NetKingdom packs
```task
id: RBT-WP-0002-T06
status: done
priority: medium
state_hub_task_id: "dae5a6fe-9f1f-553a-8b73-f47ab6d91b59"
```
2026-09-29 (CUST-WP-0074-T05 backfill): this task was `wait` with no external dependency or human gate stated, which Task Wait Qualifiers v0.1 treats as unqualified; set to `todo`. Re-add `wait` with a qualifier if a real gate exists.
Done 2026-09-29 (RBT-WP-0009-T06): the three NetKingdom packs are v0.2 (the console stays a legacy pack); the lighthouse v0.2 showcase and the test packs cover
alternatives, gates and actors.
## Showcase pack as acceptance test
```task
id: RBT-WP-0002-T07
status: done
priority: medium
state_hub_task_id: "6740457f-81a7-5761-a768-b9b0faee7552"
```
`runbooks/showcase-lighthouse/` is a harmless interactive-fiction runbook (poem, story,
scratch logbook under /tmp/rtut-*). `pack.yaml` (v0.1) runs today and is the test bed for
UI refinement. `runbooks/showcase-lighthouse-v2/pack.yaml` expresses the same story in the proposed v0.2 model
(stages, parallel steps, alternatives, gates, actors, datapoints, artefacts, irreversible
confirmation). It validates against the v0.2 schema and semantic checks and can be run by the v0.2 engine (`rtut/run2.py`); a UI for it is RBT-WP-0004.
## Acceptance Criteria
- Every pack in this repo and in `net-kingdom` validates.
- Invalid packs fail with a clear error; tests cover each rule.
- The spec names how the pre-existing console stays working.

View file

@ -0,0 +1,79 @@
---
id: RBT-WP-0003
type: workplan
title: "Engine core: run state and evidence"
domain: infotech
repo: runbook-tutorials
status: finished
flavor: implementation
owner: claude
topic_slug: stack
created: "2026-09-29"
updated: "2026-09-29"
depends_on: [RBT-WP-0002]
state_hub_workstream_id: "b7f2568a-96a2-5e92-8d04-4e7ac7b6da9b"
---
## Goal
Give the engine memory: a run of a pack keeps non-secret parameter values,
per-step state and evidence, and is the only thing allowed to change a pack's
exercise status.
## Design the run record
```task
id: RBT-WP-0003-T01
status: done
priority: high
state_hub_task_id: "e61fbba9-d69f-59d4-ad86-c1fab69e8171"
```
Specified in `docs/run-spec.md`: `runbook-run/v0.1`: pack id and revision, operator label, parameter
values, per-step state (`todo|running|done|failed|skipped`), timestamps,
evidence facts, verification results. Non-secret only, with the same secret-marker
rejection as packs. Stored under `.local/runbook-runs/` in the repo being operated.
## Implement the run store and step state machine
```task
id: RBT-WP-0003-T02
status: done
priority: high
state_hub_task_id: "fb10ebd1-d122-5b5f-9fd5-83d08539f8c1"
```
Create, resume and list runs. Enforce order, block a step until the previous
one verified, record failures without losing state. Tests for restart and
resume.
## Implement verification
```task
id: RBT-WP-0003-T03
status: done
priority: medium
state_hub_task_id: "870980df-c1e8-51e5-9a00-643f63404783"
```
`manual`, `exit-0` and `output-contains` checks. Commands are shown to the
operator; the engine runs a verify command only when the operator confirms
it, with a timeout and captured output size only (no output stored).
## Exercise-status writer
```task
id: RBT-WP-0003-T04
status: done
priority: medium
state_hub_task_id: "bad99b81-2b64-520f-b92f-1b8c6457659b"
```
When every step of a run has verified, offer to write
`exercise_status: exercised <date> by <operator>` into `pack.yaml` via a
reviewable diff. Never edit automatically.
## Acceptance Criteria
- A run survives restart and records outcomes without secrets.
- A pack becomes `exercised` only through a completed, verified run.

View file

@ -0,0 +1,282 @@
---
id: RBT-WP-0004
type: workplan
title: "Local runbook UI"
domain: infotech
repo: runbook-tutorials
status: finished
flavor: implementation
owner: claude
topic_slug: stack
created: "2026-09-29"
updated: "2026-09-29"
depends_on: [RBT-WP-0003]
state_hub_workstream_id: "bbd03473-fcf7-5b20-a295-e9ff45fb7ecc"
---
## Goal
The interface that made the operator ask for this: a local web UI (and a
terminal fallback) that shows where you are in a runbook, what to do next, and
what you have proven.
## Review the existing console's interaction model
```task
id: RBT-WP-0004-T01
status: done
priority: high
state_hub_task_id: "8309d778-3688-5cb3-bb34-18f87b66dbf3"
```
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.md`.
## Build the step view
```task
id: RBT-WP-0004-T02
status: done
priority: high
state_hub_task_id: "e15c22b6-60eb-5a54-9d22-b268897fcf4d"
```
Parameter form, ordered steps with owner tags, rendered copyable commands,
"done when" with confirm/verify, rollback shown beside each step, progress
overview, resume after restart. Localhost only, no external calls, whynot-design
posture, works without JavaScript frameworks.
## Terminal mode
```task
id: RBT-WP-0004-T03
status: cancel
priority: medium
state_hub_task_id: "a33cbd52-8759-583f-a2f0-8ab926569346"
```
Cancelled 2026-09-29 (RBT-WP-0009): the run records are usable from the CLI for v0.1 packs (`rtut run ...`), and a terminal walk-through for v0.2 is not
needed to close this workplan. It is kept as RBT-WP-0006-T05. Original scope: `rtut run <pack>` walking the same run record in the terminal, for hosts
without a browser.
## Evidence view and export
```task
id: RBT-WP-0004-T04
status: done
priority: medium
state_hub_task_id: "616255c2-091c-5948-8160-abd9dc69907f"
```
Done 2026-09-29 (RBT-WP-0009-T04): the run view is the evidence view; a closed run's record downloads as JSON and `rtut seal` verifies it.
The exercise-status diff no longer exists (retired, RBT-WP-0009-T01).
## Fix the check, record and lock-in cycle
```task
id: RBT-WP-0004-T05
status: done
priority: high
state_hub_task_id: "d635f972-0377-5581-a8fe-c01ef89559cd"
```
Done 2026-09-29 against the lighthouse showcase (tested over HTTP; a browser pass by Bernd is still the real check). 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. Follow-up done 2026-09-29 from Bernd's first hands-on: the command and
Copy button appear only once a step is started (done steps keep the command as a record);
"Mark done" and "Mark failed" sit left of the comment field; a first "Mark failed" without a
comment only warns, a second click fails without one; every action returns to the current
step instead of the top of the page.
## Questionnaire flow on the v0.2 model
```task
id: RBT-WP-0004-T06
status: done
priority: high
state_hub_task_id: "261bf74f-f5cd-55bb-9a96-12767418c980"
```
Unblocked: RBT-WP-0007 (engine) is finished. 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: done
priority: high
state_hub_task_id: "16db09c7-7707-5d17-aab3-5d8eab2c1fce"
```
Unblocked: RBT-WP-0007 (engine) is finished. 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: done
priority: high
state_hub_task_id: "23d3f5cc-e844-5077-9a4a-0435c189d98b"
```
Unblocked: RBT-WP-0007 (engine) is finished. State transparency at a glance: stage progress, gate states
and waivers, datapoint completeness by dimension.
## Visual design
```task
id: RBT-WP-0004-T09
status: done
priority: medium
state_hub_task_id: "53c74197-4747-5bdd-9b7c-8bdc42b7c1f5"
```
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: done
priority: medium
state_hub_task_id: "ddbca5e1-dcf6-5c2a-b3e2-497d2a82ba23"
```
Confirm button for reversible steps, typed phrase for irreversible ones, per the v0.2
`reversible` field.
## Mode switch and override dialog
```task
id: RBT-WP-0004-T11
status: done
priority: high
state_hub_task_id: "99320417-8261-556b-8932-4947cfd8ce11"
```
Unblocked: RBT-WP-0007 T06-T07 are finished. Choose manual or auto-confirm per run (with timeout and
push-through controls). In manual mode, an override dialog lists unmet preconditions and
the downstream risk before continuing; deviations show in the overview.
## Feedback collector
```task
id: RBT-WP-0004-T12
status: done
priority: medium
state_hub_task_id: "483e7472-ff22-5611-8010-9cf96ac34ec9"
```
Done 2026-09-29: after "All steps done." the run view offers three smileys and a comment
(what felt strange or unclear, ideas to optimize). Stored in the run record (history kept,
latest wins, secrets refused); `rtut feedback <pack.yaml>` lists the latest per run.
Follow-up: fold feedback into the overview and use it to prioritize pack refinements.
## Run outcome, score, exercise recording and captures
```task
id: RBT-WP-0004-T13
status: done
priority: high
state_hub_task_id: "d35e129c-cfcc-538f-a4bf-76761d13a28a"
```
Done 2026-09-29 from Bernd's review: runs are finalized as succeeded, failed or abandoned
(stale open runs count as abandoned after 7 days); a runbook's score (tried, succeeded, failed,
abandoned, open, feedback tally) is shown in the list and on the pack page, with a list of its
runs; finalizing a succeeded run offers an explicit "Record pack as exercised" that shows the
change before writing it to `pack.yaml`; steps can capture the command run and its output, and
`output-contains` checks can be verified against pasted output. Documented in `docs/run-spec.md`.
Open: run histories are per machine (`.local/`), so a shared or committed history is still
to be decided.
## Delivered 2026-09-29: the v0.2 walk-through UI
`rtut/ui_v2.py` (tested over HTTP with 19 tests; rendering checked in headless Chromium screenshots of the flow, data and overview
views on a mid-run state). Three views of one run:
- **Guided flow** (main): framing shown first; a banner with the recommended next action and the other items possible in parallel;
nested stages with goals, per-stage questions (datapoints saved with validation), numbered steps with owner and actor, idempotency,
irreversible and manual-only marks; alternatives with the recommended one preselected; typed confirmation phrase for irreversible steps;
override dialog (reason, acknowledged downstream risk, recorded as a deviation) for blocked steps and gates in manual mode; gates with per-check
controls and waivers; retry that asks for the partial-application confirmation on non-idempotent steps; captures and pasted-output
checks; feedback and closing as before.
- **Data**: every datapoint editable independently of the flow, grouped or filtered by dimension (click a tag), with provenance,
plus artefacts (resolved locations) and actors.
- **Overview**: progress, per-stage state, gates, datapoint states, deviations, mode changes.
- **Modes**: manual, and auto-confirm with "check once", "run until it waits" and "take over"; a stop or push-through is shown.
Projects can start v0.2 members in either mode.
- **Visual design**: a restrained stylesheet (hairlines, state pills that never rely on colour alone, highlighter accent for
the recommended action, print rules). Dark theme is written but not verified in a browser.
## Feedback round after the first v0.2 hands-on (2026-09-29)
```task
id: RBT-WP-0004-T14
status: done
priority: high
state_hub_task_id: "28582e62-335c-57d5-9adc-6b9050268139"
```
Bernd's remarks, each handled and tested: (a) forms no longer ask for a name; the active user (`user-attributes`, app-level and reusable by
projects; `RTUT_USER`, saved settings or the OS login; `/user` page); (b) the showcase's irreversible step is now genuinely irreversible (the
logbook entry carries the exact time it was written); (c) a "Latest activities" section on the main page; (d) values that steps already used
can only be changed with an override and are recorded as `changed-after-use`, saves are all-or-nothing; (e) artefacts on the Data tab can be
opened and downloaded, with safety rules; (f) run start, finish and duration, per-step duration, and the average duration of successful
runs next to the score. Documented in `docs/run-spec.md` and `docs/maturity-and-projects.md`.
## App shell, theme, attribute-set management and project editing
```task
id: RBT-WP-0004-T15
status: done
priority: high
state_hub_task_id: "a6bf64b5-4432-5fc9-bdbe-5631b65e8343"
```
Done 2026-09-29 from Bernd's feedback (no way to switch theme, no navigation to user settings or attribute sets): a sidebar shell on every
page (Home, Projects, Runbooks, Attribute sets, Activity; you and a theme switch at the bottom; a top bar on narrow screens); a theme
switch that cycles system, light and dark and remembers the choice (`?theme=dark` also sets it); dedicated Projects, Runbooks and Activity
pages; attribute sets listed, inspected with their resolved values and sources, created and edited (values, requirement, note, extends;
secrets, bad names, unknown and circular `extends` refused, a refused save changes nothing); the project name, description and goal
editable from the project page. Bernd confirmed the theme and navigation. Not done: deleting an attribute set, editing templates.
## Closed runs locked; Home headlines as shortcuts
```task
id: RBT-WP-0004-T16
status: done
priority: high
state_hub_task_id: "2622084d-b5f7-5442-962f-2f7b1e87cd8d"
```
Done 2026-09-29 from Bernd's feedback: Home headlines link to their sidebar sections; the "Back to the runbook list" link is gone; closed runs are
locked (engine refuses changes, feedback included), sealed with a hash and made read-only, tampering is shown and disqualifies the run as maturity
evidence; the closing form takes optional feedback so abandoned runs are not silent; a closed run shows its feedback read-only (no "Change my
feedback"), or no feedback section at all. See `docs/run-spec.md`.
## Project runs in the UI
```task
id: RBT-WP-0004-T17
status: done
priority: high
state_hub_task_id: "1394fb8f-a24e-5516-a7c3-e31ca1a3a40e"
```
Done 2026-09-29: the project page has "Run the whole project" (mode choice, history of project runs); a project run page shows progress, the
next or open member, the member table with status, progress and links, an override for out-of-order starts, auto-confirm controls (check once,
run until it waits, take over or hand over), a log, and the closing form. Member run pages link back to their project run; the activity
feed includes project run events. Tested over HTTP; visual check pending.
## Acceptance Criteria
- 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.

View file

@ -0,0 +1,95 @@
---
id: RBT-WP-0005
type: workplan
title: "Legacy adapter and console migration"
domain: infotech
repo: runbook-tutorials
status: finished
flavor: implementation
owner: claude
topic_slug: stack
created: "2026-09-29"
updated: "2026-09-29"
depends_on: [RBT-WP-0002]
state_hub_workstream_id: "253d0512-46e2-51b2-8e26-12da2c1534ca"
---
## Goal
Carry the NetKingdom security bootstrap console into this ecosystem without
breaking it: first as an unchanged legacy pack, then, only where worthwhile, by
moving its generic parts into the engine.
## Wrap the console as a legacy pack
```task
id: RBT-WP-0005-T01
status: done
priority: high
state_hub_task_id: "0e459512-a5b4-539e-9603-79a2cfa4f27e"
```
`net-kingdom/runbooks/security-bootstrap-console/pack.yaml`
(`engine: legacy-command`) validates and lists it, with no change to
`tools/security-bootstrap-console/`.
## Implement launch and health for legacy packs
```task
id: RBT-WP-0005-T02
status: done
priority: high
state_hub_task_id: "8ff275f5-c70f-5a12-a69e-44f8922a32f0"
```
`rtut launch <pack>` runs `legacy.command` from the owning repo root, waits for
`legacy.url` to answer, and reports it. It stops the process it started. Test
with a stub server.
## Inventory the console
```task
id: RBT-WP-0005-T03
status: done
priority: high
state_hub_task_id: "dbb5553d-fb0c-5298-85c8-cebc9dd63312"
```
Done 2026-09-29 (RBT-WP-0009-T05): `docs/console-mapping.md`. Classify the 5,300-line `security_bootstrap_console.py` into generic engine
concerns (record and state model, gates, stage derivation, copyable blocks,
approval phrase, localhost server) and NetKingdom-specific content (custody,
OpenBao ceremony, KeyCape, privacyIDEA checks). Output: a migration map with
the tests that pin current behaviour.
## Extract the generic engine parts
```task
id: RBT-WP-0005-T04
status: cancel
priority: medium
state_hub_task_id: "14261c00-65d0-55be-8ab2-bd81e579e20d"
```
Cancelled 2026-09-29: extracting the console's engine now would freeze its workarounds into the engine, because v0.2 lacks conditional applicability, gate
recheck and outputs that feed later members (`docs/console-mapping.md` G1, G3, G7). It may return as part of a v0.3 design. Original scope: move the generic parts into `rtut` behind the run record. The console in
`net-kingdom` then imports them. Gate: the existing
`tools/security-bootstrap-console/tests` pass unchanged before and after, and
`make security-bootstrap-ui` behaves the same.
## Decide the console's final form
```task
id: RBT-WP-0005-T05
status: done
priority: low
state_hub_task_id: "c54cfa35-1a34-5d5a-b85b-86ae8771dcfb"
```
Decided 2026-09-29 (Bernd, with RBT-WP-0009): the console stays a permanent legacy pack, launched unchanged. Its seven runbooks can become native v0.2
packs as separate content work (they need none of G1 to G7). Original question: keep the console as a permanent legacy pack, migrate its runbooks
to native packs, or a mix.
## Acceptance Criteria
- The console works unchanged throughout.
- No secret handling is moved into the engine.

View file

@ -0,0 +1,123 @@
---
id: RBT-WP-0007
type: workplan
title: "Engine v0.2: graph, datapoint states and gates"
domain: infotech
repo: runbook-tutorials
status: finished
flavor: implementation
owner: claude
topic_slug: stack
created: "2026-09-29"
updated: "2026-09-29"
depends_on: [RBT-WP-0002]
state_hub_workstream_id: "0ce4d5fd-6eac-5f9a-a170-8231a551f66a"
---
## 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: done
priority: high
state_hub_task_id: "55dd86f9-5f89-59a2-8a0a-85fbedd95483"
```
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: done
priority: high
state_hub_task_id: "571e8685-6eeb-54ce-bb1a-4616ea951f81"
```
`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: done
priority: high
state_hub_task_id: "707cca55-24a1-5355-8722-10740c5a2862"
```
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: done
priority: medium
state_hub_task_id: "73307bb9-2739-563b-92c7-a034a360b444"
```
`runbook-run/v0.2` with datapoints, gates, waivers; v0.1 records still load.
## Confirmation policy
```task
id: RBT-WP-0007-T05
status: done
priority: medium
state_hub_task_id: "0933ff4a-8478-50d9-aa99-991948bc2379"
```
Derive confirm button versus typed phrase from `reversible`; enforce the phrase in the
engine so no renderer can skip it.
## Operating modes: manual and auto-confirm
```task
id: RBT-WP-0007-T06
status: done
priority: high
state_hub_task_id: "1656597c-3748-5480-b136-e2872436bab4"
```
A run has a mode (`docs/pack-spec-v0.2.md`). Manual: the operator confirms; every
check, gate and precondition is shown with its state. Auto-confirm: the engine confirms
when all preconditions are met. `auto_confirm: manual-only` steps and irreversible steps
are never auto-confirmed without a recorded pre-authorization.
## Overrides, waivers, push-through and the deviation record
```task
id: RBT-WP-0007-T07
status: done
priority: high
state_hub_task_id: "0ef958ef-88b6-565b-8797-df730cf11ad3"
```
Override in manual mode when preconditions are unmet: name the unmet items and the
declared `downstream_risk`, require explicit confirmation and a reason, record a
deviation. Waivers only where a gate declares `waivable`. Auto-confirm timeouts
(`stop` or `push-through`) record a deviation and, for push-through, move on. A run with
any deviation is flagged and can never exercise a pack.
## Delivered 2026-09-29
`rtut/flow.py` and `rtut/run2.py`, documented in `docs/run-spec.md` (run record v0.2) and covered by
`tests/test_run2.py` (25 tests: readiness and recommendation, parallel items, alternatives, datapoint
states, gates, overrides, waivers, confirmation phrase, auto-confirm confirm / stop / push-through,
manual-only and pre-authorization, read-only finished runs). Two spec corrections came out of it:
a gate cannot require a datapoint it is itself `confirmed_by` (validator rule), and `run.finalize`
also requires gates passed or waived. Not done here: any UI or CLI for v0.2 runs (RBT-WP-0004).
## 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.

View file

@ -0,0 +1,161 @@
---
id: RBT-WP-0008
type: workplan
title: "Runbook maturity, projects and idempotency"
domain: infotech
repo: runbook-tutorials
status: finished
flavor: implementation
owner: claude
topic_slug: stack
created: "2026-09-29"
updated: "2026-09-29"
depends_on: [RBT-WP-0007]
state_hub_workstream_id: "8f11966b-1e6c-5b12-8bc4-a13c52307c4c"
---
## Goal
Separate what a runbook is (characteristics), how far it can be trusted (maturity, earned and bound to a
pack revision), and what state an environment is in (projects). Replaces the environment-dependent
`exercise_status`. Model and candidate terminology: `docs/maturity-and-projects.md`.
## Decide the terminology and model
```task
id: RBT-WP-0008-T01
status: done
priority: high
state_hub_task_id: "904939c5-ed69-53a0-8fe1-2a0ae6d5337d"
```
Decided 2026-09-29 (Bernd: go with the suggestions, keep *project*): `docs/maturity-and-projects.md`.
## Idempotency as a declared characteristic
```task
id: RBT-WP-0008-T02
status: done
priority: high
state_hub_task_id: "911ef051-ee55-5c65-b134-57fa9f1fddce"
```
Done 2026-09-29: `idempotent: idempotent | non-idempotent | conditional` (+ `idempotent_note`) per step in the v0.2
schema, validator rule for `conditional`, derived runbook value (`flow.pack_idempotency`), declared honestly in the
showcase. Values are words because YAML reads unquoted yes/no as booleans. Follow-ups: show it in the UI, and use
it for the retry policy (T07).
## Bind runs to a pack revision
```task
id: RBT-WP-0008-T03
status: done
priority: high
state_hub_task_id: "a79e5b3d-221b-5ac6-a7a1-44737139c8f3"
```
Done 2026-09-29: `pack.digest()`; every run records `pack_digest` and `context` (project, target, environment class).
## Derive maturity from run history
```task
id: RBT-WP-0008-T04
status: done
priority: high
state_hub_task_id: "53fe81cd-6b67-5508-bdbd-38073a0d77e7"
```
Done 2026-09-29: `rtut/maturity.py`, review records (`REVIEWS.yaml`, bound to a revision), `rtut maturity`, `rtut review`.
`proven` = reviewed + rehearsed + clean in two environments by two operators. Not yet done: retiring `exercise_status` and the
"Record pack as exercised" click in the UI (T09).
## Project specification and shared datapoints
```task
id: RBT-WP-0008-T05
status: done
priority: high
state_hub_task_id: "d022c7fb-1421-5738-a00f-5b18593fb1a2"
```
Done 2026-09-29: attribute sets (`attribute-set/v0.1`: composition with `extends`, requirement, derived state, provenance,
`modified` flag), projects with targets and members (`project/v0.1`), project templates (`project-template/v0.1`),
`rtut/attrs.py`, `rtut/project.py`, schemas, CLI (`rtut project ...`), examples under `attribute-sets/` and `project-templates/`.
Runs started from a project take the resolved attributes as defaults and record the project as context.
## Project state
```task
id: RBT-WP-0008-T06
status: done
priority: medium
state_hub_task_id: "41f2b781-3699-5d21-bdfd-4ff3c2c0b777"
```
Done 2026-09-29: `project.state()`: member status `not-applied | applying | applied | stale | failed`, project state
`planned | applying | applied | stale`, plus the members that can start next (`after`) and the attributes still needed.
## Retry policy for non-idempotent steps
```task
id: RBT-WP-0008-T07
status: done
priority: medium
state_hub_task_id: "8b34c57b-3380-5f7b-aaf5-6227a47dcf60"
```
Done 2026-09-29: `run2.retry(..., acknowledge_partial=True)` is required unless the step is declared `idempotent` (undeclared
counts as not idempotent); the UI asks with a checkbox; the acknowledgement is recorded on the step. v0.1 runs have no idempotency
declaration and keep their free retry.
## UI for projects, maturity and attributes
```task
id: RBT-WP-0008-T08
status: done
priority: high
state_hub_task_id: "913c46fa-7790-5d32-ada1-8dec430d4ff5"
```
Done 2026-09-29 (tested over HTTP, not yet reviewed in a browser): the runbook list shows maturity per runbook; the front page lists
projects (environment, state, goal) and templates; a template page shows every attribute with requirement, note and source and
creates a project; the project page shows goal, state, still-needed attributes (fillable, validated against the runbooks that
consume them), members with status, maturity, next member and a Start run button, and per-member attribute tables with state,
source, modified mark and problems; runs started from a project take its attributes and link back to it; the pack page shows
maturity evidence, idempotency and a review form. Not covered: walking v0.2 runs (RBT-WP-0004). Original scope: show maturity and idempotency next to each runbook; a project view (goal, targets, member status, next member, needed
attributes with state, source and modified marks); start a run from a project so its attributes fill the form; a
template picker that instantiates a project.
## Retire exercise_status
```task
id: RBT-WP-0008-T09
status: done
priority: medium
state_hub_task_id: "54749c4e-69d8-54ee-a1f7-5e9f781a9053"
```
Done 2026-09-29 (RBT-WP-0009-T01): the click, `apply_exercise` and `exercise_update` are removed, the field is deprecated and ignored, and the shipped packs no longer carry it.
Original scope: replace the "Record pack as exercised" click and the `exercise_status` field with derived maturity; migrate the packs.
## Templates as products: auto-confirm and auto-pilot on a project
```task
id: RBT-WP-0008-T10
status: done
priority: medium
state_hub_task_id: "917961d5-1571-52a5-b138-a15163176ed4"
```
Done 2026-09-29: `rtut/projectrun.py` and `rtut/ui_projectrun.py`. A project run snapshots the resolved attributes, then runs the members
member by member in `after` order. Manual: you start each member (out of order needs a recorded override). Auto-confirm: the engine starts
the next ready member, ticks its run, closes it when it finishes cleanly, continues through push-through, and stops wherever a person is needed
(v0.1 member, manual-only or irreversible step, failed check). Closing locks and seals it, and abandons an open member run. Auto-pilot with
execution remains RBT-WP-0006. Attribute states to explore in use: needed, optional, modified,
checked; add what real use shows.
## Acceptance Criteria
- "Exercised" has a precise, environment-aware meaning; a production project is never called "exercised".
- Maturity is derived from runs, bound to a revision, and expires when the pack changes.
- A value shared by several runbooks is entered once, in the project.

View file

@ -0,0 +1,129 @@
---
id: RBT-WP-0009
type: workplan
title: "Finalize the runbook-tutorials workplans"
domain: infotech
repo: runbook-tutorials
status: finished
flavor: implementation
owner: claude
topic_slug: stack
created: "2026-09-29"
updated: "2026-09-29"
depends_on: [RBT-WP-0002, RBT-WP-0004, RBT-WP-0005, RBT-WP-0007, RBT-WP-0008]
state_hub_workstream_id: "53103733-880f-58cc-a330-4b86375b20ad"
---
## Goal
Close every runbook-tutorials workplan before new functionality is introduced. "Closed" means finished, or moved to
`backlog` with the open decisions written down. Agreed with Bernd on 2026-09-29: the definition of done is *all workplans closed*
(no formal freeze ceremony; a security and code review remains an optional follow-up).
Decisions taken with the plan: keep old packs that still carry `exercise_status` loadable (ignored, deprecated); keep the
NetKingdom security bootstrap console as a permanent legacy pack; port the three NetKingdom packs to v0.2; move terminal mode to the
backlog and do only a small JSON export.
## Retire exercise_status
```task
id: RBT-WP-0009-T01
status: done
priority: high
state_hub_task_id: "298ba5c8-cd8c-5d0c-afdc-cd2c41b67774"
```
Done 2026-09-29. `exercise_status` mixed three things (RBT-WP-0008). Maturity, derived from run history, replaces it. Remove the "Record pack as
exercised" click and `apply_exercise` / `exercise_update`; drop the field from the shipped packs (both repositories) and from the UI
headers; make it optional and deprecated in both schemas so old packs still load; show maturity where the status was shown.
Also found and fixed while doing it: the CLI had no tests, and `rtut list` crashed from a shadowed import; `tests/test_cli.py` now covers it.
## Packaging, checks and CI
```task
id: RBT-WP-0009-T02
status: done
priority: high
state_hub_task_id: "14b17a9b-c3a3-5291-9328-e90c99caea49"
```
Done 2026-09-29. Declare the dependencies (`pyproject.toml`: PyYAML, jsonschema, pytest) so a fresh checkout can run; add `rtut check` (packs, attribute
sets, projects and templates in one go) and `make check`; replace the copied smoke-only CI with a job that runs the tests and the checks.
Also: the JSON schemas moved into the package (`rtut/schema/`) so a plain `pip install .` works (verified); `rtut check` validates packs, attribute
sets, projects and templates; `.forgejo/workflows/tests.yaml` runs tests and checks in a python:3.12 container. **The CI job has not run on a real
runner** (no way to trigger one from here); check its first execution.
## Documents and bookkeeping
```task
id: RBT-WP-0009-T03
status: done
priority: medium
state_hub_task_id: "fec1fc82-c686-524f-861f-ba0881f9408b"
```
Done 2026-09-29. Refresh `SCOPE.md` (it still says "bootstrap"), add a `docs/README.md` index, note in the specs that v0.1 and v0.2 changes from here on
become a new version, update the capability entry, and make the workplan statuses true (RBT-WP-0007 finished, RBT-WP-0002-T07 done,
RBT-WP-0006 and NK-WP-0011 to backlog).
## Evidence export
```task
id: RBT-WP-0009-T04
status: done
priority: medium
state_hub_task_id: "f6f2e2b2-7872-5565-9960-609a790b5356"
```
Done 2026-09-29, closing RBT-WP-0004-T04: a closed run's (and project run's) record can be downloaded as JSON from its page; an open run is
refused (409). Added `rtut seal <file>` so an exported record can be verified anywhere.
## Console mapping: is v0.2 expressive enough
```task
id: RBT-WP-0009-T05
status: done
priority: high
state_hub_task_id: "d90789fc-0497-5caa-979e-53289d20afc4"
```
Done 2026-09-29. Verdict: the structure maps, the behaviour does not fully; seven gaps (G1 to G7) are the v0.3 candidates. `docs/console-mapping.md`: map the security bootstrap console's 6 stages, 14 gates, roles, subsystems, integrations, 12 artefacts
and 7 runbooks onto v0.2 and say honestly where a special case is needed. This is the acceptance evidence for the model. It closes
RBT-WP-0005-T03, records the decision to keep the console as a permanent legacy pack (T05), and moves the extraction (T04) to the backlog.
## Port the NetKingdom packs to v0.2
```task
id: RBT-WP-0009-T06
status: done
priority: high
state_hub_task_id: "ca96aae8-bac5-5170-971f-d4b06e1ff252"
```
Done 2026-09-29 (net-kingdom commit 90112f3). `nk.ssh-certificates`, `nk.openbao-operating-path` and `nk.protected-system-flex-auth` become v0.2 packs with actors, datapoints,
stages, gates, idempotency and framing, so the real content uses the model and exercise evidence attaches to the format that stays.
Closes RBT-WP-0002-T06 and updates NK-WP-0044.
All three validate as v0.2; the 13 checks that need no cluster were re-run through the engine and pass; the OpenBao pack's optional record step is an
alternatives choice recommended by a datapoint; live flex-auth steps are manual-only for auto-confirm. The attended run against the cluster is
Bernd's (NK-WP-0044-T05).
## Close the workplans
```task
id: RBT-WP-0009-T07
status: done
priority: high
state_hub_task_id: "32408947-03bc-58cb-b57b-cb2ee097a3bc"
```
Done 2026-09-29. Set every status to what is true, move terminal mode and the evidence work that is not done to the backlog with the decisions written
down, archive the finished workplans, sync State Hub, and record a progress event. Work that needs Bernd's own environment
(NK-WP-0044-T05 attended runs, NK-WP-0009 T03-T05, the external STS issuer for T02) stays in net-kingdom and is named there.
## Acceptance Criteria
- No runbook-tutorials workplan is `active` with open `todo` work: each is `finished` or `backlog` with its decisions recorded.
- `exercise_status` is gone from the UI, the engine and the shipped packs; old packs still load.
- A fresh checkout can install and run the tests; CI runs them.
- The console mapping states plainly what v0.2 cannot express yet.
- The three NetKingdom packs validate as v0.2.