Redeo Docs
DocsLADR / FromSpec: The Source Vocabulary

Reads & Writes

FromSpec: The Source Vocabulary

FromSpec: The Source Vocabulary

FromSpec is the unified source vocabulary used by gated writes, dynamic step loading, retrieve result injection, and passFields. One way to specify a source, everywhere. Six forms cover all cases: keywords (previous, output), input keys (input.X), literals, step references, and slate references.

The six forms

FromSpec appears as the value of from: in write actions, dynamic step declarations, and passFields. Six forms are accepted:

FormExampleWhat it resolves to
previous (keyword)from: previousAll survivors of the immediately preceding step
output (keyword)from: outputThe current step's own combined output
input.X (input key)from: "input.context"A value from the runtime inputs map
literal stringfrom: "No data available"The literal string itself
step referencefrom: { stepId: "draft", nodeRef: current }A specific step's output (optionally a specific node)
slate referencefrom: { slate: "Memory", folder: facts, file: core.md }Contents of a slate file or metatag
yaml
# Keyword: previous step's survivors
then:
  write:
    to: { slate: "Memory", folder: trace, file: latest.md }
    from: previous

# Keyword: current step's output
then:
  write:
    to: { slate: "Memory", folder: results, file: current.md }
    from: output

# Input key
then:
  write:
    to: { slate: "Memory", folder: queries, file: log.md }
    from: "input.context"

# Literal string
then:
  write:
    to: { slate: "Memory", folder: notes, file: marker.md }
    from: "--- Execution boundary ---"

# Step reference
then:
  write:
    to: { slate: "Memory", folder: drafts, file: best.md }
    from: { stepId: generate, nodeRef: current }

# Slate reference
then:
  write:
    to: { slate: "Memory", folder: backup, file: copy.md }
    from: { slate: "Memory", folder: drafts, file: best.md }

Keywords: previous and output

Two bare-string keywords have special meaning:

previous resolves to the combined output of the step immediately before the current one in execution order. This is the step that ran just before the current step in the pipeline loop.

yaml
# Write the previous step's output to a slate
then:
  write:
    to: { slate: "Memory", folder: trace, file: latest.md }
    from: previous
    on: overwrite

output resolves to the current step's own combined output (all surviving nodes joined with double newlines). This is mainly used in gated writes under if/then — the write fires after the gate evaluates, so output is the step's output that was just evaluated.

yaml
# If the gate passes, write this step's output to memory
if:
  jsonMatches: { properties: { confidence: { minimum: 0.8 } } }
  then:
    write:
      to: { slate: "Memory", folder: facts, file: verified.md }
      from: output
      on: append

Both keywords are only meaningful in the context of a write action or passField — they refer to runtime execution state, not config-time declarations.

Input keys: input.X

Any bare string starting with input. is treated as an input-key lookup. The runtime resolves it against the execution's inputs map.

yaml
# Write the original user question to a slate
from: "input.context"

# Write the system time
from: "input.systemTime"

Common input keys:

KeyContents
input.contextThe user's message (the last user role message from the API call)
input.systemTimeThe current UTC time in ISO 8601 format
input.localTimeThe local time (when a timezone was supplied)
input.timezoneThe timezone string (when supplied)

Missing input keys resolve to an empty string — no error. This makes input.X safe to use in fallback positions.

Step references

An object with stepId resolves to a specific step's output. Optionally narrow to a specific node or node reference.

yaml
# Read a specific step's combined output
from: { stepId: generate }

# Read a specific node (by number)
from: { stepId: generate, node: 3 }

# Read the current node's output from a specific step
from: { stepId: generate, nodeRef: current }

# Read the previous node's output
from: { stepId: generate, nodeRef: previous }

nodeRef values:

  • current — the node number matching the current execution context (e.g., node 3 of step A reads node 3 of the referenced step).
  • previous — the node before the current one. If the current node is 1, falls back to node 1.
  • accumulate — all nodes of the referenced step, joined. Only valid in multi_ingest fields, not in FromSpec.

node vs nodeRef: node takes a specific integer (read node 3 regardless of context). nodeRef takes a keyword that resolves relative to the current execution context.

Slate references

An object with slate resolves to a slate location. This lets one write copy content from one slate location to another.

yaml
# Copy a file's contents
from: { slate: "Memory", folder: drafts, file: best.md }

# Read a metatag value
from: { slate: "Memory", folder: drafts, file: best.md, metatag: score }

If no file is specified, the reference is invalid for FromSpec (slate references require a file). For folder-level reads (indexes, trees), use the slateRead field type with system metatags instead.

Fallback in FromSpec contexts

Several FromSpec-consuming declarations also accept a fallback: field. When the primary from: resolves to an empty value or a source-missing error, the fallback is consulted.

yaml
# Gated write with fallback
then:
  write:
    to: { slate: "Memory", folder: trace, file: latest.md }
    from: { stepId: optional_step }       # might not have run
    fallback: previous                     # fall back to previous step's output
    on: overwrite

# Dynamic step with fallback
- id: dynamic_step
  dynamic: true
  from: { stepId: planner }                # planner's output is the config
  fromFallback: "input.context"            # if planner didn't run, use the input

Fallback resolution uses the same FromSpec vocabulary. The fallback chain is one level deep — there is no fallback-of-fallback. If both primary and fallback miss, the resolved value is empty.

Fallback is consulted when:

  • The primary source resolves to an empty string.
  • The primary source raises a NodeDependencyError (the referenced step didn't run or the node doesn't exist).

Other errors (slate store unavailable, JSON parse failures) propagate without consulting the fallback.