@crewhaus/provability 0.0.0-stage → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +9 -0
- package/README.md +300 -2
- package/dist/artifact.d.ts +9 -0
- package/dist/artifact.js +38 -0
- package/dist/builtins.d.ts +32 -0
- package/dist/builtins.js +46 -0
- package/dist/evidence.d.ts +326 -0
- package/dist/evidence.js +1391 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +22 -0
- package/dist/levels.d.ts +19 -0
- package/dist/levels.js +42 -0
- package/dist/origin.d.ts +83 -0
- package/dist/origin.js +296 -0
- package/dist/private-address.d.ts +34 -0
- package/dist/private-address.js +209 -0
- package/dist/purity.d.ts +18 -0
- package/dist/purity.js +15 -0
- package/dist/render.d.ts +47 -0
- package/dist/render.js +315 -0
- package/dist/store.d.ts +59 -0
- package/dist/store.js +319 -0
- package/dist/summary.d.ts +8 -0
- package/dist/summary.js +22 -0
- package/dist/types.d.ts +459 -0
- package/dist/types.js +2 -0
- package/dist/vacuous.d.ts +50 -0
- package/dist/vacuous.js +423 -0
- package/dist/verify.d.ts +176 -0
- package/dist/verify.js +3608 -0
- package/package.json +47 -4
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The provability contract — every type the gate, the tools, the graders, the
|
|
3
|
+
* CLI and every surface read. design/0.8.0-provability-release.md §2, §5.3.
|
|
4
|
+
*
|
|
5
|
+
* One bundle shape, every surface: the cli footer, the channel footer, the
|
|
6
|
+
* gateway envelope, the research report section, the `provability_graded`
|
|
7
|
+
* trace/event-log line (as a summary), the audit record and the JSON file
|
|
8
|
+
* under `.crewhaus/proofs/` all render THIS type. Add fields additively.
|
|
9
|
+
*/
|
|
10
|
+
import type { IrProvability, IrProvabilityLevel } from "@crewhaus/ir";
|
|
11
|
+
/** The four rungs, lowest first. Order is load-bearing: see {@link levelRank}. */
|
|
12
|
+
export declare const PROVABILITY_LEVELS: readonly ["cited", "grounded", "checked", "proven"];
|
|
13
|
+
export type ProvabilityLevel = IrProvabilityLevel;
|
|
14
|
+
/** A rung, or `"none"` for evidence that meets no rung at all. */
|
|
15
|
+
export type Rung = ProvabilityLevel | "none";
|
|
16
|
+
/** The resolved gate configuration — exactly the lowered IR block. */
|
|
17
|
+
export type ProvabilityConfig = IrProvability;
|
|
18
|
+
/**
|
|
19
|
+
* What a definition line binds a claim to (design §4.1):
|
|
20
|
+
* - `source` — `[1]: https://…` / `./path` / `doi:…` / free text
|
|
21
|
+
* - `execution` — `[4]: tool:<toolUseId>`
|
|
22
|
+
* - `formal` — `[5]: proof:prf_<16 hex>`
|
|
23
|
+
* - `assumption` — `[A1]: assume: <text>`
|
|
24
|
+
*/
|
|
25
|
+
export type BindingKind = "source" | "execution" | "formal" | "assumption";
|
|
26
|
+
/**
|
|
27
|
+
* Why a binding does not meet the floor. Stable strings: they appear in the
|
|
28
|
+
* retry nudge, the bundle, `provability audit` roll-ups and the graders.
|
|
29
|
+
*/
|
|
30
|
+
export type UnmetReason =
|
|
31
|
+
/** The claim sentence carries no marker at all. */
|
|
32
|
+
"no_citation"
|
|
33
|
+
/** A marker in the claim has no `[n]: …` definition. */
|
|
34
|
+
| "no_definition"
|
|
35
|
+
/** The source is neither a URL, a `doi:`, nor a workspace path (and
|
|
36
|
+
* `sources.bibliographic` is off). */
|
|
37
|
+
| "not_locatable"
|
|
38
|
+
/** The URL's host fails `sources.allow` or matches `sources.deny`. */
|
|
39
|
+
| "host_denied"
|
|
40
|
+
/** The URL names loopback / RFC 1918 / link-local / metadata space. */
|
|
41
|
+
| "private_address"
|
|
42
|
+
/** A path source resolves outside the workspace. */
|
|
43
|
+
| "path_outside_workspace"
|
|
44
|
+
/** A path source does not exist. */
|
|
45
|
+
| "path_missing"
|
|
46
|
+
/** `sources.resolve: head` got no 2xx/3xx answer. */
|
|
47
|
+
| "unresolved"
|
|
48
|
+
/** The source's body was never fetched/read in this run's evidence. */
|
|
49
|
+
| "not_fetched"
|
|
50
|
+
/** The body was fetched but the claim's words are not in one window of it. */
|
|
51
|
+
| "not_found_in_source"
|
|
52
|
+
/** The words are there, with a negation the claim lacks. */
|
|
53
|
+
| "polarity_conflict"
|
|
54
|
+
/** `grounded.independent` asks for more distinct origins than the claim has. */
|
|
55
|
+
| "not_independent"
|
|
56
|
+
/** `tool:<id>` resolves to no recorded call. */
|
|
57
|
+
| "tool_missing"
|
|
58
|
+
/** The recorded call returned an error result. */
|
|
59
|
+
| "tool_errored"
|
|
60
|
+
/** The tool is not on `execution.allow`. */
|
|
61
|
+
| "tool_not_allowed"
|
|
62
|
+
/** The result text does not contain the claim's numerals / quoted values. */
|
|
63
|
+
| "value_absent"
|
|
64
|
+
/** Re-running the pure tool produced a different output digest. */
|
|
65
|
+
| "replay_mismatch"
|
|
66
|
+
/** `proof:<id>` names no stored artifact. */
|
|
67
|
+
| "proof_missing"
|
|
68
|
+
/** The stored artifact records `ok: false`. */
|
|
69
|
+
| "proof_rejected"
|
|
70
|
+
/** The artifact's recorded claim does not cover the answer's sentence. */
|
|
71
|
+
| "claim_mismatch"
|
|
72
|
+
/** `assumptions: forbid`, or past `max_assumptions`. */
|
|
73
|
+
| "assumption_forbidden"
|
|
74
|
+
/** The binding is valid but below the floor (e.g. a source at `checked`). */
|
|
75
|
+
| "below_floor";
|
|
76
|
+
/** One definition a claim's marker resolved to, and what it proved. */
|
|
77
|
+
export type ProofBinding = {
|
|
78
|
+
/** The marker as written: `"[1]"`, `"[^a]"`, `"[A1]"`. */
|
|
79
|
+
readonly ref: string;
|
|
80
|
+
readonly kind: BindingKind;
|
|
81
|
+
/** The highest rung this binding satisfies (`"none"` when it satisfies none). */
|
|
82
|
+
readonly rung: Rung;
|
|
83
|
+
/** True iff `rung` is at or above the configured floor — and, under
|
|
84
|
+
* `grounded.independent > 1`, its claim has enough distinct origins (a
|
|
85
|
+
* source binding that grounded alone carries `not_independent`). An
|
|
86
|
+
* assumption binding is never `ok`: it is not evidence. */
|
|
87
|
+
readonly ok: boolean;
|
|
88
|
+
/** Present when `ok` is false: the first reason it fell short. Absent on
|
|
89
|
+
* an ALLOWED assumption binding — it is not evidence and not a failure;
|
|
90
|
+
* its claim's `status` (`assumption`) says what it is. */
|
|
91
|
+
readonly reason?: UnmetReason;
|
|
92
|
+
/** Human-readable detail for the reason (no fetched content beyond `excerpt`). */
|
|
93
|
+
readonly detail?: string;
|
|
94
|
+
/** Normalized URL / workspace path / toolUseId / `prf_` id / assumption text. */
|
|
95
|
+
readonly origin?: string;
|
|
96
|
+
/** Digest of the body / result / artifact the verdict was made against (`sha256:<hex>`). */
|
|
97
|
+
readonly sha256?: string;
|
|
98
|
+
/** ≤240 chars, whitespace-collapsed: the span that grounded the claim. */
|
|
99
|
+
readonly excerpt?: string;
|
|
100
|
+
/** Execution bindings: whether a replay ran (and matched, when `ok`). */
|
|
101
|
+
readonly replayed?: boolean;
|
|
102
|
+
/** Grounded bindings: the opt-in waiver judge accepted a paraphrase miss. */
|
|
103
|
+
readonly judgeWaived?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Grounded bindings: the claim's words in the body the run read under this
|
|
106
|
+
* origin are text an EARLIER call of the run sent to it — a `Write` or an
|
|
107
|
+
* `Edit` of the file, a PUT to the URL, or one of those to a place a copy
|
|
108
|
+
* or move then brought here — and this is that call. The binding still
|
|
109
|
+
* grounds (the file does say it now: the model may have just set the value
|
|
110
|
+
* it reports), but the run is its own source: design §10's residual "a
|
|
111
|
+
* model that fetches a page it wrote itself", surfaced on every surface and
|
|
112
|
+
* by `provability audit` rather than assumed away. Decided per origin: an
|
|
113
|
+
* `Edit` of one figure is the run's text as a `Write` of the sentence is.
|
|
114
|
+
* Also on an execution binding whose `FactCrossCheck` found the claim
|
|
115
|
+
* only in files the run wrote it into: such a check reaches `grounded` at
|
|
116
|
+
* most, and is counted with the sources (`ProofBundle.selfWritten`).
|
|
117
|
+
* (0.8.0 additive, completeness pass; convergence pass.)
|
|
118
|
+
*/
|
|
119
|
+
readonly writtenBy?: {
|
|
120
|
+
readonly toolUseId: string;
|
|
121
|
+
readonly toolName: string;
|
|
122
|
+
};
|
|
123
|
+
/** Formal bindings: the checker id and the formal statement shown beside the prose. */
|
|
124
|
+
readonly checker?: string;
|
|
125
|
+
readonly statement?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Formal bindings: the hypotheses the proof rests on (the artifact's
|
|
128
|
+
* `assumptions` — builtin `given` steps, SMT asserts and definitions),
|
|
129
|
+
* shown beside the statement. Design §6.4: hypotheses are assumptions in
|
|
130
|
+
* the bundle — counted with the declared ones (`ProofBundle.hypotheses`),
|
|
131
|
+
* refused under `assumptions: forbid` and capped by `max_assumptions`.
|
|
132
|
+
* Absent when the proof rests on none. (0.8.0 additive, fix pass.)
|
|
133
|
+
*/
|
|
134
|
+
readonly assumptions?: readonly string[];
|
|
135
|
+
};
|
|
136
|
+
export type ClaimStatus = "met" | "unmet" | "assumption";
|
|
137
|
+
/** One extracted claim and every binding its markers resolved to. */
|
|
138
|
+
export type ProofClaim = {
|
|
139
|
+
readonly index: number;
|
|
140
|
+
/** The claim sentence as it appears in the answer (clipped to 400 chars). */
|
|
141
|
+
readonly text: string;
|
|
142
|
+
readonly line?: number;
|
|
143
|
+
readonly status: ClaimStatus;
|
|
144
|
+
/** The highest rung any binding of this claim reached. */
|
|
145
|
+
readonly best: Rung;
|
|
146
|
+
readonly bindings: ReadonlyArray<ProofBinding>;
|
|
147
|
+
/**
|
|
148
|
+
* Present when the claim is text a definition line shows after what it
|
|
149
|
+
* names (`[1]: https://… Payments clear within 5 days`): that definition's
|
|
150
|
+
* marker, `"[1]"`. Such text renders as prose, so it is read as claims
|
|
151
|
+
* citing that definition rather than shown to the reader unread. (0.8.0
|
|
152
|
+
* additive, W1-C fix pass.)
|
|
153
|
+
*/
|
|
154
|
+
readonly definition?: string;
|
|
155
|
+
};
|
|
156
|
+
export type ProofVerdict = "pass" | "fail" | "unverified";
|
|
157
|
+
/** The per-answer artifact (design §5.3). */
|
|
158
|
+
export type ProofBundle = {
|
|
159
|
+
readonly version: 1;
|
|
160
|
+
/** The floor. */
|
|
161
|
+
readonly level: ProvabilityLevel;
|
|
162
|
+
/** `unverified` — the verifier threw; the gate failed open (§5.1). */
|
|
163
|
+
readonly verdict: ProofVerdict;
|
|
164
|
+
/** met / (claims − assumptions); 1 for the vacuous zero-claim case. */
|
|
165
|
+
readonly score: number;
|
|
166
|
+
readonly threshold: number;
|
|
167
|
+
/** The highest floor this answer would have passed. */
|
|
168
|
+
readonly achieved: Rung;
|
|
169
|
+
readonly claims: ReadonlyArray<ProofClaim>;
|
|
170
|
+
/** Count of extracted claims (assumption claims included). */
|
|
171
|
+
readonly claimCount: number;
|
|
172
|
+
readonly met: number;
|
|
173
|
+
readonly unmet: number;
|
|
174
|
+
/** Claims whose status is `assumption`: accepted, and out of the score. */
|
|
175
|
+
readonly assumptions: number;
|
|
176
|
+
/**
|
|
177
|
+
* Declared assumptions the config refused — every one under `assumptions:
|
|
178
|
+
* forbid`, the ones past `max_assumptions` otherwise. Their claims are
|
|
179
|
+
* `unmet` (binding reason `assumption_forbidden`), and any refusal fails
|
|
180
|
+
* the verdict whatever the score (design §2: the turn passes only when
|
|
181
|
+
* assumptions ≤ max_assumptions). The answer declared `assumptions +
|
|
182
|
+
* assumptionsRefused` assumptions in all. Absent when none was refused.
|
|
183
|
+
* (0.8.0 additive, W1-C fix pass.)
|
|
184
|
+
*/
|
|
185
|
+
readonly assumptionsRefused?: number;
|
|
186
|
+
/**
|
|
187
|
+
* Distinct hypotheses the accepted proofs behind `proven` bindings rest on
|
|
188
|
+
* (`ProofBinding.assumptions`): assumptions too (design §6.4, §10), so
|
|
189
|
+
* every surface counts them with `assumptions` — outside the score, which
|
|
190
|
+
* counts claims. A claim refused for its proof's hypotheses (`forbid`, or
|
|
191
|
+
* past `max_assumptions`) is in `assumptionsRefused` instead. Absent when
|
|
192
|
+
* none. (0.8.0 additive, fix pass.)
|
|
193
|
+
*/
|
|
194
|
+
readonly hypotheses?: number;
|
|
195
|
+
/**
|
|
196
|
+
* Distinct source origins behind the claims: at a `cited` floor every
|
|
197
|
+
* origin that passed the cited checks, at `grounded` and above every
|
|
198
|
+
* origin that grounded a claim — what "N sources" beside the floor means.
|
|
199
|
+
* A `FactCrossCheck` of a file the run wrote stands where that file would,
|
|
200
|
+
* so it counts here, by its call (`ProofBinding.writtenBy`).
|
|
201
|
+
*/
|
|
202
|
+
readonly sources: number;
|
|
203
|
+
/**
|
|
204
|
+
* Of those, the origins whose grounding text the run wrote itself earlier
|
|
205
|
+
* in the session (`ProofBinding.writtenBy`): the footer shows them beside
|
|
206
|
+
* the sources, and `provability audit` lists them as a gaming signal.
|
|
207
|
+
* Absent when none. (0.8.0 additive, completeness pass.)
|
|
208
|
+
*/
|
|
209
|
+
readonly selfWritten?: number;
|
|
210
|
+
/** Bindings the waiver judge flipped. */
|
|
211
|
+
readonly judgeWaived: number;
|
|
212
|
+
/** 0 = the original answer, n = the n-th gate-triggered retry. */
|
|
213
|
+
readonly retryIndex: number;
|
|
214
|
+
/** Proof checkers whose artifacts back `proven` bindings, with the axioms
|
|
215
|
+
* and (when any) the hypotheses each proof depends on (design §2, §6.4). */
|
|
216
|
+
readonly checkers?: ReadonlyArray<{
|
|
217
|
+
readonly id: string;
|
|
218
|
+
readonly artifact: string;
|
|
219
|
+
readonly axioms: readonly string[];
|
|
220
|
+
/** The hypotheses the proof rests on; absent when none. (0.8.0 additive, fix pass.) */
|
|
221
|
+
readonly assumptions?: readonly string[];
|
|
222
|
+
}>;
|
|
223
|
+
/** Present on a zero-claim answer: why the pass is vacuous. */
|
|
224
|
+
readonly vacuous?: string;
|
|
225
|
+
/** Present when `verdict === "unverified"`: what the verifier threw. */
|
|
226
|
+
readonly error?: string;
|
|
227
|
+
/** The waiver judge's model and spend, when it ran. */
|
|
228
|
+
readonly judgeModel?: string;
|
|
229
|
+
readonly spentUsdMicros?: number;
|
|
230
|
+
readonly createdAt: string;
|
|
231
|
+
/** `sha256:<hex>` over the canonical JSON of every other field (see `bundleHash`). */
|
|
232
|
+
readonly bundleHash: string;
|
|
233
|
+
};
|
|
234
|
+
/** The summary carried by the `provability_graded` trace/event-log line and audit record. */
|
|
235
|
+
export type ProvabilityGradedSummary = {
|
|
236
|
+
readonly level: ProvabilityLevel;
|
|
237
|
+
readonly verdict: ProofVerdict;
|
|
238
|
+
readonly score: number;
|
|
239
|
+
readonly threshold: number;
|
|
240
|
+
readonly achieved: Rung;
|
|
241
|
+
readonly claims: number;
|
|
242
|
+
readonly met: number;
|
|
243
|
+
readonly unmet: number;
|
|
244
|
+
readonly assumptions: number;
|
|
245
|
+
/** `ProofBundle.assumptionsRefused`, when any. (0.8.0 additive, W1-C fix pass.) */
|
|
246
|
+
readonly assumptionsRefused?: number;
|
|
247
|
+
/**
|
|
248
|
+
* `ProofBundle.hypotheses` — the hypotheses accepted proofs rest on,
|
|
249
|
+
* assumptions too (design §6.4, §10) — when any. (0.8.0 additive, fix pass.)
|
|
250
|
+
*/
|
|
251
|
+
readonly hypotheses?: number;
|
|
252
|
+
/**
|
|
253
|
+
* `ProofBundle.selfWritten` — source origins whose grounding text the run
|
|
254
|
+
* wrote itself — when any. (0.8.0 additive, completeness pass.)
|
|
255
|
+
*/
|
|
256
|
+
readonly selfWritten?: number;
|
|
257
|
+
readonly retryIndex: number;
|
|
258
|
+
readonly bundleHash: string;
|
|
259
|
+
readonly judgeModel?: string;
|
|
260
|
+
readonly judgeCostUsdMicros?: number;
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* One recorded tool call: the input the model sent and the result it got,
|
|
264
|
+
* verbatim, as the session event log (or the in-memory transcript) holds it.
|
|
265
|
+
*/
|
|
266
|
+
export type EvidenceRecord = {
|
|
267
|
+
readonly toolUseId: string;
|
|
268
|
+
readonly toolName: string;
|
|
269
|
+
readonly input: unknown;
|
|
270
|
+
/** The result text, verbatim, as the log holds it. */
|
|
271
|
+
readonly content: string;
|
|
272
|
+
/**
|
|
273
|
+
* The whole output when `content` is the runtime's spill preview of it
|
|
274
|
+
* (`@crewhaus/tool-result-store`: the head, then the path the output was
|
|
275
|
+
* saved at), read back from that file (evidence.ts `spilledOutput`). The
|
|
276
|
+
* verifiers read a record's text as `body ?? content`; a replay is
|
|
277
|
+
* compared with `content`, the form the log holds. (0.8.0 additive, fix
|
|
278
|
+
* pass.)
|
|
279
|
+
*/
|
|
280
|
+
readonly body?: string;
|
|
281
|
+
readonly isError: boolean;
|
|
282
|
+
/** The session whose log carried the call (child sessions included). */
|
|
283
|
+
readonly sessionId?: string;
|
|
284
|
+
/** Normalized origins (URLs / workspace paths) this call fetched or read
|
|
285
|
+
* as a WHOLE body: its input's `url`/`path` fields and the URL a fetch's
|
|
286
|
+
* header names. `bySource` answers these with the whole record. */
|
|
287
|
+
readonly origins: readonly string[];
|
|
288
|
+
/**
|
|
289
|
+
* The HTTP status a fetcher's own header reports (WebFetch's `Status:`,
|
|
290
|
+
* Fetch's status line). A body under a status outside 2xx is the server's
|
|
291
|
+
* error page, not the page: `grounded` does not read it. (0.8.0 additive,
|
|
292
|
+
* fix pass.)
|
|
293
|
+
*/
|
|
294
|
+
readonly status?: number;
|
|
295
|
+
/** Turn number, when the log recorded one (used by `scope: turn`). */
|
|
296
|
+
readonly turnNumber?: number;
|
|
297
|
+
/**
|
|
298
|
+
* A result that carries several hits, each from its own origin (Retrieve
|
|
299
|
+
* hits, a JSON search result with `url`/`source` fields): each hit's own
|
|
300
|
+
* text under its own normalized origin. `bySource` answers a hit's origin
|
|
301
|
+
* with that hit's text alone, never the whole result — otherwise one hit
|
|
302
|
+
* could ground a claim cited to another. Absent when the result has none.
|
|
303
|
+
* (0.8.0 additive, W1-C.)
|
|
304
|
+
*/
|
|
305
|
+
readonly hits?: ReadonlyArray<{
|
|
306
|
+
readonly origin: string;
|
|
307
|
+
readonly content: string;
|
|
308
|
+
}>;
|
|
309
|
+
};
|
|
310
|
+
/** The session-scoped view of every body the run read and every result it got. */
|
|
311
|
+
export interface EvidenceIndex {
|
|
312
|
+
/** Records whose fetched/read origin normalizes to `origin`. For a hit's
|
|
313
|
+
* origin (`EvidenceRecord.hits`) the record returned is a view of the call
|
|
314
|
+
* whose `content` is that hit's text and whose `origins` is `[origin]`. */
|
|
315
|
+
bySource(origin: string): ReadonlyArray<EvidenceRecord>;
|
|
316
|
+
/**
|
|
317
|
+
* The record for one toolUseId, when the run made that call: the graded
|
|
318
|
+
* session's own call first, then a sub-agent's. An id only several
|
|
319
|
+
* sub-agent sessions share (a provider that numbers ids per conversation)
|
|
320
|
+
* is ambiguous and answers `undefined` (see `callsById`).
|
|
321
|
+
*/
|
|
322
|
+
byToolUseId(toolUseId: string): EvidenceRecord | undefined;
|
|
323
|
+
/**
|
|
324
|
+
* Every call recorded under one toolUseId across the sessions the index
|
|
325
|
+
* read, the graded session's first — so a verifier can tell "no such
|
|
326
|
+
* call" from "several, and no way to tell which". Optional: an index
|
|
327
|
+
* without it reads as one call per id. (0.8.0 additive, fix pass.)
|
|
328
|
+
*/
|
|
329
|
+
callsById?(toolUseId: string): ReadonlyArray<EvidenceRecord>;
|
|
330
|
+
/** Every record, in the order the calls were made. */
|
|
331
|
+
all(): ReadonlyArray<EvidenceRecord>;
|
|
332
|
+
}
|
|
333
|
+
/** What `ProofCheck` persists and the `proven` verifier reads (design §6.4). */
|
|
334
|
+
export type ProofArtifact = {
|
|
335
|
+
readonly version: 1;
|
|
336
|
+
/** `prf_<16 hex>`. */
|
|
337
|
+
readonly id: string;
|
|
338
|
+
/** Checker id: `builtin` | `smt` | `lean4` | a plugin id. */
|
|
339
|
+
readonly checker: string;
|
|
340
|
+
/** The prose claim the proof is for (the sentence the answer will carry). */
|
|
341
|
+
readonly claim: string;
|
|
342
|
+
/** The formal statement, in the checker's language. */
|
|
343
|
+
readonly statement: string;
|
|
344
|
+
/** The proof / certificate / SMT problem, verbatim. */
|
|
345
|
+
readonly proof: string;
|
|
346
|
+
readonly ok: boolean;
|
|
347
|
+
/** Hypotheses the proof rests on (`given` steps, SMT asserts). */
|
|
348
|
+
readonly assumptions: readonly string[];
|
|
349
|
+
/** Axioms beyond the checker's base (lean `#print axioms`). */
|
|
350
|
+
readonly axioms: readonly string[];
|
|
351
|
+
/** Checker output, clipped. */
|
|
352
|
+
readonly output: string;
|
|
353
|
+
readonly counterexample?: string;
|
|
354
|
+
readonly reason?: string;
|
|
355
|
+
/** `sha256:<hex>` of `output`. */
|
|
356
|
+
readonly outputDigest: string;
|
|
357
|
+
readonly checkedAt: string;
|
|
358
|
+
readonly durationMs?: number;
|
|
359
|
+
};
|
|
360
|
+
export interface ProofArtifactStore {
|
|
361
|
+
get(id: string): Promise<ProofArtifact | undefined>;
|
|
362
|
+
put(artifact: ProofArtifact): Promise<void>;
|
|
363
|
+
list(): Promise<ReadonlyArray<ProofArtifact>>;
|
|
364
|
+
}
|
|
365
|
+
/** Result of re-executing a pure tool for `checked` replay. */
|
|
366
|
+
export type ReplayResult = {
|
|
367
|
+
readonly content: string;
|
|
368
|
+
readonly isError: boolean;
|
|
369
|
+
};
|
|
370
|
+
/**
|
|
371
|
+
* A HEAD the caller's resolver refused to send (`VerifyOptions.resolveHead`):
|
|
372
|
+
* `egress` — the run's egress fabric found content a boundary tagged (a
|
|
373
|
+
* secret a tool read) in the URL, so the request would have carried it out.
|
|
374
|
+
* The URL is not checked, and the binding says why. (0.8.0 additive, fix
|
|
375
|
+
* pass.)
|
|
376
|
+
*/
|
|
377
|
+
export type HeadRefusal = {
|
|
378
|
+
readonly refused: "egress";
|
|
379
|
+
};
|
|
380
|
+
/** A stored proof checked again (`VerifyOptions.recheckProof`). */
|
|
381
|
+
export type RecheckedProof = {
|
|
382
|
+
readonly ok: boolean;
|
|
383
|
+
readonly assumptions?: readonly string[];
|
|
384
|
+
readonly axioms?: readonly string[];
|
|
385
|
+
};
|
|
386
|
+
/** Verdict of the opt-in paraphrase-waiver judge (design §6.2). */
|
|
387
|
+
export type JudgeWaiverVerdict = {
|
|
388
|
+
readonly supported: boolean;
|
|
389
|
+
readonly model?: string;
|
|
390
|
+
readonly costUsdMicros?: number;
|
|
391
|
+
};
|
|
392
|
+
export type VerifyOptions = {
|
|
393
|
+
readonly config: ProvabilityConfig;
|
|
394
|
+
readonly evidence: EvidenceIndex;
|
|
395
|
+
/** Workspace root for path sources (default: process.cwd()). */
|
|
396
|
+
readonly workspaceRoot?: string;
|
|
397
|
+
/**
|
|
398
|
+
* Directories that hold the harness's own state — the session logs, the
|
|
399
|
+
* proofs tree, spilled results, memory — wherever this run put them
|
|
400
|
+
* (absolute, or relative to `workspaceRoot`). A path source under one is
|
|
401
|
+
* never grounded: what is there is the model's own text (an
|
|
402
|
+
* `assistant_message` line is an answer verbatim). `.crewhaus/` and
|
|
403
|
+
* `.crewhaus-shared/` under the workspace are always refused; this names
|
|
404
|
+
* the rest (a relocated `CREWHAUS_SESSION_DIR`, a tenant's root). (0.8.0
|
|
405
|
+
* additive, fix pass.)
|
|
406
|
+
*/
|
|
407
|
+
readonly stateRoots?: ReadonlyArray<string>;
|
|
408
|
+
/** Where relative path sources are measured from (default: workspaceRoot). */
|
|
409
|
+
readonly baseDir?: string;
|
|
410
|
+
/** Proof artifacts for `proof:` bindings. Absent ⇒ every formal binding is `proof_missing`. */
|
|
411
|
+
readonly artifacts?: ProofArtifactStore;
|
|
412
|
+
/**
|
|
413
|
+
* Re-run a stored artifact's checker on its statement and proof (design
|
|
414
|
+
* §6.4: a registered checker ACCEPTED it) — wired for a checker that is
|
|
415
|
+
* pure and cheap enough to run at gate time, the builtin certificate
|
|
416
|
+
* checker. `undefined` when it cannot re-check this one (another checker,
|
|
417
|
+
* none wired); a throw reads the same. A re-check that rejects is
|
|
418
|
+
* `proof_rejected`; one that accepts supplies the hypotheses and axioms
|
|
419
|
+
* the bundle lists, in place of the stored ones. (0.8.0 additive, fix
|
|
420
|
+
* pass.)
|
|
421
|
+
*/
|
|
422
|
+
readonly recheckProof?: (artifact: ProofArtifact) => Promise<RecheckedProof | undefined> | RecheckedProof | undefined;
|
|
423
|
+
/**
|
|
424
|
+
* Accept a stored artifact WITHOUT the `ProofCheck` call that wrote it in
|
|
425
|
+
* `evidence`. Off by default and never on the gate: an artifact is a file
|
|
426
|
+
* in the workspace, so the model can write one (or flip a rejected one to
|
|
427
|
+
* `ok: true`) with its own file tools, and only the run's own record of
|
|
428
|
+
* the check shows a checker accepted it. For an offline check of a
|
|
429
|
+
* document whose run's log is not at hand. (0.8.0 additive, fix pass.)
|
|
430
|
+
*/
|
|
431
|
+
readonly trustStoredProofs?: boolean;
|
|
432
|
+
/** Re-execute a tool with its logged input. Absent ⇒ no replay (bindings record `replayed: false`). */
|
|
433
|
+
readonly replay?: (toolName: string, input: unknown) => Promise<ReplayResult | undefined>;
|
|
434
|
+
/** Whether a tool is pure (readOnly && concurrencySafe) and so may be replayed. */
|
|
435
|
+
readonly isPureTool?: (toolName: string) => boolean;
|
|
436
|
+
/**
|
|
437
|
+
* `sources.resolve: head` — the HTTP status of one guarded HEAD, or
|
|
438
|
+
* undefined on failure. Up to a few run at once, under one deadline for
|
|
439
|
+
* the whole verification (`headDeadlineMs`); `signal` aborts when that
|
|
440
|
+
* deadline passes.
|
|
441
|
+
*/
|
|
442
|
+
readonly resolveHead?: (url: string, signal?: AbortSignal) => Promise<number | HeadRefusal | undefined>;
|
|
443
|
+
/**
|
|
444
|
+
* How long one verification waits on its HEAD requests in all (default
|
|
445
|
+
* 15 s): a URL not answered by then is `unresolved`, not checked. (0.8.0
|
|
446
|
+
* additive, fix pass.)
|
|
447
|
+
*/
|
|
448
|
+
readonly headDeadlineMs?: number;
|
|
449
|
+
/** The opt-in waiver judge; called only for paraphrase-coverage misses at `grounded`. */
|
|
450
|
+
readonly judgeWaiver?: (input: {
|
|
451
|
+
readonly claim: string;
|
|
452
|
+
readonly excerpt: string;
|
|
453
|
+
readonly source: string;
|
|
454
|
+
}) => Promise<JudgeWaiverVerdict>;
|
|
455
|
+
/** Restrict evidence to these turn numbers (`scope: turn`). */
|
|
456
|
+
readonly turnNumbers?: ReadonlySet<number>;
|
|
457
|
+
readonly retryIndex?: number;
|
|
458
|
+
readonly now?: () => Date;
|
|
459
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The vacuous-pass backstop (design §2, §0 A and B).
|
|
3
|
+
*
|
|
4
|
+
* An answer with no claims passes every floor with nothing to prove — the
|
|
5
|
+
* right verdict for a greeting, a clarifying question or a code block, and
|
|
6
|
+
* the wrong one for an answer whose claim the extractor failed to see.
|
|
7
|
+
* Review rounds one and two each found new shapes that merged a claim into
|
|
8
|
+
* a question or a heading — "30 days [1] — anything else?", "1,284.60; want
|
|
9
|
+
* the PDF?", a no-break space, a `<br>`, U+2028, a table row, a heading over
|
|
10
|
+
* a question — and claim-ledger's `extractClaims` saw none of them, so the
|
|
11
|
+
* gate served scenario A or B with a ✓. Each was fixed shape by shape, and
|
|
12
|
+
* each fix left the next shape open. So the verdict does not rest on the
|
|
13
|
+
* extractor alone: an answer may be vacuous only when what a reader sees
|
|
14
|
+
* of it, code and definition lines aside, carries
|
|
15
|
+
*
|
|
16
|
+
* - no citation marker at all, and
|
|
17
|
+
* - no figure outside a question,
|
|
18
|
+
*
|
|
19
|
+
* read by a segmenter far blunter than the extractor, which cuts at every
|
|
20
|
+
* line break (U+0085, U+2028, U+2029, `\f`, `\v` and `<br>` included),
|
|
21
|
+
* every sentence terminator whether a space follows it or not, every
|
|
22
|
+
* semicolon, em or en dash and table pipe — never at a comma. A heading
|
|
23
|
+
* is a title to the figure rule but for what it states after a label
|
|
24
|
+
* (claim-ledger's `headingClaim` reads the headings that state one); a
|
|
25
|
+
* marker in it still counts. Otherwise
|
|
26
|
+
* each segment that carries a marker, and each that states a figure and is
|
|
27
|
+
* no question, is a claim, verified like any other: "30 days" cut off a
|
|
28
|
+
* trailing "anything else?" is checked against the page, and fails where
|
|
29
|
+
* the page says 14.
|
|
30
|
+
*
|
|
31
|
+
* A question stays a question. A piece of text that ends in `?` is a
|
|
32
|
+
* question from the first segment in it that opens as one ("Which of the 4
|
|
33
|
+
* plans do you mean — Basic or Pro?", "Should I book 2 rooms\nfor Monday?")
|
|
34
|
+
* or ends as one; what comes before that segment is said, not asked ("The
|
|
35
|
+
* refund window is 30 days — anything else?"). A clarifying question with a
|
|
36
|
+
* figure in it ("Do you want 2 or 3 copies?"), a greeting, and an answer
|
|
37
|
+
* that is only code stay vacuous.
|
|
38
|
+
*/
|
|
39
|
+
import { type ExtractedClaim } from "@crewhaus/claim-ledger";
|
|
40
|
+
/**
|
|
41
|
+
* Claims the backstop reads in an answer the extractor found nothing to
|
|
42
|
+
* count in (see the module doc), numbered from `firstIndex`. Each is the
|
|
43
|
+
* segment as written (`raw`, markers in it), read as `plainClaim` reads a
|
|
44
|
+
* sentence, citing the markers it carries — a marker the document defines,
|
|
45
|
+
* a numeral, a footnote or an assumption id; a segment that is only
|
|
46
|
+
* markers gives them to the segment before it. A segment the extractor
|
|
47
|
+
* already returned (an assumption it read) is not read twice. Empty when
|
|
48
|
+
* the answer may be vacuous.
|
|
49
|
+
*/
|
|
50
|
+
export declare function backstopClaims(text: string, definitions: ReadonlyMap<string, string>, extracted: ReadonlyArray<ExtractedClaim>, firstIndex: number): ExtractedClaim[];
|