Skip to main content

Worked example: an investigation

Generated from fixtures/investigation/protocol.yaml by running Canon's own parser, validator and compiler over it. The protocol is deliberately not about software: Canon is meant to express any evidence-governed undertaking, and this is the fixture Canon's own tests use.

Decide whether an explanation is supported by observation and survives an attempt to falsify it.

The protocol​

fixtures/investigation/protocol.yaml
format: protocol/1

protocol:
id: investigation
revision: 1
description: Decide whether an explanation is supported by observation and survives an attempt to falsify it.

artifacts:
explanation:
description: The explanation under investigation.

evidence_kinds:
supporting_observation:
description: An observation consistent with the explanation.
falsification_attempt:
description: An attempt to refute the explanation; its result is survived or refuted.

claims:
explanation.supported:
description: The explanation is supported by observation and has survived falsification.
true_when:
all:
- evidence:
kind: supporting_observation
- evidence:
kind: falsification_attempt
result: survived

actions:
inspect:
description: Look for observations bearing on the explanation.
may_produce:
- evidence: supporting_observation

attempt_falsification:
description: Try to refute the explanation.
may_produce:
- evidence: falsification_attempt

outcomes:
supported:
description: The explanation is supported.
requires:
claim: explanation.supported

What it declares​

Protocol investigation at revision 1.

Artifacts​

ArtifactDescription
explanationThe explanation under investigation.

Evidence kinds​

Evidence kindDescription
supporting_observationAn observation consistent with the explanation.
falsification_attemptAn attempt to refute the explanation; its result is survived or refuted.

Claims​

ClaimTrue whenDescription
explanation.supportedall of: evidence of kind supporting_observation; evidence of kind falsification_attempt with result survivedThe explanation is supported by observation and has survived falsification.

Obligations​

None declared.

Actions​

ActionPreconditionRequires authority forEffectMay produceDescription
inspectnone: always appliesnonenonesupporting_observationLook for observations bearing on the explanation.
attempt_falsificationnone: always appliesnonenonefalsification_attemptTry to refute the explanation.

Outcomes​

OutcomeRequiresDescription
supportedclaim explanation.supported is trueThe explanation is supported.

Validation​

canon validate --path fixtures/investigation/protocol.yaml accepts it: the validator reports no problem. See validation for what it checks.

The compiled form​

canon compile --path fixtures/investigation/protocol.yaml prints its canon-ir/1:

{
"actions": {
"attempt_falsification": {
"description": "Try to refute the explanation.",
"effect": null,
"may_produce": [
{
"evidence": "falsification_attempt"
}
],
"precondition": {
"all": []
},
"requires": []
},
"inspect": {
"description": "Look for observations bearing on the explanation.",
"effect": null,
"may_produce": [
{
"evidence": "supporting_observation"
}
],
"precondition": {
"all": []
},
"requires": []
}
},
"artifacts": {
"explanation": {
"description": "The explanation under investigation."
}
},
"claims": {
"explanation.supported": {
"description": "The explanation is supported by observation and has survived falsification.",
"true_when": {
"all": [
{
"evidence": {
"kind": "falsification_attempt",
"result": "survived"
}
},
{
"evidence": {
"kind": "supporting_observation",
"result": null
}
}
]
}
}
},
"evidence_kinds": {
"falsification_attempt": {
"description": "An attempt to refute the explanation; its result is survived or refuted."
},
"supporting_observation": {
"description": "An observation consistent with the explanation."
}
},
"format": "canon-ir/1",
"obligations": {},
"outcomes": {
"supported": {
"description": "The explanation is supported.",
"requires": {
"claim": {
"id": "explanation.supported",
"is": "true"
}
}
}
},
"protocol": {
"description": "Decide whether an explanation is supported by observation and survives an attempt to falsify it.",
"id": "investigation",
"revision": 1
}
}

Evaluating a case​

canon evaluate reads the compiled protocol, a canon-case/1 snapshot and a directory of canon-evidence/1 records, and prints a canon-decision/1 document. These values are computed by Canon's evaluator for the case below; see evaluation for the rules.

case.yaml
format: canon-case/1
id: INV-18
protocol: investigation
artifacts:
explanation:
revision: r1
Evidence on recordValue
Nothing yetexplanation.supported is unknown
A supporting observation onlyexplanation.supported is unknown
A supporting observation, and a falsification attempt the explanation survivedexplanation.supported is true
A supporting observation, and a falsification attempt that refuted itexplanation.supported is false
A supporting observation, and two falsification attempts that disagreeexplanation.supported is unknown

With a supporting observation and a falsification attempt the explanation survived, the evidence directory holds these two records:

format: canon-evidence/1
id: obs-1
kind: supporting_observation
subject: explanation
subject_revision: r1
format: canon-evidence/1
id: fal-1
kind: falsification_attempt
result: survived
subject: explanation
subject_revision: r1

and canon evaluate --ir investigation.ir.json --case case.yaml --evidence evidence/ prints:

{
"actions": {
"attempt_falsification": {
"status": "admissible"
},
"inspect": {
"status": "admissible"
}
},
"case": "INV-18",
"claims": {
"explanation.supported": {
"value": "true"
}
},
"explanation": {
"computed_from": {
"case": {
"artifacts": {
"explanation": {
"revision": "r1"
}
},
"format": "canon-case/1",
"id": "INV-18",
"protocol": "investigation"
},
"evidence": [
"fal-1",
"obs-1"
],
"protocol": "investigation",
"protocol_revision": 1,
"semantics": {
"canon": "0.9.0",
"format": "canon-decision/1"
}
}
},
"format": "canon-decision/1",
"outcomes": {
"supported": {
"status": "legitimate"
}
},
"protocol": "investigation",
"protocol_revision": 1
}

Besides the claims, the decision gives each declared action admissible, approval-required or blocked under the authority decisions given (none here), and each declared outcome legitimate or blocked. This protocol declares no obligation, so the decision has no obligations section. See evaluation for each section. Both records are bound to explanation at its current revision; a record bound to any other revision would be listed under the claim as excluded and would not count.

Broken variants​

The repository keeps broken copies of this protocol in fixtures/investigation/invalid. Each is rejected; these are the problems the validator reports for them.

VariantCodeProblem
case-open-self.yamlself-opened-caseaction reaudit opens a case under protocol audit, the protocol's own id
duplicate-identifier.yamlduplicate-identifieraction inspect is declared more than once
input-duplicate-value.yamlduplicate-input-valueinput severity lists value low more than once
input-empty-values.yamlempty-input-valuesinput urgency declares no value
input-test-duplicate-value.yamlduplicate-input-test-valueobligation peer.review tests input severity for value high more than once
input-test-empty.yamlempty-input-testobligation peer.review tests input severity for no value
input-undeclared-value.yamlundeclared-input-valueobligation peer.review tests input severity for value critical, which the input does not declare
input-undeclared.yamlundeclared-inputaction publish_finding references input urgency, which is not declared
undeclared-claim.yamlundeclared-claimoutcome supported references claim explanation.refuted, which is not declared
undeclared-discharge-claim.yamlundeclared-claimobligation establish.explanation references claim explanation.refuted, which is not declared
undeclared-evidence-kind.yamlundeclared-evidence-kindaction attempt_falsification references evidence kind expert_opinion, which is not declared