Query Semantics
Query as contract
Aa
All entries made in the ledger have to be double entries—that is, if you make one creditor, you must make some one debtor.
This chapter formalizes query semantics as Anchor A25, defining a query as a contract that produces both candidates and obligations. A25 specifies candidate standing (certified, witnessed, proposed), witness policies (strict, best-effort, exploratory), equivalence policies for cross-context joins, and a structured receipt system that makes every inclusion, exclusion, and reconciliation auditable. The formalization builds on the certification contract (A19b), predicate packages (A24), and identity maintenance (A23), unifying them into a single query-level discipline. For the narrative motivation behind treating queries as contracts rather than filters, see Vol I, Chapter 7 (The Witness Protocol).
The Hidden Contract
"Show me puffy blue dresses under $200."
The hypothetical catalog can answer it under several different contracts. It might search current regional stock or every listed item. It might use the styling team’s measurement of puffiness or a learned approximation, treat navy as blue, and choose one merchant’s price for a product that appears twice.
Those choices determine what the returned list means. A recipient trying to compare prices needs more than the list’s order; a recipient investigating an omitted item needs the definition and coverage used. An existing service may already preserve this information. The proposed query contract makes it part of what must remain available when the result travels.
The Query Contract
Chapter 22 defined what predicates promise: the predicate package bundles a predicate's signature, intension, runtime spec, tests, invariants, provenance, and scope. A predicate's package is its citizenship papers.
This chapter defines what queries promise. A query in the Third Mode is not a filter but a contract that specifies what the caller is asking for, what evidence the caller requires, and what the substrate guarantees in return.
Definition (A25: Query Semantics). A completed result carries candidates and the obligations governing their use:
The full operation also permits an established unsatisfiability result, a rejection and Inconclusive with unfinished checks (Appendix I, Operation 9). The pair above describes a returned candidate result, not a promise that every query completes.
Candidates: Items proposed or established to satisfy the query predicates in the referenced contexts, each with the corresponding standing label.
Obligations: A structured record of what the query assumed and what the substrate guaranteed.
The obligations make the contract explicit:
QueryObligations {
contexts_referenced: [Context, ...],
predicates_used: [(PredicatePackage, version), ...],
witnesses_required: WitnessPolicy,
uncertainty_tolerated: UncertaintyBound,
equivalence_policy: EquivalencePolicy,
invariants_enforced: [Invariant, ...],
agreement_requirements: [(predicate, contract), ...]
}
The query declares these terms; an implementation must enforce those it promises. The result records the checks, grounds and unresolved obligations needed to assess that promise.
Candidate Standing
Each candidate carries a standing label. This is the missing link between "queries return results" and "queries return auditable results."
CandidateResult {
item: Item,
standing: certified | witnessed | proposed,
standing_scope: Context,
standing_kind: identity | isomorphism | approximation,
witnessed_gaps: [GapType, ...],
confidence: Option<f64>
}
| Standing | Meaning | Downstream Use |
|---|---|---|
certified | Required checks passed on the declared scope and evidence | Use within that checked contract and applicable authority |
witnessed | Evidence present but gaps exist | Use with caveats; inspect gaps |
proposed | Candidate not established under the required evidence policy | May inform exploration; cannot be used as though certified |
The standing reports which obligations the procedure discharged. Trust in the result also depends on what those obligations cover and on the grounds supplied. A certified candidate has full provenance: every predicate evaluation is witnessed, every equivalence used in joins is certified, every invariant passed. The witnessed_gaps list is empty relative to the declared required checks; an empty field does not establish complete discovery of every relevant obligation. A witnessed candidate has supplied evidence while some required grounds remain unestablished. The label does not count how much of the chain is adequate. The witnessed_gaps list tells you exactly which links: equivalence_uncertified, invariant_partial, predicate_uncertified, or agreement_untested. A proposed candidate is a hypothesis: it looks like it might satisfy the query, but the system cannot certify it.
The standing_kind is the minimum kind in the candidate's evidence chain. If one join used approximation-kind equivalence while another used identity, the candidate's overall standing_kind is approximation. This is a non-escalating metadata convention. Compatible maps, error propagation and dependence still require actual justification.
A proposal may carry a score; call it confidence only under an identified interpretation or calibration. Scores from different mechanisms are not automatically comparable.
Unknown means the required conclusion has not been established by this evaluation. Its cause may be missing evidence, a failed lookup or an unfinished check. “Uncertified” likewise needs a recorded reason; it is not uniformly a numerical score below a threshold.
If the receiving institution uses that incomplete result to maintain a restriction or postpone a consequential decision, it acquires a further obligation. Appendix I, I.1.6 requires the missing grounds, responsible disposition, applicable review point and authorized response to continued uncertainty to remain available. The query has reported what it could not establish. It has not decided how long the institution may leave the affected use pending.
Witness Policies
The query declares its evidence standard through a witness policy.
| Policy | Meaning | Standings Included |
|---|---|---|
strict | Only certified claims | certified only |
best_effort | Certified + witnessed | certified, witnessed |
exploratory | All standings; scores carry their declared interpretation | All three |
Strict. Use where this operation requires completed certification. Every result can be traced to witnesses. If a predicate lacks certification, its results are excluded. If an equivalence is not certified, the join refuses to proceed. A conforming implementation must return only candidates certified under that declared contract.
Best effort. Use for operational search where recall matters but auditability is required. Certified candidates come first. Witnessed candidates are included but tagged, so the caller knows which results have partial provenance. Proposed candidates are excluded.
Exploratory. Use for discovery, research, hypothesis generation. Candidates may carry scores under an identified interpretation. Proposed results remain hypotheses; their inclusion does not certify them. A separately justified action may use different grounds without representing these hypotheses as established facts.
This ties to A19b (Certification Contract): the query specifies whether it demands certification or accepts proposals. Chapter 17's distinction between similarity and equivalence becomes operational here. Similarity can generate proposals. Evidence can earn witnessed standing, and completed applicable checks can earn certification within the declared scope.
Equivalence Policy
When a query joins across contexts, it uses equivalences. The product in the merchant's catalog and the product in the inventory system may be recorded differently. Are they the same product? That depends on what equivalences exist and whether the query trusts them.
The equivalence policy declares how the query handles unknowns and conflicts:
EquivalencePolicy {
equivalence_unknown_handling: reject | include_tagged | explore,
conflict_handling: fail | include_obstruction | choose_precedence(rule)
}
| Handling | Meaning |
|---|---|
reject | Exclude items where equivalence is unknown or conflicted |
include_tagged | Include with explicit tag |
include_obstruction | Include with obstruction witness attached |
choose_precedence(rule) | Apply precedence rule |
Unknown equivalences. If the query joins two contexts and no equivalence is declared for a pair of items, what happens? Under reject, those items are excluded from the join. Under include_tagged, they are included but marked with an "equivalence_unknown" tag. Under explore, they are included as candidates for investigation.
Conflicting equivalences. If one context says two items are equivalent and another says they are not, what happens? Under fail, the query fails with an obstruction witness. Under include_obstruction, the candidates are included with the obstruction witness attached, so the caller can see the conflict. Under choose_precedence, the substrate applies a declared rule (most recent, narrowest scope, highest authority) to resolve the conflict.
Precedence rules are governance. They must themselves be declared policies with provenance: author, timestamp, authority. Otherwise you reintroduce silent semantics through the back door. The precedence rule is a first-class artifact, not a hidden default. Including a conflict record or selecting a preferred source does not complete a hard check that the result’s claimed standing requires. Such candidates must retain their lower standing or unresolved obligation; the policy cannot silently override the witness requirement.
Query Decomposition
A natural language query decomposes into structured components. Consider: "puffy blue dresses under $200, not formal."
| Component | Predicate | Type | Package | Context |
|---|---|---|---|---|
| "puffy" | puffy(x) | Score | puffy_v1 | user_session |
| "blue" | color(x) = blue | Bool | color_v3 | product_catalog |
| "dresses" | category(x) = dress | Bool | category_v2 | product_catalog |
| "under $200" | price(x) < 200 | Bool | price_v1 | merchant_view |
| "not formal" | ¬formal(x) | Bool | formal_v1 | style_taxonomy |
The query spans four contexts: user_session (where "puffy" is meaningful), product_catalog (categories and colors), merchant_view (prices), and style_taxonomy (formality). These contexts may have different records for the "same" product. The join must be explicit.
join_on: equivalent(
merchant.product,
catalog.product,
U_product_identity,
kind ≥ isomorphism
)
The full query:
Query {
filter: puffy(x) > 0.7 ∧ color(x) = blue ∧ category(x) = dress
∧ price(x) < 200 ∧ ¬formal(x),
contexts: [user_session, product_catalog, merchant_view, style_taxonomy],
predicates: [puffy_v1, color_v3, category_v2, price_v1, formal_v1],
join_on: equivalent(merchant.product, catalog.product,
U_product_identity, kind ≥ isomorphism),
witnesses: best_effort,
uncertainty: {
equivalence_kind: at_least_isomorphism,
score_threshold: 0.7,
unknown_handling: reject
},
equivalence_policy: {
equivalence_unknown_handling: reject,
conflict_handling: include_obstruction
},
invariants: [price > 0, category ∈ valid_categories],
agreement_requirements: [(puffy, calibrated(ε=0.05)), (formal, decidable)]
}
This is T6 (puffy, an invented predicate), T7 (contextual equivalence for "same dress" across merchants), and T8 (subjective "formal" predicate) in one query. Each has explicit semantics. None is silent.
T6: Puffy in Query
The query references puffy_v1, the predicate package from Chapter 22. The package specifies that puffy is a measurement-based score with a calibrated test suite and known exemplar coverage.
The query declares:
- Version: puffy_v1 (pinned, not "latest")
- Threshold: > 0.7
- Agreement requirement: calibrated(ε=0.05)
Pinning a version does not restore support withdrawn by a correction; A26 governs reassessment. If puffy has been versioned to puffy_v2 since the query was written, the substrate does not silently substitute. It either uses the pinned version or emits a version drift warning. The query can accept drift or fail; silent substitution is forbidden.
The agreement requirement specifies that if puffy is evaluated in multiple contexts, the values must agree within ε=0.05 on overlapping items. If merchant A’s puffy score is 0.8 and merchant B’s is 0.72 on the same calibrated scale, their difference is 0.08: they fail the 0.05 tolerance. If merchant A's is 0.8 and merchant B's is 0.5, that is an agreement failure. The substrate produces an obstruction witness.
The query cannot silently relax the grounds required for the standing it claims. If it demands exact agreement, a statistical comparison alone is insufficient. That mismatch must be reported as an unmet requirement, not a proved disagreement of the values. Additional exact grounds may support the requested use; an explicitly different exploratory contract may support a narrower one.
T7: Contextual Equivalence in Join
The query joins merchant_view and product_catalog. Both contexts contain product records. Are the records for the "same" product?
The query declares:
- Equivalence scope: U_product_identity
- Equivalence kind: ≥ isomorphism
- Unknown handling: reject
- Conflict handling: include_obstruction
The join clause is explicit:
join_on: equivalent(merchant.product, catalog.product,
U_product_identity, kind ≥ isomorphism)
If no equivalence is declared for a pair of products, the substrate excludes them from the join. The receipt should identify excluded candidate pairs. It cannot claim to have accounted for every possible pair outside the enumerated search domain. If equivalences exist but conflict (merchant A says two records are the same product; merchant B says they are different), the substrate includes the obstruction witness so the caller can see the disagreement.
This is Chapter 21's identity maintenance becoming operational. The context graph stores equivalence declarations. The query consults them. Joins are auditable.
T8: Subjective Predicate Resolution
"Formal" is a subjective predicate. Different contexts may define it differently. The fashion taxonomy's "formal" may differ from a wedding planner's "formal."
The query declares which context's "formal" to use: style_taxonomy. But what if multiple packages exist for "formal" in the query's contexts?
The substrate uses package resolution:
resolve_package(formal, query_contexts, intension_constraints, scope_constraints)
→ PredicatePackage | AmbiguityWitness | MissingPackage | Inconclusive
If exactly one adequate package is established, the substrate uses it. A completed search with no match returns MissingPackage; an unfinished required check returns Inconclusive. If multiple packages match (formal_fashion vs formal_events), the substrate returns AmbiguityWitness. The query must then:
- Specify which package explicitly
- Accept the substrate's precedence rule
- Fail with explicit ambiguity error
Silent resolution is forbidden. The query knows exactly which definition of "formal" was used, or it knows that ambiguity prevented resolution.
The Substrate's Promises
The substrate makes seven promises:
-
Scope fidelity. Results come only from declared contexts. The substrate will not silently expand scope to improve recall.
-
Version pinning. Predicates are evaluated at declared versions. If a predicate has been versioned, the substrate uses the pinned version or emits a migration notice.
-
Witness compliance. Results satisfy the witness policy. Each candidate carries a standing label. The result set respects the policy filter.
-
Uncertainty bounds. Where required, the result carries a bound with its procedure and population. A score falling below a decision threshold is different from an uncertainty bound being inadequate; the contract must distinguish them.
-
Equivalence compliance. Joins use declared equivalence scope and kind. Unknown equivalences and conflicts are handled per equivalence policy.
-
Invariant enforcement. Hard invariants are checked on results. Violations are excluded or surfaced as constraint conflicts.
-
Agreement on overlaps. Perform the comparisons the contract requires. Record established disagreement separately from missing grounds or unfinished checking.
These are proposed implementation obligations. The receipt must carry enough evidence to check the promises actually made. A completed record does not prove completeness of its grounds, and the contract does not grant authority for every subsequent use.
Exclusions and Receipts
The query result includes not just candidates but the audit trail:
QueryResult {
candidates: [CandidateResult, ...],
obligations: QueryObligations,
receipts: {
contexts_consulted: [Context, ...],
predicate_evaluations: [(item, predicate, value, witness?, standing), ...],
equivalences_used: [(item_pair, equivalence, scope, kind), ...],
invariants_checked: [(invariant, status), ...],
agreement_reconciliations: [(overlap, predicate, status), ...]
},
exclusions: [
{ item: Item, reason: ExclusionReason, witness_ref: Option<Witness> }
],
warnings: [...]
}
Exclusions matter. Knowing what was excluded is as important as knowing what was included. The exclusions ledger tells you:
| Reason | Meaning |
|---|---|
below_threshold | Score predicate below declared threshold |
invariant_violation | Failed hard invariant check |
equivalence_unknown | Join failed due to unknown equivalence |
equivalence_conflict | Join failed due to conflicting equivalences |
agreement_failure | Overlap reconciliation failed |
standing_insufficient | Only proposed standing under strict policy |
If a dress was excluded because its puffy score was 0.65 (below the 0.7 threshold), the exclusions ledger records this. If a dress was excluded because two merchants disagreed about whether it was the same product, the exclusions ledger records this with the obstruction witness.
Receipts are summaries, not traces. The substrate stores witness references and evaluation keys, not replayed computations. References are stable IDs: witness hashes, evaluation keys, package version IDs. They identify artifacts a verifier can retrieve and examine; whether the audit also requires replay depends on the claim and the artifacts available. A21 assigns the cost of producing and checking these records to a declared budget. It does not establish that every receipt will be cheap or sufficient. The implementation must preserve the evidence its promised audit requires.
Filter vs Contract
A returned list alone need not say which definitions, mappings or evidence governed it. A receiving contract makes those requirements inspectable. Ordinary databases and application services can provide the records; the proposed contribution concerns what must survive their composition, not a limitation imposed by the word “filter.”
The result records the scope and package versions used, the witness policy, uncertainty bounds, equivalences, invariants and evaluated exclusions. It also identifies the premises actually consumed. When one is corrected, A26 requires reassessment of the affected use; repeating a result through another query must not detach it from that obligation.
Consequence
The package and query meet at an actual evaluation. The package identifies the definition and its grounds; the query states which use it proposes to make of them. Retaining both lets another recipient examine why an item was included, which tested alternative was excluded and whether either judgment still has its support.
A satisfied contract can make a result useful without making it self-sufficient. The next operation may ask a different question. An established conflict can block that request; a missing check can leave it unresolved. The receipt must preserve that difference along with the grounds on which any answer continues to rely.
Chapter 24 asks the next question: how do predicates and queries survive time? Versioning, compatibility, and operational coherence.