Effect Interpreter Packet

August 16, 2026 · View on GitHub

This page documents the canonical read lens for quota should-run:

effect_request -> interpretation -> observation -> next_effect

It does not add a new runtime contract. It names the existing packet fields that already play each role.

Code Lens

loopx.control_plane.effect_program.interpret_quota_should_run_packet maps an existing quota should-run packet onto the canonical slots, and interpret_turn_result_packet maps an existing loopx_turn_result_v0 packet:

  • EffectRequest
  • EffectInterpretation
  • EffectObservation
  • EffectNext
  • EffectTurn

Both functions are intentionally read-only. They do not replace quota decision or turn-settlement logic; they give refactor and test code one stable abstraction for reading the effect program shape across packet families.

Turn Journal Lens

interpret_turn_journal reads an existing fenced Turn journal and returns an EffectTurn. It compares goal, agent owner, and Turn-key identity across the journal, stored plan, typed settlement identity, host result, and receipt. It also validates that completed phases are an ordered transaction prefix and exposes retained committed, stopped, and failed journal tombstones.

request.context.replay_legal is the replay-legality signal. Identity, phase-order, and terminal-status failures appear together as stable typed violation values in request.context.violations; semantic mismatches return a blocked observation instead of raising an exception.

EffectObservation.should_run remains false and EffectNext remains empty. Interpretation therefore grants no authority to execute or retry a Turn, schedule work, write state, or spend quota. In particular, failed-journal recovery with retry_failed=True remains owned by the Turn executor.

The public read-only consumer is:

loopx turn inspect-journal \
  --goal-id <goal-id> \
  --agent-id <agent-id> \
  --turn-key <sha256:64-hex-digest> \
  --format json

It resolves only the canonical journal location. There is no arbitrary --journal-path input. The command validates selectors, takes the existing journal lock, schema-checks the stored JSON, and returns the versioned loopx_turn_journal_inspection_v0 projection. That projection allowlists only the replay decision, journal status, replay legality, identity-match booleans, ordered phase-prefix result, completed phase ids, tombstone retention, typed violation ids, and the explicit effect-free marker effects: [].

JSON and Markdown render the same projection. They do not expose raw journal, plan, host-result, or receipt bodies; request context; capabilities; recommended actions; credentials; evidence; or resolved local paths. A successfully interpreted replay_blocked journal exits zero because replay legality is diagnostic data. Invalid selectors, missing journals, malformed JSON, and unsupported schemas exit non-zero.

Canonical Example

1. Effect Request

The agent or host proposes the next bounded turn. The inputs include:

  • goal_id
  • agent_id
  • available_capabilities
  • host surface and scheduler execution context
  • current host RRULE where relevant

2. Interpretation

The harness interprets the request through:

Packet fieldRole
work_lane_contract.laneRoute: advancement, monitor, gate, or wait
work_lane_contract.obligationWhat the selected route must do
interaction_contract.modeThe host-facing interaction mode
capability_gate.actionCapability decision when a gate is present
scheduler_hint.cadence_classTiming decision for the next host wake

3. Observation

The decision is returned as:

Packet fieldRole
decisionRun, skip, observe, or repair
should_runWhether compute is allowed
effective_actionMachine-visible effective action
recommended_actionNext concrete action text
protocol_action_packet.summaryCompact actor-facing summary

4. Next Effect

The observation points back into the loop:

Packet fieldRole
interaction_contract.cli_channel.next_cli_actionsNext CLI effects
execution_modeExecution strategy (serial / parallel / interleaved) for an ordered effect program
scheduler_hint.actionScheduler around decision
scheduler_hint.cadence_classCadence for the next host wake
scheduler_hint.codex_app.ack_hint.cli_argsHost ACK effect
scheduler_hint.codex_app.failure_hint.cli_argsHost failure effect

EffectTurn.next_effect is the code lens for this slot. It keeps the data-encoded handler visible: the host invokes the CLI actions and settles success or failure through the ACK/failure hints instead of LoopX holding a callable across turns. execution_mode is the data-encoded strategy when the next effect is an ordered effect program; it defaults to None when the packet does not declare one.

Around Semantics

capability_gate, interaction_contract, work_lane_contract, and scheduler_hint are around decisions over the canonical effect step, not separate feature modules:

Around layerCan short-circuitCan rewrite
capability_gateask_owner, repair_bridge, unsupportedRepair todo and next CLI actions
interaction_contractaction_required, modePrimary/protocol action and notification
work_lane_contractMonitor/inbox preemption, must_attempt_work=falseLane, obligation, next_lane
scheduler_hintPause/delete heartbeat, no-spend quietRRULE, cadence, stateful backoff

The ordering and effect semantics are contracts. A capability gate must not be collapsed into a generic exception handler: owner_missing, repair_missing, and decision_owner stay visible because ask_owner and repair_bridge lead to different next effects.

A CLI packet is a higher-density effect than a single tool call: one command can carry permission, budget, validation, execution, failure semantics, ACK, and writeback. Vendor serial or interleaved tool APIs are execution modes inside the interpreter, not new state machines.

Ordered Effect Program

loopx.control_plane.effect_program.effect_program_from_ordered_steps maps an existing guided_transaction.ordered_steps value onto EffectProgram:

  • EffectStep keeps step_id, kind, command, and purpose;
  • EffectProgram keeps ordered steps and an optional execution_mode.

This is still a read-only lens. The executor remains host-driven until a LoopX runtime caller owns multi-step execution.

Terminal Closeout Ordering

The settlement plan keeps final Goal closure distinct from ordinary Todo continuation. Its ordered contract is:

validation -> durable_writeback -> quota_spend -> terminal_closeout?

terminal_closeout is conditional: it is present only when the validated completion declares no_followup. Ordinary successor completion remains a Todo-lifecycle action and does not pretend to be a terminal settlement step. The final closeout must prove the same effect identity and matching writeback and spend receipts before it may make the Goal terminal.

This order is deliberate. Completing the final Todo first would make strict terminal guards reject the spend that accounts for the same material effect. The repair is not an after-terminal spend exception: terminal state remains strict, and the closeout moves after spend. If closeout fails, its journaled receipt may be retried without repeating writeback or spend. Scheduler apply and ACK remain host handoffs outside this settlement chain.

Relationship To State Machines

Each state family is an interpretation table over this lens:

input effect -> interpreter -> decision -> observation -> next effect

See the Agent Loop Effect Interpreter RFC and Harness Is the Effectful Program. The public framing comes from 齐梦星空, 主线一:Agent Loop 是 effectful program(1).