ADR 0002: Pinned process versions, explicit migration

Decision

Tickets pin the process definition hash in effect at creation — the hash is the identity (ADR 0006); the human-readable version number is a label carried as metadata. Re-evaluation under a newer definition happens only via an explicit, signed :process/migrate event carrying the new hash. tik migrate --dry-run shows the derived-stage diff before anyone commits to it — a migration is a consequence-bearing decision (“under the new rules, security-review is now missing”), not a version-number edit.

Context

The derivation function is part of the evidence context. The conclusion is not events → stage but (events + process-definition + evaluation-time) → stage: silently changing the definition changes the meaning of the historical record. The choice here is reproducibility over freshness — a live workflow product asks “what is the correct state under today’s rules?”; an evidence system asks “what conclusion did these rules produce from these facts?” — and the auditor, regulator, and customer dispute all need the second question answered.

The original design floated tickets to the latest version by default (“stage is derived, so migration is free re-evaluation”). External review correctly identified this as an audit integrity failure: a ticket that was :resolved yesterday silently ceasing to be resolved because a definition changed violates least surprise and poisons any compliance narrative built on verify.

The inversion is cheap because migration passes ADR 0001: it is just another event — with an actor, a timestamp, parents, signatures, the new definition hash, and a derivable consequence. Mutable ticket.process_version metadata would instead raise “who changed it, when, was it authorized, what did it mean before?” as special questions; as an event they are ordinary log questions with no special trust path.

Consequences

see history · edit this page