Skip to content

Assertions

An assertion is a thing that makes a claim about another thing. It has its own shape, name, and version history — but it also carries an about reference linking it to its subject.

Assertions are the right choice when:

  • Attribution matters — you need to know who said something about an entity, not just the current state
  • Multiple perspectives coexist — different agents or sources have different views on the same thing
  • Confidence varies — claims carry uncertainty, evidence, or scores that evolve over time
  • History of belief matters — you want to trace how understanding of an entity changed

In practice, assertions are the primary way to model agent observations, opinion-bearing assertions, relationships between things (via collections), evaluations and judgments, and any attributed metadata about an existing entity.

Assertions may be unnecessary when:

  • You’re storing plain facts with a single source of truth — a regular thing with revisions may be simpler
  • The data doesn’t need attribution — if no one will ever ask “who said this?”, a thing is enough
  • You’re modeling static reference data that rarely changes — shapes and things handle this well on their own

When you want to capture how confident an agent is about an assertion — not just what it asserted — attach a Subjective Logic opinion to the assertion. The opinion is a tuple (b, d, u, α) — belief, disbelief, uncertainty, and a base rate — and requires the assertion’s underlying proposition to be binary (true or false).

Veritas is the WarmHub component that consumes and revises these opinions across sources. Its Certainty shape is the canonical form for opinions Veritas writes about another assertion.

Keep opinion metadata in a separate assertion from the data being asserted — see Opinions as Separate Assertions for the full pattern and the binomial-opinion constraint.

Use the assertion convenience command:

Terminal window
wh assertion create --shape Belief --about Location/cave --data '{"safe": true, "confidence": 0.8}'

Or as a commit operation:

{
"operation": "add",
"kind": "assertion",
"name": "Belief/cave-safe",
"about": "Location/cave",
"data": { "safe": true, "confidence": 0.8 }
}

The confidence: 0.8 field in this example is generic payload data, not a Subjective Logic opinion — see Assertions with subjective-logic opinions for that pattern.

The about field specifies which thing this assertion is about. It accepts local wrefs (Location/cave), canonical wrefs (wh:org/repo/Location/cave), or inline collection syntax ({ "pair": ["Location/A", "Location/B"] }). Assertion names follow the same naming conventions as things — hierarchical names work here too.

The about target is set at creation and cannot be changed. On revise, you can update the assertion’s data, but never its about reference (use retract to mark an assertion inactive):

Terminal window
# Update the assertion's data — about stays the same
wh assertion revise Belief/cave-safe --data '{"safe": false, "confidence": 0.3}' -m "Update belief"

This immutability is a core design principle — it guarantees that the relationship between an assertion and its subject is stable and auditable.

If you assert to the wrong target by mistake, the recovery path is:

  1. Retract the mis-targeted assertion
  2. Create a new assertion pointing at the correct target
Terminal window
# Retract the wrong assertion
wh assertion retract Belief/cave-safe -m "Wrong target — meant Location/dungeon"
# Create the correct one
wh assertion create --shape Belief --about Location/dungeon --data '{"safe": true, "confidence": 0.8}'

The retracted assertion remains in the version history for auditability, but is hidden from default queries.

When you create an assertion, the about target is version-pinned to the exact version of the subject at commit time:

  • about: "Location/cave" — bare wref, auto-pinned to current HEAD version
  • about: "Location/cave@v3" — explicit pin to version 3
  • about: "Location/cave@HEAD" — resolved to current HEAD version number

This is the write-path behavior — bare wrefs in commit operations always resolve to @HEAD. Read operations may resolve bare wrefs differently depending on the endpoint (see Version Modifiers for full defaults).

The pinned version is recorded alongside the assertion as the precise version the assertion was made about. This means you can always answer “which version of cave was this belief about?”

List all assertions about a specific thing:

Terminal window
wh thing about Location/cave

From the SDK, client.thing.about returns { target, assertions, nextCursor } — the array is named assertions, not items. (HeadResult, FilterResult, SearchResult, RefsResult, and LogResult all use items; AboutResult is the outlier.)

const { target, assertions } = await client.thing.about("acme", "world", "Location/cave");
for (const a of assertions) {
console.log(a.wref, a.shapeName);
}

Filter by shape:

Terminal window
wh thing about Location/cave --shape Belief

Include child assertions about the returned assertions:

Terminal window
wh thing about Location/cave --depth 2

wh assertion list --about Location/cave is the equivalent assertion-domain form when you are already browsing assertions.

Browse all assertions in HEAD:

Terminal window
wh assertion list
wh assertion list --shape Belief

To inspect one assertion’s full details, use wh assertion view (or equivalently wh thing view, since assertions are things):

Terminal window
wh thing about Location/cave --shape Belief
wh assertion view Belief/cave-safe
wh thing view Belief/cave-safe # equivalent

The about field supports structured collection objects for making assertions about groups of things:

{
"operation": "add",
"kind": "assertion",
"name": "Distance/A-B",
"about": { "pair": ["Location/A", "Location/B"] },
"data": { "value": 5 }
}

This automatically creates a Pair collection thing and pins the assertion to it. See Collections for the full syntax.

The about reference is more than a foreign key — it’s a modeling decision that determines how beliefs cluster around subjects. Choose your about targets thoughtfully.

The about ref defines your navigation axis

Section titled “The about ref defines your navigation axis”

The about target determines what you’ll browse by. If you assert about Company/acme, you can later query “everything we believe about Acme.” If you instead assert about Filing/acme/10-k/2024, your beliefs cluster around individual filings — a different navigation axis.

Choose based on how agents and humans will explore the data: what will you most often want to ask “what do we know about X?” for?

The write pipeline resolves the about wref and verifies that the target thing exists. If the target doesn’t exist, the assertion operation fails with a NOT_FOUND error. This means you cannot assert about an entity before it has been added.

If you need to create a thing and immediately assert about it, put both operations in one write request — the thing is created before the assertion is resolved:

Terminal window
wh commit submit --ops '[
{"operation": "add", "kind": "thing", "name": "Company/acme", "data": {"industry": "fintech"}},
{"operation": "add", "kind": "assertion", "name": "Thesis/acme-bull", "about": "Company/acme", "data": {"outlook": "bullish"}}
]' -m "Add company with initial thesis"

Don’t rely solely on the about wref to carry key identifiers. If an assertion is about Company/acme, include the company name or ticker in the assertion’s data too — this makes the assertion self-describing when read in isolation, without requiring a follow-up query to resolve the about target.