Titentiten.devꦠꦶꦠꦺꦤ꧀
v0.1.1 · npmGitHub
DocsThe memory loopConsolidate claims

Consolidate claims

A claim is a compact conclusion that names the observations behind it, created deterministically today with no model in the path.

POST /v1/consolidationsclaims:writeclaim_ + 32 hexmodel_used false

An observation says what happened. A claim says what someone concluded, and points at the evidence. Keeping the two apart is what lets a compiled pack carry conclusions that stay checkable: every claim resolves back to observations through GET /v1/claims/:id/evidence.

Create a claim

consolidate.tstypescript
const result = await titen.consolidate('user_rama', [
  {
    kind: 'procedural',
    statement: 'Deploy smoke must pass before release.',
    confidence: 0.95,
    sources: [{ observation_id: obs.observation_id, relation: 'supports' }],
  },
]);
// result.claims[0].claim_id → "claim_f3963d7b876143f5bfc8230db2757067"
// result.model_used         → false
curl -X POST http://127.0.0.1:8787/v1/consolidations \
  -H "authorization: Bearer $TITEN_API_KEY" \
  -H 'content-type: application/json' \
  -d '{"subject_id":"user_rama","claims":[{
       "kind":"procedural","statement":"Deploy smoke must pass before release.",
       "confidence":0.95,
       "sources":[{"observation_id":"obs_ed91a2d0f66143fbba66c932494d5e64","relation":"supports"}]}]}'

One request carries up to 50 claims, each with up to 20 sources and a statement up to 4000 characters.

Kinds

The kind is a typed field because pack diversity reads it: at most three items of one kind enter a compiled pack.

Kind What it holds
semantic_fact A fact about the subject that is not tied to one moment.
episodic_event Something that happened, as a conclusion rather than raw evidence.
preference What the subject wants.
procedural Guidance for how work should be done.
decision A choice that was made, and therefore something a later decision can supersede.
relationship A link between two subjects, backed by evidence.

Sources carry the relation

Every source names an observation and how it relates to the claim: supports, contradicts or qualifies. At least one supports is mandatory.

{ "error": { "code": "VALIDATION_ERROR",
    "message": "A claim needs at least one supporting source." },
  "meta": { "request_id": "req_e23da3bea5924b3f99cf84cf856e72ed" } }

That rule is what keeps the store from accumulating free-floating assertions.

An unknown source id, a foreign tenant’s observation and someone else’s private record all return the same non-disclosing 404 NOT_FOUND.

Trust and visibility are inherited

Omit trust and the claim takes the highest trust among its supporting sources. Omit visibility and it takes the narrowest visibility across all its sources, including the ones that contradict or qualify. Supplying either field can only narrow the result:

{ "error": { "code": "VALIDATION_ERROR",
    "message": "Claim trust may not exceed the trust of its supporting evidence." },
  "meta": { "request_id": "req_baae3681b26d44fe9ebd10f1b264bb3d" } }

Consolidation therefore cannot launder trust: evidence enters with a ceiling from its credential, and the claim above it inherits that ceiling.

confidence is separate and defaults to 0.8: how sure the author is, greater than 0 and at most 1. It never substitutes for trust. Both appear in a compiled pack, and ranking uses them for different things.

Contradiction produces a dispute, not a winner

Attach a contradicts source and the claim commits with status: "disputed":

{ "data": { "subject_id": "user_docs_loop", "project_id": null, "model_used": false,
    "claims": [{ "claim_id": "claim_d5ce4657d6b947aa8ade42271b4176f5",
      "kind": "procedural", "status": "disputed", "trust": "verified",
      "visibility": "team", "confidence": 0.9,
      "valid_from": "2026-07-30T10:47:30.946Z", "valid_to": null,
      "evidence_ids": ["obs_c98879c3adc44f6a9b2227b821a033bd",
                       "obs_bc4984ed9153467eb41b4753c5c96d6c"] }] },
  "meta": { "request_id": "req_…", "replayed": false, "model": "disabled" } }

The claim is still retrievable. It arrives in a context pack with status: "disputed", a conflict score component of 1 and an entry in the pack’s conflicts array. The disagreement is the part an agent needs to ask a better question. Resolving it is an explicit lifecycle transition that records who decided and why.

No model is involved

model_used: false in data and model: "disabled" in meta are literal. Consolidation today is deterministic, and no model call happens on this route.

Planned: model-driven extraction

Proposing claims from eligible observations with a model is on the roadmap. It changes what Titen proposes, not what it accepts. Every proposed claim would still pass the same schema, scope, evidence, trust and temporal validation as a hand-written one, and a model could not invent a source identifier, raise trust above its evidence, delete evidence, or resolve a dispute. Deterministic rules run first, and a model returning invalid sources commits nothing.

Next

↑↓ navigate↵ open