Skip to main content

Concepts · 2 of 7

Protocols and compositions

A protocol says what must be true. A composition says who, when and with which tools.

Decision record 0087, with each status checked against Canon and engineering protocols code

Governing engineering work takes two kinds of statement, and engineering protocols keep them apart.

  • A protocol says what must be true before work counts, which evidence establishes it, which actions exist and which of them need authority. It never names a person, a model, a tool or a schedule. Engineering protocols are Canon protocol/1 documents.
  • A composition says, for one organization, who does the work, when a case opens and with which tools: agents, triggers, policy, runtime bindings and projections. It never decides what counts as done. A composition is its own document family, composition/1 (decision record 0087).

The split is what lets the same protocol run in another organization, with other people, other agents and other tools.

Shipped · runs today

Decided · recorded, not built

  • DecidedTwo layers: protocol and compositionDecision record 0087.
  • Decidedcomposition/1 as its own document familyRead by Commission, the intent router and the projector; none of them owns it. No format exists yet: its ESS domain comes first.

Planned · roadmap only

  • PlannedTriggers in the compositionOpen: they may move to the intent router's own configuration.
  • PlannedComposition validation and protocol pinningOpen: a composition may only reference capabilities its pinned protocols declare.

A protocol​

incident.response/1 ships here. An excerpt: two claims, an urgent obligation, and the action that leaves emergency mode once the service is healthy and the impact bounded, whatever is known of the cause.

protocols/incident-response/1.yaml (excerpt)
claims:
service.healthy:
true_when:
evidence: {kind: operational_observation, result: healthy, subject: service}
cause.identified:
true_when:
evidence: {kind: cause_analysis, result: identified}

obligations:
restore_service:
description: urgent; bring the affected service back to health
discharged_when: {claim: service.healthy, is: true}

actions:
release.rollback:
effect: write
requires:
- capability: release.rollback
emergency.leave:
precondition:
all:
- {claim: service.healthy, is: true}
- {claim: impact.bounded, is: true}

Nothing in it says who rolls back, which deployment tool does it, or who approves. The protocol only says that release.rollback needs the capability release.rollback.

Protocol · revision 1

incident.response/1

Respond to an incident through two obligations that progress independently: restore_service, on which emergency mode is left, and investigate_cause, which stays open after emergency mode ends until a cause analysis of a current revision of the service or the release identifies the cause. A rollback of the release is verified only on a complete rollback result from a verifier the case lists as another principal than the one who rolled it back. The service is healthy only on an observation at most 30 minutes old.

  • Actions6
  • Evidence kinds4
  • Claims4
  • Obligations2
  • Precondition, traced on hover
  • Needs authority
ACTIONemergency.leaveACTION · READlogs.searchACTION · READmetrics.inspectACTION · READrelease.inspectACTION · WRITErelease.rollbackACTION · WRITEtraffic.shiftEVIDENCE KINDcause_analysisEVIDENCE KINDimpact_assessmentEVIDENCE KINDoperational_observationEVIDENCE KINDrollback_resultCLAIMcause.identifiedCLAIMimpact.boundedCLAIMrollback.verifiedCLAIMservice.healthyOBLIGATIONinvestigate_causeOBLIGATIONrestore_service

Hover or focus a node to trace what it rests on and what rests on it. Press Enter to pin it, Escape to clear.

Protocol as text
Actions
NameDescriptionRuleLeads to
emergency.leaveleave emergency mode; admissible once restore_service is discharged and the impact is bounded, whatever is known of the causeall of claim impact.bounded claim service.healthy—
logs.searchsearch the system's logseffect readproduces cause_analysis
metrics.inspectread the system's metricseffect readproduces impact_assessment; produces operational_observation
release.inspectread what a release containseffect readproduces cause_analysis
release.rollbackreturn to a previous releaseneeds release.rollback effect writeproduces rollback_result
traffic.shiftmove traffic between deploymentsneeds traffic.shift effect write—
Evidence kinds
NameDescriptionRuleLeads to
cause_analysisan analysis of why an incident happened—establishes cause.identified (identified)
impact_assessmentan assessment of who and what an incident affects—establishes impact.bounded (bounded about service)
operational_observationan observation of the running system; its result is healthy or unhealthy, and it applies for 30 minutes after it is observed, after which it no longer says anything—establishes service.healthy (healthy about service)
rollback_resultthe result of returning a release to the one before it; its result is complete or partial—establishes rollback.verified (complete about release, independent on different_principal)
Claims
NameDescriptionRuleLeads to
cause.identifiedthe incident's cause is knownevidence = identified: cause_analysisrequires investigate_cause
impact.boundedthe incident's impact is known and containedevidence = bounded: impact_assessmentgates emergency.leave
rollback.verifiedthe release's rollback is complete, by a rollback result from a producer the case lists as another principal than the one who rolled it backevidence = complete: rollback_result—
service.healthythe service is running healthilyevidence = healthy: operational_observationrequires restore_service; gates emergency.leave
Obligations
NameDescriptionRuleLeads to
investigate_causeestablish why the incident happened; stays open after emergency mode ends until a cause analysis of a current revision of the service or the release identifies the causeclaim cause.identified—
restore_serviceurgent; bring the affected service back to healthclaim service.healthy—

Source: protocols/incident-response/1.yaml

A composition​

There is no composition/1 format yet. The sketch below is illustrative: it shows the five sections decision record 0087 names, for an organization running incident.response/1.

composition sketch (illustrative, no format yet)
format: composition/1
id: example-operations
protocols: # pinned protocol sources
- els/incident.response@1
triggers: # what opens a case
- on: {event: alert.fired, where: {severity: page}}
open: {protocol: incident.response, subject: {service: $event.service}}
agents: # who takes which cases
responder:
executor: harness
model: example-model
takes: [incident.response]
policy: # capability → who, and how
release.rollback: {require_approval: [human:operator]}
traffic.shift: {require_approval: [human:operator]}
metrics.read: {allow: [agent:responder]}
bindings: # capability → data contract → connection
metrics.read: {contract: series/v1alpha1, connection: metrics-prod}
logs.read: {contract: logs/v1alpha1, connection: logs-prod}
projections: # where case state is mirrored
- from: incident.response
to: {connection: chat, channel: incidents}
SectionAnswersRead by
triggersA schedule or an event opens a case of protocol Xthe intent router
agentsExecutor, model, budget, and which protocols each takesCommission
policyFor each capability: allow, require approval or deny, per principal, plus limitsCommission
bindingsWhich connection implements a capability (Capabilities and bindings)Commission
projectionsWhere case state is mirrored, such as a tracker or a chat channelthe projector

A rule that today lives in prose, such as "only the operator decides" or "never force-push", lands in exactly one place: a protocol claim or outcome when it is about what counts, or a composition policy line when it is about who may act.