Redeo Docs
DocsLADR / Gate Actions: continue, abort, jump, write

Gates

Gate Actions: continue, abort, jump, write

Gate Actions: continue, abort, jump, write

Under then: and else:, four actions are accepted. Each action determines what the runtime cursor does after the gate evaluates. The default for then: is continue; the default for else: is abort. Jumps and writes are how gates become productive — they turn a pass/fail decision into cursor movement or persistent memory.

continue

Advance the cursor to the next step. The default for then:.

yaml
then: continue

This is the most common action. Survivors (if any) are visible to downstream steps. The cursor moves to the next step in declaration order.

yaml
- id: verify
  nodes: 5
  if:
    jsonMatches: { properties: { score: { minimum: 4 } } }
    then: continue          # survivors advance; pruned nodes disappear
    # else defaults to abort

When then: continue fires after per-node pruning, only the surviving nodes are visible to the next step. A 5-node step where 3 pass the gate means the next step sees 3 inputs (via multi_ingest: { nodeRef: accumulate }), not 5.

abort

Terminate the ladder. The exit step's output from the most recent completed loop is returned to the caller. The default for else:.

yaml
else: abort

Abort does not produce an error. The caller receives a normal OpenAI-compatible response with the best-so-far output. The trace shows the abort event so the caller can distinguish "completed normally" from "aborted by gate."

yaml
- id: safety_check
  systemPrompt: 'Output "safe" or "unsafe".'
  if:
    equals: "safe"
    then: continue          # proceed
    else: abort             # stop immediately, return best-so-far

When else: abort fires, the runtime returns the exit step's output from the previous loop iteration. If this is the first loop, the exit step may not have run yet — in that case, the output is empty or the best-so-far output from whatever step did complete.

Abort vs graceful ceiling exit. Abort is an author-declared termination. Ceiling exhaustion is a runtime-enforced termination. Both return best-so-far output without error. The difference: abort is intentional (the gate decided to stop), ceiling exhaustion is forced (the budget ran out).

{ jump: ... }

Reposition the cursor. Within-ladder jumps take a stepId; cross-ladder jumps take a ladderId (and optionally a stepId).

yaml
then: { jump: { stepId: refine } }                                   # within-ladder
else: { jump: { ladderId: "@alice/helper" } }                       # cross-ladder
else: { jump: { ladderId: "@alice/helper", stepId: "step3" } }      # cross-ladder mid-entry

Within-ladder jumps move the cursor to any step in the current ladder's steps: array. Forward jumps skip steps (early exit). Backward jumps create loops (reflexion). The hop ceiling bounds total jumps, so loops are safe.

yaml
# Reflexion loop: critique fails → jump back to draft
- id: critique
  if:
    jsonMatches: { properties: { verdict: { enum: [good] } } }
    then: continue
    else: { jump: { stepId: draft } }     # backward jump → retry loop

Cross-ladder jumps terminate the current ladder and start the target ladder via a tail-call handoff. The firing step's output becomes the target ladder's input.context. The target's exit-step output becomes the user-visible result.

See Jumps for the full reference, including passFields for wiring data into jump targets.

{ write: ... }

Write a source verbatim to a slate. No schema matching; just write the named source. Used for "if the gate passes, persist the relevant content" patterns.

yaml
then:
  write:
    to: { slate: "Memory", folder: trace, file: verified.md }
    from: previous              # all survivors of the previous step
    on: append                  # append | overwrite | mergeByKey

The from: field uses the unified source vocabulary (previous, output, { stepId, ... }, { slate, ... }, or a literal string). See Reads and Writes for the full reference.

Gated write vs slateWrite. A gated write action writes unconditionally when the gate fires — no JSON extraction or schema validation. A slateWrite block on the step extracts JSON from the output and validates against a schema before writing. Use gated writes when you want to persist raw text; use slateWrite when you want to persist only validated structured data.

yaml
# Gated write: persist survivors verbatim when gate passes
- id: verify
  if:
    jsonMatches: { properties: { score: { minimum: 4 } } }
    then:
      write:
        to: { slate: "Memory", folder: winners, file: best.md }
        from: previous
        on: append
    else: continue

# slateWrite: persist validated JSON after the step runs
- id: extract
  slateWrite:
    to: { slate: "Memory", folder: facts, file: core.md }
    field: fact
    on: append
    match:
      type: object
      required: [fact]
      properties:
        fact: { type: string, minLength: 5 }

The gated write fires only when the gate passes and writes raw text. The slateWrite runs after every execution of the step and writes only validated JSON.