runbook-tutorials/docs/run-spec.md
tegwick f5619e1a52
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Work Records / validate (push) Successful in 14s
Rename open to stalled and autopilot to auto-confirm; add pushed state; declare idempotency; propose maturity and projects model (RBT-WP-0008)
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 12:19:58 +02:00

6.7 KiB

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 unfinished (stalled) 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 unfinished 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, stalled (unfinished), 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 auto-confirm
datapoints.<id> state nil, set, err, ok or pushed; value, how (initial, manual, produced, check, manual confirmation), error
steps.<id> as v0.1 (pushed is an additional state), plus alternative (chosen one_of branch), authorized_by
gates.<id> state open, passed, failed, waived or pushed; per-check results; waiver or pushed
deviations[] every override, waiver and push-through (see docs/pack-spec-v0.2.md)
auto-confirm 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 auto-confirm they run only if the run pre-authorized them, and never if the step is auto_confirm: manual-only.
  • Auto-confirm (auto-confirm_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 state pushed 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.
  • Pushed is its own state. A step, gate or datapoint passed over by push-through is pushed: not done, not set, not err. Dependents may proceed (that is the point of pushing through), but a pushed datapoint has no value, so a command that needs it fails its check instead of running with nothing. A run with pushed items can be finished as failed (never succeeded) and never exercises a pack.
  • Stalled: an unfinished run is counted as stalled in the score, and as abandoned after a week.
  • Modes are manual and auto-confirm. Auto-confirm applies confirmation only; running the step's own command is a separate, later level ("auto-pilot with execution", RBT-WP-0006).