Schema
YAML Schema Reference
YAML Schema Reference
Authoritative schema for LADR ladder configs. Every field, every type, every default.
Top-level fields
The root config object. Saved as a .ladr file (YAML) or transmitted as JSON.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | yes | Human-readable display name. | |
description | string | no | "" | One-line description shown in library listings. |
allowedTargets | object | yes | Model access policy. See below. | |
exit | string | yes | ID of the step whose output is returned. | |
knobs | map<string, Knob> | yes | {} | Caller-tunable controls. May be empty. |
steps | array<Step> | yes | The step sequence. Minimum 1 step. | |
slates | array<SlateDecl> | no | [] | Persistent memory declarations. |
executionBudget | object | no | platform defaults | Resource ceilings. |
trace | object | no | Trace config (advanced). |
Set by the platform at publish time (NOT in author YAML): author, version, visibility. The runtime strips these on save. (id is a valid author-set field but is normally platform-assigned on first publish; subsequent versions preserve the assigned id.)
allowedTargets shape:
# Universal; accept any model the caller passes.
allowedTargets: { strategy: universal }
# Constrained; only listed providers/models accepted.
allowedTargets:
strategy: constrained
providers: [openai, anthropic]
models: [gpt-4o, claude-sonnet-4-20250514]Knob schema
Knobs are caller-tunable controls. The map key is the knob's identifier.
knobs:
branches: # knob id (map key)
name: Branches # display name
type: nodes # semantic category
input: slider # UI input kind
steps: # slider input: discrete ticks
- { title: Low, value: 3, default: true }
- { title: Mid, value: 5 }
- { title: High, value: 7 }
rounds: # another knob
name: Rounds
type: loops
input: numerical # numerical input: continuous range
default: 2
min: 1
max: 4| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Display name shown in Studio/Foundry. |
type | enum | yes | Semantic category. One of: loops, recursion, nodes, generic. Used by the engine for cap enforcement and by the UI for grouping. |
input | enum | yes | UI kind. One of: slider, numerical. |
steps | array | yes (slider) | Slider ticks: [{ title, value, default? }]. Exactly one tick should have default: true. |
min, max | number | yes (numerical) | Inclusive bounds. |
default | number | no (numerical) | Default value if caller doesn't override. Falls back to min if omitted. |
Knob categories (type):
| Type | What it semantically controls |
|---|---|
nodes | Branch count / fanout. Engine uses this to cap concurrent LLM calls. |
loops | Loop iteration count. Engine uses this for hop budgeting. |
recursion | Recursion depth. Engine uses this for recursion-depth ceiling. |
generic | Anything else (thresholds, temperatures, ratios). |
The category doesn't constrain where you reference the knob; it's metadata for the engine + UI. Reference any knob value anywhere a number/string template is accepted.
Step schema
Three step types: normal (parallel nodes), sequential (nodes run one after another), group (sibling steps running side by side).
steps:
- id: draft # required, unique
name: Draft # required
type: normal # required: normal | sequential | group
nodes: 5 # optional: number | "template" | { from: ... }
fields: # optional but usually present
- { name: Context, type: text, from: "input.context" }
systemPrompt: "..." # optional
timeline: circle # optional: circle | init
recursion: { maxDepth: 3 } # optional
checkpoint: { ... } # optional (advanced)
if: { ... } # optional: gate (see Control Flow)
slateWrite: { ... } # optional: schema-matched write (see Writes)
retrieve: { ... } # optional: bounded fetch (see Retrieve)
dynamic: false # optional: load config at runtime
from: previous # optional: used when dynamic: true
onInvalid: continue # optional: fallback when dynamic load fails
# Group step; parallel siblings.
- id: parallel_review
name: Parallel Review
type: group
steps:
- { id: security, type: normal, ... }
- { id: style, type: normal, ... }| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Step identifier. Unique within the ladder. |
name | string | yes | Display name. |
type | "normal" | "sequential" | "group" | yes | Step type. |
nodes | number | string | object | no | Node count. Number, knob-template string ("{{knobs.branches}}"), or { from: ... }. Default 1. Groups don't accept nodes. |
fields | array<Field> | string | no | Field declarations. May be omitted for steps that don't need prompt fields. String form is a clone reference (advanced). |
systemPrompt | string | no | The system instruction appended to the assembled prompt. |
continueIf | string | no | DEPRECATED; alias for if: { equals: "..." }. |
timeline | "circle" | "init" | no | Render hint for Studio/Foundry timeline. |
recursion | object | no | { maxDepth: number | "{{knobs.x}}" }. |
if | object | string | no | Gate. See Control Flow. |
slateWrite | object | no | Schema-matched write. See Reads & Writes. |
retrieve | object | no | Bounded fetch. See Retrieve. |
dynamic | boolean | no | If true, the step loads its config from from: at runtime. See Dynamic Steps. |
from | string | object | no | Source spec; used when dynamic: true. Same vocabulary as writes. |
onInvalid | action | no | Fallback action when a dynamic step's loaded config fails validation. Default abort. |
Field schema
Each field has a name (rendered as a label in the prompt), a type (one of seven), and a from source whose shape depends on type.
fields:
# Text; reads input or a literal.
- { name: Context, type: text, from: "input.context" }
# Ingest; single step's matching node (parallel alignment).
- name: Draft
type: ingest
from: { stepId: draft, loopRef: current }
- name: Earlier Draft
type: ingest
from: { stepId: final, loopRef: previous, nodeRef: current }
# Multi-ingest; many node outputs joined into one string.
- name: Evaluations
type: multi_ingest
from:
- { stepId: evaluate, loopRef: current, nodeRef: accumulate }
# Node info; runtime injects the current node number.
- { name: Branch Number, type: nodeInfo }
# Knob info; runtime injects the knob's current value.
- { name: Total Branches, type: knobInfo, from: branches }
# Slate read; file contents, metatag, or system metatag (index/tree).
- name: Core
type: slateRead
from: { slate: "Project Memory", folder: facts, file: core.md }
- name: Tags
type: slateRead
from: { slate: "Project Memory", folder: facts, metatag: tags }
- name: Tree
type: slateRead
from: { slate: "Project Memory", folder: facts, metatag: tree, depth: 2 }
# Manifest; runtime injects the full available-source snapshot (for dynamic steps).
- { name: Available, type: manifest }type | from shape | Required from? |
|---|---|---|
text | string (e.g. "input.context") | yes |
ingest | { stepId, loopRef, nodeRef? } | yes |
multi_ingest | [{ stepId, loopRef, nodeRef? }, ...] | yes |
nodeInfo | (none; runtime injects) | no |
knobInfo | string; the knob name (e.g. "branches") | yes |
slateRead | SlateTarget ({ slate, folder, file?, metatag? }) + optional depth | yes |
manifest | (none; runtime injects) | no |
loopRef is required on ingest/multi_ingest sources and is one of:
"current"; current loop iteration only."previous"; previous loop iteration."accumulate"; all prior loop iterations concatenated.- A number (e.g.
0,1); absolute loop index.
nodeRef is optional and is one of: "current", "previous", "accumulate".
if (gate) schema
# Shorthand; exact string equality, then continue, else abort.
if: "1"
# Full form; condition + then/else actions.
if:
<conditionKey>: <value>
then: <action> # default: continue
else: <action> # default: abortCondition keys (exactly one per if):
| Key | Value | What it checks |
|---|---|---|
equals | string | Exact string match. |
integerEquals | integer | Output parsed as int, compared equal. Tolerates trailing .0. |
integerRange | [a, b] | Output as int, must be in inclusive [a, b]. |
numberEquals | number | Output as float, compared equal (epsilon tolerance). |
numberRange | [a, b] | Output as float, in inclusive range. |
contains | string | Substring match. |
in | array<string> | Output is one of the listed strings. |
jsonMatches | JSON Schema | First JSON block extracted from output, validated against the schema. |
Actions (under then or else):
| Form | Behavior |
|---|---|
continue | Proceed normally. Per-node on multi-node steps; preserves ToT pruning. |
abort | Stop ladder execution. Default for else. |
{ jump: { stepId: "X" } } | Within-ladder jump. |
{ jump: { ladderId: "@author/name" } } | Cross-ladder handoff. |
{ jump: { ladderId: "@author/name", stepId: "X" } } | Cross-ladder to a specific step. |
{ write: { to, from, on? } } | Gated slate write. |
See Control Flow and Jumps for full semantics.
Slate schema
| Field | Type | Required | Description |
|---|---|---|---|
title | string | yes | Slate identifier. Unique within the ladder. |
folders | array<FolderDecl> | yes | One or more folders. See Slates. |
Folder:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | yes | Folder name. Unique within the slate. | |
tokenLimit | integer | yes | Per-file token budget. | |
access | "readWrite" | "read" | no | readWrite | Folder-level access policy. No write-only. |
evictionPolicy | "FIFO" | "LRU" | "reject" | no | FIFO | What happens when a write exceeds tokenLimit. |
metatags | array<Metatag> | no | [] | Folder-level schema; applies to ALL files. |
files | array<FileDecl> | no | [] | Pre-declared files. Engine can create more on write. |
File:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | yes | File name. Unique within folder. | |
init | "blank" | string | no | "blank" | Initial content. "blank" = empty; any other string = literal initial content. |
metatags | array<Metatag> | no | [] | File-level schema extensions. |
Metatag:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Metatag identifier. |
type | "string" | "string[]" | "number" | "boolean" | "object" | yes | Value type. |
schema | JSON Schema | no | Required when type: "object". Inline schema for object metatags. |
Effective schema for a file = folder.metatags ∪ file.metatags (union; file-level wins on conflicts).
slateWrite + from: schema
Two write mechanisms. Schema-matched (opportunistic, step-level) and gated (explicit, under if/then).
Schema-matched (slateWrite):
slateWrite:
to: { slate: "Memory", folder: facts, file: core.md }
field: fact # optional: extract one field from validated JSON
on: append # optional: append | overwrite | mergeByKey (default: append)
key: id # required for mergeByKey: field name INSIDE JSON objects
atomic: true # optional: array writes are all-or-nothing
match: # required: JSON Schema for validation
type: object
required: [fact, confidence]
properties:
fact: { type: string, minLength: 1 }
confidence: { type: number, minimum: 0, maximum: 1 }
additionalProperties: falseAfter the step runs, the engine extracts the first JSON block from the LLM output, validates against match, and on success writes per on/field/key. On failure: no-op, not error. Is a silent no-op (no error, no event).
Gated write (under if/then):
if:
equals: "RECORD"
then:
write:
to: { slate: "Memory", folder: facts, file: core.md }
from: previous # write all survivors of preceding step
on: append # default
else: continuefrom: accepts the unified source vocabulary:
| Form | Meaning |
|---|---|
previous | All survivors of the immediately preceding step. Engine formats based on target type (\n\n-joined for text/file contents; JSON array for array-typed metatags). |
output | The current step's own output. |
"literal text" | A literal string. |
{ stepId: "X" } | All survivors of step X. |
{ stepId: "X", nodeRef: "current" } | Per-node routing: writer node N ← source node N. |
{ stepId: "X", node: 3 } | One specific node by index. |
{ slate: "...", folder: "...", file?: "..." } | Slate reference (cross-slate writes). |
See Reads & Writes for parsing rules and composition patterns.
executionBudget schema
| Field | Type | Required | Default | Platform max | Description |
|---|---|---|---|---|---|
maxSpend | number | no | 5.0 | 50.0 | Dollar spend cap per execution. |
maxHops | integer | no | 200 | 10,000 | Total hops (loops + jumps + recursion). |
maxLlmCalls | integer | no | 500 | 5,000 | Total LLM API calls. |
maxRecursion | integer | no | 5 | 20 | Maximum recursion depth. |
All fields are optional pointers; omitting one means "use platform default." Validation rejects values > platform max or ≤ 0. See Execution Budget.