# How LoopX Differentiates Hard Boundaries (Quota Claims) from Steering Guidance (next_cli_actions)

> Understand how LoopX distinguishes hard boundaries like quota claims from steering guidance with next_cli_actions. Learn about enforcement and optional suggestions.

- Repository: [huangruiteng/loopx](https://github.com/huangruiteng/loopx)
- Tags: deep-dive
- Published: 2026-09-02

---

**LoopX enforces hard boundaries through the quota subsystem that validates resource claims before a turn executes, while steering guidance via `nextcli_actions` provides optional post-execution CLI suggestions that never block execution.**

The LoopX control plane manages task execution through two distinct constraint mechanisms: immutable resource limits and advisory user prompts. Understanding how the framework differentiates between **hard boundaries** (claims, gates, and quota enforcement) and **steering guidance** (`nextcli_actions`) is essential for developers implementing custom control logic in the `huangruiteng/loopx` repository.

## Hard Boundaries: Quota Claims and Gates

### Implementation in the Quota Subsystem

Hard boundaries represent non-negotiable resource limits enforced by the quota subsystem located in `loopx/control_plane/quota/`. These constraints determine whether a turn may proceed based on available resources and are validated before any state mutation occurs.

The `build_turn_envelope` function in [`loopx/control_plane/quota/turn_envelope.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/quota/turn_envelope.py) constructs the turn envelope containing a **quota claim** entry. This claim specifies parameters such as `gate_id` and `should_run` flags that dictate resource allocation requirements.

```python
from loopx.control_plane.quota.turn_envelope import build_turn_envelope

envelope = build_turn_envelope(
    goal_id="my-goal",
    claim={"gate_id": "explicit-quota-gate", "should_run": True},
)

# The envelope now contains a quota claim that the quota subsystem will check.

```

### Turn Envelope Validation

Before execution proceeds, the `decide_loop_disposition` function evaluates the quota claim. If the claim cannot be satisfied, the system marks the envelope with a `quota_gate_failed` error and aborts the turn. When validation succeeds, the system sets `spends_quota: true` and permits the turn to commit.

```python
from loopx.control_plane.quota.decision import decide_loop_disposition

turn_receipt = None                      # No prior receipt

quota_decision = envelope["quota"]       # Comes from the envelope

disposition = decide_loop_disposition(
    turn_receipt=turn_receipt,
    quota_decision=quota_decision,
)

if disposition["spends_quota"]:
    # Proceed with state write‑back

    pass
else:
    # Abort: quota gate failed

    pass

```

## Steering Guidance: next_cli_actions

### Advisory CLI Suggestions

Unlike hard boundaries, steering guidance provides optional next steps for operators. Implemented in [`loopx/control_plane/next_cli_actions.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/next_cli_actions.py), the `add_nextcli_actions` function appends CLI command suggestions to the host packet without affecting execution flow. The `NextCliActions` dataclass defines the structure for these advisory commands.

### Post-Execution Attachment

The runtime invokes `add_nextcli_actions` from [`loopx/control_plane/runtime.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/runtime.py) only after a successful turn completion. This timing ensures that steering guidance never interferes with quota validation, as it occurs after the hard boundary checks in [`loopx/control_plane/effect_program.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/effect_program.py) have already passed.

```python
from loopx.control_plane.next_cli_actions import add_nextcli_actions

host_packet = {}                     # Result of a successful turn

next_actions = [
    "loopx status --goal-id my-goal",
    "loopx quota should-run --goal-id my-goal",
]

# Enrich the packet with advisory commands; this does NOT affect quota.

host_packet = add_nextcli_actions(host_packet, next_actions)

```

## Key Differences Between Boundary Types

- **Hard boundaries** enforce resource limits before execution begins, while **steering guidance** suggests actions after successful completion.
- **Quota claims** are validated by `decide_loop_disposition` in [`loopx/control_plane/quota/decision.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/quota/decision.py) and can abort the turn, whereas `nextcli_actions` are appended by `add_nextcli_actions` and never affect turn status.
- **Hard boundary errors** trigger `quota_gate_failed` dispositions when the envelope fails validation, while steering guidance contains no error path—the actions are purely informational.
- **Timing**: Quota validation occurs during the turn envelope processing phase; `nextcli_actions` are attached post-commit by the runtime.

## Summary

- Hard boundaries in LoopX are enforced through the quota subsystem ([`turn_envelope.py`](https://github.com/huangruiteng/loopx/blob/main/turn_envelope.py), [`decision.py`](https://github.com/huangruiteng/loopx/blob/main/decision.py)) that validates resource claims before state mutation.
- Steering guidance (`nextcli_actions`) is implemented in [`next_cli_actions.py`](https://github.com/huangruiteng/loopx/blob/main/next_cli_actions.py) and [`runtime.py`](https://github.com/huangruiteng/loopx/blob/main/runtime.py) as non-blocking post-execution suggestions.
- Quota claims can abort turns with `quota_gate_failed` errors, while CLI actions are strictly advisory and never block execution.
- The `decide_loop_disposition` function governs hard boundary enforcement, whereas `add_nextcli_actions` governs guidance attachment after successful completion.

## Frequently Asked Questions

### What happens if a quota gate fails in LoopX?

The `decide_loop_disposition` function detects the failure and sets `spends_quota: false`, aborting the turn before any state mutation occurs. The envelope is marked with a `quota_gate_failed` disposition, preventing the effect program from committing changes.

### Can next_cli_actions prevent a turn from executing?

No. The `add_nextcli_actions` function in [`loopx/control_plane/runtime.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/runtime.py) only executes after a turn has successfully completed and quota validation has passed. These actions are purely advisory and have no mechanism to block or reverse turn execution.

### Where are quota claims defined in the LoopX source code?

Quota claims are constructed in [`loopx/control_plane/quota/turn_envelope.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/control_plane/quota/turn_envelope.py) by the `build_turn_envelope` function, which embeds the claim parameters into the turn envelope structure before validation occurs.

### How does LoopX determine when to attach steering guidance?

The runtime detects successful turn completion and calls `add_nextcli_actions` to populate the `nextcli_actions` field in the host packet. This occurs only after the quota gate has been satisfied and the turn has been committed, ensuring guidance never interferes with hard boundary enforcement.