Skip to main content

Integrity states and "why do we believe this?"

Every fact Horologium reports can answer one question with a precise, checkable citation: why do we believe this? That answer is built from three layers that are never collapsed into each other.

The three layers

LayerAnswersMutability
EvidenceWhat did a source say, exactly where, and when?Immutable, append-only, never closed
Claim / RelationshipWhat does that mean about a subject?Temporally versioned — closed, never deleted
FindingWhat follows from all the claims together?Derived, re-computed deterministically, closed when its basis changes

Evidence never becomes wrong, even when the world turns out to disagree with it. If Jira said the refund window was 30 days, the evidence "Jira said 30 days" stays true forever — the claim built from it is what closes when someone corrects the ticket. This separation is what lets Horologium say "we used to believe X, now we believe Y, here's exactly when and why that changed" instead of silently overwriting history.

Evidence: a citation you can paste

Every evidence item carries a source_ref_canonical — an exact, re-fetchable citation string a human (or an agent) can follow straight to the source:

SourceExample canonical citation
A git commitgit+https://github.com/acme/store@9f2c1ab…
A specific line range in a filegit+https://github.com/acme/store@9f2c1ab…:src/refund.rs#L12-L14
A Jira issue fieldjira+acme.atlassian.net/SHOP-412#status@2026-06-01T00:00:00Z
A documentation sectiondoc+https://docs.acme.com/refunds@3f9c1e2…#refund-window:840-902
A deployment recorddeploy+cloud-run/production#rev-00042

A source that can't produce a re-fetchable reference doesn't get to emit evidence at all — that's a conformance requirement on every provider, not a convention.

Claims: multiple, possibly conflicting, all valid at once

A claim is "this subject has this property with this value, according to this evidence." Claims are per-source assertions, and several conflicting claims about the same property being simultaneously true is normal, not an error — it's the entire reason Horologium exists. If Jira says the refund window is 30 days, the docs say 14, and the code says 30, all three claims stand at once, each citing its own evidence.

Claim values are typed, not free text (duration, quantity, boolean, enum_label, string_exact, or unresolved) specifically so that "30 days" vs. "1 month" vs. "30 day" can be compared exactly instead of by string similarity. Comparing two claims returns one of three results:

  • Agree — same kind, same unit, identical canonical value.
  • Conflict — same kind, same unit, different canonical value.
  • Incomparable — different kind or unit, or either side is unresolved. This never produces a conflict finding — a truth system that guesses when it can't actually compare two values would be manufacturing certainty it doesn't have.

Every claim also carries a derivation: observed (read directly from structured data — a Jira status field, a git tag) or inferred (extracted from prose by a model, then validated and accepted as a proposal). The two are never conflated in storage, in the API, or in the UI.

Unresolved is a real answer, not a null

When Horologium can't determine something, it says so explicitly, with a reason, rather than defaulting to a guess or a blank field:

ReasonMeaning
no_provider_configuredNo evidence source exists for this dimension on this install
no_evidence_foundA provider ran and found nothing relevant
conflicting_evidenceSignals exist but can't be reduced to one value
below_confidence_thresholdA model proposal existed but wasn't accepted
provider_errorCollection failed, and the failure is recorded, not swallowed
not_computedReconciliation hasn't run since the inputs last changed

This is why a fresh self-host install with only Git connected will correctly show most of a capability's lifecycle as Unresolved(no_provider_configured) rather than a false No — see Evidence sources for what each connected source unlocks.

Findings: the deterministic conclusions

A finding is what follows from the claim set, produced only by deterministic reconciliation rules — never by a model:

FindingFires when
claim_conflictTwo or more open claims on the same subject/property disagree
documentation_conflictAs above, and at least one participating claim comes from a documentation source
released_not_liveA capability is implemented and released, deployed on at least one target, but not on the target marked primary production
implemented_not_releasedA capability is implemented, but no release yet contains the change
unresolved_lifecycleAny lifecycle dimension is Unresolved for a reason other than "no provider configured"

A finding is content-addressed — re-running reconciliation over unchanged evidence produces zero new rows, and when the underlying claim closes, the finding closes with it (status: resolved). A finding may carry a model-written narrative explaining it in prose, but the narrative is never load-bearing: the finding's existence and its citations are entirely deterministic. See the hosted demo for these findings firing against a real (synthetic) fixture, and docs/architecture/product-ontology-v0.0.0.md in the repository for the full field-level model.