Lifecycle Shapes
Every subject log answers the same four questions about a subject, and until this cut each log answered them in its own words.
The repetition was counted rather than estimated. The arm refusing a write to a subject that is no longer live appears fifteen times in demand, thirteen in order, nine in the order line — one per mutating kind. Liveness itself is defined three times over in each of those adopters, as a trio of predicates. The mirror arm on the create side, refusing a create on a subject that already started, is hand-built five times. Demand’s admission witness runs to eighteen lines, one per kind.
None of that is wasted motion in the sense of typing. It is wasted motion in the sense that matters: fifteen copies of a rule are fifteen places the rule can quietly differ, and nothing in the model notices when one of them does.
The four shapes are distinguished by effect, not by verb
Section titled “The four shapes are distinguished by effect, not by verb”The classification that works is by what an occurrence does to the record, not by what the caller called it.
| Shape | Model sig | Effect on the record | The refusal it owns |
|---|---|---|---|
| Create | lc/CreateOcc | the first row | a create on a subject that already started |
| Mutate | lc/MutateOcc | the record may change; post = pre is legal, because records are values | a mutation on a subject that is not live |
| Retire | lc/RetireOcc | the tombstone: post = pre, and terminal | a retire on a subject that is not live — a second retire is refused, never a no-op |
| Affirm | aff/AffirmOcc | post = pre, carrying the version the caller claims | not created, retired, or a claim about the wrong version |
Two of these have a total frame — post = pre — which is why they lift out of every adopter cleanly. Mutate does not: “everything but the notes unchanged” names fields of a record the spine cannot see, so Mutate lifts its guard and leaves its frame behind.
Classifying by verb was tried first and produced a wrong theorem. An AnnotateLine occurrence looked like a third top-level shape, a note-only touch, because the verb sounded like one. Read by effect it is an ordinary mutation of the line’s internal notes, and the theorem it appeared to break — that nothing commits after a committed retire — needed no weakening at all.
The four shapes and their effects on the record:
Liveness is defined once and read everywhere
Section titled “Liveness is defined once and read everywhere”liveAt[o] says a subject has started and has not been retired. liveSubjectAt[s, t] is the same fact read from outside an occurrence, and it is the one the runtime needs: a subject is live exactly when the head of its log is not a retire kind.
The definition that was being repeated mixed two things, and only one of them was ever generic. Demand’s liveness conjoined a shape fact — the subject exists and no tombstone precedes it — with a domain fact: that its status is one of the live statuses, because COMPLETE and CANCELED are terminal by demand’s own state machine rather than by the log. The shape half lifts. The domain half stays where it belongs, beside the adopter’s other domain arms.
That split is why the extraction removes definitions rather than references. A supertype removes the liveness definition from every adopter at once. Whether it also removes the fifteen, thirteen and nine references depends on restating the admission witness by shape instead of by kind, and that restatement is the one place the type itself is load-bearing.
Three laws come with the shapes
Section titled “Three laws come with the shapes”ShapeAdmission. A create on a started subject, and a mutation or retire on a subject that is not live, are rejected — with the refusal atom named by the adopter, not by the family.
nothingAfterRetire. No occurrence of any shape commits on a subject after its committed retire. Each adopting root checks it as a theorem. This is worth separating from the guard that enforces it: the guard is a condition every kind carries, the theorem is a property of the log that a reader can rely on without auditing the kinds. Uniqueness of the tombstone follows from it, which is why the cut adds no index for it.
mutateHasPre. A mutation is never the first row and never the tombstone. It states as a law what was previously a consequence of each adopter’s own guard, so the contract table can cite it.
One further property arrives as a theorem rather than a fact once reference data converts: liveness is immune to mutation. It is a function of Create and Retire rows alone, so no mutation can move it, by construction. The frame lines that existed in each adopter only to protect the tombstone reading — copying a status field forward so nothing could disturb it — stop having a job.
What the shapes cannot carry
Section titled “What the shapes cannot carry”Stated so nobody looks for it later.
Frame conditions. “Everything but the notes unchanged” names the fields of a record that is opaque to the spine. Per kind, always.
Bindings. A kind’s bindings are the kind’s by definition.
Domain arms. The family can say “a live subject”. It cannot say “a draft order”. The frozen, bad-state and not-attached refusals, and the pin-currency guards, belong to the adopter’s state machine.
A law that a mutation must change something. Tempting as the definition of the word, but the spine does not fix whether writing the same quantity twice yields a fresh record atom or the same one. That is a question to answer before the law can be written, not a law to adopt in advance of the answer.
Retiring is two acts where it used to be one
Section titled “Retiring is two acts where it used to be one”Removing an order line used to drop its attached demand as part of the removal. Under the cut, the retire is a tombstone and nothing else, so the demand must be detached first: two acts, detach then remove, with a new refusal when a caller tries to remove a line that still has one attached.
This is a real change at the edge of the system, not a tidying. A caller that forgets to detach leaves the demand held where removal used to release it to the queue, and no existing test would catch it — the only test that removes a line uses one with no demand attached. It is recorded as an interface break rather than a refactor.
The same two-act shape governs the inventory item later: write off, then delete.
Reference data’s lifecycle is the log’s shape
Section titled “Reference data’s lifecycle is the log’s shape”A reference datum is live exactly while the head of its log is not a retire kind. It carries no status of its own. The reads keep their names, and the status enumeration and its two values cease to exist in the model.
This supersedes the four-state machine. Reference Data defines the lifecycle as DRAFT, PUBLISHED, ARCHIVED and RETIRED with eight named transitions between them. That page describes the earlier model; the operator ruled on 2026-09-09 that the subject-log shape is the one of record, and rewriting the domain page to match is tracked separately. Until it is rewritten, that page carries a notice saying so — a reader should not meet the old model without being told.
Two of the four states are worth accounting for rather than dropping silently. RETIRED becomes the tombstone: the same fact, expressed as the head of the log rather than as a field. The distinction between ARCHIVED and RETIRED — no longer active, versus permanently removed after a retention period — has no counterpart in the log’s shape, and reinstating it, if the business still needs it, is a domain question about kinds rather than a lifecycle one.
The consumer-side refusal, a reference to a retired datum, is unchanged either way.
Sources
Section titled “Sources”The lifecycle family is meta/subject_log/lifecycle.als in Saldubatech/manufacturing-ontologies, on branch jmpicnic/domain-ontology-affirm-kind: cut at commit 793cfe0, with two further adoption roots at the branch tip 4b53f118. The branch is unmerged.
The repetition counts, the liveness split, and the list of laws the abstract level cannot carry are from notebooks/domain-ontology/streams/samwise/mutate-occ-abstract-supertype.md, which measured them with grep -c against the model text at 3b2ad797 rather than sampling. Its §4 is a withdrawn conclusion kept as the derivation of a wrong turn — the note-only third shape described above.
The two-act removal and its interface consequence are from generic-retire-impact.md and the finding recorded against PDEV-1898.
See also
Section titled “See also”- D13 Contract — the per-adopter names, codes and atoms the runtime builds against.
- Affirm — the fourth shape, and why a claim of no change is an act.
- Universe Write Contract — the five verbs that carry these shapes into the runtime.
Copyright: © Arda Systems 2025-2026, All rights reserved