Rulvar API reference / @rulvar/rulvar / OrchestrateClaimConsistency
Interface: OrchestrateClaimConsistency
Defined in: packages/core/dist/index.d.ts
The claim-consistency pass's knobs (RV1501/RV1502). The pairing half is a PURE fold (pairDraftClaims) over the accepted draft and the same settled pool the contradiction pass judges, so it costs nothing and journals nothing. The judge half is ONE bounded structured-output invocation under role 'synthesize' (the routing key picks its model unless judge.model overrides), dispatched only when the fold produced at least one pair; its verdict is an ordinary journaled agent entry, so a resumed run replays it with zero paid calls and the derived findings are byte identical.
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
coveragePolicy? | "observed" | "strict-final" | What the FINAL pass's coverage grade is allowed to be (RV4003, the fifth comparison experiment). 'observed' (the default) keeps today's bytes: the grade is reported and nothing gates on it. 'strict-final' refuses acceptance typed when the final meta's grade is anything but 'full' (partial, vacuous, critical uncovered, judge declined, judge failed alike), UNLESS a waiver is declared: the experiment's pass covered 54 of 74 citing sentences, graded itself 'partial' honestly, met its own declared 0.72 target, and the run still shipped three unsupported citations inside the uncovered fraction. The ratio floors (coverageTarget, minimumCoverageRatio) stay untouched underneath: this policy binds the GRADE, the one word that already folds every truncation and dead-judge reading. Requires stage 'final' or 'both': a draft-only pass grades no final document, so the policy would gate on nothing. | packages/core/dist/index.d.ts |
coverageRepair? | boolean | Coverage joins the bounded repair round (RV4202, the sixth comparison experiment). The experiment's run reached its strict-final gate with a 'partial' grade and had exactly two doors: a typed refusal or the standing waiver, because the round armed on FINDINGS alone; the uncovered 27 percent of its citing sentences was a defect class no machinery could consume. With this set, a final grade that is not 'full' arms the same ONE bounded round (RV3307): the still-uncovered citing sentences ride the round's prompt as the UNCOVERED CLAIMS block (ground each claim in material the pool actually read, or drop the citation), the repaired document is re-paired and re-judged from its new hash, and a grade that is STILL not 'full' after the round meets the strict-final gate exactly as before (the typed refusal, or a waiver where the posture allows one). Requires onFound: 'repair' (the round is that posture's machinery) and coveragePolicy: 'strict-final' (the gate whose refusal the round averts); a ConfigError otherwise. Off by default: every existing config keeps its bytes, round triggers included. | packages/core/dist/index.d.ts |
coverageTarget? | number | The declared coverage target (RV2903), in (0, 1]: the pass sizes itself to COVER this share of the draft's citing sentences instead of judging the first max pairs blind. The ninth comparison run covered 43 of 115 citing sentences because its host guessed max: 56 plus the default run-fact bound, and the honest 'partial' grade was the constant's echo, not a policy. Under a target the pairing selects coverage-first (criticals, then one pair per uncovered sentence until the target is met; max stays a hard ceiling), the run-fact pass judges EVERY matched candidate instead of the default bound, and an undeclared minimumCoverageRatio defaults to the target, so the RV1809 floor machinery (the lowCoverage block, onLowCoverage, the strict CLI exit) enforces the same number that sized the pass. | packages/core/dist/index.d.ts |
critical? | string[] | Critical anchor declarations (RV1603): paths (a file, or a directory matched as a prefix) or span anchors (src/exec.ts:250-300). Pairs whose draft anchor matches sort FIRST, before the max cap, so the bounded judge spends its budget on the declared claims, and the meta names every critical draft anchor that ended up unjudged (criticalUncovered). The eighteenth comparison benchmark judged 40 of 144 citing sentences with nothing steering which 40 and nothing saying what was left out. Unset = the exact historical pairing order, byte for byte. | packages/core/dist/index.d.ts |
judge? | { effort?: Effort; estCost?: number; limits?: UsageLimits; model?: ModelSpec; } | The judge invocation's own knobs; the routing chain applies otherwise. | packages/core/dist/index.d.ts |
judge.effort? | Effort | - | packages/core/dist/index.d.ts |
judge.estCost? | number | - | packages/core/dist/index.d.ts |
judge.limits? | UsageLimits | - | packages/core/dist/index.d.ts |
judge.model? | ModelSpec | Model override for the judge invocation. | packages/core/dist/index.d.ts |
max? | number | Bound on judged pairs; default DEFAULT_MAX_CLAIM_PAIRS. | packages/core/dist/index.d.ts |
maxExcerptChars? | number | Bound on each excerpt; default DEFAULT_MAX_PAIR_EXCERPT_CHARS. | packages/core/dist/index.d.ts |
maxPoolPerPair? | number | Bound on each pair's pool readings; default DEFAULT_MAX_POOL_PER_PAIR. | packages/core/dist/index.d.ts |
minimumCoverageRatio? | number | The declared coverage floor (RV1809): the minimum coveredCitingSentences over draftCitingSentences ratio, in (0, 1]. The nineteenth benchmark's pass covered 36 of 122 citing sentences and graded itself 'partial' honestly, but nothing could ENFORCE a floor: a consumer had to read the counts and decide externally. Below the floor, onLowCoverage decides. A draft with zero citing sentences is vacuously full and never trips it. | packages/core/dist/index.d.ts |
onFound? | "report" | "carry" | "fail" | "repair" | What a judged contradiction does. 'report' (the default) puts the findings on the acceptance envelope and in an info log, and changes nothing else. 'carry' additionally names them in the 'single' synthesis prompt with the instruction to resolve each explicitly (a ConfigError without that synthesis, the contradictions precedent), and non-empty findings block the skipWhenDraftValid gate: a draft contradicting its own pool never earns the skip. The carry can only ride a prompt that still lies ahead, so it binds the pass that runs BEFORE the synthesis: under stage: 'both' the draft pass carries and the final pass reports, and stage: 'final' with 'carry' is a ConfigError at intake, because a posture that reads as a gate must not quietly behave as 'report'. 'repair' (RV3307) is the honest carry for the final pass: judged findings ride ONE more synthesis invocation (the same CLAIM CONTRADICTIONS block, over a prompt that now lies ahead again), the repaired document is judged again, and findings that survive the round fail the run typed, exactly like a dead or declined judge under this posture, because a gate armed to repair must not pass silently. It needs a pass that runs AFTER a synthesis, so stage must be 'final' or 'both' (a ConfigError beside the default 'draft', whose findings the ordinary carry already consumes). 'fail' fails the run typed with data.source 'orchestrator_claim_consistency' BEFORE any synthesis dispatch; the judge itself has already been paid, which is the honest minimum for a semantic verdict. A judge that does not settle ok is named on the meta (judgeFailed) and fails the run only under 'fail': a gate armed to stop the run must not pass silently when its judge dies. | packages/core/dist/index.d.ts |
onLowCoverage? | "report" | "fail" | What a below-floor ratio does (RV1809): 'report' (the default) stamps the machine-readable lowCoverage block on the meta; 'fail' fails the run typed BEFORE the judge dispatch, exactly like onUncoveredCritical, so a run that cannot meet its declared verification floor never pays for a partial verdict. Requires at least one declared floor. | packages/core/dist/index.d.ts |
onUncoveredCritical? | "report" | "fail" | What an unjudged critical anchor does (RV1603): 'report' (the default) names them on the meta only; 'fail' fails the run typed with data.source 'orchestrator_claim_consistency' BEFORE the judge dispatch, so a run whose declared claims cannot be verified never pays for a partial verdict. Requires critical. | packages/core/dist/index.d.ts |
pattern? | string | Overrides DEFAULT_ANCHOR_PATTERN for both sides; fail-closed at intake. | packages/core/dist/index.d.ts |
runFactCoverageRatio? | number | The run-fact coverage floor (RV1809): the minimum judged run-fact pairs over matched run-fact candidates ratio, in (0, 1]. Requires runFacts: true; a draft with zero matched run claims never trips it. | packages/core/dist/index.d.ts |
runFacts? | boolean | The run-facts grounding opt-in (RV1603): the run's own recorded execution facts (accepted children, statuses, recorded evidence entry counts, wire request and token totals; the executionFactsOf material plus the entries plumbing) become one more pool reading, and draft sentences that SPEAK about the run (naming a minted id, a recorded fact value of two or more digits, or a runFactTerms phrase) are paired with that sheet under the (run-facts) anchor, judged by the same invocation. Closes the eighteenth benchmark's live gap: a dossier claimed "each role recorded 18-20 evidence entries" over recorded profiles of 23/18/22/20/20/20 and "real models were not run" beside 125 recorded wire requests, with executionFacts enabled; facts offered to the composer verify nothing about what it composed. Off by default: judge prompt bytes stay identical when unset. | packages/core/dist/index.d.ts |
runFactTerms? | string[] | Case-insensitive phrases that mark a draft sentence as a run claim for the runFacts pass (negations carry no number: "real models were not run" pairs only through a term). Requires runFacts: true. | packages/core/dist/index.d.ts |
stage? | "draft" | "final" | "both" | WHICH document the pass judges (RV2509), default 'draft', the historical behavior byte for byte. The pass has always read the coordination draft, strictly BEFORE the synthesis, so that a draft contradicting its own pool fails before anything pays to compose it. That ordering is right and stays; what it cannot do is verify the document that actually SHIPPED. The synthesis rewrites the draft, and under 'draft' the semantic verdict on the terminal describes a document no consumer ever receives: the twenty-fifth comparison run's judge cleared a draft and the synthesis then composed a different text three times over. 'final' moves the pass after the synthesis, over the artifact the run settles on. 'both' keeps the pre-synthesis gate AND judges the final, at the price of a second judge invocation; the terminal then reports the FINAL pass in claimConsistencyMeta (the shipped document is what a consumer gates on) and the earlier one in claimConsistencyDraftMeta. Every meta says which document it read (judgedStage, judgedHash), and the envelope's draftToFinal says whether the synthesis changed the document at all, so the question "is this verdict about what I received" is a field read under every setting, including the default. Meaningful only with a synthesis configured: without one the draft IS the final and all three settings judge the same document. | packages/core/dist/index.d.ts |
waiver? | { expiresAt?: string; principal: string; reason: string; } | The signed exception to 'strict-final' (RV4003): a named principal accepting a non-'full' final grade, with the reason on record. The acceptance then proceeds, the decision journals as claim_coverage_waived (principal, reason, expiry, and the grade it waived, term for term), and the envelope carries the waiver verbatim beside the meta, so a consumer reading coverage: 'partial' on a strict run always finds WHO accepted it and why. expiresAt (ISO 8601) bounds the standing waiver: an expired one refuses exactly like no waiver, evaluated once at the enforcement point and journaled, so a resume replays the recorded verdict instead of re-reading the clock (RV4104): a run that waived, crashed, and outlived its waiver finishes under the recorded exception. The frozen decision licenses exactly the document it judged: an entry carrying a judgedHash is honored only for that hash (the RV603 bound), and entries written before the field existed stay reusable. Requires coveragePolicy: 'strict-final'; declaring it without the policy is a ConfigError, because a waiver over an unenforced grade is a signature over nothing. | packages/core/dist/index.d.ts |
waiver.expiresAt? | string | - | packages/core/dist/index.d.ts |
waiver.principal | string | - | packages/core/dist/index.d.ts |
waiver.reason | string | - | packages/core/dist/index.d.ts |