Capability-to-Provider Execution Path vs Kernel Writeback Control Path in LoopX
The capability-to-provider execution path handles external work delegation without state mutation privileges, while the Kernel writeback control path exclusively validates transition proposals and persists state changes according to quota and authority contracts.
LoopX (huangruiteng/loopx) separates the "doing" of work from the "governing" of state changes through two orthogonal flows. Understanding the distinction between the capability-to-provider execution path and the Kernel writeback control path is essential for safely extending the system and implementing custom capabilities.
The Capability-to-Provider Execution Path
This forward-moving path performs the concrete work requested by agents, such as calling external APIs, running tools, or issuing Git commands.
Flow and Ownership
The execution follows a strict chain documented in README.md (line 438):
- The Agent asks a Capability for an operation.
- The Capability builds a Provider request (read-only or effectful).
- The Provider executes the external action and returns a read-back payload.
The Capability defines what should be done, while the Provider implements how to do it. As described in docs/reference/extensions.md (lines 34-40), the "Provider readback → Capability transition proposal → LoopX Kernel" chain ensures that no external actor bypasses the Kernel's authority.
Authority and Constraints
Providers operate in a sandboxed context without Kernel authority. They cannot directly mutate LoopX state; they only produce read-back payloads that must be packaged into transition proposals. This constraint ensures that all state mutations flow through the Kernel's validation layer.
The Kernel Writeback Control Path
This backward-moving path validates, authorizes, and persists the results of the provider’s work, deciding whether further turns are allowed.
Flow and Validation
According to docs/reference/protocols/computer-use-runtime-v0.md (lines 68-71), the Kernel must never author a write-back itself. Instead, it acts on proposals:
- The Provider returns its read-back payload to the Capability.
- The Capability packages the payload into a transition proposal.
- The Kernel inspects the proposal, checks authority and quota, then either accepts it (writing back state, creating todos/gates, updating quota) or rejects it (producing a controlled error).
Runtime enforcement occurs in loopx/extensions/governed_capability_execution.py (lines 224-340), where governed transition proposals require proper Kernel context before persistence.
State Mutation Authority
Only the Kernel holds the sole authority to mutate durable state, including todos, gates, quota, and evidence. This centralized control guarantees that all state changes obey the system's contracts and quota limits.
Key Differences Between the Paths
Direction: The capability-to-provider path moves forward (agent → capability → external side), while the Kernel writeback path moves backward (provider → capability → kernel).
Responsibility: The execution path determines what happens and how to invoke external systems. The control path determines whether results may persist and how core state changes.
Error Handling: Provider errors return to the capability for potential fallback suggestions. Kernel rejections occur when authority or quota checks fail, turning errors into controlled turn-settlements rather than system failures.
State Mutation: The execution path only produces read-back payloads. Only the Kernel performs actual state write-backs, such as creating new todos or updating quotas.
Implementation in Code
The following examples illustrate how these paths interact in practice, from the capability module to the core control-plane.
First, the capability builds a provider request and wraps the response into a transition proposal:
def run(self, ctx: CapabilityContext, args: dict) -> ProviderResponse:
provider = ctx.provider_factory.get('git')
# Provider executes external work (e.g., create a PR)
response = provider.create_pull_request(
repo=args["repo"], branch=args["branch"], title=args["title"]
)
# Wrap provider's read-back into transition proposal
proposal = {
"type": "github_pr_created",
"payload": response,
"author": ctx.agent_id,
}
return proposal
Then, the Kernel receives the proposal and decides whether to persist the changes:
def handle_transition(self, proposal: dict) -> None:
if not self.quota.can_spend(proposal["type"]):
raise KernelError("Quota exceeded")
# Kernel writes back durable state (e.g., a new Todo)
self.state.todo.create(
todo_id=proposal["payload"]["pr_number"],
description=proposal["payload"]["title"],
owner=proposal["author"],
)
The first snippet typically resides in a capability module (e.g., loopx/capabilities/issue_fix/), while the second reflects the Kernel's implementation in loopx/kernel.py.
Summary
- The capability-to-provider execution path delegates external work to providers without granting state mutation privileges.
- The Kernel writeback control path exclusively validates transition proposals and owns all durable state changes.
- Transition proposals bridge the two paths, carrying read-back payloads from capabilities to the Kernel for approval.
- Only the Kernel may mutate todos, gates, quota, or evidence after checking authority constraints.
- Providers operate in sandboxed contexts according to the protocol definitions in
docs/reference/protocols/.
Frequently Asked Questions
Can a Provider directly modify LoopX state?
No. Providers operate in a sandboxed context and can only return read-back payloads. Direct state mutation is restricted to the Kernel writeback control path as enforced in docs/reference/protocols/computer-use-runtime-v0.md (lines 68-71).
What happens if a transition proposal violates quota limits?
The Kernel rejects the proposal. In loopx/kernel.py, the handle_transition method raises a KernelError when quota.can_spend() returns false, preventing the state write-back and producing a controlled error response rather than allowing the mutation.
How does the Capability know which Provider to invoke?
The Capability builds Provider requests using a provider factory available in the CapabilityContext. As shown in the execution diagram at README.md (line 438), the Capability defines what operation is needed, then retrieves the appropriate Provider implementation to handle the external execution.
Why must the Kernel never author its own write-backs?
This constraint ensures that all state mutations flow through validated transition proposals, maintaining the separation of concerns. The Kernel only accepts or rejects proposals authored by capabilities, preventing arbitrary state changes and ensuring quota and authority checks apply consistently.
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 →