/** * ContextError — the ONE visible finding type, named in the words people * already use for these defects. * * Pattern: plain data + identity-keyed dedup. Pure. * Role: everything a Context Integrity check detects is filed as * exactly this shape, at every seam — a uniform finding is what * makes findings a CORPUS (each one a labelled instance carrying * its check, seam, subjects and witnesses) and what keeps the * disposition accounting honest across seams. * * NAMING LAW: the `kind` is the plain software-defect name, never the * algebra term — the people reading a finding are not reading the * mechanism. The one guardrail that outranks the naming: never use a * familiar name that is subtly wrong. ("State loss" for the evicted- * identifiers failure would send an engineer hunting a storage bug that * does not exist; the ledger held every identifier — they stopped being * SERVED. `dangling-reference` is what a linker means and what happened.) */ import type { Assertion, SubjectRef } from '../assertion/types.js'; import type { IntegritySeam } from '../disposition/types.js'; /** * The nine defect classes, by their plain names: * * | kind | means | mechanism | * |---|---|---| * | `invariant-violation` | two things that cannot both be true were both asserted | exclusion | * | `unsupported-argument` | acted on a value nothing served | domain | * | `dangling-reference` | offered an action whose inputs are no longer available | closure | * | `duplicate-execution` | did settled work again | once | * | `unsupported-claim` | stated something the record does not support | grounding | * | `empty-lookup` | the run produced this value, and the lookup for it found nothing | join | * | `column-type-mismatch` | a column holds something other than the type its tool declared | type | * | `missing-column` | a column the tool declared is in none of its rows | presence | * | `prior-turn-evidence` | every value in the answer was served before this turn | recency | * * `empty-lookup` is the one class that is ADVISORY BY CONSTRUCTION (9.77.0) — * every finding it files carries `advisory: true`, because an empty result * can be perfectly true and nothing in the library can tell a true absence * from a lookup that could never have matched. It is a place to look, not a * defect that was proven. It is deliberately NOT `dangling-reference`, whose * meaning is the opposite: there the ground has left reach, here the ground * is in reach and the lookup came back with nothing. * * `column-type-mismatch` and `missing-column` (9.78.0) are two classes rather * than one ON PURPOSE, and the field failure they come from is the argument: * a LUN of 0 stored as `''` and a LUN column that was never delivered send a * person to two different files, and a checker that said only "something is * off with logical_unit_number" would have helped with neither. Unlike * `empty-lookup`, neither is advisory: a column declared `number` that holds * a string is not a place to look, it is a broken promise — though what the * check can see about it is bounded, and the bound ships as * `COLUMN_TYPE_CEILING` in every message. * * `prior-turn-evidence` (9.83.0) is the family's SECOND advisory-by- * construction class, and for the same shape of reason as `empty-lookup`: * referring back to an earlier result is ordinary conversation, so an answer * built entirely from earlier turns is a place to look and never a proven * defect. It is deliberately NOT `unsupported-claim`, which is the opposite * fact — there the answer says something the record contradicts, here every * value in it is in the record and the question is only WHEN it got there. * Its bound ships as `PRIOR_TURN_EVIDENCE_CEILING` in every message. */ export type ContextErrorKind = 'invariant-violation' | 'unsupported-argument' | 'dangling-reference' | 'duplicate-execution' | 'unsupported-claim' | 'empty-lookup' | 'column-type-mismatch' | 'missing-column' | 'prior-turn-evidence'; /** One detected context error — a labelled instance, automatically. */ export interface ContextError { readonly kind: ContextErrorKind; readonly seam: IntegritySeam; /** The stamped subjects this is about. */ readonly subjects: readonly SubjectRef[]; /** The two-or-more assertions that prove it — copies, plain data. */ readonly witnesses: readonly Assertion[]; /** * WHICH RELATION the defect is about, when the subjects alone do not * determine it (9.61.0). * * The substrate already treats the predicate as identity-bearing — * `assertionKey` is `(subject, predicate, epoch)` — and a finding's * identity was strictly coarser than the algebra key one file over. That * gap lost real defects: two claims about two FIELDS of one entity * rendered the same identity, so the second was deduplicated away and the * event channel disagreed with the disposition ledger about the same run. * * Absent on the checks whose subjects already discriminate (a tool name * is the whole story there), which keeps their identities byte-identical. */ readonly predicate?: string; /** The epoch the conflict was judged at, when the witnesses carry one. */ readonly epoch?: number; /** True when every witness is canary material — never mixed with real. */ readonly synthetic?: true; /** * A SOFTER CLASS (9.61.0): the finding reports doubt rather than * contradiction — today, an answer that declines to claim (`null`, * `'unknown'`) a fact the run verified. Presence-only, and counted apart * from real defects: an advisory is a thing worth seeing, never a thing * that was wrong. `contextErrorIdentity` does not read it, so an * advisory and a contradiction about the same subjects would collapse to * one finding — which is correct: they are the same disagreement, and * the first filing wins. */ readonly advisory?: true; /** One plain sentence a person can act on. States the defect, never a verdict on who is right. */ readonly message: string; } /** * The identity a finding deduplicates by: the same defect about the same * subjects at the same seam is ONE finding however many passes re-detect * it — a findings channel that spams recreates the noise problem it * exists to prevent. */ export declare function contextErrorIdentity(e: ContextError): string; /** Keep the FIRST filing of each identity, in input order. */ export declare function dedupeContextErrors(errors: readonly ContextError[]): readonly ContextError[]; //# sourceMappingURL=types.d.ts.map