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
Section titled “evaluationStatus — was it computed”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
Section titled “truthStatus — what the computation supports”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
Section titled “Value shapes per kind”truthandfocused_truth: the verdict istruthStatus;valuecarries the result payload of the engine.why_not:value.value.blockersholds the blocker graph — one entry per candidate rule with its conjunct states — andwhyNotprojects the same list;whyNotTermErrorsholds term errors beside it.collect:valueholds the bindings; on the frist scenariovalue[0].valueis'2026-03-20'.calendar_op(deadline):valueholds the computed date.term(calc):valueholds the evaluated term.positions: the duties and their statuses —positionson the Python answer, the value on the TypeScript answer.
missingInputs, sources, proof, issues
Section titled “missingInputs, sources, proof, issues”missingInputslists what aMISSING_INPUTanswer lacks, as input requirements your code can turn into form fields.sourceslists the source anchors of the applied rules when the canon attaches them; the periods canon build returns an empty list, and the rule identifier inproofremains the address.proofis the proof graph: the facts as assertions and the rules that fired, withrulesAppliedread from it.issuescarries the engine’s messages by code; on a clean call there are only defaulted context fields.hashescarriesprogram(the canon that answered),semantic(the case as evaluated), andresult(the outcome):
export type Hashes = { program: string; semantic?: string; result?: string; case?: string; code?: string; request?: string; focusedResult?: string; focusedProof?: string; answer?: string;};LocalAnswer versus RemoteAnswer
Section titled “LocalAnswer versus RemoteAnswer”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
Section titled “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 |
// 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 formtry { 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
Section titled “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.
Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.