Query types
One request shape, seven question kinds. The kind says what the engine does with the facts: check a claim, compute a value, count days, explain a gap, or list what the case requires. This chapter says when to use each, what the answer carries, and which exist in Python.
export type AskRequest = { kind: 'truth' | 'focused_truth' | 'why_not' | 'collect' | 'calendar_op' | 'term' | 'positions'; predicate?: string; args?: FactArg[]; caseInput: CaseInput; queryId?: string; caseName?: string; extra?: Record<string, unknown>;};truth — is the claim established
Section titled “truth — is the claim established”truth(predicate: Rel, args: FactArg[], caseInput: CaseInput): Promise<Answer>;def truth(self, predicate: str, args: list[Any], case_input: dict[str, Any]) -> Answer: ...Use truth to check a complete claim: does the period end on 20
March. The answer carries truthStatus — one of TRUE_ONLY,
FALSE_ONLY, BOTH, NEITHER — with the proof of what fired. The
candidate date is yours; the engine only judges it.
await fristen.truth('frist_ende', ['frist', '2026-03-20'], caseInput);// COMPUTED, TRUE_ONLYawait fristen.truth('frist_ende', ['frist', '2026-03-21'], caseInput);// COMPUTED, NEITHER — the wrong date is supported by nothingfocused_truth — the same answer, sliced by the question
Section titled “focused_truth — the same answer, sliced by the question”focusedTruth(predicate: Rel, args: FactArg[], caseInput: CaseInput): Promise<Answer>;The same answer as truth, with the proof and the issues reduced to
the question’s cone only. The answer is marked focused_truth and
carries a focus manifest instead of the full proof graph. It is not an
audit document: a sliced answer has no full result hash. Python does
not ship this kind; ask truth instead.
why_not — what blocked the claim
Section titled “why_not — what blocked the claim”whyNot(predicate: Rel, args: FactArg[], caseInput: CaseInput): Promise<Answer>;def why_not(self, predicate: str, args: list[Any], case_input: dict[str, Any]) -> Answer: ...def whyNot(self, predicate: str, args: list[Any], case_input: dict[str, Any]) -> Answer: ...Use why_not when truth answered NEITHER and the application must
ask the user for more. The answer carries whyNot: one blocker per
candidate rule, each with its applicability, a summary trigger, and
the state of every conjunct. Compare the premises with the facts you
supplied and the gap is named.
const w = await fristen.whyNot('frist_ende', ['frist', '2026-03-20'], partial);w.value.value.blockers;// two blockers: TagesfristEnde waits on frist_ereignis and frist_dauer_tage,// Verlegung193 waits on frist_ende_kalenderOn the partial frist case — the duration fact removed — the report
holds exactly two blockers. Term errors of candidate rules, if any,
are reported next to them in whyNotTermErrors.
collect — compute the value
Section titled “collect — compute the value”collect(predicate: Rel, args: FactArg[] | { args: FactArg[]; free?: unknown }, caseInput: CaseInput): Promise<Answer>;def collect(self, predicate: str, args: Any, case_input: dict[str, Any]) -> Answer: ...Use collect to compute rather than check: on which day does the
period end. The free position is named with ?name in the argument
list, or passed explicitly as free with args as a dict. The answer
carries the bindings in value.
const end = await fristen.collect('frist_ende', ['frist', '?end'], caseInput);end.value[0].value; // '2026-03-20'Choose collect when the application does not have a candidate, and
truth when it does — a form that asks “when does it end” collects,
a form that asks “does it end on this day” checks.
deadline — count days on the calendar
Section titled “deadline — count days on the calendar” deadline( opArgs: { date: string; days?: number; unit?: 'business_day' | 'calendar_day'; afterTime?: string; policy?: unknown; suspensions?: Array<{ start: string; end: string }> }, caseInput: CaseInput, ): Promise<Answer>;def deadline(self, op_args: dict[str, Any], case_input: dict[str, Any]) -> Answer: ...Use deadline for the calendar operation itself: a start date plus a
number of days under a counting policy. The policy defaults to the
case’s deadlinePolicy. Python sends the operation as
{"op": "deadline", **op_args}. The answer carries the computed date
in value.
calc — evaluate a term
Section titled “calc — evaluate a term”calc(term: unknown, caseInput: CaseInput): Promise<Answer>;def calc(self, term: Any, case_input: dict[str, Any]) -> Answer: ...Use calc to evaluate a term — an amount, a comparison, an aggregate
over the case — without asking a predicate. The term travels in the
request and the answer carries its value. A term that needs the case’s
counting policy reads deadlinePolicy from the context.
positions — what the case requires
Section titled “positions — what the case requires”positions(caseInput: CaseInput): Promise<Answer>;def positions(self, case_input: dict[str, Any]) -> Answer: ...Use positions to list the duties the facts give rise to and their
statuses, without naming a predicate. The answer carries them in
positions on the Python shape and in the value on the TypeScript
shape.
unfold and questions — no case needed
Section titled “unfold and questions — no case needed”unfold(predicate: Rel | string, options?: { lang?: string; depth?: number; quote?: number; fold?: boolean }): { tree: unknown; text: string };questions(lang?: string): FormManifest;Neither executes a rule. unfold returns the tree of producers of a
predicate over the package’s world — every rule, its strength, the
provision it is anchored to, and the facts it needs — plus the text
the engine prints for it. questions returns the canon’s inventory:
the questions that can be asked, the facts that can be supplied, their
parameters with types and widgets, and the author’s labels. Both are
TypeScript-only; Python reads the inventory at author time instead, as
the Python chapter describes.
Which kinds exist where
Section titled “Which kinds exist where”| Kind | TypeScript | Python |
|---|---|---|
truth | truth | truth |
focused_truth | focusedTruth | — |
why_not | whyNot | why_not / whyNot |
collect | collect | collect |
calendar_op | deadline | deadline |
term | calc | calc |
positions | positions | positions |
unfold | unfold | — |
| manifest | questions | — (author-time workaround) |
Limits
Section titled “Limits”collectneeds exactly one free position:?nameinline or an explicitfree.deadlinewithout a policy — neither in the operation nor in the case — answers that the policy is missing; the engine never assumes how days are counted.focused_truthanswers are slices: same verdict, reduced proof, no full result hash.
Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.