> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vainona.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Answers

> The current, queryable value of a judgment for a document.

export const productName = "Vainona";

An answer is the current materialized value of a judgment for a document. Answers come back inside documents and query rows, keyed by judgment name.

```json theme={null}
{
  "needs_escalation": {
    "type": "bool",
    "p": 0.91,
    "thresholds": {"escalate": true},
    "freshness": "fresh",
    "revision": 43,
    "judgment_version": 3,
    "engine": "jev",
    "engine_version": "current+2026-09-24.1",
    "evaluation_id": "ev_01J...",
    "evaluated_at": "2026-09-23T12:00:02Z"
  },
  "intent": {
    "type": "choice",
    "value": "billing",
    "dist": {"billing": 0.88, "technical": 0.05, "sales": 0.02, "none_of_the_above": 0.05},
    "escape_p": 0.05,
    "freshness": "fresh"
  }
}
```

* **The numbers are the engine's.** `p`, `dist` and `score` are the engine's raw output. Once a judgment has 100 outcomes, each answer also carries a `calibrated` object with the same fields plus `method`, `outcomes` and `from_previous_epoch`. It never replaces the raw fields, and thresholds, filters and ranking use the raw fields. See [calibration](/concepts/calibration).
* **A [composite judgment](/guides/composite-judgments)'s `p` is combined.** It comes from weights fitted on your labels, and `parts` gives each part's raw `p`. It has no `calibrated` object, and thresholds, filters and ranking use the combined `p`.
* **Every answer has provenance.** It names the document `revision` it was computed for, the `judgment_version`, the `engine_version` and the `evaluation_id`, so you can always see how it was produced. When a change leaves the compiled context the same, the answer is reused for the new revision without calling the engine: `revision` moves on, and `evaluation_id` and `evaluated_at` still name the earlier evaluation that computed the numbers.
* **The answer of a judgment with [relations](/concepts/relations) has a `watermark`,** the position in the namespace's log its context was read at. Every write at or below it, to the document or to the documents that point at it, is reflected. `revision` still names the document's own revision. For a relation that reads the document the judged one points at, the watermark also says which version of that document the answer read; an answer outside the judgment's [re-judge scope](/guides/freshness-policies#fan-out-when-a-referenced-document-changes) keeps that version after the document changes. On a get, such an answer also lists `referenced_changes`: the newest write to each document it points at that changed what the relation shows, with its `revision` and time. One at or below the watermark is in the answer; one above it leaves the answer `fresh` only when the document is outside the scope. A `failed` answer of such a judgment keeps its last good numbers but has no `watermark`, because the failed attempt's position does not describe them. A judgment with `applies_to` has no answer at all for the documents it does not apply to.
* **Every answer has a [freshness](/concepts/freshness).** `stale` and `failed` answers still carry the last good numbers and the revision they were computed for.

## Querying answers

Queries filter and rank on answers like any other field:

```json theme={null}
{
  "filters": ["And", [
    ["attributes.plan", "Eq", "pro"],
    ["answers.needs_escalation.p", "Gte", 0.85],
    ["answers.intent.value", "In", ["billing", "technical"]],
    ["answers.needs_escalation.freshness", "Eq", "fresh"]
  ]],
  "rank_by": ["answers.needs_escalation.p", "desc"],
  "top_k": 100,
  "include": {"attributes": ["plan", "region"], "answers": ["needs_escalation", "intent"], "state": false},
  "answers": "fresh_only",
  "consistency": "strong"
}
```

* **Filters** are `[field, op, value]`, `["And" | "Or", [...]]` or `["Not", filter]`. The operators are `Eq`, `NotEq`, `In`, `NotIn`, `Lt`, `Lte`, `Gt`, `Gte`, `Glob`, `Contains` (on string arrays) and `Exists`.
* **Filterable fields** are `id`, `revision`, `updated_at`, `attributes.*`, and for each judgment `p`, `value`, `score`, `dist.{option}`, `escape_p`, `freshness` and `thresholds.{name}`. `state` is never filterable.
* **`rank_by`** is one field and a direction, `["updated_at", "desc"]` by default.
* **`top_k`** is at most 1,000. A `cursor` from `next_cursor` fetches the next page. Cursors last 10 minutes and pin the namespace's state, so pages are consistent with each other. `more: true` means more rows matched.
* **`answers: "fresh_only"`** drops rows whose included answers are not `fresh`.
* **`consistency: "eventual"`** may serve a view of the namespace up to 60 seconds old, for lower latency.
* A query whose estimated scan is over 4 GB is refused with `too_large` and the estimate, and is not billed. Add attribute filters to narrow it.

You can filter or rank only on judgments with the `on_change` policy, because the query needs every answer to exist. Using an `on_read` judgment in a filter returns `invalid_request`; switch it to `on_change` first, which backfills the missing answers after you confirm an estimate. {productName} never backfills silently.
