Stage 7: CLI, Dashboard, and Extensions
Course: LoopX Source Code Class · Stage Test Prerequisite: Stage 6, Understanding Facts and Projections Corresponding Overview:
core-mechanisms.mdthe interface and extension parts Goal of this stage: To see how the same control plane serves humans, scripts, Hosts, and external channels without duplicating the business core.
1. What This Stage Resolves
Section titled “1. What This Stage Resolves”LoopX has CLI, Dashboard, Lark/IM, Goal Mode, and different Agent Hosts. They look like multiple products, but in fact, they should all follow the same boundary:
- Facts are provided by registry/state/journal;
- Read models are generated by status/presentation;
- Actions are handled by typed command/authority;
- Host adapters only deal with connecting to the specific model runtime;
- Channels only handle ingress/egress, without rewriting target facts.
If each interface keeps its own copy of the ‘current task’, the system will immediately lose a single source of truth.
2. Remember One Judgment First
Section titled “2. Remember One Judgment First”Interfaces are consumers, not the control plane itself; Host adapters are translation layers, not rule layers.
CLI outputs can help humans and Agents decide, but changes in output format cannot change the semantics of should-run, validation, or settlement.
3. Source Code Mainline
Section titled “3. Source Code Mainline”cli.pyAssemble command families: status, turn, quota, todo, goal, presentation, dash, extended capabilities, etc., and unify JSON/markdown outputs.status_server.pyProvide read-only/control API projections; Dashboard fetches data fromcollect_status()and the presentation layer.presentation/Responsible for markdown/HTML/API views;renderers/status_markdown.py,turn_envelope_markdown.py, etc. only render existing facts.pi_goal_mode/,zcode_goal_mode/,dsh_goal_mode/,opencode_goal_mode/Translate LoopX contracts into invocation methods for different Hosts.turn_driver/host_process.ts,host_bridge_transport.py,host_interaction.tsHandle processes, stdio, interaction, and timeout boundaries.extensions/lark/and other channels handle events, identity, receipts, and user notifications, but still return to the same state and Turn entry.
4. Key Objects and Contracts
Section titled “4. Key Objects and Contracts”| Entry | Input | Output | Should Not Own |
|---|---|---|---|
| CLI | argv, workspace/runtime config | Human- or machine-readable projection | Independent state database |
| status server | Query/control request | status, attention, action projection | Directly fabricate completion |
| Dashboard | Read model | Visualization | Another set of Todo facts |
| Goal Mode adapter | Host request | Host result/event | Its own validation rules |
| extension/channel | External events | normalized ingress | Bypass gate/quota |
| Host process | Contract and context | typed candidate | Directly write canonical state |
Why Goal Mode Is Not Another Core
Section titled “Why Goal Mode Is Not Another Core”Different Hosts have different models, tool protocols, and session mechanisms, so adapters are needed to translate requests and results. But Turn identity, envelope, validation, writeback, and spend are still owned by the LoopX core. Adapters cannot skip stages just because a certain Host is more convenient.
Why CLI Should Retain JSON
Section titled “Why CLI Should Retain JSON”Markdown is suitable for humans to locate information, while scripts and Agents need stable fields. next_cli_actions, quota reason, envelope, receipt can all be consumed in a structured way; recommended actions are only steering, execution still goes through authority.
5. An Observable Trace
Section titled “5. An Observable Trace”CLI / Dashboard / IM event → normalized command or ingress → registry + status projection → should-run / typed action authority → Turn plan → Goal Mode Host adapter → host process / bridge → typed result Return to kernel settlement → status refreshPay attention to the last paragraph: the results must return to the kernel, rather than the adapter updating the Dashboard data source itself.
6. Experiments
Section titled “6. Experiments”Experiment A: Tracking a status field
Section titled “Experiment A: Tracking a status field”From the Dashboard, observe should_run, then follow collect_status() → should-run payload to find the source field. Acceptance criteria: be able to indicate that the field comes from quota/route, not calculated by the presentation itself.
Experiment B: Comparing two Goal Modes
Section titled “Experiment B: Comparing two Goal Modes”Read the host adapters in pi_goal_mode and dsh_goal_mode. Acceptance criteria: though the host protocols differ, both receive the same turn identity/envelope and return results to the same validation and settlement.
Experiment C: Injecting an event from a channel
Section titled “Experiment C: Injecting an event from a channel”Use an extended test to construct an external event. Acceptance criteria: the event must first become an auditable ingress, then pass through gate/authority; it cannot directly be marked as Todo complete or skip quota.
Reference Answers for Experiments
Section titled “Reference Answers for Experiments”- The source of
should_runshould be canonical decisions and states like quota/route; the presentation only displays and does not calculate facts itself. - The host protocols of
pi_goal_modeanddsh_goal_modecan differ, but they must share the turn identity/envelope and return to the same validate/writeback/spend semantics. - An external event must first become an auditable ingress, then go through gate/authority; it cannot directly write Todo completion, skip quota, or forge next actions.
7. Failure and Recovery
Section titled “7. Failure and Recovery”| Failure | Common Root Cause | Recovery |
|---|---|---|
| Dashboard inconsistent with CLI | Projection cache/version differences | Recalculate using canonical state |
| Host adapter drops fields | Translation layer loses contract | Fix adapter, restore contract tests |
| Channel duplicate delivery | Lack of idempotent ingress | Deduplicate using event id/receipt |
| Recommended actions not executable | Projection expired or authority changed | Re-run should-run/authority |
| Host process timeout | Tool/model long blocking | Retain journal, resume according to recovery policy |
| UI directly marks complete | Bypass writeback | Remove write entry, return to typed command |
8. Self-Test for Clearance
Section titled “8. Self-Test for Clearance”- What do CLI, Dashboard, and Goal Mode each consume and own?
- Why can’t the Goal Mode adapter determine completion itself?
- Why can’t recommended actions serve as a permissions whitelist?
- How should duplicate messages from external channels be handled?
- Why can’t the adapter rerun privately after a host process crash?
- How to verify an interface is not secretly maintaining a second set of states?
Reference Answers
Section titled “Reference Answers”- CLI consumes commands and fact projections, producing human/machine-readable results; Dashboard consumes status/presentation read models; Goal Mode consumes turn contracts and translates Host protocols. None of them can own canonical Goal/Todo/quota facts or settlement rights.
- Completion requires evidence verification, lifecycle writeback, spend, and closeout. The adapter only sees Host candidate results and cannot prove these stages have been committed; self-determination would bypass the kernel and create false completions.
- Recommended actions are only steering and may expire due to version, filtering, or permission restrictions. Valid actions must still pass typed authority, preflight, receipt binding, and settlement; prohibited actions should return explicit errors.
- Deduplicate using stable event id/ingress receipt and distinguish “accepted” and “processed”. Duplicate deliveries can only replay existing states, without re-executing side effects.
- The adapter does not know whether Host effects have occurred or which stage the journal has been committed to. Private reruns may duplicate tool side effects; it must return to the kernel, read the journal/receipt, and recover according to prefix.
- After modifying interface display, refresh the canonical state to see if it returns to facts; then trace all write operations to ensure they go through typed command, authority, journal, and receipt. If the interface has its own persistence bucket, that is a second set of states.
9. Source Code References
Section titled “9. Source Code References”loopx/cli.pyloopx/status.pyloopx/status_server.pyloopx/presentation/loopx/presentation/renderers/status_markdown.pyloopx/pi_goal_mode/loopx/zcode_goal_mode/loopx/dsh_goal_mode/turn_host_adapter.pyloopx/control_plane/turn_driver/host_process.tsloopx/extensions/lark/
10. Next Steps
Section titled “10. Next Steps”Enter Stage 8: What engineering measures ensure these boundaries? How do tests, journal, atomic writes, and recovery audits prevent system distortion during crashes and concurrency?