Docs
Playbooks

Playbook: Author Flows

Load when creating or editing a Breyta flow, adding steps, changing inputs,
copying template patterns, or preparing a draft for release.

Mental Model

Flow definitions are a Breyta DSL with Clojure/EDN syntax. They are not normal
Clojure programs. The DSL describes an orchestration graph plus contracts:
:requires, :invocations, :interfaces, :concurrency, reusable
:templates, :functions, packaged :steps, :agents, and finally :flow.

Author with platform limits in mind: deterministic orchestration, explicit step
boundaries, serializable maps/vectors, bounded loops, persisted large payloads,
and live/install targets that may differ from draft.

For first proof, inline small transform functions and step bodies when that is
the shortest path to a green draft run. Extract repeated or bulky pieces into
top-level :functions, :templates, or packaged :steps after the first proof,
before release or marketplace review.

Default Loop

  1. Start a small session capsule:
    • workspace, flow slug, task mode
    • intended interface and target
    • refs consulted
    • chosen pattern
    • next proof command
    • risks
  2. Reuse before writing:
    • breyta flows search "<integration or pattern>" --limit 5
    • breyta flows grep "<literal>" --surface definition,tools --limit 5 when metadata is not enough
    • breyta flows templates search "<problem>" --limit 5
    • breyta flows templates grep "<step or config>" --surface steps,tools --limit 5 when template metadata is not enough
    • breyta resources search "<existing data>" --limit 5 when prior uploads, reports, or run outputs may be reused
    • treat hits like rg: carry forward hitRef, matched field/surface,
      snippet/preview, and nextCommand; open one focused target, not every hit
    • for existing-flow edits, inspect the current flow before comparing examples
    • in clearly empty hosted workspaces, skip proving absence and start from the requested outcome
  3. Define the contract before source grows:
    • :requires
    • :invocations
    • :interfaces
    • :concurrency
    • output shape
    • side effects and failure behavior
  4. Build a minimal draft slice with one manual interface and one meaningful
    boundary. Avoid solving every integration in the first flow version.
  5. Run fast feedback before mutating draft:
    • breyta flows lint --file ./flows/<slug>.clj --local-only for offline static checks
    • breyta flows lint --file ./flows/<slug>.clj --server when API context is available and canonical pre-push checks matter
    • breyta flows push --file ./flows/<slug>.clj
    • breyta flows configure check <slug> when the flow has required slots
    • breyta flows validate <slug> after push for stored draft/live validation
  6. Prove the same entrypoint a user will exercise:
    • breyta flows run <slug> --interface-id <id> --input '<json>' --wait
    • omit --interface-id when the single manual interface can be inferred
    • keep at most one manual interface; use invocation inputs for mode choices
    • use --target live or --installation-id for release/install proof
    • inspect one step with breyta runs inspect <workflow-id> --step <step-id>
      before expanding the full run payload

Stop Discovery When

  • you have current state or a clear blank-workspace signal
  • one nearby workspace/template pattern is enough
  • docs for touched primitives are known
  • the next command is an edit, lint, push, configure check, run, or resource read

Do not repeat identical search/help/docs commands unless state or the question
changed.

If development needs excessive trial/error, docs/help are misleading, a command
shape is blocked or unclear, or examples do not cover the authoring path, submit
breyta feedback send with the commands tried, URLs/workflow ids, expected path,
and the friction. This helps Breyta evaluate whether the agent loop is working.

Complex Flow Phase Gates

Complex flows should still move in small slices. Start with this authoring
playbook, then phase-load only the next surface:

  • provider/model/API call: references/provider-api-freshness.md
  • paging, fanout, child flows, waits, checkpoints, or retries:
    playbooks/advanced-reliability.md
  • persisted reports, tables, files, media, or large outputs:
    references/outputs-and-tables.md and references/runtime-data-shapes.md
  • release, install, public, Discover, or marketplace work:
    the release/public playbooks

Before source grows, define a proof ladder and reuse it across steps run and
flows run:

  • skeleton interface run with one safe input
  • one-record or one-page local JSON fixture
  • representative small batch
  • empty/failure fixture
  • live or install-shaped input

For irreversible side effects such as email, CRM writes, billing, or external
mutations, build preview/dry-run behavior, an approval wait, or an explicit
author approval checkpoint before real writes. Add idempotency keys or dedupe
guards when retries or reruns can repeat a write.

Progressive Disclosure

Use search result cards first. Open the full template/source only for:

  • cross-step architecture reuse
  • install behavior
  • parent/child or fanout structure
  • unclear dependencies
  • public/marketplace patterns

Prefer primitive snippets and only copy referenced dependencies:
:requires, :templates, :functions, packaged :steps, and :agents.

Do not open a full template definition unless snippet context is insufficient or
architecture, install behavior, fanout, child-flow structure, or unclear
dependencies require it.

For step config questions, use field lookup before opening a full reference:

  • breyta docs fields http for a compact config-object overview
  • breyta docs fields http response-as persist retry --format json for selected
    fields
  • breyta docs fields files source paths --section read when a step page has
    operation-specific tables
  • breyta docs show reference-step-http --section "Canonical Shape" only when
    the field rows are not enough

Single-Step Development

Use single-step commands to reduce full workflow reruns while developing a
touched primitive:

  • breyta steps run --type <type> --id <id> --params '<json>'
  • breyta steps run --flow <slug> --source draft --type <type> --id <id> --params '<json>'
  • breyta steps run --flow <slug> --source draft --type <type> --id <id> --params-file ./params.json
  • breyta steps record --flow <slug> --source draft --type <type> --id <id> --params '<json>'

Use --flow when the step depends on flow-local :templates, :functions,
:requires, packaged :steps, or installation bindings. Use --source draft
while iterating on a just-pushed draft; use --source active or --version <n>
when verifying released behavior. Add --installation-id <id> when slot-backed
connections should resolve as they will for an installed run.

Use inline --params '<json>' for small inputs. Switch to --params-file when
the payload is long, reused, or easier to edit outside the command line. Build
the params from the smallest input map that exercises the touched primitive.
Good candidates are pure functions, HTTP/API request shape, LLM prompt shape,
file/resource read/write payloads, and notification payloads. Use care with real
side effects, waits, fanout, child flows, callbacks, and params mostly produced
by previous pipeline state.

steps run accepts JSON but normalizes safe step-config keys to the authored
Clojure shape. For example, responseAs becomes :response-as and
persist.type can become :persist {:type :blob}. HTTP payload surfaces such
as headers, query, body, json, and form keep their exact external key
shape.

steps run returns compact output by default: data.resultPreview.value is an
EDN-style preview of the value as it would appear in a downstream let binding.
Use --result-path rows.0 or --result-path '[:rows 0]' to focus one branch,
--preview-depth, --preview-items, and --preview-runes for bounded
expansion, --result-file ./tmp/result.json to keep the full value locally, and
--full only when the complete data.result belongs in context.

Isolated step runs and stored step test verifies are real executions for
accounting: they authorize against workspace billing state, create an audit
workflowId, and count completed or failed step attempts toward step usage.

Single-step proof is not final proof. After the primitive works, push and run
the authored flow interface with the intended target, input, bindings, and side
effect path.

Interfaces First

New callable flows should use :interfaces and :invocations. --trigger-id
is legacy compatibility. For manual smoke runs, prefer --interface-id <id> so
the CLI exercise matches the authored user entrypoint.

Persist And Resource Refs

Default to :persist for unknown or unbounded payloads: exports, paged API
responses, files, transcripts, generated media, long Markdown, or row sets.

Choose blob tier deliberately: retained/default for durable or user-visible
artifacts; :tier :ephemeral on streaming :http steps for temporary downloads,
exports, generated media, and response blobs. Function/table/KV persists remain
retained/default today.

Persisted step results are compact refs. Downstream steps should pass refs
through maps and explicitly hydrate only where needed, for example a function
step with :input {:resp http-step-result} and :load [:resp].

Function Shape

Most runtime values are already Clojure maps. Keep :function steps small:

  • use get, get-in, select-keys, update, mapv, and destructuring
  • use json/parse and json/write-str for JSON
  • use breyta.sandbox/* helpers for common safe utilities
  • avoid large custom parser/guard layers unless external input is truly ambiguous

Installable Mindset

Assume a new or edited flow may become installable later:

  • keep workspace-specific ids, user ids, secrets, emails, private URLs, and model
    choices out of source defaults
  • put installer/user-specific values in :requires, setup inputs, run inputs,
    connections, or resources
  • split child flows or packaged steps when isolated testing and reuse are clearer
    than one large orchestration
  • keep :flow focused on orchestration; reusable structure belongs in
    :requires, :templates, :functions, packaged :steps, and reusable
    :agents
  • grouping is mutable display metadata, not source. Verify groupFlows with
    breyta flows list --pretty or breyta flows show <slug> --pretty; runtime
    linkage still comes from flow/call-flow, :fanout, or another primitive

References

As of May 21, 2026