GroundedContextAssembler turns retrieved content into model-ready context that is guaranteed consistent with a truth-maintenance session at the moment of assembly. When the evidence behind a registered summary or citation is retracted or superseded, the content disappears from the current answer — while historical coordinates still reproduce exactly what was known at the time. The stored records themselves are never modified.

The Four Stages

The stack is four small layers, each consuming only the public interface of the one below it: The registry only manages content you explicitly register. Ordinary candidates without grounded_artifact_id remain eligible under the existing truth_maintenance annotation rules: their namespace, facts, supports, and attachments must validate against the captured view. They retain their retrieval source and render without registered citation footnotes. Candidates carrying grounded_artifact_id must additionally match a registered artifact’s content and satisfy its dependency and citation contracts; an unknown ID is excluded.

Complete Example: Retracting a Source

The program below runs standalone with no model, database, or network — only semantica itself. It asserts the HR support, registers one citation and one summary that cites it, assembles, then retracts the HR support in the same apply batch that introduces a replacement badge source. The fact survives through the badge, but the cited content correctly does not:
The stored rows are untouched: retriever.vector_store.rows still holds both records verbatim. Only the assembled answer changed, because the summary is bound to the retracted citation.

Complete Example: A Late Correction, Read Bitemporally

A correction recorded on 2026-09-20 supersedes the original HR record hr-v1 but is itself only valid until 2026-09-10. The current answer becomes empty, yet the historical coordinates valid_at=2026-09-15, known_at=2026-09-15 still reproduce the superseded answer exactly:

API Reference

GroundedContextAssembler(retriever, *, provider, artifacts)

retriever is a ContextRetriever, provider a TruthSnapshotProvider, and artifacts a ContextArtifactIndex in the same namespace as the provider.

assemble(query, *, max_results=5, max_context_chars=8000, valid_at=None, known_at=None, candidate_pool=None)

reconcile is not needed before assemble: assembly checks every artifact against the view it captures. Call index.reconcile(view) when you want the report of which artifacts were invalidated or became eligible again. Grounded assembly does not apply trust tiers (min_trust_tier); validity comes only from the declared dependencies.

GroundedContext

Exclusion reasons

Errors

  • ValidationError: invalid arguments, mismatched provider and registry namespaces, a view from another provider passed to assert_current, or an invalid artifact at registration.
  • ProcessingError: the source or the registry changed while the context was being assembled. Call assemble again.
GroundedArtifact.validity_policy defaults to "snapshot", the strict policy: any new view invalidates the artifact. Use "dependencies" when the artifact should stay valid while its declared facts and supports hold.

Boundaries

The assembly guarantee is deliberately narrow. Each boundary below is a commitment you can rely on — or a non-commitment you must not rely on:
  • Four stages, one direction of trust. Each layer trusts only the public interface of the layer below. A view is an immutable value; a registry record is immutable once registered. Nothing in the stack writes back into the session, the adapter, or the vector store.
  • Filter vs. assembler. The truth filter validates per-row annotations during retrieval, before ranking. The assembler validates registered artifact contracts during assembly, adds snapshot consistency, the character budget, and citation footnotes. Both leave stored records untouched; they answer different questions and can be combined.
  • Namespace incarnation. A registered artifact is only valid for the namespace it was stamped from. Recreating a session under a new namespace (or a new session ID) starts a fresh incarnation: artifacts stamped from the old one never become valid again in the new one.
  • Provider instance identity. Captured stamps include an opaque provider_id. assert_current rejects views from another provider instance, even when both providers wrap the same source and all counters match. Hand-built stamps may omit the identity for pure value validation, but cannot pass provider freshness checks. This identity is not an authentication token.
  • Snapshot policy is sensitive to anything new. A dependencies-policy artifact stays valid as long as its namespace, source kind, declared facts and supports match. Switching source kind re-evaluates every registered artifact, even when facts and support IDs are unchanged. A snapshot-policy artifact additionally requires the view stamp to be the one it was built from, so any new session version — even one that keeps every fact — or a different provider instance invalidates it.
  • Citation constraints. A citation must use the dependencies policy and must declare a support ID; it may not reference other artifacts. A summary whose citation is invalid is itself excluded (invalid_citation) — a grounded answer never keeps its prose while silently dropping its source.
  • Only explicitly registered content is managed. The index never infers dependencies and never annotates records on your behalf. Ordinary candidates can participate with valid annotations without being registered; candidates with an unknown artifact ID cannot bypass registry validation.
  • Value validation. Read-view facts and artifact fact dependencies use the same ground-atom validation and canonical whitespace as the truth-maintenance session. Temporal stamps store coordinates in UTC without changing the instant. Coordinates passed to capture or assemble follow the temporal adapter, which reads naive datetimes as UTC; a hand-built SnapshotStamp requires timezone-aware values. The provider and registry namespaces must match, even when retrieval would return no candidates.
  • Historical reads are isolated. Assembling at a valid_at / known_at coordinate evaluates history and never mutates the adapter, the provider, or the registry. Moving the live cursor (advance) during a historical assembly is allowed; syncing new retained evidence during one raises ProcessingError rather than returning a mixed-version answer.
  • Character budget. Assembly selects content greedily within the configured budget; over-budget blocks are excluded and reported, not truncated mid-sentence. It continues through the ranked, threshold-filtered candidate pool already collected, without a pre-budget top-k cut. Each source returns at most candidate_pool candidates; at most max_results blocks are emitted. Ordinary retrieval retains its default top-k behavior.
  • Freshness ends at return. A returned bundle is a snapshot of the view it was assembled from. It does not expire, and it does not track later retractions; call assemble again for the current answer.
  • Not a storage or semantics guarantee. Consistency here means: the assembled context matches the registered content contracts against the captured truth-maintenance view. It does not make your vector store transactionally consistent, and it does not make the model’s conclusions semantically correct.