How to Debug LoopX Applications: A Complete Guide to Troubleshooting the AI-Agent Orchestration Framework
To debug LoopX applications, use dry-run flags to inspect state changes without mutation, query the status server for runtime health, trace errors through the CLI → registry → state refresh pipeline, and examine the projection_enabled flag to diagnose sync failures.
LoopX is a modular AI-agent orchestration framework built around a runtime directory, global registry, and CLI commands that manipulate goal state. Debugging effectively requires understanding how these components interact—from argument parsing in the CLI to markdown manipulation in state files. This guide shows you exactly how to trace problems through the LoopX codebase according to the underlying source implementation.
Understanding the LoopX Architecture for Debugging
The framework consists of layered components. Knowing which file handles what responsibility lets you isolate bugs quickly.
Core Components and Responsibilities
| Component | Key Source File | Primary Responsibility |
|---|---|---|
| Runtime manager | loopx/runtime.py |
Resolves active runtime root, validates goal IDs, archives completed goals |
| State refresh engine | loopx/state_refresh.py |
Parses goal markdown, updates Next Action sections, builds refresh records |
| State projection | loopx/state_projection.py |
Detects gaps between public-safe representation and active state |
| Global registry | loopx/registry.py |
Stores goal metadata, resolves state-file locations, lists registered agents |
| Status server | loopx/status_server.py |
Exposes HTTP endpoint reporting runtime and registry health |
| CLI front-ends | loopx/cli.py |
Thin wrappers invoking services with argument validation |
The Debugging Pipeline: Five Layers to Trace
When something fails, walk through these layers in order:
-
CLI invocation — Check arguments like
--dry-runand--goal-id. Early validation functionsvalidate_goal_id_path_segmentandvalidate_public_safe_textcatch malformed input immediately. -
Runtime path resolution — The runtime root derives from
resolve_runtime_rootin the registry. Missing goal directories usually indicate staleregistry.jsonentries. -
State file parsing — Functions
parse_frontmatter,extract_section_lines, andreplace_next_action_sectionmanipulate markdown. Errors here stem from malformed frontmatter or missing## Next Actionheadings. -
Projection and repair —
state_projection_gap_warningflags todo-expansion gaps. Seeingrequires_todo_expansionin output means investigating the Agent Todo section. -
Status server verification — The HTTP
/statusendpoint mirrorsloopx statusCLI output. Query it withcurlfor JSON snapshots without re-invoking the refresh pipeline.
Essential Debugging Commands and Techniques
Using Dry-Run Mode to Preview Changes
The --dry-run flag is your most powerful debugging tool. It executes logic without file mutations, letting you inspect every decision.
# Preview a state refresh without writing files
loopx refresh-state \
--registry /path/to/registry.json \
--goal-id my-goal \
--dry-run \
--classification "state_refreshed"
Inspect the generated markdown in /tmp/loopx/run-<timestamp>/refresh-state.md to verify classification logic and Next Action generation.
Querying the Status Server for Runtime Health
The status server avoids the overhead of full refresh cycles when you need quick health checks.
# Start the server (default port 8000)
loopx status-server &
# Get JSON snapshot of runtime, registry, and projection route
curl http://localhost:8000/status | jq .
The response includes runtime_projection_route.projection_enabled—critical for diagnosing why global registry sync may be disabled.
Archiving Goals Safely
Always dry-run before executing destructive operations:
# Verify before archiving
loopx archive-goal \
--registry /path/to/registry.json \
--goal-id my-goal \
--dry-run
# Execute once verified
loopx archive-goal \
--registry /path/to/registry.json \
--goal-id my-goal \
--execute
Common Debugging Scenarios and Solutions
Unexpected Classification Results
Symptom: Goal classification doesn't match expectations.
Resolution: Run loopx refresh-state --dry-run and examine the generated markdown for the classification field. The dry-run bypasses state mutation, exposing the logic that determines classifications in state_refresh.py.
Goal Directory Not Found
Symptom: FileNotFoundError on runtime/goals/<goal-id>.
Resolution: Verify registry entries with registry_goals and runtime root resolution via resolve_runtime_root. Use loopx status --verbose to print resolved paths. The runtime manager raises this error only after failing to locate the directory.
Next Action Section Not Updating
Symptom: State refresh completes but Next Action remains unchanged.
Resolution: Check the return value of replace_next_action_section. This function returns a tuple (new_text, updated_flag). If updated_flag is False, the section already matches the desired action. When dry_run=True, the function returns updated text but does not persist it.
Persistent Projection Gaps
Symptom: Warning continues after attempted fixes.
Resolution: Examine the warning object from state_projection_gap_warning. It contains fields requires_todo_expansion, user_open, and agent_open. The projection logic only collapses gaps after parsing todos cleanly—fix malformed bullet lines or missing todos in the state file.
Global Registry Sync Failures
Symptom: Changes don't propagate to shared runtime projection.
Resolution: Inspect runtime_projection_route via compact_runtime_projection_route. If status is "missing" or "single_runtime", global sync is intentionally disabled by design, not by error.
Performance Bottlenecks
Symptom: Slow refresh operations.
Resolution: Enable the status server and monitor runtime_projection_route.projection_enabled. Use loopx status --metrics for timing statistics. The server aggregates metrics without re-invoking the full refresh pipeline.
Source File Reference for Deep Debugging
| File | Purpose | Key Functions |
|---|---|---|
loopx/runtime.py |
Goal validation and archiving | archive_runtime_goal, resolve_runtime_root |
loopx/state_refresh.py |
Core refresh routine | refresh_state_run, parse_frontmatter, replace_next_action_section |
loopx/state_projection.py |
Gap detection | state_projection_gap_warning |
loopx/registry.py |
Metadata and path resolution | registry_goals, load_registry |
loopx/status_server.py |
HTTP health endpoint | main |
loopx/cli.py |
Command entry points | Argument parsing and service invocation |
loopx/paths.py |
Directory location helpers | Runtime and archive path utilities |
loopx/feedback.py |
Text validation | validate_goal_id_path_segment, validate_public_safe_text |
Summary
- Start with
--dry-runto inspect logic without side effects when debugging LoopX applications - Trace errors through five layers: CLI → runtime resolution → state parsing → projection → status server
- Query
localhost:8000/statusfor lightweight runtime health checks without pipeline re-execution - Check
projection_enabledandruntime_projection_route.statusto diagnose sync failures - Monitor
replace_next_action_sectionreturn values to verify whether text actually changed
Frequently Asked Questions
What is the fastest way to check if LoopX is running correctly?
Start the status server with loopx status-server & and query curl http://localhost:8000/status. This returns a JSON snapshot including runtime health, registry state, and projection route status without triggering the expensive refresh pipeline.
Why does my goal's Next Action never update?
The replace_next_action_section function returns (new_text, updated_flag). If updated_flag is False, the desired action already matches the current section content. Use --dry-run to see the proposed text, or check that your --next-action argument differs from the existing heading.
How do I debug classification decisions in LoopX?
Run loopx refresh-state --dry-run --classification <value> and inspect /tmp/loopx/run-*/refresh-state.md. The classification field in the generated markdown reveals exactly how the state refresh engine categorized your goal based on the current state file contents.
What causes global registry sync to fail silently?
Check runtime_projection_route.status via the status server or loopx status --verbose. Values of "missing" or "single_runtime" indicate intentional disablement of global sync, not an error. The compact_runtime_projection_route logic in the source code determines this based on runtime configuration.
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 →