:: In active development. Codebase tracks the dev branch. Explore at your own risk. Official release coming soon.
Skip to content

Agent Cookbook

After reading: you'll know which docs to fetch first, what the typed Rust SDK gives an agent over an untyped boundary, how to drive vesl-test watch for closed-loop feedback, and which failure modes are recoverable in-loop vs. need human review.

This page is the working companion to Orientation, which names what's published. Orientation tells you the artifacts exist; this page tells you how to use them.

Ingestion Order

Three fetches cover most agent tasks:

  • /llms.txt first. The index lists every page with a one-line description. Fetching it once tells the agent the shape of the guide.
  • Per-page .md mirrors as needed. /setup/quickstart.md, /build/hull.md, etc. — fetch only what the task requires. One page costs one page of context.
  • /llms-full.txt for bulk ingestion. The whole guide concatenated in sidebar order. Use when the task spans the docs surface; prefer per-page fetches otherwise.

For source-level questions, the canonical repos are linked from every page that names a primitive. SHA-pinned cross-references in the docs (e.g. vesl-core at 11d110d, vesl-nockup at 6e2127c) point at the exact snapshot the docs were written against. When the agent's checkout is newer, the source is authoritative.

What the Typed Surface Gets You

The Rust SDK at the kernel boundary is typed at every seam. An agent driving it gets feedback shapes that an untyped boundary would have to discover at runtime:

  • PokeOutcome enum. Every app.poke(...) returns one of Accepted { effects } | Rejected { reason } | Crashed { error }. The agent matches on the variant; an unhandled variant is a compile error, not a silent miss.
  • assert_kernel_cause_tag! at compile time. With drift-detection codegen wired (see Hull → Hull/Kernel Drift Detection), a typo in a cause tag fails cargo build, not at runtime as a silent Ok(vec![]). Wire nockup graft codegen kernel-cause-tags from build.rs to opt in.
  • Codegen-driven harness methods. nockup graft codegen harness-methods generates typed GraftTestHarness::<verb>(...) methods from harness-bindings.toml. A rename in either the manifest or the binding surfaces as a codegen-time error.
  • build_*_poke builders. One per cause; the canonical 14-graft surface is on Grafts — Per-Graft Rust Snippets. Each takes typed Rust primitives and returns a NounSlab. The agent doesn't construct nouns by hand.

The typed surface compresses the agent's feedback loop. Where an untyped poke surfaces a problem as Ok(vec![]) with no effects (silent), the typed shape fails cargo build or returns a concrete PokeOutcome::Rejected variant the agent can branch on.

Closed-Loop Development

vesl-test watch streams effects from a running kernel, which makes for a tight read-eval-print loop:

  • Start the loop. Boot the kernel via cargo run, then in a second terminal: vesl-test watch. The watch stream emits one line per effect.
  • Poke and observe. Drive a poke through the hull (or via the Serve arm's HTTP routes). The watch stream prints each emitted effect as it lands.
  • Branch on the effect. Success effects (e.g. %settle-noted) confirm the path. Error effects (e.g. %settle-error msg=@t) carry the rejection reason as a cord.
  • Iterate. Edit Hoon, recompile, restart. State survives via PMA-resume. Boot drops from ~15s cold to ~1s warm.

For a one-shot inspection without watch, vesl-test inspect peek <path> returns the current value at a peek path. Full surface: Testing / CLI.

Different tasks lean on different pages. A short map:

Graft Selection

The 14 shipped grafts cluster by family. A short selection guide:

  • Commitment (settle, mint, guard, forge) — pick by lifecycle. settle for the full register/verify/note cycle with replay protection. mint for one-shot root binding without verification. guard for hash-leaf inclusion checks. forge for STARK proofs over committed data.
  • State (kv, counter, queue, rbac, registry) — pick by access shape. kv for key-value, counter for atomic increments, queue for FIFO, rbac for permission grants, registry for structured records.
  • Behavior (validate, log, clock, batch) — pick by wrap point. validate for pre-?--switch input rules. log for append-only audit. clock for deterministic timestamps. batch for settlement-flush bundling.
  • Intent (intent-graft) — placeholder, no builder. Causes crash on invocation until upstream lands.

The full taxonomy with priority bands lives on Grafts. Per-graft Rust snippets — one realistic poke per graft — live on Grafts — Per-Graft Rust Snippets.

Common Failure Modes

A short catalog of failure shapes an agent will see, with the recovery path:

  • Ok(vec![]) from app.poke(...). No effects came back. Likely causes: an unknown cause tag (drift detection opt-out), a kernel crash via ?> (bare assertion on user input — see Kernel / Causes — Denying a Cause Without Crashing), or a mule-trapped panic in a graft body. Wire drift detection, refactor ?> to ?:/?. branching, and grep vesl-test watch output for mote=Exit traces.
  • Compile error cause tag <X> not in KERNEL_CAUSE_TAGS. Drift detection caught a rename. Either update the hull's poke builder call site to match the kernel's renamed tag, or rerun nockup graft codegen kernel-cause-tags after a manifest edit. Full surface: Hull → Hull/Kernel Drift Detection.
  • Rejected::RbacDenied from a peek-then-poke gate. The caller's pubkey lacks the requested permission. The peek-then-poke pattern returns a typed rejection without sending the downstream poke. Full surface: Hull → Peek-Then-Poke Gating.
  • verify-jam reports stale. out.jam predates the last Hoon source edit. Re-run ./compile.sh. The fingerprint covers both manifest TOMLs and library .hoon files; either surface changing triggers staleness.
  • /health returns 503 with "stage":"booting". The hull hasn't finished kernel boot. Cold boot is ~15s; PMA-resume is ~1s. Wait or wire readinessProbe to the 200.

Failure modes with error: prefix from nockup graft inject --apply are gating lints — they refuse the write. Each one names a silent-fail surface in the composer or hoonc. See Inject Lints for the per-lint shape.

Stuck?

Something broken? The breakage is probably already in Common Pitfalls.

See Also