Skip to main content

Composing the Rail

The rail is the ordered sequence of stages that defines a Spec. You compose it visually in the Spec editor, or set it through the API. When you run the Spec, the rail compiles deterministically into the pipeline phases the engine executes. The rail is a faithful description of the run: the compiler preserves order and stage configuration, so what you see in the editor is exactly what the engine does.

A typical rail reads left to right as the document journey: Source (where documents come from), Field Registry (deterministic transfer), Extraction (AI capture of gaps), Resolution (Data Policy normalization), Validation (quality checkpoints), and a terminal Data Product. Beyond that core, the rail carries first-class stages for Matching (decisive reference linkage), Agent (via MCP) (external-agent field filling — placed after Assembly it becomes Agentic Review), and Assembly (post-run composition). You add only the stages you need. The minimum runnable rail is a single extraction stage; everything else is optional configuration layered on top.

Rail stage types

ParameterTypeDescription
schemaextractionThe extraction stage. Compiles to the Extraction phase that runs Claude over gap fields. The minimum runnable rail is a single schema stage.
registrytransferField Registry transfer. Compiles to the Transfer phase that fills cells deterministically from known field occurrences at no AI cost.
resolveresolutionResolution. Carries json.policy_ids; compiles to one resolution phase per active Data Policy, applied in order.
validcheckpointA positional validation checkpoint. Carries json.stage_ids (member gates) and optional json.target_phases. Validates the output of the stages before it.
reconcilematchingThe Matching stage. Bound to a matcher stage via json.matcher_stage_id, it compiles to a per-document matching phase at its rail position with a decisive verdict (auto_match, shortlist, or no_match). Unbound, it emits no phase.
agentagentAgent (via MCP). Before Assembly it compiles to a per-document agent phase that parks the document as a task for an external agent; after Assembly it becomes Agentic Review, running once per composed record and writing canonical cells.
assemblycomposePost-run compose. Carries json.grouping_field and json.anchor_field, and compiles only when both are set. Always runs last, once every document is terminal, regardless of its rail position.
source / delivermarkerComposition markers for where documents enter and where the data product is delivered. They frame the rail; the per-document phases sit between them.

Each stage points at server-backed configuration rather than carrying its own copy of the data. A resolve stage references the Data Policies bound to the schema by ID. A valid stage references validation gates configured through the validation-stages endpoints. A reconcile stage references its matcher stage by ID. An assembly stage names the grouping and anchor fields. This indirection keeps the rail small and means editing a policy or a gate updates every Spec that uses it, with no rail rewrite.

Compiling the rail produces phases from a seven-type union: transfer, extraction, resolution, agent, validation, assembly, and matching. A few authoring stages expand rather than mapping one-to-one: a switch stage (Extraction with Routing) compiles to one extraction phase per lane and suppresses the plain full extraction; business_rules and decide stages are authoring conveniences that expand into validation checkpoints before compile. And position changes meaning: a resolve, valid, or agent stage dragged after the Assembly node becomes a pipeline-scoped tail step over the composed records instead of a per-document phase.

The agent stage carries its own configuration: the input fields snapshotted into each task, the output fields the agent is expected to fill (each with a data type and required flag), free-text instructions, and an agent binding naming which API key or OAuth client may claim the tasks. A lease keeps a claimed task exclusive (default 15 minutes, renewed by heartbeat), and a timeout (default 24 hours) decides what happens to a task nobody completes: hold the document, skip the stage, or route the fields to review. An autonomy block bounds what the agent may do, from observe-only, through propose (every output lands as a pending approval), to autonomous writes gated by a confidence floor.

Setting the rail via API

Set the rail with a PUT to the schema rail endpoint. Pass an array of stages; an empty array clears the rail. The example below composes a four-stage rail: registry transfer, extraction, resolution against one policy, and a validation checkpoint that covers the extraction output.

Compose a rail
curl -X PUT https://api.talonic.com/v1/schemas/sch_delivery_notes/rail \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "rail": [
      { "type": "registry", "name": "Field Registry" },
      { "type": "schema", "name": "Extraction" },
      { "type": "resolve", "name": "Normalize",
        "json": { "policy_ids": ["pol_dates_amounts"] } },
      { "type": "valid", "name": "Checks",
        "json": { "stage_ids": ["vs_required_fields"] } }
    ]
  }'
Minimal runnable rail
curl -X PUT https://api.talonic.com/v1/schemas/sch_quick_start/rail \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "rail": [ { "type": "schema", "name": "Extraction" } ] }'
# One extraction stage is enough to run. An empty rail array clears the rail.
A minimal runnable rail is a single extraction stage: {"rail":[{"type":"schema","name":"Extraction"}]}. Add a registry stage in front to fill known fields for free, a resolve stage to normalize values, and one or more valid checkpoints to gate quality. The order you set is the order the engine runs.

Frequently asked questions

What stages can a rail contain?+
The compiler understands source, registry (transfer), schema (extraction), switch (one extraction phase per routing lane), resolve (resolution, one phase per policy), valid (positional validation checkpoint, with business_rules and decide expanding into it), reconcile (matching), agent (Agent via MCP, or Agentic Review after Assembly), assembly (post-run compose), and deliver. The compiled phase types are transfer, extraction, resolution, agent, validation, assembly, and matching; assembly and the post-assembly tail run once after all documents finish.
What is the minimum rail I can run?+
A single extraction stage: {"rail":[{"type":"schema","name":"Extraction"}]}. That compiles to one Extraction phase and runs the documents through Claude with registry context. Everything else (transfer, resolution, validation, assembly) is optional and added in the order you want it to run.
How do rail stages reference policies and gates?+
Stages point at server-backed config by ID rather than embedding it. A resolve stage carries json.policy_ids referencing Data Policies; a valid stage carries json.stage_ids referencing validation gates. Editing the underlying policy or gate updates every Spec that references it without rewriting the rail.
Does the order of rail stages matter?+
Yes. The rail order is the execution order. A validation checkpoint validates the cumulative output of the stages before it, so a checkpoint after Resolution sees resolved values, while one after Extraction sees raw extraction. Place transfer before extraction so known fields are filled for free before the AI runs.