Skip to main content

Playbook TUI

verum playbook launches a terminal UI for interactive exploration of a Verum project — a faster-feedback alternative to the REPL + editor cycle.

Think of it as the IDE-on-the-terminal: everything you want to do to a function (call it, test it, verify it, inspect its CBGR report, profile it) one keystroke away.

Launching

$ cd my-project
$ verum playbook

On first launch Playbook indexes the project, wires up an async runtime, and starts an empty session in the project root's module.

What it does

  • Discover — auto-indexes functions, types, protocols in your project, plus their dependencies.
  • Invoke — call functions interactively with typed argument prompts.
  • Inspect — view results with pretty-printing for every stdlib type.
  • Profile — measure execution time, allocations, SMT time per call.
  • Verify — run @verify(formal) on the function at cursor; see obligations discharged live with per-obligation timing.
  • Replay — re-run prior invocations with modified arguments.
  • Trace — live-replay an invocation's VBC steps, seeing local values at each point.

Layout

Three panels, always visible:

PanelRole
ExplorerFile tree on the left; select any file to view it.
Editor / ResultTop-right panel shows the current function's source and last result.
PromptBottom panel is a line-editing REPL.
KeyAction
TabSwitch focus among explorer, editor, prompt.
Ctrl-PCommand palette.
Ctrl-FFind function / type / protocol.
Ctrl-RSearch command history.
F5Re-run current invocation.
F7Open function's source.
F9Toggle profiling panel.
F10Open CBGR tier report for this function.
F11Open SMT trace for the latest verification.
Ctrl-CCancel running invocation.
Ctrl-LClear prompt (no history loss).
EscLeave search / dialog / modal.

Command palette

Ctrl-P opens a fuzzy-search menu. Common actions:

  • Run test module — pick a file, execute every @test in it.
  • Verify selected function — runs @verify(formal) on the cursor's function.
  • Explain refinement failure — on a failed verification, open the counter-example explorer.
  • Open CBGR report — show tier-analysis for the current function.
  • Toggle proof search trace — stream tactic invocations live.
  • Export session as test — turn the current invocation history into a @test file.
  • Profile current function — benchmark with 10 000 warmup + 100 000 iterations.
  • Switch runtime profile — toggle between debug, release, release-with-proofs.

The prompt language

The prompt accepts three forms:

Bind a value

> xs := [1, 2, 3, 42, 100]
> key := 42

The name is declared in the session's scope. Types are inferred.

Invoke a function

> search(&xs, key)
Result: Maybe.Some(3)

Arguments use ordinary Verum expressions — literals, name references, or method chains.

Evaluate an expression

> xs.len() + 1
6

Expressions that are not function calls evaluate and print.

Session persistence

Playbook sessions are saved to .verum/playbook/sessions/. Each session records every invocation, every bound value, and every result.

To restore a session next time:

$ verum playbook --session last
$ verum playbook --session "2026-04-17-abc123"

Export a session

> export session tests/playbook_session.vr

Generates a runnable test file from your exploration:

// tests/playbook_session.vr (generated by verum playbook)
mount my_project.*;

@test
fn session_20260417_1423() {
let xs = [1, 2, 3, 42, 100];
let key = 42;
assert_eq(search(&xs, key), Maybe.Some(3));
}

Context bindings

Bind contexts interactively; they persist for the session:

> bind Database = postgres://localhost/dev
> bind Logger = ConsoleLogger.new(LogLevel.Debug)
> bind Clock = SystemClock.new()

> fetch_user(UserId(42))
User { id: 42, name: "Alice", email: "alice@example.com", ... }

The bindings propagate through every call. Call a function that needs a different context and Playbook prompts you for it:

> send_email(UserId(42), "welcome")
? Email context not bound. Bind now? (s)mtp (m)ock (f)ile (n)one
> m
✓ bound Email = MockEmail.new()
Result: Result.Ok(())

Verification in the TUI

Put the cursor on a function and press F10. The verification panel shows:

Strategy: formal

ObligationTimeSolverResult
requires xs.is_sorted()18 msZ3pass
ensures result.is_some() => xs[result.unwrap()] == key42 msZ3pass
ensures result.is_none() => forall i in xs. xs[i] != key500 mstimeout

Total: 2 / 3 discharged, 1 timed out.

Actions:

KeyAction
aExplain failure (counter-example)
rRetry with thorough strategy
eEdit the function in place

Press a for the counter-example, r to race more solvers, e to edit the function without leaving Playbook.

Integration with LSP

Playbook uses the same indexer as the LSP server — no duplicate parsing. Changes to source files invalidate cached call results automatically. Run verum lsp alongside Playbook in a second pane, and your editor's inline diagnostics and Playbook's call results stay in sync.

Profiling

Press F9 to toggle the profiling panel. Sample output for search(&xs, key):

MetricValue
wall time18 ns (2 000 000 iters, σ 1.1 ns)
allocations0
SMT time0 (cached)
CBGR checks0 (all promoted)

Most costly callees:

FunctionTimeShare
List::binary_search_by13 ns72%
List::len1 ns6%

Breakpoints and step-through

Playbook is not a full debugger, but it can step through VBC execution for debugging:

> trace search(&xs, key)
step 1 / 27: call search(...) locals: xs, key
step 2 / 27: let lo = 0 locals: xs, key, lo=0
step 3 / 27: let hi = xs.len() locals: xs, key, lo=0, hi=5
...

Press space to advance, b to set a conditional breakpoint (e.g. "when lo > 10").

Command-line flags

verum playbook [options]
--session NAME Resume the named session.
--no-verify Skip verification on invocation (faster iteration).
--profile PROFILE Use a named build profile.
--workspace PATH Switch to a different workspace root.
--bind K=V Pre-bind a context before the TUI opens.

See also

  • REPL — line-oriented interactive mode, without the TUI overhead.
  • LSP — language server (same indexer).
  • stdlib/term — the 7-layer TUI framework Playbook uses.
  • tutorials/cli-tool — a program whose exploration benefits from Playbook.