Response envelope
Most systems return rows. RememberStack returns rows plus a machine-readable account of the answer itself — because the caller is an agent that must decide whether to act, re-query, or escalate to a human.
This page documents the shipped wire shape for assured operations (and primitive compositions that emit the same envelope). Open SQL uses QueryResult/v1 instead; see Open query.
Envelope: one cohesive typed response
An Envelope is flat. Top-level grain selects which result tuples are
populated, and temporal_scope states the exact selection applied:
{
grain: fact | evidence | compiled | composite,
temporal_scope:
| { mode: current, evaluated_at, believed_at, identity_regime }
| { mode: at, at, evaluated_at, believed_at, identity_regime }
| { mode: overlap, from, to, evaluated_at, believed_at, identity_regime }
| { mode: history, evaluated_at, believed_at, identity_regime }
| { mode: as_of, valid_at, evaluated_at, believed_at, identity_regime },
// result tuples (populated by grain / operation)
entities: [ EntityCandidate… ],
facts: [ FactResult… ],
evidence: [ EvidenceResult… ],
fact_evidence: [ { fact_kind, fact_id, claim_id, stance: supports|contradicts }… ],
evidence_totals: [ { fact_kind, fact_id, stance, returned, total }… ],
chunks: [ ChunkEvidenceResult… ],
sources: [ SourceRecord… ],
transcript: [ … ],
nodes / paths / edges / ranking / changes / aggregate / pages: …,
freshness: {
pg_live_ts,
p1_written_inline,
p1_believed_at_horizon,
k: { compiled_at, stale, open_flags } | null
},
truncation: { truncated, returned, estimated_total, total_is_exact, continuation, reason } | null,
dropped_by_hydration: n,
excluded_unstamped: n,
negative: null | { kind, explanation, workaround }
}
FactResult (fact grain)
| Field | Meaning |
|---|---|
fact_id, kind, label | Relation or observation identity |
evidence_count | Distinct current-testimony lineages |
validity | {valid_from, valid_until, valid_precision, ingested_at, invalidated_at} |
contradiction / contradiction_group | Live co-members package |
support | current | withdrawn |
temporal_match | confirmed or possible for the requested time scope |
valid_from and valid_until describe one chosen world interval: its start is
included and its end excluded. valid_precision distinguishes calendar units,
instants, explicitly open intervals and unknown dates. A missing boundary is not
permission to assume the fact held at every date. ingested_at and
invalidated_at describe when the engine believed it, not when it happened.
A possible match means incomplete dates have not ruled it out. It is not a
stored dispute flag. Fact-grain operations (facts_context, relation and
observation lookups) return possible matches in the same list as confirmed
ones, each flagged; only the published strict SQL view facts_current and the
live graph exclude them. For example: "Three wins are dated to 2022; one
additional win has no accepted date." Context results are bounded candidates,
so their length never proves an exhaustive count.
There is no confidence field on the shipped fact record.
EvidenceResult (evidence grain)
| Field | Meaning |
|---|---|
claim_id, doc_id, chunk_id | Anchors |
claim_text, source_span, char_start, char_end | Text + origin grounding (the target-chunk owner) |
evidence_spans | Complete supporting body ranges for the origin occurrence identified by chunk_id ({char_start, char_end} objects in that chunk's representation). Empty when that occurrence list is missing; origin scalars are not substituted as complete support. Current-version remapped positions are on memory_v1.claim_occurrences_live. |
is_current_testimony | Currency filter result |
asserted_at, claim_valid_* | When the source made the statement, and when the claim says it happened or was true (source-asserted, not system belief) |
corroboration_count, grouped_claim_ids | Duplicate collapse metadata when present |
Provenance is flat on the claim (and via top-level sources[]), not a nested provenance: { hydrate_handle, derivation } object.
fact_evidence + evidence_totals
How facts_context binds facts to testimony without blending grains:
fact_evidence[]— explicit fact↔claim stance edges returned with the answerevidence_totals[]— exact per-fact stance counts (returned/total) so caps stay honest
Both arrays identify a fact by (fact_kind, fact_id). Relation and observation
UUIDs are separate namespaces and may contain the same UUID, so consumers must
never join or group these records by fact_id alone.
ContextBundle/v2: both authorities, still separate
combined_context is the sole side-by-side testimony/fact response. It does not
use grain = composite, and it does not nest parts inside an envelope:
{
contract: "ContextBundle/v2",
claims_and_sources: Envelope, // complete evidence-grain claims_and_sources_context response
facts: Envelope // complete fact-grain facts_context response
}Each child retains its own temporal scope, freshness, truncation, drops, and
typed negative. The wrapper adds no retrieval, ranking, or transformation. A
schema or execution failure in either child fails the whole request; a typed
negative is a valid completed child and remains inside the bundle. There is no
EnvelopePart, Envelope.parts, or compatibility wire shape.
Grain discipline
| Grain | May answer | Must not pretend to answer |
|---|---|---|
| fact | What we currently hold true (validity-filtered) | Source gossip as verdict |
| evidence | What sources asserted (claims) / current source text (chunks) | “Is it true now?” without adjudication |
| compiled | Pre-paid synthesis with citations | Live confirmed fact |
| composite | One operation's cohesive mixed typed payload | A container for independent responses |
Evidence envelopes may carry both evidence[] (claims) and chunks[] (confirmed source-text). Different semantics — never fuse as one unlabeled UUID soup.
Default evidence mode: current testimony only. Opt in for superseded testimony; historical operations declare history explicitly.
Three non-negotiable rules
1. Contradiction co-members are never silently absent
Returning one side of a live contradiction group without indication of the others is a contract violation.
- Co-members return inline up to a guaranteed cap.
- Beyond cap: still always
group_id,returned,total,continuation.
2. No silent caps
Hub neighborhoods and large sets return ranked pages with truncation markers and continuations. total_is_exact tells you whether the estimated total itself hit a cap; reason carries a machine-readable budget cause when the producer can distinguish one (for example expansion_budget or result_budget).
3. Hydration drops are counted
Projections may nominate candidates the spine rejects. dropped_by_hydration keeps ranking honest. Compound structures (paths) drop as units.
Freshness block (shipped field names)
| Field | What it tells the agent |
|---|---|
pg_live_ts | Live spine clock for confirmed rows |
p1_written_inline | Whether P1 was written on the inline path (lag measurement evolves) |
p1_believed_at_horizon | Oldest system-time P1 can answer (null = unbounded) |
k | Compile time, stale flag, open evidence-change flags when K was consumed |
The graph has no separate freshness stamp: SQL/PGQ and recursive helpers read the same PostgreSQL repeatable-read snapshot as hydration.
Finite believed_at horizons → query before horizon yields typed boundary, not partial silent history.
Typed negatives
| kind | Meaning | Correct agent move |
|---|---|---|
unknown_entity | Nothing resolves | Widen resolve / spelling / search |
known_empty | Entity exists; no matching facts | Trust absence within freshness |
boundary | Stated capability limit | Read workaround; re-plan |
Hard-forgotten content is not a separate kind — it is indistinguishable from never-existed. There is no content-level denied in the library.
Media derivation fields (open query, not envelope)
derivation_kind / evidence_mode / rich source locators for media are available on the SQL query-space occurrence views, not as nested envelope provenance objects on EvidenceResult. Use Open query for those columns and for claim_occurrences_live.evidence_spans. Envelope evidence_spans is the complete occurrence support; source_span / char_start / char_end remain the immutable origin.
Support marker
| support | Meaning |
|---|---|
current | At least one current-testimony lineage supports |
withdrawn | Fact still present but current testimony support hit zero via toolchain path — caveat + audit |
Temporal scope
temporal_scope is required and discriminated by mode. facts_context
returns current, at, overlap, or history; each response includes its
evaluation and belief instant plus the requested world-time coordinates.
These modes use current system belief. A historical system-belief audit uses
the separate facts_as_of(valid_at, believed_at, …)/open-SQL path and returns
an as_of scope where applicable.
identity_regime prevents silently mixing today’s merge map with yesterday’s
beliefs when an explicit identity-as-of audit is requested.
Agent consumption checklist
- Read
grainfirst — refuse load-bearing action on wrong grain. - If
negativenon-null — branch on kind. - If
contradiction— report all sides (or fetch continuation). - If
truncated— decide whether to continue. - If
dropped_by_hydrationhigh — consider re-query / freshness. - Prefer
fact_evidence+evidence_totalswhen usingfacts_context. - For
ContextBundle/v2, inspect both complete child envelopes separately. - If using K — check
freshness.k.