runbook-tutorials/docs/run-spec.md
tegwick 60d983769f
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 4s
Work Records / validate (push) Successful in 12s
Engine v0.2: flow graph, datapoint states, gates, modes, overrides, deviations (RBT-WP-0007)
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
2026-09-29 11:34:07 +02:00

100 lines
5.9 KiB
Markdown

# Run record `runbook-run/v0.1`
One run of one native pack, stored as JSON in
`<owning repo>/.local/runbook-runs/<run_id>.json` (git-ignored). Non-secret only.
| Field | Meaning |
| --- | --- |
| `run_id` | Timestamp plus random suffix |
| `pack_id`, `pack_path` | The pack run |
| `operator` | One word: the person who ran it |
| `params` | Resolved parameter values (validated, never secret) |
| `steps.<id>.state` | `todo`, `running`, `done`, `failed`, `skipped` |
| `steps.<id>.verification` | `kind`, `passed`, and for commands `exit_code`, `output_bytes`, `seconds`. Output text is never stored |
| `steps.<id>.evidence` | The facts the step declared, supplied by the operator |
## Rules
- Steps run in order; a step starts only after its predecessors are done or skipped.
- A step completes only with a passing verification and its declared evidence.
- A verify command runs only when the operator confirms (`--yes`), with a 60 s timeout.
- Only read-only steps may be skipped, and a run with skips never exercises a pack.
- Values matching the secret markers are refused everywhere they could be recorded.
- The engine never edits `pack.yaml`. `rtut run finish` shows the exercise-status
diff; `--apply` writes it, and only for a run in which every step is done.
CLI: `rtut run new|list|status|cmd|start|verify|done|fail|retry|skip|finish <pack.yaml> ...`
## Outcome, score and exercise status
A run is **open** until finalized. `rtut run finalize` (or the UI's *Close this run*) records
an `outcome`:
| Outcome | Rule |
| --- | --- |
| `succeeded` | every step is `done` (skipped steps do not count) |
| `failed` | at least one step has failed; otherwise abandon |
| `abandoned` | any time. An open run untouched for 7 days also counts as abandoned in the score |
A finished run is read-only, except for feedback. The **score** of a runbook is derived from
its run records: tried, succeeded, failed, abandoned, open, plus a tally of feedback ratings
(`rtut score <root>`; shown in the UI). Run records live in `.local/` of the machine that ran
them, so the score is per machine until run histories are shared.
Finalizing never edits the pack by itself. For a `succeeded` run the UI offers **Record pack
as exercised**, which shows what will be written, and on click sets
`exercise_status: exercised <date> by <operator>` in `pack.yaml` (`rtut run finalize ... --outcome
succeeded --apply` does the same). The change is an ordinary edit in the owning repository, to
be reviewed and committed there.
## Feedback
`feedback` entries (`rating` good|neutral|poor, `comment`, `at`) are added after a run; history
is kept and the latest counts. `rtut feedback <pack.yaml>` lists them.
## Captures
A step may carry optional `captures`: the command actually run, and the output that came
back, as documentation or for inspection when the engine cannot reach the system itself. Limits:
20 000 characters of output, 2 000 of command. Obvious secret markers are refused; the engine cannot
detect every secret, so the operator stays responsible. For `output-contains` steps the output can
be **pasted for verification** (`source: pasted-for-verification`), which checks the `contains` text
without running anything. Exit-code checks cannot be verified from pasted output.
## Run record `runbook-run/v0.2` (packs of `runbook-pack/v0.2`)
Implemented in `rtut/run2.py` (graph in `rtut/flow.py`). It adds to the v0.1 record:
| Field | Meaning |
| --- | --- |
| `mode` | `manual` or `autopilot` |
| `datapoints.<id>` | `state` nil, set, err or ok; `value`, `how` (initial, manual, produced, check, manual confirmation), `error` |
| `steps.<id>` | as v0.1, plus `alternative` (chosen `one_of` branch), `authorized_by`, `pushed_through` |
| `gates.<id>` | `state` open, passed, failed or waived; per-check `results`; `waiver` |
| `deviations[]` | every override, waiver and push-through (see `docs/pack-spec-v0.2.md`) |
| `autopilot` | `preauthorized` irreversible steps, `authorized_by`, and `stopped` if a timeout stopped the run |
Rules the engine enforces:
- **Preconditions** of an item are its `requires` (and those of enclosing stages), the `set`/`ok`
state of the datapoints it `uses`, and, for a gate, completion of the steps of its stage.
- **Recommended next action**: the running item first, else the first ready item in the pack's canonical
order. `next_actions(run)` returns the recommended item, all ready items (parallel work) and the blocked
ones with what they wait for.
- **Alternatives**: a `one_of` step is started with an alternative (default: the first whose
`recommended_when` matches the datapoints).
- **Datapoints**: invalid input leaves the datapoint `err` and is never stored; a step's `produces` become `set`
when it completes; `confirmed_by` promotes them to `ok` when that step or gate passes.
- **Override** (manual mode only): starting an item with unmet preconditions needs a reason and an acknowledged
downstream risk; it is recorded as a deviation.
- **Waiver**: only for gates that declare `waivable`, with a reason; recorded as a deviation.
- **Confirmation**: irreversible steps need the exact confirmation phrase at start. In autopilot they run only
if the run pre-authorized them, and never if the step is `autopilot: manual-only`.
- **Autopilot** (`autopilot_tick`): the engine applies confirmation when preconditions are met: it starts the
recommended item, runs its checks (manual checks are auto-confirmed and marked so) and completes it. It
never runs a step's own command; the work is done by the operator or, later, by opt-in execution. A step
with `evidence` waits for the operator. If checks keep failing until the item's `timeout` (or the pack
default), the run stops, or with `on_timeout: push-through` the item is marked done with
`pushed_through` and a deviation is recorded.
- **Deviations and exercise**: a run with any deviation or pushed-through step can be finalized but never exercises a pack.
`finalize(succeeded)` also needs every gate passed or waived.