> Status: draft. Part of the Harmovela 0.2 specification.
Define optional capability bundles (profiles) that may be adopted independently from the core protocol. Profiles allow implementations to declare and negotiate capabilities beyond the minimum conformance baseline without requiring every implementation to support every feature.
Each profile has a unique string identifier following the pattern harmovela.<domain>.<name>.<version>, for example harmovela.delivery.v1. Profile identifiers are stable within a major version and must not change semantics in a backward-incompatible way without a version bump.
A profile may declare dependencies on other profiles or on core conformance levels. Dependencies are transitive: adopting a profile implies adopting all profiles it depends on.
| Profile | Depends On |
|---|---|
harmovela.delivery.v1 | Core HARMOVELA-C0 + HARMOVELA-C1 |
harmovela.security.v1 | Core HARMOVELA-C0 + HARMOVELA-C1 |
harmovela.runtime-semantics.v1 | Core HARMOVELA-C0 + HARMOVELA-C1 |
harmovela.coordination.v1 | harmovela.core.v1 + harmovela.security.v1 |
harmovela.adaptation.v1 | harmovela.coordination.v1 + harmovela.security.v1 |
harmovela.transport.websocket.v1 | Core HARMOVELA-C0 |
harmovela.transport.sse.v1 | Core HARMOVELA-C0 |
harmovela.transport.grpc.v1 | Core HARMOVELA-C0 |
harmovela.transport.nats.v1 | Core HARMOVELA-C0 |
harmovela.transport.kafka.v1 | Core HARMOVELA-C0 |
harmovela.transport.redis-streams.v1 | Core HARMOVELA-C0 |
During session initialization, a peer declares supported profiles in capabilities.profiles:
{
"capabilities": {
"aep_version": "0.2",
"profiles": [
"harmovela.delivery.v1",
"harmovela.security.v1",
"harmovela.transport.websocket.v1"
]
}
}
Both sides negotiate a shared profile set. If a required profile is not supported by the peer, the session must not become ready. The peer should send session.error with code unsupported_profile and details.required listing the unavailable profiles.
Profiles version independently of the protocol envelope and of each other. A profile version bump indicates one of:
Implementations should reject requests requiring an unsupported profile version.
Each profile defines its own conformance requirements through the standard conformance levels (HARMOVELA-C0 through HARMOVELA-C3) plus profile-specific test fixtures. A profile conformance manifest lives under conformance/profiles/<profile-id>/manifest.json.
Profiles are declared in the top-level profiles object of conformance/manifest.json:
{
"profiles": {
"delivery": {
"display_name": "Durable Delivery",
"description": "At-least-once and replayable delivery...",
"fixtures": [
"fixtures/delivery.ndjson",
"fixtures/delivery-stateful.ndjson",
"fixtures/delivery-e2e.ndjson"
]
}
}
}
Each fixture may declare a profile field to associate itself with a specific profile. Fixtures without a profile field are considered core fixtures and are always run.
The conformance runner supports --profile=<name> to run only fixtures belonging to a specific profile, plus all core fixtures (those without a profile field). When profile filtering is active:
1. Core fixtures (no profile field) are always included. 2. Only fixtures whose profile field matches the selected profile AND whose path appears in the profile's fixtures list are included. 3. Fixtures belonging to other profiles are excluded.
Example: --profile=delivery runs core fixtures plus the three delivery-specific fixtures.
This filtering behavior is available in:
node tools/conformance-runner.js --profile=deliverynode implementations/typescript/src/cli/harmovela.js conformance --profile=deliverycd implementations/python && python -m axisrobo_harmovela.cli.main conformance --profile=deliverycd implementations/go && go run ./cmd/harmovela conformance --profile=deliverycd implementations/java && mvn -q exec:java -Dexec.mainClass=com.axisrobo.harmovela.cli.HarmovelaCli -Dexec.args="conformance --profile=delivery"| Dimension | Contract document |
|---|---|
| Event | Event contract |
| Recovery | Delivery + Reliability |
| Governance | Governance contract + Security |
| Task | Task lifecycle |
| State | Event dimension classification |
| Context / Memory | Event dimension classification |
| Delegation | Agent runtime semantics + Coordination profile |
| Tool | Event dimension classification |
| Agent | Event dimension classification |
| Environment | Event dimension classification |
| Adaptation | Adaptation feedback + Adaptation budget + Governance contract |
| Command | Command and Query |
| Query | Command and Query |
Identifier: harmovela.core.v1
Conformance: HARMOVELA-C0 + HARMOVELA-C1
Scope: Protocol envelope, session lifecycle, subscription model, task lifecycle, error model, event routing. Every conformant Harmovela implementation must satisfy the core profile.
Covered specifications:
Identifier: harmovela.delivery.v1
Conformance: HARMOVELA-C2 + HARMOVELA-C3
Scope: Durable delivery, acknowledgement and negative acknowledgement, dead-letter, replay, delivery tracking statistics.
Covered specifications:
Identifier: harmovela.security.v1
Conformance: HARMOVELA-C0 + HARMOVELA-C1
Scope: Identity, authorization, audit, tenant isolation.
Covered specifications:
event.rejected with code unauthorized.Identifier: harmovela.runtime-semantics.v1
Conformance: HARMOVELA-C0 + HARMOVELA-C1
Scope: Agent-oriented runtime semantics including belief, freshness, delegation, interruption, compensation, and provenance.
Covered specifications:
Identifier: harmovela.coordination.v1
Conformance: HARMOVELA-C1
Dependencies: harmovela.core.v1 + harmovela.security.v1
Scope: Task lifecycle state-machine enforcement, State freshness and invalidation semantics, Delegation ownership, handoff, escalation, and cancellation propagation, Command directed instruction lifecycle with negotiation windows, and Query directed information requests with snapshot-versioned responses.
This profile exists alongside harmovela.runtime-semantics.v1, which retains agent-oriented belief, freshness, interruption, compensation, and provenance semantics. Where runtime-semantics covers cognitive and epistemic concerns, coordination covers operational multi-agent collaboration: who owns work, how work transfers between agents, how stale state is detected and invalidated, and how cancellation cascades through a delegation tree.
Covered specifications:
valid_from and stale_after metadata. Consumers may subscribe to freshness.* events. A stale state assertion triggers invalidation through the context dimension.delegation.requested → delegation.accepted → delegation.handoff.completed. Ownership transfer is atomic and trackable through a delegation chain. Handoff rejects (delegation.rejected) terminate the delegation flow for that target.delegation.escalated. Escalation is only valid while the delegation is active (not after rejection).task.cancelled for each child referencing the parent via causation_id. Cancellation is irreversible; a completed task cannot be cancelled.command.requested → command.accepted/command.rejected → command.completed/command.failed. Commands carry target agent, correlation_id, delegation chain, and authorization scope. Accepted commands must ack within negotiation window. Specified in command-query.md.query.requested → query.response/query.rejected → query.error. Queries carry target, query scope, freshness requirements, and pagination hint. Responses carry snapshot version for idempotent re-query. Specified in command-query.md.Identifier: harmovela.adaptation.v1
Conformance: HARMOVELA-C1
Dependencies: harmovela.coordination.v1 + harmovela.security.v1
Scope: Feedback/outcome correlation, protocol-level budget authority and enforcement, and adaptation-operation authorization and audit linkage. This is a C1-level optional profile that depends on both the coordination profile (for delegation and task-ownership semantics) and the security profile (for identity, authorization, audit, and tenant-isolation boundaries).
The adaptation profile extends the coordination layer with the capability to observe outcomes, enforce resource boundaries, and link adaptation operations to authority and audit records. It does not duplicate coordination, security, or event envelope behavior; it defines only the adaptation-specific extensions.
Covered specifications:
adaptation.outcome.correlated, adaptation.goal.achieved, adaptation.goal.blocked, adaptation.cost.exceeded. Specified in adaptation feedback.budget.establish capability), the enforcement point (harness-level check before each action dispatch), and structured events for budget lifecycle. Event types: adaptation.budget.established, adaptation.budget.limit_approaching, adaptation.budget.limit_exceeded. Specified in adaptation budget.budget.establish and budget.enforce actions against the capability-based authorization model. No agent may establish a budget or trigger enforcement without the corresponding capability. Specified in governance contract.Negotiation: An implementation declares adaptation support by including harmovela.adaptation.v1 in capabilities.profiles. Because the adaptation profile depends on harmovela.coordination.v1 and harmovela.security.v1, both must also be present in the negotiated profile set. If either dependency is absent, the session must not become ready.
Profile family: Adaptation feedback and budget events use the adaptation.* event family prefix, owned by the Governance dimension under the event registry governance model.
Transport profiles define wire-level bindings for Harmovela communication. Each transport profile is independent and optional. An implementation may support zero or more transport profiles.
| Profile ID | Transport | Specification |
|---|---|---|
harmovela.transport.stdio.v1 | stdio | design/protocol/transport-stdio.md |
harmovela.transport.websocket.v1 | WebSocket | design/protocol/transport-websocket.md |
harmovela.transport.sse.v1 | HTTP SSE | design/protocol/transport-sse.md |
harmovela.transport.grpc.v1 | gRPC streaming | design/protocol/transport-grpc.md |
harmovela.transport.nats.v1 | NATS | design/protocol/transport-nats.md |
harmovela.transport.kafka.v1 | Kafka | design/protocol/transport-kafka.md |
harmovela.transport.redis-streams.v1 | Redis Streams | design/protocol/transport-redis-streams.md |
Each transport profile specification defines framing rules, connection lifecycle, error handling for transport-level failures, and subprotocol or content-type identifiers.
A topology identifier is a distinct conformance axis from both profiles and transports. It names the participant structure a deployment runs under and is recorded alongside the transport profile in compatibility evidence. Topology identifiers follow the pattern harmovela.topology.<name>.<version>, version independently of profiles and transports, and are used when a matrix cell or pilot report must state which participant structure produced the result.
| Topology ID | Description |
|---|---|
harmovela.topology.hub-spoke.v1 | A central runtime/harness hub with producer and consumer agents attached via sessions; the hub owns routing, subscription fanout, and delivery state. This is the topology every reference runtime's fanout architecture implements. |
A topology identifier is named and versioned so that conformance and pilot evidence is reproducible; two reports with the same topology identifier must describe the same participant structure.
Profiles are declared during session establishment in the capabilities object. The negotiation flow:
1. Client sends session.open with capabilities.profiles listing supported profiles and versions. 2. Server responds with session.opened containing the intersection of supported profiles. 3. Client sends session.ready confirming the negotiated profile set. 4. If a required profile is absent from the intersection, either peer sends session.error with code unsupported_profile.
Example negotiation:
// Client → Server: session.open
{
"type": "session.open",
"aep_version": "0.2",
"capabilities": {
"aep_version": "0.2",
"profiles": [
"harmovela.core.v1",
"harmovela.delivery.v1",
"harmovela.security.v1"
]
}
}
// Server → Client: session.opened
{
"type": "session.opened",
"aep_version": "0.2",
"session_id": "sess-abc123",
"capabilities": {
"aep_version": "0.2",
"profiles": [
"harmovela.core.v1",
"harmovela.delivery.v1"
]
}
}
// Client → Server: session.ready (accepts negotiated set)
{
"type": "session.ready",
"session_id": "sess-abc123"
}
In this example, the security profile was not supported by the server and was dropped from the negotiated set. The client accepted the reduced set by sending session.ready. If the client required the security profile, it would instead send session.error with code unsupported_profile.