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 requestdurable_writeback— persists the turn statequota_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 (nonTerminalCompletionErrorcheck). -
Terminal close-out requirement: If
terminal_closeout_required === true, the route extends with"terminal_closeout"and the result kind must be"validated_completion"; otherwiseterminalCloseoutRequestFailurerejects 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 processingsettlementNextAction— computes the next step from the current route positionvalidateTurnOutcomeKind— 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, withFAILED_TURN_RESULT_KINDSpreventing 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_kindfield 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →