# Runtime Responsibility Contracts for Agent, Provider, Capability, and Kernel in LoopX

> Understand LoopX runtime responsibility contracts: Agent handles execution, Provider manages external calls, Capability validates transitions, and Kernel controls state and scheduling.

- Repository: [huangruiteng/loopx](https://github.com/huangruiteng/loopx)
- Tags: architecture
- Published: 2026-09-04

---

**LoopX enforces strict runtime responsibility contracts across its four core components: Agent owns bounded execution and planning, Provider owns external calls and observations, Capability owns validation and transition proposals, and Kernel exclusively owns durable state and scheduling authority.**

The LoopX framework implements a layered architecture that prevents authority leakage through unidirectional data flow. Each component operates within well-defined boundaries, ensuring that domain logic, external interactions, and state persistence remain cleanly separated. This design enables independent evolution, testing, and reasoning about each layer.

## Core Responsibility Contracts

LoopX formalizes ownership rules in its architecture documentation. The following table summarizes what each component **owns** and **must not own**:

| Component | Owns | Must Not Own |
|-----------|------|--------------|
| **Agent** | Planning, analysis, tool use, and one bounded execution through a host/runtime | Durable goal lifecycle or unscoped effect authority |
| **Provider** | External calls, bounded observations, effect results, and read-back | Domain transition policy or LoopX todo state |
| **Capability** | Caller-facing outcome contract, domain policy, observation normalization, validation, and typed transition proposals | Durable scheduling, claims, gates, or direct lifecycle writes |
| **LoopX Kernel** | Goal, todo, claim, gate, monitor, quota, accepted write-back, recovery, and scheduling | Domain-specific reasoning or provider implementation details |

These contracts create a **unidirectional flow** of requests and results:

```

Agent → Capability → Provider → external system
external observation/effect read-back → Provider → Capability
typed transition proposal → LoopX Kernel → next todo/gate/monitor/turn

```

## Agent: Bounded Execution Owner

The **Agent** is restricted to a single bounded execution. It owns planning, analysis, and tool use within that scope, but never directly manipulates durable goal state.

Key obligations:
- Creates plans and invokes capabilities
- Operates within host/runtime boundaries
- Cannot claim unscoped effect authority

```python

# Example: Agent creates a plan and invokes a capability

agent_plan = agent.plan(goal)                     # Agent owns planning

capability = CapabilityRegistry.get('issue_fix')
transition = capability.validate_and_propose(agent_plan)  # Capability validates

```

## Provider: External Interaction Boundary

The **Provider** serves as the exclusive boundary for external system communication. It owns all external calls, bounded observations, and effect result read-back.

Provider limitations:
- Returns observations only; cannot alter LoopX todo or transition policies
- No access to domain transition policy
- Stateless with respect to LoopX internal state

```python

# Provider fetches external data (e.g., GitHub PR status)

provider = ProviderRegistry.get('github')
observation = provider.fetch_pr_status(transition.pr_id)  # Provider owns external call

```

Provider implementations are located in `loopx/providers/**/*.py`.

## Capability: Validation and Proposal Layer

The **Capability** owns the **caller-facing outcome contract** and acts as the policy enforcement layer. It validates observations, normalizes them to domain types, and proposes typed transitions.

Capability responsibilities include:
- Domain policy enforcement
- Observation normalization
- Validation logic
- Typed transition proposals

Critically, Capability **does not** directly write to kernel scheduling, claims, or gates. It proposes; the Kernel disposes.

The `CapabilityRegistry` in [`loopx/capabilities/registry.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/registry.py) manages these contracts.

## Kernel: Sole State Authority

The **LoopX Kernel** ([`loopx/kernel.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/kernel.py)) is the **exclusive owner** of durable state changes. No other component persists state or orchestrates scheduling.

Kernel owns:
- Goal lifecycle
- Todo state
- Claim and gate management
- Monitor and quota enforcement
- Recovery mechanisms
- Scheduling decisions

Kernel explicitly excludes domain-specific reasoning and provider implementation details, maintaining architectural neutrality.

```python

# Kernel commits the transition after validation

kernel = LoopXKernel()
kernel.apply_transition(transition, observation)  # Kernel owns write-back

```

## Contract Enforcement in Practice

The complete flow respects all ownership boundaries:

```python

# Agent plans

agent_plan = agent.plan(goal)

# Capability validates and proposes

capability = CapabilityRegistry.get('issue_fix')
transition = capability.validate_and_propose(agent_plan)

# Provider observes external state

provider = ProviderRegistry.get('github')
observation = provider.fetch_pr_status(transition.pr_id)

# Kernel finalizes state change

kernel = LoopXKernel()
kernel.apply_transition(transition, observation)

```

Each handoff enforces the contract: Agent never writes to kernel, Provider only returns observations, Capability validates and proposes without direct writes, and Kernel exclusively commits state.

## Key Source Files

- **Architecture definition:** [`docs/architecture.md`](https://github.com/huangruiteng/loopx/blob/main/docs/architecture.md) — runtime responsibility table at line 123
- **Capability registry:** [`loopx/capabilities/registry.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/registry.py)
- **Provider implementations:** `loopx/providers/**/*.py`
- **Kernel core:** [`loopx/kernel.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/kernel.py)

## Summary

- **Agent** handles planning and bounded execution without durable state access
- **Provider** manages external calls and returns observations without policy authority
- **Capability** enforces domain contracts and proposes transitions without direct persistence
- **Kernel** exclusively owns scheduling, goals, todos, gates, and state recovery

This layered contract system ensures independent testability, prevents accidental authority leakage, and enables safe evolution of each LoopX component.

## Frequently Asked Questions

### What happens if a Provider tries to modify LoopX state directly?

The architecture prevents this by design. Providers in `loopx/providers/**/*.py` have no import or access path to kernel state methods. They return observations back through the Capability layer, which proposes transitions the Kernel may accept or reject.

### Can an Agent interact with the Kernel without a Capability?

No. The Agent's only interaction path is through Capability invocation. The Capability layer in [`loopx/capabilities/registry.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/capabilities/registry.py) owns the contract boundary that translates Agent intent into validated, typed proposals for Kernel evaluation.

### How does the LoopX Kernel handle conflicting transition proposals?

The Kernel owns claim, gate, and monitor mechanisms. According to [`loopx/kernel.py`](https://github.com/huangruiteng/loopx/blob/main/loopx/kernel.py), it evaluates proposals against quota and scheduling constraints, applying only accepted transitions to the durable goal and todo state. Rejected proposals do not mutate state.

### Why does Capability own "typed transition proposals" but not "durable scheduling"?

Capability provides domain-validated, type-safe proposals representing *what should happen*. The Kernel decides *when and if* it happens based on scheduling, quota, and recovery policies. This separation prevents domain logic from circumventing resource and safety controls.