Concepts · 5 of 7
Profiles and generated protocols
Specialising a protocol for a kind of work, and producing new protocols under governance.
One protocol does not fit every change. A bug fix should prove red before green; a refactor should not have to. Some requests fit no library protocol at all. Engineering protocols answer both with the same rule: specialise only by composing vetted parts, never by relaxing what an organization requires.
Shipped · runs today
- ShippedRisk profiles of software.change/1 (trivial, standard, elevated, critical)The case input risk selects which of four obligations apply. The obligations report the proof burden; they do not yet gate accepted.
- ShippedChange-kind profiles of software.change/1 (feature, bugfix, refactor)Decision record 0084. The case input change_kind; bugfix adds the red-first rule to implementation.edit.
Decided · recorded, not built
- DecidedGenerated protocols compose vetted parts onlyDecision record 0086: no invented evidence kinds, claims or capabilities.
- DecidedOrganization floorThe floor construct is not built.
- Decidedcanon diff: no relaxation against the floorThe command exists in Canon and reports that it is not built yet.
- DecidedAdoption as a case, protocol.adopt/1Whether it lives in engineering protocols or Canon is open.
Planned · roadmap only
- PlannedAuthority that varies by profileCanon cannot make a capability requirement depend on a case input yet.
- Plannedcanon check: reachability, authority, bounded state spacePlanned in Canon; not built.
- Plannedimports of library partsCanon's design says likely yes; no story yet.
Profiles
A profile is a named specialisation of a protocol for one kind of work. It is not a second protocol:
it is the value of a case input, which a case fixes when it opens, in Canon's case: inputs:. One
compiled protocol serves every profile, and a profile changes only what its input is tested in.
software.change/1 has two such inputs.
risk:trivial,standard,elevatedorcritical. Each level applies the obligations of the level below it and one more. An obligation a profile does not apply is reportednot_applicable.change_kind:feature,bugfixorrefactor. Thebugfixprofile adds the red-first rule (Step order);refactoromits it, and so doesfeaturefor now.
| Obligation | Discharged when | Applies at risk |
|---|---|---|
tests.required | tests.pass | trivial, standard, elevated, critical |
review.required | implementation.reviewed | standard, elevated, critical |
provenance.required | release.proven | elevated, critical |
health.required | deployment.healthy | critical |
More columns: swipe horizontally, or focus the table and use the arrow keys.
The obligations report the proof burden; accepted does not wait on them yet. Authority does not
vary by profile either: Canon cannot make a capability requirement depend on a case input. Below is
software.change/1; its full page, with the case inputs, is under
Protocols.
Protocol · revision 1
software.change/1Deliver a change to a software system: implement it, verify the current implementation revision, merge it under authority, release and deploy it, and accept it once its objective is realized; or close it declined, superseded or abandoned on an explicit decision, or rolled back on a complete rollback result. A case fixes its risk, which selects the obligations that apply, and its change kind, which selects whether a regression must be reproduced before the implementation is edited, and whether its regression test must fail on its first run, before the implementation is first changed; and whether it affects a security boundary, in which case the implementation is verified only once a principal other than the implementer approved its security review. A deployment is healthy only on an observation at most 30 minutes old.
- Actions6
- Evidence kinds9
- Claims9
- Outcomes5
- Obligations6
- Claim supports claim
- Precondition, traced on hover
- Needs authority
Hover or focus a node to trace what it rests on and what rests on it. Press Enter to pin it, Escape to clear.
Case inputs
affects_security_boundaryfalsetruewhether the change affects a security boundary; one that does needs an approving security review from a principal other than the implementer before its implementation is verifiedchange_kindbugfixfeaturerefactorwhat the change is; a bugfix must reproduce its regression with a failing test before the implementation is edited, and its regression test must fail on its first run, before the implementation is first changedriskcriticalelevatedstandardtrivialhow much proof the change must carry; each level applies every obligation of the level below it and one more
Protocol as text
| Name | Description | Rule | Leads to |
|---|---|---|---|
implementation.edit | change the implementation in the repository's working revision; a bugfix needs its regression reproduced first | any of claim regression.reproduced input change_kind in feature, refactor effect write | produces implementation_change |
release.rollback | return to a previous release; needs authority to roll back, and invoking it earns no outcome until a rollback result says it is complete | needs release.rollback effect write | produces rollback_result |
repository.inspect | read the repository | effect read | — |
repository.merge | merge a revision into the repository's mainline; needs the current implementation revision verified and authority to merge, never only a connection to the repository host | claim implementation.verified needs repository.merge effect write | — |
tests.run | run the tests against an implementation revision | effect read | produces regression_test_result; produces test_result |
tests.write | change the tests in the repository's working revision | effect write | — |
More columns: swipe horizontally, or focus the table and use the arrow keys.
| Name | Description | Rule | Leads to |
|---|---|---|---|
build_provenance | the record of how a release was built from an implementation | — | establishes release.proven (about release) |
code_review | a review of an implementation revision; its result is approved or rejected | — | establishes implementation.reviewed (approved about implementation) |
implementation_change | the record that the implementation was changed, moving it to a new revision | — | establishes regression.shown_first (after regression_test_result about implementation) |
objective_observation | an observation of whether the intent's objective is met; its result is satisfied or unsatisfied | — | establishes objective.realized (satisfied about intent) |
operational_observation | an 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 deployment.healthy (healthy about deployment) |
regression_test_result | the result of running a bugfix's regression test against an implementation revision; its result is pass or fail | — | establishes regression.reproduced (first fail about implementation); establishes regression.shown_first (before implementation_change about implementation); establishes regression.shown_first (first fail about implementation) |
rollback_result | the result of returning a release to the one before it; its result is complete or partial | — | — |
security_review | a review of an implementation revision's effect on a security boundary; its result is approved or rejected | — | establishes security.reviewed (approved about implementation, independent on different_principal) |
test_result | the result of running tests against an implementation revision; its result is pass or fail | — | establishes implementation.verified (pass about implementation); establishes regression.reproduced (fail about implementation); establishes tests.pass (pass about implementation) |
More columns: swipe horizontally, or focus the table and use the arrow keys.
| Name | Description | Rule | Leads to |
|---|---|---|---|
deployment.healthy | the deployment is running healthily | evidence = healthy: operational_observation | requires accepted; requires health.required |
implementation.reviewed | the current implementation revision is reviewed | evidence = approved: code_review | requires review.required |
implementation.verified | the current implementation revision is verified: its tests pass and, when the change affects a security boundary, it is security reviewed | all of any of claim security.reviewed input affects_security_boundary in false evidence = pass: test_result | supports release.proven; gates repository.merge |
objective.realized | the intent's objective is met | evidence = satisfied: objective_observation | requires accepted |
regression.reproduced | the regression a bugfix repairs is reproduced: a test has failed on the current implementation revision, or the first run of the regression test, on any revision of the implementation, failed | any of evidence = fail: test_result first evidence = fail: regression_test_result about implementation | gates implementation.edit |
regression.shown_first | the regression test failed first, before the implementation was first changed: the first regression test result about the implementation failed, and it was observed before the implementation's first change | all of evidence regression_test_result before implementation_change about implementation first evidence = fail: regression_test_result about implementation | requires red_first.required |
release.proven | the current implementation revision is verified and the current release revision carries build provenance; nothing here ties that release to the verified implementation revision | all of claim implementation.verified any evidence: build_provenance | requires accepted; requires provenance.required |
security.reviewed | the current implementation revision's security review is approved by a producer the case lists as another principal than the implementer | evidence = approved: security_review | supports implementation.verified; requires security_review.required |
tests.pass | the tests pass for the current implementation revision | evidence = pass: test_result | requires tests.required |
More columns: swipe horizontally, or focus the table and use the arrow keys.
| Name | Description | Rule | Leads to |
|---|---|---|---|
abandoned | the case closed because the change was explicitly abandoned without reaching any planned outcome | — | — |
accepted | the case closed with its result accepted; needs the release proven, the deployment healthy and the objective realized | all of claim deployment.healthy claim objective.realized claim release.proven | — |
declined | the case closed because the change was explicitly declined; needs no implementation | — | — |
rolled_back | the case closed with its release rolled back; needs a rollback result about the current release revision that says the rollback is complete | evidence = complete: rollback_result | — |
superseded | the case closed because another change explicitly superseded it | — | — |
More columns: swipe horizontally, or focus the table and use the arrow keys.
| Name | Description | Rule | Leads to |
|---|---|---|---|
health.required | the deployment is healthy; applies at critical risk | applicable when input risk in critical claim deployment.healthy | — |
provenance.required | the release is proven; applies at elevated risk and above | applicable when input risk in critical, elevated claim release.proven | — |
red_first.required | the regression test failed on its first run, before the implementation was first changed; applies to a bugfix, at every risk | applicable when input change_kind in bugfix claim regression.shown_first | — |
review.required | the current implementation revision is reviewed; applies at standard risk and above | applicable when input risk in critical, elevated, standard claim implementation.reviewed | — |
security_review.required | the current implementation revision is security reviewed by another principal than the implementer; applies to a change that affects a security boundary, at every risk | applicable when input affects_security_boundary in true claim security.reviewed | — |
tests.required | the tests pass for the current implementation revision; applies at every risk | applicable when input risk in critical, elevated, standard, trivial claim tests.pass | — |
More columns: swipe horizontally, or focus the table and use the arrow keys.
Source: protocols/software-change/1.yaml
Generated protocols
When a request fits no library protocol, a generator may write one, under four constraints:
- Composeimports only
Vetted library protocols and fragments, tightened, never extended with new names.
- Floorcanon diff
Against the organization's floor: tightening and expansion pass; relaxation and breaking changes are refused.
- Checkcanon check
Every outcome reachable, no authority bypass, the state space within its bound.
- Adoptprotocol.adopt/1
Adoption is its own case and needs the capability protocol.adopt.
A request such as "upgrade the database driver in a service; the schema migration must be
reversible and the public API must not change" fits no single library protocol. The generator
combines software.change/1 with a reversible-migration fragment and a contract-frozen fragment, and
tightens two claims:
protocol:
id: generated.example-service.driver-upgrade
revision: 1
imports:
- software.change/1
- fragment.reversible-migration/1
- fragment.contract-frozen/1
floor: floor.code-change/1 # what this protocol must not relax
claims:
implementation.verified: # tightened: two more conditions
true_when:
all:
- claim: tests.pass
- claim: implementation.reviewed
- claim: coverage.not_degraded
- claim: migration.rehearsed
- claim: contract.unchanged
release.proven: # tightened: rollback proven before release
true_when:
all:
- claim: implementation.verified
- claim: rollback.verified
- evidence: {kind: build_provenance, result: reproducible}
The diff against the floor shows only tightening and expansion, so it passes. A generation that
drops implementation.reviewed to make the request easier is refused:
$ canon diff --from floor.code-change/1 --to generated.example-service.driver-upgrade/2
RELAXATION claim implementation.verified − implementation.reviewed
→ refused: a generated protocol may not relax its floor
Adoption is a case
Adopting a generated protocol runs under its own protocol, so the decision is evidence, not a chat message:
protocol.adopt/1 (subject: the generated protocol, at one revision)
evidence diff_report from canon diff result: within_floor
evidence check_report from canon check result: passed
action protocol.approve requires capability protocol.adopt
outcome adopted requires within_floor + passed + approved
Who holds protocol.adopt is composition policy: a human by default, or an allow rule for
generations built only from trusted fragments. The adopting case pins the generated revision. When
the same shape is generated repeatedly, it becomes a candidate for the library as a profile.