Bounded Context Layout¶
LoopX control-plane code is moving from a flat collection of status/quota helper modules toward bounded contexts. The goal is to keep the open-source kernel readable: source parsing, policy selection, projection shaping, and rendering should not all accumulate in one generic namespace.
Package Shape¶
New control-plane code should live under loopx.control_plane:
| Context | Responsibility |
|---|---|
work_items |
Attention items, work-item selection, work-item read models, lifecycle and delivery signals. |
goals |
Goal state, active-state sections, registry health, and goal-level planning surfaces. |
todos |
Todo parsing summaries, todo-derived attention helpers, and todo handoff summaries. |
agents |
Agent-scope filtering, lane recommendation, capability gates, subagent activity, and the reusable multi-agent execution kernel. |
quota |
Quota-specific control-plane helpers. |
scheduler |
Scheduler-facing monitor display and cadence helpers. |
runtime |
Runtime/session projections and run-compaction helpers. |
handoff |
Handoff readiness, handoff state, handoff-run classification, cross-runtime review packets, and exact review-decision batching. |
Repo-local control-plane code, examples, and smokes should import the owning bounded context directly. Do not add compatibility shims for internal moves; if an external compatibility break matters, make it an explicit release decision instead of keeping a generic legacy namespace alive by default.
Projection Boundary¶
A projection is a derived read model with a stable consumer contract. It should be:
- deterministic from public-safe source state;
- side-effect free;
- small enough for hot status/quota/dashboard surfaces;
- consumed through a named contract rather than copied across renderers.
Not every extracted helper is a projection. Selection rules belong near the
domain policy, parser helpers belong near the state they parse, and renderer
formatting belongs in the sink. If a module is moved only because a source file
is too long, choose the bounded context first and the projection.py name only
when it really exposes a read model contract.
Migration Rule¶
When moving an existing module:
- Move the implementation into the owning bounded context.
- Update LoopX runtime imports to the new context path.
- Update repo-local examples, docs, and smokes to the bounded-context import path in the same batch.
- Add or keep a focused smoke that exercises the runtime path and rejects internal imports from stale legacy namespaces.
- Use a deliberate compatibility-breaking release note if an old public import path must be removed.
This keeps the kernel architecture clean without preserving internal shims that invite future code to grow in the wrong namespace.
Compatibility Decisions¶
The July 2026 package-ownership migration removed the internal
loopx.capabilities.multi_agent, loopx.capabilities.cross_runtime, and
loopx.capabilities.review_batch import paths. Their implementations now live
under the owning agents and handoff contexts, while the review-batch CLI
registration lives under loopx.cli_commands. These paths had no maintained
external compatibility window, so the migration updates active callers and
tests directly instead of keeping wrappers that would preserve the wrong
ownership boundary.