Schema
Quick Reference Cheat Sheet
Quick Reference Cheat Sheet
One-page syntax summary for experienced ladder authors. Every primitive, every keyword, every shorthand. Bookmark this.
Top-level config
yaml
name: My Ladder # required
allowedTargets: { strategy: universal } # or { strategy: constrained, providers: [...], models: [...] }
exit: answer # required — step ID returned to caller
knobs: { ... } # required — can be empty {}
steps: [ ... ] # required — at least one
description: "..." # optional
slates: [ ... ] # optional — persistent memory
executionBudget: { ... } # optional — resource ceilings
trace: { mode: reasoning, allSteps: false } # optionalSteps
yaml
# Normal (parallel, default)
- id: generate
type: normal # optional — default
nodes: 5 # or knob ref: branches or "{{knobs.branches}}"
fields: [ ... ]
systemPrompt: "..."
if: { ... } # optional gate
recursion: { maxDepth: 3 } # optional
slateWrite: { ... } # optional
retrieve: { ... } # optional
dynamic: true # optional — loads config from "from:"
from: previous # source for dynamic config
timeline: circle # or "init"
# Sequential (ordered chain)
- id: refine
type: sequential
nodes: 3
fields:
- { name: Previous, type: ingest, from: { stepId: refine, loopRef: current, nodeRef: previous }, skipFirstNode: true }
# Group (parallel sub-steps, cannot nest)
- id: reviewers
type: group
steps:
- id: security
fields: [ ... ]
- id: style
fields: [ ... ]Fields (7 types)
yaml
fields:
# text — from runtime inputs
- { name: Q, type: text, from: input.context }
# ingest — one node output from a prior step
- { name: Draft, type: ingest, from: { stepId: draft, loopRef: current, nodeRef: current } }
# multi_ingest — multiple node outputs joined
- { name: All, type: multi_ingest, from: [{ stepId: gen, loopRef: current, nodeRef: accumulate }] }
# nodeInfo — current node number (1-indexed)
- { name: Num, type: nodeInfo }
# knobInfo — resolved knob value
- { name: Count, type: knobInfo, from: branches }
# slateRead — file or metatag from persistent memory
- { name: Facts, type: slateRead, from: { slate: Memory, folder: facts, file: core.md }, fallback: "" }
# manifest — runtime snapshot for dynamic steps
- { name: Available, type: manifest }
# Fallback (all types except nodeInfo/manifest/knobInfo)
- { name: X, type: text, from: input.context, fallback: "default" }loopRef: current | previous | accumulate | number
nodeRef: current | previous | accumulate | omitted
Gates (if/then/else)
yaml
# Shorthand (equals + defaults)
if: "READY"
# Full form
if:
integerRange: [4, 5]
then: continue # default
else: { jump: { stepId: refine } } # default: abort
# Conditions (12 keys):
# equals: "string"
# integerEquals: 5
# integerRange: [4, 5]
# numberEquals: 0.95
# numberRange: [0.7, 1.0]
# contains: "VERDICT: ACCEPT"
# in: ["yes", "Y", "accept"]
# jsonMatches: { JSON Schema }
# matches: "(?i)\bPASS\b" # RE2 regex (partial match)
# and: [{ contains: "X" }, { matches: "\d" }] # all must pass
# or: [{ equals: "yes" }, { equals: "Y" }] # any must pass
# not: { contains: "ERROR" } # negation
# Actions (4 types):
# continue
# abort
# { jump: { stepId: "x" } } # within-ladder
# { jump: { ladderId: "@author/name" } } # cross-ladder
# { jump: { ladderId: "@author/name", stepId: "step3", passFields: [...] } }
# { write: { to: { slate, folder, file }, from: previous, on: append } }
# Legacy (still supported):
continueIf: "READY" # desugars to if: { equals: "READY" }Memory (slates, writes, retrieve)
yaml
# Slate declaration
slates:
- title: Memory
folders:
- name: facts
tokenLimit: 500
evictionPolicy: FIFO # FIFO | LRU | reject
metatags:
- { name: category, type: string }
files:
- { name: core.md, init: blank }
# Metatag types: string | string[] | number | boolean | object
# slateWrite (schema-matched, on step)
slateWrite:
to: { slate: Memory, folder: facts, file: core.md }
field: fact # extract one field before writing
on: append # append | overwrite | mergeByKey
key: id # for mergeByKey only
match: { type: object, required: [fact] }
# Gated write (under if/then)
then:
write:
to: { slate: Memory, folder: trace, file: latest.md }
from: previous # previous | output | "input.X" | { stepId } | { slate } | "literal"
on: overwrite
fallback: previous # optional
# Retrieve (on-demand fetch loop)
retrieve:
to: { slate: Knowledge, folder: docs }
as: RetrievedDocuments
maxRounds: 3
requestMatch: { type: object, properties: { files: { type: array } } }
# Retrieval modes: files | subfolders | metatag | globKnobs
yaml
knobs:
# Slider (discrete choices)
branches:
name: Branches
type: nodes # nodes | loops | recursion | generic
input: slider
steps:
- { title: Fast, value: 3, default: true }
- { title: Wide, value: 5 }
# Numerical (continuous range)
threshold:
name: Threshold
type: generic
input: numerical
default: 0.8
min: 0.0
max: 1.0
# Usage in steps:
# nodes: branches # shorthand
# nodes: "{{knobs.branches}}" # template form
# recursion: { maxDepth: "{{knobs.depth}}" }
# knobInfo field: { name: T, type: knobInfo, from: threshold }Budget and ceilings
yaml
executionBudget:
maxSpend: 5.0 # dollars (default: $5, max: $50)
maxHops: 200 # loops+jumps+recursion (default: 200, max: 10000)
maxLlmCalls: 500 # total API calls (default: 500, max: 5000)
maxRecursion: 5 # depth (default: 5, max: 20)On ceiling hit: graceful exit with best-so-far output. No error to caller.
Budget inheritance: cross-ladder children share parent's remaining budget.
Resource budget (engine defaults): maxLoops=50, maxNodesPerStep=20, maxRecursionDepth=5, maxTotalLlmCalls=500.
Events (16 types)
text
pipeline_start loop_start step_start step_complete
step_paused loop_complete recursion_start recursion_complete
handoff_start handoff_complete pipeline_complete pipeline_resumed
node_count_resolved node_survivors node_failed errorKey event data:
node_survivors:{ requestedNodes, survivingNodes, survivingNodeNumbers }node_count_resolved:{ requested, clamped, limit }error:{ message, ceiling_exceeded?, nonFatal? }