How to Debug Quota Eligibility Failures in LoopX: A Step-by-Step Diagnostic Guide

LoopX determines whether an agent turn proceeds through the quota-should-run subsystem, and debugging failures requires tracing the envelope construction, signature verification, and disposition logic across three core stages.

When an agent turn fails to execute in the huangruiteng/loopx repository, the root cause often lies in the quota eligibility check. This subsystem evaluates whether sufficient resources exist and whether gates permit execution. Understanding how to debug quota eligibility failures in LoopX involves tracing the flow from the CLI command through envelope construction to the final disposition decision.

How Quota Eligibility Works in LoopX

The quota decision flow consists of three interconnected stages defined in loopx/control_plane/quota/. A failure typically originates when any stage returns should_run = False or fails to validate the envelope signature.

Stage 1: Building the Turn Envelope

Located in loopx/control_plane/quota/turn_envelope.py, the build_turn_envelope() function assembles a turn envelope that travels with the turn receipt. This envelope encapsulates the quota decision, the effective_action (such as run, quiet-noop, or terminal-no-follow-up), and the turn metadata. The envelope serves as the canonical record of why a turn was permitted or blocked.

Stage 2: Interpreting the Quota Packet

The interpret_quota_should_run_packet() function in loopx/control_plane/quota/effect_program.py decodes the JSON output from the CLI command loopx quota should-run. It creates a QuotaDecision object containing the boolean should_run, the effective_action string, and the signature block. This stage transforms the raw provider response into a typed structure that downstream logic consumes.

Stage 3: Deciding Loop Disposition

Also in loopx/control_plane/quota/turn_envelope.py, the decide_loop_disposition() function combines the turn receipt with the quota envelope to determine if the loop will spend quota, wait, re-plan, or terminate. This final stage checks for signature mismatches, stale source_hash values, and propagation errors in turn_key or selected_todo_id.

Step-by-Step Debugging Checklist

1. Run the Quota Command with Full Details

Execute the CLI command to see the raw provider decision:

loopx quota should-run \
    --goal-id <your-goal-id> \
    --include-detail scheduler \
    --format json

Examine the JSON payload for the should_run field. If this value is false, the failure originates from the quota provider itself—indicating limits, missing resources, or explicit gating. The effective_action field reveals whether the system intends to run_now, stop_until_explicit_resume, or execute a quiet-noop.

2. Inspect the Signature Block

The signature object proves that the quota decision matches the current goal state. Check the source_hash against the goal's latest state stored in the goal ledger (loopx/state/). A stale or mismatched hash causes the envelope to be rejected later in the pipeline even if should_run is true.

3. Trace the Turn Envelope Construction

Verify that build_turn_envelope() receives the correct arguments:

from loopx.control_plane.quota.turn_envelope import build_turn_envelope

envelope = build_turn_envelope(
    quota_decision=quota_decision,  # Must match CLI output

    turn_key=receipt.turn_key,      # Must match the turn receipt

    selected_todo_id=None,          # Propagate correctly if present

)

Mismatched keys cause the envelope to be ignored during disposition. Ensure the quota_decision argument matches the CLI JSON exactly, including the signature block.

4. Check the Disposition Logic

The disposition function determines whether quota is actually consumed:

from loopx.control_plane.quota.turn_envelope import decide_loop_disposition

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

The disposition["spends_quota"] field should be True when should_run is True. If it is False, inspect the envelope for flags such as quiet_noop_allowed, replan_required, or a failed signature verification.

5. Enable Debug Logging

Set the environment variable to capture detailed trace logs:

export LOOPX_LOG_LEVEL=debug

The logs emit messages from critical functions including quota_action_signature_document (signature creation), interpret_quota_should_run_packet (payload parsing), and decide_loop_disposition (final decision).

6. Validate the Quota Provider

Provider implementations reside in loopx/control_plane/quota/provider/. The ecosystem includes:

If using a custom provider, ensure it returns a JSON object with the strict schema: should_run, effective_action, and signature. Missing fields cause parsing failures in effect_program.py.

7. Run the Relevant Unit Tests

Isolate failures using the dedicated test suites:

pytest tests/test_turn_envelope.py -v
pytest tests/test_turn_loop_disposition.py::test_quota_failure -v

These tests validate envelope construction, signature handling, and disposition logic for both success and failure scenarios.

Practical Code Examples

Inspecting a Quota Packet Manually

Simulate CLI output to debug parsing logic without running the full agent:

import json
from loopx.control_plane.quota.effect_program import interpret_quota_should_run_packet

raw = """
{
  "should_run": false,
  "effective_action": "stop_until_explicit_resume",
  "signature": {
    "source_hash": "sha256:abc123",
    "gate_id": "explicit-quota-gate"
  }
}
"""
packet = json.loads(raw)
decision = interpret_quota_should_run_packet(packet)

assert decision.should_run is False
assert decision.effective_action == "stop_until_explicit_resume"

Source: loopx/control_plane/quota/effect_program.py

Building a Turn Envelope and Deciding Disposition

Programmatically replicate the envelope flow to verify integration:

from loopx.control_plane.quota.turn_envelope import (
    build_turn_envelope,
    decide_loop_disposition,
)
from loopx.control_plane.quota.effect_program import interpret_quota_should_run_packet

# Assume receipt from a previous turn

receipt = ...  # TurnReceipt object

quota_payload = {
    "should_run": True,
    "effective_action": "run_now",
    "signature": {"source_hash": "sha256:def456", "gate_id": "default"}
}
quota_decision = interpret_quota_should_run_packet(quota_payload)

envelope = build_turn_envelope(
    quota_decision=quota_decision,
    turn_key=receipt.turn_key,
    selected_todo_id=None,
)

disposition = decide_loop_disposition(
    turn_receipt=receipt,
    quota_decision=envelope
)
print(disposition["spends_quota"])  # Expected: True when eligible

Source: loopx/control_plane/quota/turn_envelope.py

CLI Diagnostic Output

Generate full diagnostic data including scheduler internals:

loopx quota should-run \
    --goal-id my-goal \
    --include-detail scheduler \
    --format json

The output includes a "scheduler" block indicating whether execution occurs immediately or is deferred, which distinguishes between hard gate failures and scheduling waits.

Source: loopx/control_plane/quota/cli.py

Key Source Files

Summary

  • Trace the CLI output to verify the raw should_run and effective_action values using loopx quota should-run --include-detail scheduler --format json
  • Verify signatures by ensuring source_hash matches the current goal ledger state to prevent stale envelope rejections
  • Inspect envelope construction in build_turn_envelope() to confirm correct propagation of quota_decision, turn_key, and selected_todo_id
  • Check disposition logic to ensure decide_loop_disposition() returns spends_quota=True when execution is expected, and watch for quiet_noop_allowed or replan_required flags
  • Enable debug logging with LOOPX_LOG_LEVEL=debug to capture detailed traces from quota_action_signature_document, interpret_quota_should_run_packet, and decide_loop_disposition
  • Run unit tests in tests/test_turn_envelope.py and tests/test_turn_loop_disposition.py to isolate component-level failures

Frequently Asked Questions

What causes a quota eligibility failure in LoopX?

A failure occurs when the quota provider returns should_run: false due to resource limits, explicit gates, or missing prerequisites. Failures also happen when the envelope's signature contains a stale source_hash that does not match the goal ledger, causing decide_loop_disposition() to reject the envelope even if the provider initially approved execution.

How do I check if the quota signature is valid?

Compare the source_hash field in the quota decision's signature block against the latest hash stored in the goal ledger (loopx/state/). The quota_action_signature_document function generates this hash during envelope construction; if the ledger has advanced since the quota check, the hash mismatch triggers a rejection.

Where are quota provider implementations located?

Providers reside in loopx/control_plane/quota/provider/. The repository includes static gates for testing (defined in tests/test_summary_all.py) and dynamic services that query external HTTP endpoints (quota_service.py). Custom providers must return JSON with should_run, effective_action, and signature fields to be compatible with effect_program.py.

Can I test quota logic without running the full agent?

Yes. Use the unit tests in tests/test_turn_envelope.py to validate envelope construction and signature handling, and tests/test_turn_loop_disposition.py to verify disposition decisions against mock quota decisions. You can also manually call interpret_quota_should_run_packet() with JSON payloads to simulate provider responses without invoking the CLI.

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 →