Skip to main content

Evaluation documents

Generated from the model types in crates/canon/src/model. canon evaluate reads a compiled protocol, one case snapshot, a set of evidence records and, optionally, a list of authority decisions and a list of explicit decisions, and writes a decision. canon check reads a protocol and, optionally, the properties declared beside it. Every key is listed; a key Canon does not know is refused.

canon-case/1​

Read by canon evaluate. The JSON Schema is generated from the same types.

Case​

A canon-case/1 case snapshot as written.

KeyValueRequiredMeaning
formattextrequiredThe document format; the evaluator accepts only canon-case/1.
ididentifier (CaseId)required—
protocolidentifier (ProtocolId)requiredThe protocol that governs the case.
artifactsmap from identifier (ArtifactId) to CaseArtifactrequiredThe current revision of each declared artifact, keyed by artifact id.
terminationidentifier (OutcomeId)optionalThe outcome the case terminated through; absent while the case is open. Whether the protocol declares it is checked by the outcomes section (story:outcomes).
revisionidentifier (Revision)optionalThe case's own current revision. An explicit decision applies only while its case_revision is this one; a snapshot without one has no explicit decision applying.
inputsmap from identifier (InputId) to identifier (InputValue)optionalThe value of each case input, keyed by input id, fixed when the case opens. Left out by a case of a protocol that declares no input.
independencemap from identifier (Principal) to list of identifier (IndependenceDimensionId)optionalThe dimensions on which each producer is independent of the case's work, keyed by producer, as the trusted context that writes the case resolved them. A producer absent from it, or listed with [], is independent on no dimension.

CaseArtifact​

One declared artifact as the case snapshot records it.

KeyValueRequiredMeaning
revisionidentifier (Revision)requiredThe artifact's current revision.

canon-evidence/1​

Read by canon evaluate. The JSON Schema is generated from the same types.

EvidenceRecord​

One canon-evidence/1 record as written. subject and subject_revision bind it: the evaluator refuses a record whose subject the protocol does not declare, and applies a record only while its subject revision is the case's current revision of that subject.

KeyValueRequiredMeaning
formattextrequiredThe document format; the evaluator accepts only canon-evidence/1.
ididentifier (EvidenceId)required—
kindidentifier (EvidenceKindId)requiredThe evidence kind, which the protocol declares.
resulttextoptionalWhat the observation found; a record without one matches only an evidence match that names no result.
subjectidentifier (ArtifactId)requiredThe artifact the record is about.
subject_revisionidentifier (Revision)requiredThe revision of that artifact the record is about.
observed_attext (Instant)optionalWhen the observation was made; its age at the evaluation instant is measured from here. A record without it never expires.
upstream_revisionsmap from identifier (ArtifactId) to identifier (Revision)optionalThe revision of each upstream artifact the observation was made against, keyed by artifact. A record without it is never invalidated.
produceridentifier (Principal)optionalWho produced the record, recorded as given: Canon does not prove it. A record without one is of no evidence match that demands independence.
child_caseidentifier (CaseId)optionalThe child case a case_outcome record is about (story:case-composition): one record per child case, its result the child's outcome, open while the child runs. Written only on a case_outcome record, which must name its child and give an outcome.

canon-decision/1​

Written by canon evaluate.

Decision​

A canon-decision/1 document. A section slot that is None is not serialized.

KeyValuePresentMeaning
formattextalwaysAlways canon-decision/1.
caseidentifier (CaseId)always—
protocolidentifier (ProtocolId)always—
protocol_revisioninteger, 0 or morealwaysThe revision of the compiled protocol that applied.
claimsmap from identifier (ClaimId) to ClaimDecisionalwaysEvery declared claim, in identifier order.
obligationsany JSON valuewhen presentEach declared obligation, in identifier order, with its ObligationStatus; written when the protocol declares an obligation. Its shape is fixed by CANON-OBLIGATION-001 and, for an obligation with an applicability predicate, CANON-INPUT-001.
actionsany JSON valuewhen presentEach declared action, admissible, approval-required or blocked, with the reasons for a status other than admissible; written when the protocol declares an action. Its shape is fixed by CANON-AUTHORITY-001.
outcomesany JSON valuewhen presentEach declared outcome, legitimate or blocked, with the reasons it is blocked; written when the protocol declares an outcome. Its shape is fixed by CANON-OUTCOME-001 and, for an outcome that requires an explicit decision, by CANON-OUTCOME-002: a legitimate one records decided_by ({"decision": <name>, "principals": [...]}), and a blocked one gives the reason {"decision": <name>, "present": false}.
explanationany JSON valuewhen presentWhy each claim that is not true, each open obligation, each action that is not admissible and each blocked outcome has its status, traced to the evidence records that applied or were excluded, and what the decision was computed from (computed_from); the evaluator writes it on every decision. Its shape is fixed by CANON-EXPLAIN-001.

ClaimDecision​

One claim's entry in a decision.

KeyValuePresentMeaning
valueTruthalways—
excluded_evidencelist of EvidenceExclusionwhen not emptyThe evidence an exclusion stage kept from this claim, in evidence-id order. Empty unless a stage excluded something; an empty list is not serialized.

EvidenceExclusion​

One evidence record an exclusion stage kept from a claim, and why.

KeyValuePresentMeaning
evidenceidentifier (EvidenceId)always—
reasonExclusionReasonalways—

ExclusionReason​

Why evidence was excluded: before claims were evaluated, or, for NotIndependent, from the evidence matches that demand an independence its producer lacks.

ValueMeaning
revision_mismatchBound to a revision of its subject that is not the current one.
expiredOlder than its kind allows at the evaluation instant.
invalidatedInvalidated by an invalidation rule.
not_independentProduced by a producer the case does not list as independent on every dimension an evidence match demands.

canon-authority/1​

Read by canon evaluate --authority: a list of AuthorityDecision entries; an empty list is allowed. A capability decided twice is refused, whatever the decision; the JSON Schema cannot express that, and refuses only an entry repeated exactly. The JSON Schema is generated from the same types.

AuthorityDecision​

One entry of a canon-authority/1 document: a capability and whether it is granted.

KeyValueRequiredMeaning
capabilityidentifier (CapabilityId)requiredThe capability decided, an identifier an action's requires may name.
decisionGrantrequiredWhether it is granted.

Grant​

An authority decision on one capability. With its precondition true, an action is admissible when every capability it requires is granted, blocked when one is denied, and approval-required when none is denied and one is not decided.

ValueMeaning
grantedThe capability is granted.
deniedThe capability is denied; asking again would not change it.

canon-decisions/1​

Read by canon evaluate --decisions: a list of ExplicitDecision entries; an empty list is allowed. An entry given twice, every key equal, is refused. The JSON Schema is generated from the same types.

ExplicitDecision​

One entry of a canon-decisions/1 document. It applies to outcome when the outcome requires a decision named decision and case_revision is the case snapshot's revision.

KeyValueRequiredMeaning
decisionidentifier (DecisionName)requiredWhich decision was taken.
outcomeidentifier (OutcomeId)requiredThe outcome it was taken for.
principalidentifier (Principal)requiredWho took it.
case_revisionidentifier (Revision)requiredThe case revision it was taken at.

canon-properties/1​

Read by canon check --properties. The JSON Schema is generated from the same types.

Properties​

A canon-properties/1 document as written.

KeyValueRequiredMeaning
formattextrequiredThe document format; canon check accepts only canon-properties/1.
protocolidentifier (ProtocolId)requiredThe id of the protocol the properties are about; canon check refuses another.
propertiesmap from identifier (PropertyId) to PropertyoptionalThe properties, keyed by identifier. A property declared twice is refused.

Property​

One property: its subject's status is the same in every two states that agree on everything except the evidence the independent_of claim reads.

KeyValueRequiredMeaning
descriptiontextoptional—
subjectPropertySubjectrequiredThe action or outcome whose status the property is about.
independent_ofPropertyDependencyrequiredWhat the subject's status must not depend on.

PropertySubject​

What a property is about. Written as a map with exactly one of the keys action or outcome.

KeyValueMeaning
actionidentifier (ActionId)The action's status: admissible, approval-required or blocked.
outcomeidentifier (OutcomeId)The outcome's status: legitimate or blocked.

PropertyDependency​

What a property's subject must not depend on. Written as a map with the one key claim.

KeyValueMeaning
claimidentifier (ClaimId)The claim, standing for the evidence it reads, by kind and subject, directly or through the claims it tests.

Identifiers​

An identifier is text. A well-formed identifier is not empty, and without whitespace, control characters or Unicode format characters (general category Cf). Each kind of identifier is its own type, so one cannot stand in for another. These are the kinds these documents use:

TypeIdentifies
ProtocolIdIdentifies a protocol, independently of its revision.
CaseIdIdentifies one case governed by a protocol.
ArtifactIdIdentifies an artifact a protocol declares.
RevisionIdentifies one revision of an artifact, or of the case itself: the case snapshot's own revision, and the case revision an explicit decision was taken at.
ClaimIdIdentifies a claim a protocol declares.
EvidenceIdIdentifies one evidence record.
EvidenceKindIdIdentifies a kind of evidence a protocol declares.
ActionIdIdentifies an action a protocol declares.
OutcomeIdIdentifies an outcome a protocol declares.
CapabilityIdNames a capability an action requires authority for.
DecisionNameNames an explicit decision an outcome may require (explicitly_inconclusive).
PrincipalWho took an explicit decision, or who produced an evidence record, recorded as given: Canon resolves no identity and proves no production.
IndependenceDimensionIdIdentifies an independence dimension a protocol declares (different_principal). Canon gives no dimension a meaning; the trusted context that writes the case resolves it.
InputIdIdentifies a case input a protocol declares.
InputValueOne value a case input may take: an identifier its input declares. Read from any scalar, alike in the protocol and in the case: values: [true, false] declares the values true and false, and a case gives one as flag: true.
PropertyIdIdentifies one property of a canon-properties/1 document.

Text formats​

These values are text in a fixed form, not identifiers. Canon refuses text that does not match its pattern, and also checks what the pattern cannot:

TypeWritten asPattern
InstantAn instant written YYYY-MM-DDTHH:MM:SSZ in UTC, or with a fraction of one to nine digits after the seconds, YYYY-MM-DDTHH:MM:SS.fffZ; uppercase T and Z, no leap second (2026-10-04T12:00:00Z, 2026-10-04T12:00:00.400Z): when evidence was observed, and the evaluation instant. Order forms compare every instant of one evaluation at one resolution, the coarsest precision written among its records, dropping finer digits (12:00:00.4Z beside 12:00:00Z reads as 12:00:00Z); expiry reads the whole seconds and ignores the fraction. Calendar validity is checked by Canon, not by the pattern: the date must exist (leap years included) and the time be at most 23:59:59.^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]{1,9})?Z$