Introduction
What is LADR?
What is LADR?
LADR (Language for Adaptive Deliberation and Reasoning) is a declarative YAML dialect for writing multi-step reasoning programs. A LADR program is called a ladder. A ladder declares the steps to execute, the data dependencies between them, the control flow that gates or redirects execution, the memory model that persists state across calls, the knobs callers can tune, and the resource ceilings the runtime enforces. The author writes the structure; the runtime executes it.
What LADR is for
Inference-time techniques — chain-of-thought, tree-of-thoughts, reflexion, self-consistency, and others — structure how a model reasons across multiple calls. LADR is the declarative language for writing those structures down.
LADR sits between the model and the application. The author declares a reasoning strategy in YAML; the runtime engine executes it, managing parallel dispatch, gating, jumps, memory, and budget enforcement.
What LADR is not:
- Not a general-purpose programming language. It is declarative, analyzable, and bounded. Every primitive is first-class and resource-accountable.
- Not a framework or library. It is a language, a runtime, a memory model, and a hosting platform.
- Not a model wrapper. It orchestrates calls to any model the caller supplies.
Properties of a ladder
A LADR ladder makes the structure of a multi-step reasoning program explicit and machine-analyzable. Because a ladder is a declarative document rather than application code, it has properties that hand-rolled orchestration typically lacks:
- Inspectability. Every ladder is a YAML file. You can read it, diff it, version it, render it visually, lint it.
- Analyzability. The runtime knows what fields a step will read, what steps a jump can target, what slates a write will hit. Validation catches mistakes before a single LLM call runs.
- Publishability. A ladder is data, not code. It can be listed in a directory, forked, priced, embedded as structured data on a crawlable page.
- Composability. Cross-ladder jumps turn published ladders into building blocks. One ladder can hand off to another mid-execution.
- Bounded cost. Every execution runs under a spend cap. A published ladder cannot exceed its declared budget.
For a comparison to LangChain, DSPy, raw API calls, and prompted reasoning models, see LADR vs. Alternatives.
What a ladder looks like
A minimal two-step ladder that drafts an answer and refines it:
name: Draft and Refine
allowedTargets:
strategy: universal
exit: refine
knobs: {}
steps:
- id: draft
name: Draft
fields:
- { name: Question, type: text, from: input.context }
systemPrompt: "Answer the question. Output only the answer."
- id: refine
name: Refine
fields:
- name: Draft
type: ingest
from: { stepId: draft, loopRef: current }
systemPrompt: "Improve the given draft. Fix errors, tighten prose, preserve facts."Execution trace:
- Caller sends
POST /v1/{author}/draft-and-refine/chat/completionswithmessages: [{role: "user", content: "..."}]. - Runtime resolves
input.contextto the last user message. draftruns: dispatches one LLM call with the assembled prompt. Output is stored as node 1 of stepdraft.refineruns: ingests the draft output via theDraftfield, dispatches one LLM call. Output is stored as node 1 of steprefine.- Because
exit: refine, the runtime returns the refine output to the caller in OpenAI Chat Completions format.
Two LLM calls. Total wall time is the sum of both call latencies (steps run sequentially unless explicitly parallelized). No gates, no slates, no knobs. This is the smallest useful ladder.
The root object
A ladder is a single YAML document with a fixed schema. The root object has ten fields, of which five are required.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Human-readable ladder name. |
allowedTargets | object | yes | Provider/model strategy. { strategy: universal } or { strategy: constrained, providers: [...], models: [...] }. |
exit | string | yes | The step ID whose output is returned to the caller. |
knobs | object | yes | Map of knob ID to knob declaration. Can be empty ({}). |
steps | array | yes | Ordered list of step declarations. At least one step must exist. |
id | string | no | Platform-assigned UUID identifier. |
description | string | no | Free-text description shown in Foundry and the directory. |
slates | array | no | Persistent memory declarations. |
executionBudget | object | no | Per-ladder resource ceilings (maxSpend, maxHops, maxLlmCalls, maxRecursion). |
trace | object | no | Trace output controls (mode, allSteps). |
The parser is strict: unknown top-level keys are rejected at parse time. Adding a new field is a grammar change, not a silent extension. Missing required fields fail parse. See Top-Level Config for the full reference.
Declarative execution
LADR separates what the ladder does (declared in YAML) from how the runtime executes it. The author never writes imperative control flow. There are no loops, conditionals, or function calls in the YAML itself; instead, the author declares the structure and lets the runtime execute it.
| Author declares | Runtime handles |
|---|---|
| Steps and their fields | Prompt assembly from declared field sources |
Node counts (nodes: 5 or nodes: branches) | Parallel dispatch of LLM calls |
Gates (if: blocks) | Condition evaluation against node outputs, per-node pruning |
Jump targets (then: { jump: { stepId: refine } }) | Cursor updates, loop iteration, cross-ladder handoff |
| Slates and metatags | Token-counted writes, eviction, schema-matched reads |
executionBudget | Spend tracking, hop counting, hard abort on ceiling breach |
| Knobs | Per-call parameter resolution with clamping |
This separation is what makes the budget guarantee enforceable. The runtime owns the loop, so the runtime can stop the loop. There is no escape hatch in the YAML that lets a ladder exceed its declared budget.
The safety model
LADR is declarative and Turing-complete. Ladders can loop, recurse, jump, and rewrite themselves at runtime via dynamic steps. Termination is not statically guaranteed (halting problem; undecidable). Instead, every execution runs under four hard runtime ceilings:
| Ceiling | Default | Per-ladder configurable via | Platform max |
|---|---|---|---|
| Spend (dollars) | $5.00 | executionBudget.maxSpend | $50.00 |
| Hops (loops + jumps + recursion) | 200 | executionBudget.maxHops | 10,000 |
| LLM calls | 500 | executionBudget.maxLlmCalls | 5,000 |
| Recursion depth | 5 | executionBudget.maxRecursion | 20 |
The spend cap is the primary safety mechanism. A ladder can loop freely, but every LLM call costs money. The runtime kills execution the moment cumulative spend crosses the cap and returns the best-so-far output. This is what allows published ladders to be invoked safely — the runtime owns the loop, so the runtime can stop it.
A ladder can lower any ceiling (always safe) or raise it up to the platform max. The grammar places no restriction on how many times you jump or how deep you recurse; the ceilings bound the worst case at a declared dollar amount.
Design principles
| Principle | Implication |
|---|---|
| YAML-only authoring. No embedded scripts, no inline code. | Anything computable must be expressible in the grammar. Complex logic is decomposed into multiple steps. |
| Strict schema. Unknown top-level keys are rejected at parse time. | Forward compatibility is opt-in. Adding a field is a schema change, not a silent extension. |
| Runtime-owned execution. Authors cannot inject arbitrary code into the dispatch path. | Resource ceilings are enforceable. A misbehaving ladder exhausts its budget, not the platform. |
OpenAI-compatible surface. Every ladder exposes POST /v1/{author}/{ladder}/chat/completions. | Any OpenAI client is a LADR client. No SDK required. |
| Explicit memory. Slates are declared, not implicit. | The author controls what persists. No invisible context stuffing. |
| Ladders are data, not code. Ladders and slates are configuration data, not programs that link to the platform. | Users publishing ladders to the directory do not need to license them AGPL; they are data, not derivative works. |
URL-as-identifier. The canonical ladder identifier is @author/name, rendered at library.redeo.io/@author/name. | Shareable and indexable. See Ladder Addressing. |
LADR's grammar is Turing-complete by design, paired with runtime caps. A more restricted grammar would force authors to flatten natural strategies into the runtime's primitive set; a Turing-complete grammar with runtime caps lets authors express a strategy and bound the worst case at a declared dollar amount.
Where to go next
Read these in order:
- The LADR Mental Model. The six ideas that make every other concept intuitive.
- Getting Started. Self-host a LADR stack in 5 minutes with Docker Compose.
- Use Cases. Workload characteristics that justify a ladder.
- LADR vs. Alternatives. Direct comparison to LangChain, DSPy, raw OpenAI calls, and reasoning models.
- Adoption Phases. How teams typically roll out LADR internally.
- Hello World. Build and run a ladder end-to-end.
- Language Overview. Top-to-bottom tour of the grammar.
- YAML Schema. Complete field reference.
If you learn better by example, start with Tutorials > Hello World and work through the Core Patterns. For a large composed example, see Examples > Reference Ladder: Crucible.