Skip to content
← Documentation

docs/cessation-composition.md


Is cessation already representable?

The standing rule requires exhausting composition before accepting architectural pressure. Applied to temporal extent.

Verdict: already representable — and blocked by a canonicalization defect, not by the ontology.


The six encodings

Each uses only existing concepts. None requires a new primitive.

Phenomenon Encoding Loses truth?
employee leaves condition: unavailable on the actor no — the person still exists, and is unavailable
service decommissioned condition: unavailable on the resource no
contract expires condition: unavailable on the agreement no
metabolite consumed measure: concentration = 0 no — and it is more precise than cessation
package delivered placement changes to the new place no — the package persists, its location changed
connection terminated condition: unreachable no

The metabolite case is the strongest. concentration = 0 is better than "ceases to exist": it preserves the missing-versus-negative distinction the whole provenance apparatus rests on. Absence of a fact means nobody measured; a fact with value 0 means someone measured and found none. Modelling cessation as subject-deletion would destroy that distinction.

So the ontology does not need cessation. It needs magnitudes that can change.


Why the composition fails anyway

It fails at collapse, not in the vocabulary. Measured with a correctly typed fixture:

identity: measure:concentration:resource:cell/glucose
same identity for both observations? true

early first  -> value=1  validAt=00:10   ← the LATE timestamp
late  first  -> value=0  validAt=00:10   ← with the EARLY value

Two defects, in one function:

1. collapse is order-dependent

The same two facts produce a different world depending on array order. A canonical model whose output depends on input ordering is not canonical.

2. It fabricates a fact that was never observed

collapse advances validAt to the latest while keeping the first-encountered value. The surviving fact therefore asserts "at 00:10, concentration was 1 mM" — when the observation at 00:10 said 0 mM. That is not information loss; it is a fact nobody reported.

The root

factIdentity for a measure is measure:${metric}:${subject}time-invariant identity for a time-varying quantity. Two measurements of the same quantity at different times therefore collapse as duplicates.

For condition the assumption holds: a condition is present or absent, and two observers reporting it are reporting one fact. For measure and placement it does not: the same subject and metric at two times is two observations of a changing quantity, not one fact seen twice.

The vocabulary carries validAt on every fact. The identity function discards it. The information is present and canonicalization throws it away — which is the same failure shape as every other defect this audit has found.


Classification

Candidate Verdict
already representable yes — by composition
composition condition: unavailable, or measure = 0, or a placement change
architectural pressure no
false lead no — the phenomenon is real, the diagnosis was wrong

Temporal extent is not architectural pressure. Window remains unused because nothing needs it: a bounded existence is expressible as a magnitude falling to zero or a condition becoming true. What is needed is that a later observation of the same quantity supersede an earlier one, which is a defect in collapse and factIdentity.

Hypothesis 3 confirmed — the mapping into the vocabulary was wrong. The ontology is not implicated.


A retraction

I first ran this with any[] fixtures and reported that factIdentity produced [object Object], concluding that every measure of a metric collapsed regardless of subject. That was my error. Fact.subject is typed Urn, a string; my fixture passed a SubjectRef object. Using any[] disabled exactly the type check that would have caught it.

Same shape as every measurement error in this project: the instrument was wrong, and it was wrong because I had switched off the thing that would have told me.


Why this defect has never been observed

core has no consumers. lib/world uses its own mergeFacts (later substrate wins — correct), not core.collapse. So the defect is latent: it lives in the most heavily verified module in the repository, and the verification never exercised a changing quantity, only duplicate observations of a static one.

That closes a loop with the platform-boundary finding. core's zero-consumer status is not merely an adoption gap — it means core's defects go undetected, because nothing pushes real time-varying data through it.