How LoopX's Turn Decision Vocabulary Works: Turn Route and Turn Result Kind Explained

LoopX models every turn as a transactional workflow where the Turn Route determines which provider step executes next and the Turn Result Kind classifies the semantic outcome, with both concepts tightly coupled in the settlement engine to ensure valid state transitions.

In the LoopX control plane, turn settlement is the core mechanism that orchestrates provider-side effects and communicates results back to callers. The system uses a precise decision vocabulary built around two TypeScript constructs: LoopXTurnRoute (the ordered pipeline of provider steps) and LoopXTurnResultKind (the public enumeration of turn outcomes). This article examines how these abstractions interact in loopx/control_plane/turn_driver/settlement.ts to drive deterministic execution and outcome validation.


What Is the Turn Route in LoopX

The Turn Route is the ordered sequence of provider steps that every turn must traverse. In settlement.ts, this route is defined by the constant BASE_SETTLEMENT_STEPS at lines 33-38:

  • validation — validates the turn request
  • durable_writeback — persists the turn state
  • quota_spend — consumes quota for the operation

When a terminal close-out is required, the route extends with an additional "terminal_closeout" step.

The settlement engine computes the route dynamically at runtime using settlementNextAction. This function inspects completed_phases against BASE_SETTLEMENT_STEPS to determine the next provider effect to prepare or execute. The route is therefore deterministic: given the same completion state, the engine always selects the same next step.

import { settlementNextAction } from "./loopx/control_plane/turn_driver/settlement.ts";

const next = settlementNextAction({
  identity,
  ordered_steps: ["validation", "durable_writeback", "quota_spend"],
  committed_payloads: { validation: {}, durable_writeback: null, quota_spend: null },
  completed_phases: [],
  transaction_phases: ["validation", "durable_writeback", "quota_spent"],
  require_validation: true,
  source_ref_prefix: "turn_journal",
});

console.log(next.step_kind);  // → "validation"

What Is the Turn Result Kind

The Turn Result Kind is a public enumeration of semantic outcomes that a turn can report. Defined at lines 49-63 in settlement.ts, the constant TURN_RESULT_KINDS exposes valid values typed as TurnResultKind. These include:

  • "validated_progress" — turn made forward progress
  • "validated_completion" — turn finished successfully
  • "validation_failed" — validation rejected the request
  • "host_failure" — unrecoverable error occurred

The result kind is attached to every settlement request via the turn_result_kind field and later projected into the final outcome through reductionWithTurnOutcome.

Certain kinds are classified as failures in FAILED_TURN_RESULT_KINDS. The system rejects any attempt to complete a turn with these kinds, preventing invalid state transitions.

import { reduceTurnSettlementTransaction } from "./loopx/control_plane/turn_driver/settlement.ts";

const request = {
  schema_version: "loopx_turn_settlement_transaction_v0",
  transaction_plan: {/* … */},
  transaction_phases: ["validation", "durable_writeback", "quota_spend"],
  completed_phases: [],
  committed_effect_id: null,
  writeback_payload: null,
  quota_spend_payload: null,
  terminal_closeout_required: false,
  terminal_closeout_payload: null,
  failed_provider_attempt: null,
  effect_attempts: {},
  provider_observations: {},
  turn_result_kind: "validated_progress",  // ← selected from TURN_RESULT_KINDS
};

const reduction = reduceTurnSettlementTransaction(request);

How Turn Route and Turn Result Kind Interact

The settlement engine tightly couples routing and result classification through four mechanisms:

1. Route-Driven Step Selection

settlementNextAction uses BASE_SETTLEMENT_STEPS to advance the turn. The function examines which phases are complete and returns the next unexecuted step in base.step_kind. This ensures the Turn Route progresses deterministically regardless of the result kind.

2. Result-Kind Validation

Before finalizing, validateTurnOutcomeKind checks the requested turn_result_kind. If it belongs to FAILED_TURN_RESULT_KINDS, the settlement aborts:

const badRequest = { /* …request… */, turn_result_kind: "validation_failed" };
try {
  reduceTurnSettlementTransaction(badRequest);
} catch (e) {
  console.error(e.message);
  // "Turn settlement cannot complete with failed result_kind validation_failed"
}

3. Result-Kind-Conditional Routing

Specific result kinds influence route behavior:

  • Non-terminal completion: When turn_result_kind === "validated_completion" and no terminal close-out is required, the engine validates that the write-back payload does not contain an illegal "no_followup" continuation (nonTerminalCompletionError check).

  • Terminal close-out requirement: If terminal_closeout_required === true, the route extends with "terminal_closeout" and the result kind must be "validated_completion"; otherwise terminalCloseoutRequestFailure rejects the request.

4. Outcome Projection

When settlement finishes, reductionWithTurnOutcome encodes the turn_result_kind into the turn outcome payload under the key result_kind. The Python adapter and downstream consumers read this field to interpret the turn's semantic result.


Source Code Deep Dive

Understanding these interactions requires examining three files:

File Relevance
loopx/control_plane/turn_driver/settlement.ts Defines BASE_SETTLEMENT_STEPS, TURN_RESULT_KINDS, validation logic, and the core reduction functions that bind route and result kind together
tests/control_plane_ts/turn_settlement.test.ts Unit tests verifying correct routing decisions, result-kind validation, and error handling paths
tests/test_loopx_turn_transaction.py Python adapter demonstrating cross-language consumption of turn_result_kind, confirming the vocabulary contract

The settlement module exports the key functions that implement the decision vocabulary:

  • reduceTurnSettlementTransaction — main entry point for turn processing
  • settlementNextAction — computes the next step from the current route position
  • validateTurnOutcomeKind — enforces valid result kinds before completion

Summary

  • Turn Route (BASE_SETTLEMENT_STEPS) is the deterministic provider-step pipeline: validation → durable_writeback → quota_spend, optionally extended with terminal_closeout.

  • Turn Result Kind (TURN_RESULT_KINDS) classifies semantic outcomes, with FAILED_TURN_RESULT_KINDS preventing completion on failure states.

  • The settlement engine couples both: route selection drives execution order while result-kind validation ensures only valid outcomes are committed.

  • Cross-language contracts are maintained through the result_kind field in the final outcome payload, consumed by Python adapters and downstream systems.


Frequently Asked Questions

What happens if a turn tries to complete with a failed result kind?

The settlement engine rejects the request. In validateTurnOutcomeKind, if the turn_result_kind belongs to FAILED_TURN_RESULT_KINDS (such as "host_failure" or "validation_failed"), the function throws with the message "Turn settlement cannot complete with failed result_kind [kind]". This prevents corrupted terminal states.

Can the Turn Route change during settlement?

The base route defined by BASE_SETTLEMENT_STEPS is fixed, but the engine conditionally appends "terminal_closeout" when terminal_closeout_required is true. The route is otherwise deterministic—settlementNextAction always selects the first uncompleted step in the ordered sequence.

How does the Python side consume the Turn Result Kind?

The Python adapter reads the result_kind field from the outcome payload produced by reductionWithTurnOutcome. This field carries the original turn_result_kind value across the language boundary, allowing Python code to branch on turn outcomes using the same semantic vocabulary defined in TypeScript.

What is the difference between "validated_progress" and "validated_completion"?

"validated_progress" indicates the turn advanced through its route but remains active for future continuation. "validated_completion" signals terminal success—when used without terminal close-out, the engine validates that no illegal "no_followup continuation exists; when terminal close-out is required, it enables the additional close-out step in the route.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →