CAP_02 — Core Model¶
1. Core roles¶
The current v0.1 package implements four functional roles. Roles are semantic responsibilities, not deployment units. A single process MAY implement multiple roles, but every CAP message MUST identify the capability under which it acts.
| Role | Core responsibility | Examples outside Core |
|---|---|---|
Controller |
Forms intent and issues Directive objects. |
Planner, reasoner, supervisor, orchestrator node. |
Guard |
Evaluates Directives and emits GuardDecision objects. |
Safety policy adapter, privacy gate, compliance engine, OPA sidecar. |
Executor |
Accepts, refuses, or executes Directives under constraints. | Tool runner, browser actor, robot actor, API caller, UI renderer. |
Observer |
Emits telemetry/provenance from CAP lifecycle events. | OTel collector, PROV exporter, audit dashboard. |
CAP v1 keeps these roles but adds explicit deployment and enforcement roles around them:
| v1 role or component | Responsibility |
|---|---|
Local PEP |
Enforces hot-path local policy, privacy, refusal, offline fallback, and streaming gates before user-visible output. |
Edge PEP |
Enforces CAP envelopes at process, host, service, agent, or tool network boundaries. |
Decomposed Control Plane |
Coordinates Controller, Supervisor Gateway, Session Router, logical Interrupt Manager, PDP adapters, and Human Review integration without absorbing registries or observability sinks into one process. |
Supervisor Gateway |
Mediates structured supervisor output, validates authority scope, and applies privacy filtering before supervisor consultation. |
PDP |
Evaluates OPA, Cedar, or equivalent policy locally and centrally. |
Session Router |
Tracks active session participants and routing decisions without owning raw session content. |
Federated Registries |
Capability, Policy, and Evidence registries provide independently cacheable metadata and signed bundles; agent, tool, service, human, and policy-subject records use the unified Capability shape. |
Observability Plane |
Receives signed audit records, OpenTelemetry telemetry, and W3C PROV independently of synchronous control traffic. |
The Supervisor is not a single CAP component. CAP v1 separates the Supervisor authority role, the Supervisor Gateway endpoint, and the model/human/rule engine behind that endpoint.
Capability is the v1 target metadata object for agent, tool, service, human, and policy subjects. It uses one shared structure and a required kind discriminator instead of separate Core shapes for agents, tools, services, humans, and policies.
Required v1 Capability fields:
| Field | Semantics |
|---|---|
capability_id |
Stable identifier for this capability record. |
kind |
Subject discriminator: agent, tool, service, human, or policy. |
subject_id |
Stable identity or URI for the subject that holds or exposes the capability. |
operations |
Non-empty list of operations this capability authorizes or advertises. |
Optional v1 Capability fields:
| Field | Semantics |
|---|---|
endpoint |
Transport or local reference used to reach the subject, such as a local URI, SPIFFE URI, MCP URI, or service endpoint. |
risk_level |
Profile- or deployment-defined risk label used by policy and registry decisions. |
policy_refs |
Policies governing use, discovery, or delegation of the capability. |
profile_extensions |
Namespaced integration/profile metadata. A2A AgentCard pointers and MCP server/tool/schema details belong here, not as CAP Core fields. |
Federated Capability Registries resolve these records by capability_id, check metadata freshness/version/digest, and authorize requested operations against the operations list. Registry entries may cache A2A or MCP metadata in profile_extensions, but CAP does not redefine AgentCard, MCP server, MCP tool, or MCP input-schema formats.
The current deterministic Python registry scaffold stores agent, tool, service, human, and policy-subject registrations as the same closed Capability metadata shape. AgentRegistry, ToolRegistry, ServiceRegistry, HumanRegistry, and PolicySubjectRegistry remain compatibility views for callers that want a kind-specific registry, but their stored metadata is normalized to Capability with a fixed kind; the central CapabilityRegistry can resolve and authorize all five subject kinds directly.
Legacy-role mapping¶
Older CAP drafts used eleven roles. In v0.1-candidate these become specializations:
| Older role | v0.1-candidate mapping |
|---|---|
| PlannerAgent, ReasonerAgent, CriticAgent | Controller specialization or internal orchestration role. |
| SafetyAgent, PolicyAgent, PrivacyAgent | Guard specialization or external policy decision point. |
| InterfaceAgent, ExecutionAgent | Executor specialization. |
| MemoryAgent | Evidence/memory infrastructure, not a Core role. |
| AuditorAgent | Observer or observability infrastructure. |
| HumanReviewer | External workflow actor; may produce an authority step or policy decision through an application workflow. |
2. Envelope¶
Every CAP object MAY be carried directly or embedded inside another protocol such as A2A. When serialized by the current package, it uses this v0.1 envelope.
| Field | Required | Semantics |
|---|---|---|
cap_version |
yes | CAP profile version, e.g. 0.1. |
message_id |
yes | Globally unique message identifier. ULID or UUID recommended. |
message_type |
yes | One of Directive, GuardDecision, RefusalMessage, ExecutionReport, DecisionRecord. |
session_id |
recommended | Stable interaction/session identifier. |
task_id |
recommended | Task/work item identifier. MAY map to A2A Task id. |
correlation_id |
optional | Cross-message correlation id. |
created_at |
yes | RFC 3339 timestamp. |
expiry |
conditional | Required for Directive and GuardDecision; optional otherwise. |
sender_id |
yes | Stable agent/workload identity URI. |
receiver_id |
optional | Required for unicast; absent for broadcast telemetry. |
sender_capability |
recommended | Capability claim under which the sender acts. |
receiver_capability |
optional | Expected receiver capability. |
payload |
yes | The CAP primitive payload. |
attestation_ref |
optional | DSSE/COSE/JOSE/in-toto reference or embedded object. |
trace_context |
optional | W3C Trace Context fields. |
profile_extensions |
optional | Namespaced profile-specific extension object. |
CAP v1 renames this concept to CAPEnvelope and tightens the target verification model. The checked-in v1 LinkML and JSON Schema artifacts define target scaffolding for CAPEnvelope; the gRPC reference demo and independent HTTP/JSON demo now use v1 CAPEnvelope plus v1 Core payload objects on their active hot paths. The v1 CAPEnvelope required fields are:
cap_version,envelope_id,session_id,trace_id,sender_id,receiver_id,message_kind, exactly one ofpayload_reforpayload,authority_chain_ref,policy_refs,privacy_boundary_ref,timestamp,ttl_ms, andsignature;- canonicalization before signing, with the current signing decision summarized in
CAP_04_security_trust_evidence.md; - sender signature verification before cross-trust-boundary processing;
- privacy-boundary validation before payload dereference or user-visible delivery.
Placement rules¶
- Constraints belong in the
Directive.payload.constraints, not in the envelope. - Evidence references belong in the payload that uses or produces evidence.
- In v1
CAPEnvelope,policy_refsare required boundary metadata; payload-specific policy references still belong in objects such asDirective,GuardDecision, orExecutionReport. - Authority MUST NOT be inferred from
sender_idalone. Authority requires identity, capability, scope, policy, freshness, and attestation.
3. Lifecycle finite-state machines¶
CAP v1 now has machine-checkable lifecycle finite-state machines in cap_protocol.runtime.lifecycle. The runtime scaffold covers the envelope, directive, interrupt, execution, evidence, audit, and provenance domains; conformance calls the same definitions instead of relying only on prose. The table below is the human-readable Directive projection of that executable model.
A Directive has one lifecycle. Multiple messages may refer to it, but implementations MUST maintain a single effective state per directive_id.
| From state | To state | Trigger/event | Actor | Required validation | Terminal |
|---|---|---|---|---|---|
null |
proposed |
Directive drafted | Controller | Schema valid; expiry in future; idempotency key not conflicting. | no |
proposed |
under_guard_review |
Guard review requested | Controller or runtime | PolicyRef resolvable; evidence refs syntactically valid. | no |
under_guard_review |
approved |
Required GuardDecision set allows dispatch | Guard/runtime | Decisions unexpired; no deny; constraints merge valid. | no |
under_guard_review |
denied |
Any required GuardDecision is deny, or conflict cannot be resolved |
Guard/runtime | Denial reason recorded. | yes |
under_guard_review |
proposed |
Guard requires more evidence or modification | Controller/runtime | Missing evidence/remediation attached. | no |
approved |
dispatched |
Controller sends to Executor | Controller | Effective constraints and authority chain attached. | no |
dispatched |
accepted |
Executor accepts | Executor | Authority, evidence, policy, capability, expiry, and constraints verified. | no |
dispatched |
refused |
Executor emits RefusalMessage | Executor | Refusal reason maps to closed enum. | yes |
accepted |
executing |
First external action begins | Executor | No expiry; no active deny; idempotency checked. | no |
executing |
succeeded |
Execution completed | Executor | ExecutionReport valid; evidence/side effects recorded. | yes |
executing |
partially_succeeded |
Partial completion | Executor | Report includes incomplete steps and side effects. | yes |
executing |
failed |
Execution failed | Executor | Error object included. | yes |
executing |
aborted |
Execution stopped before completion | Executor/runtime/Guard | Abort reason and side effects recorded. | yes |
succeeded or partially_succeeded |
compensated |
Reversal/compensation completed | Executor/runtime | Compensation result recorded. | yes |
| any non-terminal | expired |
Expiry passes before terminal state | Runtime | Expiry timestamp verified. | yes |
The executable lifecycle domains use these initial and terminal states:
| Domain | Initial state | Terminal states |
|---|---|---|
envelope |
created |
accepted, refused, expired |
directive |
proposed |
denied, refused, succeeded, partially_succeeded, failed, aborted, compensated, expired |
interrupt |
issued |
applied, superseded, refused, expired |
execution |
not_started |
succeeded, partially_succeeded, failed, aborted, compensated |
evidence |
referenced |
accepted, refused, expired |
audit |
pending |
replicated, retained, failed |
provenance |
pending |
queryable, failed |
Allowed transitions are explicit. Unknown states, skipped precondition states, and terminal-to-non-terminal resumes fail validation. Compensation is modeled as an explicit terminal-to-terminal transition from succeeded or partially_succeeded to compensated, preserving the invariant that terminal states never resume active execution.
4. Lifecycle invariants¶
A CAP Core implementation MUST enforce these invariants:
- No external execution without a valid, unexpired
Directive. - No execution when any required, unexpired
GuardDecisionisdeny. allow_with_constraintsMUST strictly narrow or preserve Controller constraints. It MUST NOT broaden them.- Every
ExecutionReportMUST reference exactly oneDirective. - Every
RefusalMessageMUST reference exactly one refused message, normally aDirective. - Duplicate
Directivedelivery MUST be idempotent or safely refused. - A terminal Directive state MUST NOT transition to a non-terminal state.
- Required evidence MUST be available, authorized, fresh, and hash-valid before execution.
- A late Guard denial after execution has started MUST abort execution if possible; if not possible, it MUST trigger compensation if compensation is available and policy requires it.
- Observability events MUST be emitted for all terminal states.
5. Effective constraint merge¶
The retained v0.1 compatibility helpers carry an open ConstraintSet object inside Directive.payload.constraints. CAP v1 narrows that shape into Core OperationalConstraints plus namespaced profile constraints. v0.1 compatibility remains in the v0.1 schemas and fixtures; migrated gRPC and HTTP/JSON hot paths use OperationalConstraints.
The Executor acts on the effective constraints, computed from:
If two constraints cannot be intersected safely, the result is denial. Examples:
| Constraint type | Merge rule |
|---|---|
allowed_tools |
Intersection. |
forbidden_tools |
Union. |
max_wall_time_ms |
Minimum. |
max_tool_calls |
Minimum. |
max_cost |
Minimum. |
budget |
Minimum. |
network_egress |
Intersection/most restrictive. |
data_access_scope |
Intersection/most restrictive. |
Profile-specific constraints, such as non-diagnostic style, psychometric scoring, medical thresholds, escalation thresholds, or human confirmation requirements, MUST NOT become top-level Core fields. They belong under profile_constraints in an OperationalConstraints object or under the containing object's profile_extensions. A policy-driven human review block is represented by GuardDecision.require_human_review, not by adding requires_human_confirmation to Core OperationalConstraints.
6. Guard conflict resolution¶
Default conflict behavior is conservative.
| Situation | Default result |
|---|---|
Any required Guard returns deny |
Deny. |
| Required GuardDecision expired | Treat as absent; deny or require revalidation. |
allow + allow_with_constraints |
Allow with narrowed constraints. |
require_more_evidence and no evidence supplied |
Return to proposed; no dispatch. |
require_human_review |
Block until external workflow produces a valid authority or policy decision. |
Only advisory_warning |
Does not block, but MUST emit telemetry. |
| Conflicting non-deny decisions without resolution strategy | Deny safely. |
Profiles MAY define more specific conflict-resolution policies, but Core implementations MUST have a safe-deny fallback.
7. Authority verification overview¶
Authority is an explicit warrant chain, not a role label or a trusted sender_id. Before execution, the PEP or Executor verifies:
- The Directive schema is valid.
- The Directive has not expired.
- Required Guard decisions are present and valid.
- The resolved
AuthorityChaindeclares itswarrant_formatand every step carriesdelegator,delegatee,identity_binding,capability,scope,policy_ref,issued_at,expires_at,revocation_ref,delegation_constraints, andsignature. - The final delegatee is holder-bound to the sender or actor identity, for example by SPIFFE SVID, X.509, OIDC, DID, or a profile-selected equivalent.
- Capability and scope cover the requested action/resource/tool.
- Delegated steps attenuate scope and constraints monotonically.
- Expiry, not-before, revocation, and policy metadata are acceptable for the decision class.
- Signatures, DSSE/COSE/JOSE/in-toto attestations, or profile-selected capability warrants verify offline where the active profile requires offline verification.
- Evidence references are resolvable, authorized, fresh, and hash-valid.
- Effective constraints allow the requested action.
Failure at any step yields RefusalMessage.
8. v1 tiers, planes, and enforcement points¶
CAP v1 has two deployment tiers and three logical planes. The local tier contains Local PEPs near agents, tools, local memory, and user surfaces. The federated tier contains the decomposed Control Plane, Edge PEPs, PDP adapters, Human Review integration, and independently deployable Capability, Policy, and Evidence registries.
The data plane is ordinary A2A, MCP, HTTP, gRPC, WebSocket, and local IPC traffic carrying CAP metadata or payload references. The control plane carries CAPEnvelope, Directive, GuardDecision, InterruptDecision, RefusalMessage, and ExecutionReport objects. The observability plane carries signed audit records, OpenTelemetry telemetry, and W3C PROV graphs to separate sinks; it should not be required for every hot-path policy decision unless a profile explicitly makes audit persistence a precondition.
See architecture.md#architecture-diagrams for the visual target topology and the current-vs-target status captions.
9. v1 runtime lanes and enforcement points¶
CAP v1 uses three runtime lanes:
| Lane | Location | Purpose |
|---|---|---|
| Fast lane | Local PEP | Local policy, redaction, evidence-reference substitution, and low-latency output gates. |
| Control lane | Control Plane and Supervisor Gateway | Supervisor consultation, cross-cutting policy, routing, and interrupt coordination. |
| Analysis lane | Async specialists and observability sinks | Non-blocking scoring, trend analysis, telemetry, audit, and provenance export. |
The motivating Therapist/Supervisor scenario is a profile example, not CAP Core. It uses the fast lane for non-diagnostic, non-prescriptive output filtering and local privacy enforcement. Sensitive or uncertain turns can pause into the control lane for central Supervisor review through a Supervisor Gateway. Longer-running specialist analysis stays asynchronous and can constrain future turns rather than blocking the current one. The Local PEP remains the final local veto for Supervisor directives that violate privacy, non-diagnostic, jurisdiction, or safety policy.
10. v1 implementation status¶
Current implementation evidence:
- Controller, Guard, Executor, and Observer flows exist in gRPC and HTTP/JSON bindings, and a v1
ControllerServicenow separates Controller-owned intent formation/orchestration from injected Guard/PDP evaluation,SessionRouterdelivery, and observability sinks. - Directives, GuardDecisions, RefusalMessages, ExecutionReports, EvidenceRefs, and AuthorityChainSteps are represented.
- CAP-Med profile constraints demonstrate non-diagnostic and non-prescriptive Therapist/interviewer behavior, raw-transcript minimization, and Local PEP veto of unsafe Supervisor directives. The v1 runtime-profile fixture keeps those rules under
profile_constraints.cap-med/v1andprofile_extensions.cap-med/v1while reusing CAP Core objects unchanged.
Open v1 gaps:
- Local PEP and Edge PEP now exist as minimal reusable runtime scaffolds and are wired into selected gRPC/HTTP v1 demo paths; production deployment and trust modes remain open.
- The old gRPC
CAPCenterstill combines Controller, Guard, and Observer as a preserved v0.1 legacy compatibility path; production Controller deployment, production Guard/PDP clients, router discovery, observer pipelines, HA state, and live Control Plane service wiring remain open. CAPEnvelope,InterruptDecision, structuredPrivacyBoundary,Capability, andOperationalConstraintsnow have initial v1 LinkML authoring schemas, JSON Schema artifacts, examples, migrated gRPC/HTTP hot-path coverage, and deterministic in-process privacy PDP evaluation; retained v0.1 helpers still preserve the legacy message shapes for compatibility.- Streaming transform/correction behavior exists as Local PEP reference scaffolding with configurable lookahead metadata, deterministic semantic slow-path classification, wall-clock release, a pull-based live model-stream adapter for local scripted chunks or optional Ollama chunks, and CLI/WebSocket-style abort replacement contracts. Shipping native UI wrappers, production provider rollout, organization-selected model-judge rollout, and deployed stream control remain open.
- Federated Capability, Policy, and Evidence registries now have deterministic runtime clients plus SQLite-backed reference services. Capability views cover agent, tool, service, human, and policy subjects; agent/tool demo discovery resolves A2A and MCP metadata from service-backed Capability records; Evidence Registry storage can put/get/verify content-addressed blobs with attestation metadata and delete expired backing content while preserving content-minimized audit records. Production network deployment, service authentication, HA replication, scheduled retention operations, and access-policy enforcement remain open.
- Independent observability-plane sink scaffolding now exists for durable/tamper-evident audit, signed audit operations, lossy/sampled telemetry, and queryable W3C PROV-JSONLD lineage; production exporter/collector/PROV-store deployment and v0.1 demo wiring remain migration tasks.