Markdown for LLMs
Results and errors
The source Markdown for this article. Copy it into your assistant or download it as a text file.
# Results and errors
Every answer says two things: whether it was computed at all, and what
the computation supports. Your code must keep those axes apart — a
computed answer can still support neither side — and must treat every
unknown variant as failure, never as success.
## evaluationStatus — was it computed
```ts
export type EvaluationDocumentEvaluationStatus = "COMPUTED" | "MISSING_INPUT" | "MISSING_POLICY" | "REQUIRES_JUDGMENT" | "NON_EXECUTABLE" | "EXTERNAL_UNAVAILABLE" | "INTERPRETATION_REQUIRED" | "SOURCE_RESOLUTION_FAILED" | "PRIORITY_CONFLICT" | "UNRESOLVED_NORMATIVE_CONFLICT" | "CONFLICTED_INPUTS" | "TYPE_ERROR" | "RUNTIME_ERROR" | "RESOURCE_LIMIT";
```
| Status | Meaning for your code |
|---|---|
| `COMPUTED` | The engine evaluated the question; read `truthStatus` or `value` |
| `MISSING_INPUT` | Named inputs are absent; read `missingInputs` and ask for them |
| `MISSING_POLICY` | A counting policy was needed and none was supplied |
| `REQUIRES_JUDGMENT` | Only a court can decide; the engine stops |
| `NON_EXECUTABLE` | The question is outside the executable model |
| `EXTERNAL_UNAVAILABLE` | An external source the question needs did not answer |
| `INTERPRETATION_REQUIRED` | A reading must be chosen before evaluation |
| `SOURCE_RESOLUTION_FAILED` | A source the question refers to did not resolve |
| `PRIORITY_CONFLICT` | Competing rules could not be ordered |
| `UNRESOLVED_NORMATIVE_CONFLICT` | Competing norms stand unresolved |
| `CONFLICTED_INPUTS` | The supplied facts contradict each other |
| `TYPE_ERROR` | A value did not fit its declared type at evaluation |
| `RUNTIME_ERROR` | Evaluation itself failed |
| `RESOURCE_LIMIT` | Evaluation exceeded its budget |
Only `COMPUTED` carries a verdict. Every other status is the engine
telling you why there is no verdict — handle it as "not computed",
never as a negative answer.
## truthStatus — what the computation supports
```ts
export type EvaluationDocumentTruthStatus = "TRUE_ONLY" | "FALSE_ONLY" | "BOTH" | "NEITHER";
```
| Status | Exact meaning |
|---|---|
| `TRUE_ONLY` | The computation establishes the claim |
| `FALSE_ONLY` | The computation refutes the claim |
| `BOTH` | The computation supports the claim and its negation |
| `NEITHER` | The computation supports neither side |
`NEITHER` is not "no". On the frist scenario, the right candidate
answers `TRUE_ONLY`, a wrong candidate answers `NEITHER`, and a case
with the duration fact removed answers `NEITHER` too — the third says
"one premise is absent", which `why_not` then names. `FALSE_ONLY`
needs a derivation of the negation, not merely the absence of a
derivation of the claim.
## Value shapes per kind
- `truth` and `focused_truth`: the verdict is `truthStatus`; `value`
carries the result payload of the engine.
- `why_not`: `value.value.blockers` holds the blocker graph — one
entry per candidate rule with its conjunct states — and `whyNot`
projects the same list; `whyNotTermErrors` holds term errors beside
it.
- `collect`: `value` holds the bindings; on the frist scenario
`value[0].value` is `'2026-03-20'`.
- `calendar_op` (`deadline`): `value` holds the computed date.
- `term` (`calc`): `value` holds the evaluated term.
- `positions`: the duties and their statuses — `positions` on the
Python answer, the value on the TypeScript answer.
## missingInputs, sources, proof, issues
- `missingInputs` lists what a `MISSING_INPUT` answer lacks, as input
requirements your code can turn into form fields.
- `sources` lists the source anchors of the applied rules when the
canon attaches them; the periods canon build returns an empty list,
and the rule identifier in `proof` remains the address.
- `proof` is the proof graph: the facts as assertions and the rules
that fired, with `rulesApplied` read from it.
- `issues` carries the engine's messages by code; on a clean call
there are only defaulted context fields.
- `hashes` carries `program` (the canon that answered), `semantic`
(the case as evaluated), and `result` (the outcome):
```ts
export type Hashes = {
program: string; semantic?: string; result?: string; case?: string; code?: string;
request?: string;
focusedResult?: string; focusedProof?: string; answer?: string;
};
```
## LocalAnswer versus RemoteAnswer
```ts
export type Answer = LocalAnswer | RemoteAnswer;
```
A local answer is the engine's own document: `document` is a
`Uint8Array` of canonical bytes and `via` is `'local'`. A host answer
is the host's projection: `document` is `null`, `via` is `'mcp'`, and
the raw payload stays in `host`. Both carry `evaluationStatus`,
`hashes`, and — where the kind produces them — `truthStatus`, `value`,
`whyNot`, and `missingInputs`. Archive the bytes of a local answer;
you cannot archive what a host answer never attached.
Python's `Answer` is always the local shape with `document: bytes`.
## Error classes
Failures of the call are exceptions; "not established" is a value on
the answer. The table lists every class with the condition that raises
it.
| Class | Raised when |
|---|---|
| `FactError` | A fact or the query does not match the declarations: unknown relation, wrong arity, a value that does not fit its type. Carries `path` and `nearest` |
| `PackageNotFoundError` | The spec is versionless, or no source — installed canon, checkout tree, cache, registry — has the package. Carries the name and version |
| `LawClientError` | Common ancestor of the transport family below |
| `TransportError` | The network, the HTTP code, a cap, or an unreadable body failed; also an `explain` on an offline package |
| `ProtocolError` | The envelope or handshake had the wrong shape |
| `RpcError` | The server answered with an error |
| `ValidationError` | An answer did not pass its schema; carries the field path |
| `IntegrityError` | A digest did not match its manifest hash, a path led outside, or a name had the wrong shape |
| `ServeError` (TS) | The `serve` connection refused or failed; carries `status` and `code` |
```js
// Sketch of the catch ladder — the helpers stand for your UI.
const checked = validateFormInput(raw);
if (!checked.ok) return askUserFor(checked.errors); // only these reach the form
try {
await fristen.truth('frist_ende', ['frist', '2026-03-20'], toCaseInput(checked.value));
} catch (e) {
// The form was already valid, so a FactError here is the
// integration's bug — an unknown relation, a wrong arity, a value
// the adapter mis-wrapped. Never bounce it to the user as a field
// correction: log it and fix the adapter or the query.
if (e instanceof FactError) throw e;
if (e instanceof PackageNotFoundError) return install(e.packageName, e.version);
throw e;
}
```
## The unknown-variant rule
Statuses and error codes are open vocabularies: the engine and the
host may return a value your code has never seen. The rule is fixed —
an unknown `evaluationStatus`, an unknown `truthStatus`, or an unknown
error code fails safe. Show "not computed", ask for the missing input,
or re-raise; never map the unknown onto success, onto
`FALSE_ONLY`, or onto a default value. A `switch` over statuses ends
in the failure branch, not in a guess.