@melra/verifier-core 0.3.0-alpha.10 → 0.3.0-alpha.12

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/README.md CHANGED
@@ -16,15 +16,54 @@ const verifier = await Verifier.create(workspaceRoot);
16
16
  const items = await verifier.verify(request.requiredEvidence, output);
17
17
  ```
18
18
 
19
- Supported predicates cover file existence, content hashes, path absence, exit
20
- codes, output matches, and HTTP status. Read-only operations with no declared
19
+ Supported predicates cover file existence, absence, and content hashes, exit
20
+ codes, result values and substrings, URL globs, page text, and
21
+ `http_resource_matches`, a second `GET`/`HEAD` that asks the provider rather
22
+ than the call that acted. Read-only operations with no declared
21
23
  evidence get a synthetic `operation_completed` item, so a receipt never has an
22
24
  empty evidence list.
23
25
 
24
26
  Every path is resolved through `realpath` and rejected if it lands outside the
25
27
  workspace root, including the root itself — a symlink cannot be used to verify a
26
- file the task was never allowed to touch. Keep that confinement when adding
27
- predicates.
28
+ file the task was never allowed to touch.
29
+
30
+ ## Your own verifiers
31
+
32
+ Each predicate type is checked by a `PredicateVerifier`, the built-ins included.
33
+ An embedder can register more for types the kernel does not ship:
34
+
35
+ ```ts
36
+ import { Verifier, type PredicateVerifier } from "@melra/verifier-core";
37
+
38
+ const rowExists: PredicateVerifier<{ type: "row_exists"; id: string }> = {
39
+ type: "row_exists",
40
+ async check(predicate, result) {
41
+ const passed = Array.isArray(result.rows) && result.rows.includes(predicate.id);
42
+ return { passed, summary: `row ${predicate.id} ${passed ? "present" : "missing"}` };
43
+ },
44
+ };
45
+
46
+ const withRows = await Verifier.create(workspaceRoot, { verifiers: [rowExists] });
47
+ await withRows.verify([{ type: "row_exists", id: "r1" }], output);
48
+ ```
49
+
50
+ What a verifier does **not** decide:
51
+
52
+ - **Its strength.** `type` and `strength` are stamped by the kernel from the
53
+ predicate type, over anything `check` returns, so a new type reads as the
54
+ weakest claim (`execution`) rather than declaring itself `independent`.
55
+ - **Whether an unanswerable question passes.** A type with no verifier, and a
56
+ `check` that throws, are failed items.
57
+ - **What a built-in means.** Registering a built-in type is refused
58
+ (`verifier_type_taken`).
59
+ - **Where files are.** The only file access offered is
60
+ `context.workspacePath()`, which applies the confinement above.
61
+
62
+ A task request reaches a registered verifier with
63
+ `{ "type": "custom", "verifier": "row_exists", "params": { "id": "r1" } }`, once
64
+ the runtime has it (`createMelraRuntime({ evidenceVerifiers })` in
65
+ `@melra/server`). The evidence is stamped `custom:row_exists`, and `custom` can
66
+ never name a built-in.
28
67
 
29
68
  Requires Node.js 22 or newer. Full documentation:
30
69
  [github.com/XAGI-Lab/melra](https://github.com/XAGI-Lab/melra)
package/dist/index.d.ts CHANGED
@@ -1,12 +1,89 @@
1
1
  import type { EvidencePredicate } from "@melra/protocol";
2
- import type { EvidenceItem } from "@melra/receipt-schema";
2
+ import { type EvidenceItem } from "@melra/receipt-schema";
3
+ /**
4
+ * A read the verifier can make through a channel it does not own.
5
+ *
6
+ * Injected rather than imported so this package keeps no adapter dependency:
7
+ * whoever supplies the probe decides what a read costs and what it is allowed
8
+ * to reach, and the verifier only decides whether the answer matches.
9
+ */
10
+ export type EvidenceProbe = (request: {
11
+ url: string;
12
+ method: "GET" | "HEAD";
13
+ timeoutMs: number;
14
+ }) => Promise<Record<string, unknown>>;
15
+ /**
16
+ * What a verifier may use besides the predicate and the recorded result.
17
+ *
18
+ * Files are reachable only through `workspacePath`, which resolves through
19
+ * `realpath` and refuses anything outside the workspace root, the root
20
+ * included. The confinement lives here, in the kernel, so a verifier cannot
21
+ * opt out of it by doing its own path handling.
22
+ */
23
+ export interface VerificationContext {
24
+ /** A confined, real path; `mayBeAbsent` for a file that should not exist. */
25
+ workspacePath(input: string, options?: {
26
+ mayBeAbsent?: boolean;
27
+ }): Promise<string>;
28
+ /** `path` relative to the workspace root, for an item's `source`. */
29
+ relative(path: string): string;
30
+ /** Absent when the runtime has no independent channel. */
31
+ probe?: EvidenceProbe;
32
+ }
33
+ /**
34
+ * One way to confirm an effect. Returns what it found; `type` and `strength`
35
+ * are stamped by the kernel from the predicate type, so a verifier cannot
36
+ * claim a stronger kind of knowing than its type is entitled to. Throwing
37
+ * fails the predicate.
38
+ */
39
+ export interface PredicateVerifier<P extends {
40
+ type: string;
41
+ } = {
42
+ type: string;
43
+ }> {
44
+ type: P["type"];
45
+ check(predicate: P, result: Record<string, unknown>, context: VerificationContext): Promise<Omit<EvidenceItem, "type" | "strength">>;
46
+ }
47
+ /** Any verifier, whatever predicate it takes: the shape the registry holds. */
48
+ export interface RegisteredVerifier {
49
+ readonly type: string;
50
+ check(predicate: never, result: Record<string, unknown>, context: VerificationContext): Promise<Omit<EvidenceItem, "type" | "strength">>;
51
+ }
52
+ export interface VerifierOptions {
53
+ /** Absent means `http_resource_matches` fails rather than passes. */
54
+ probe?: EvidenceProbe;
55
+ /**
56
+ * Verifiers for predicate types the kernel does not ship. A built-in type
57
+ * cannot be replaced: what `file_hash` means is not an embedder's to change.
58
+ */
59
+ verifiers?: ReadonlyArray<RegisteredVerifier>;
60
+ }
3
61
  export declare class Verifier {
4
62
  readonly root: string;
63
+ private readonly probe;
64
+ private readonly verifiers;
5
65
  private constructor();
6
- static create(root: string): Promise<Verifier>;
66
+ /** Names of the registered verifiers the kernel does not ship. */
67
+ customVerifiers(): string[];
68
+ /** Whether a verifier is registered for this predicate; planning asks first. */
69
+ supports(predicate: EvidencePredicate | {
70
+ type: string;
71
+ [field: string]: unknown;
72
+ }): boolean;
73
+ /**
74
+ * The verifier for a predicate, the evidence type to stamp, and what `check`
75
+ * receives. A request's `{ type: "custom", verifier, params }` reaches only a
76
+ * registered custom verifier, never a built-in: a built-in's fields are
77
+ * validated by its own schema arm, and `custom` must not be a way round it.
78
+ */
79
+ private resolve;
80
+ static create(root: string, options?: VerifierOptions): Promise<Verifier>;
7
81
  private filePath;
8
82
  private potentiallyAbsentFilePath;
9
- verify(predicates: EvidencePredicate[], result: Record<string, unknown>): Promise<{
83
+ verify(predicates: ReadonlyArray<EvidencePredicate | {
84
+ type: string;
85
+ [field: string]: unknown;
86
+ }>, result: Record<string, unknown>): Promise<{
10
87
  verified: boolean;
11
88
  evidence: EvidenceItem[];
12
89
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAwB1D,qBAAa,QAAQ;IACC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAAzC,OAAO;WAEM,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;YAItC,QAAQ;YAYR,yBAAyB;IA6BjC,MAAM,CACV,UAAU,EAAE,iBAAiB,EAAE,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;CAuH5D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAwB5E;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAyCvC;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,6EAA6E;IAC7E,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnF,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,0DAA0D;IAC1D,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;IAC9E,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAChB,KAAK,CACH,SAAS,EAAE,CAAC,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;CACrD;AAED,+EAA+E;AAC/E,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,KAAK,CACH,SAAS,EAAE,KAAK,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;CACrD;AAmJD,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CAC/C;AAED,qBAAa,QAAQ;IAIjB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyC;IAEnE,OAAO;IAmBP,kEAAkE;IAClE,eAAe,IAAI,MAAM,EAAE;IAI3B,gFAAgF;IAChF,QAAQ,CAAC,SAAS,EAAE,iBAAiB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,GAAG,OAAO;IAI5F;;;;;OAKG;IACH,OAAO,CAAC,OAAO;WAiBF,MAAM,CACjB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,QAAQ,CAAC;YAIN,QAAQ;YAYR,yBAAyB;IA6BjC,MAAM,CAEV,UAAU,EAAE,aAAa,CAAC,iBAAiB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC,EACzF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;CAmC5D"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  import { createHash } from "node:crypto";
4
4
  import { lstat, readFile, realpath, stat } from "node:fs/promises";
5
5
  import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
6
+ import { evidenceStrength } from "@melra/receipt-schema";
6
7
  function inside(root, candidate) {
7
8
  const rel = relative(root, candidate);
8
9
  return rel === "" || (!rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute(rel));
@@ -20,13 +21,224 @@ function wildcardMatches(value, pattern) {
20
21
  .replaceAll("\\*", ".*");
21
22
  return new RegExp(`^${escaped}$`, "u").test(value);
22
23
  }
24
+ /**
25
+ * A result with its JSON body parsed alongside the transport fields, so
26
+ * `json.id` reads the payload and `status` reads the response. A body that is
27
+ * not JSON simply has no `json`, and a path into it goes unresolved rather
28
+ * than throwing here.
29
+ */
30
+ function withParsedBody(result) {
31
+ if (typeof result.content !== "string")
32
+ return result;
33
+ try {
34
+ return { ...result, json: JSON.parse(result.content) };
35
+ }
36
+ catch {
37
+ return result;
38
+ }
39
+ }
40
+ const TOKEN = /\{\{([A-Za-z0-9_.]{1,64})\}\}/gu;
41
+ /**
42
+ * Splices values from the recorded result into a verification URL.
43
+ *
44
+ * The id of the thing to re-read is only known after the effect ran, so the
45
+ * URL has to be completed from the result. Tokens are bounded to a dotted path
46
+ * and each value is percent-encoded, so a response field carrying `../` or a
47
+ * `?` cannot rewrite the path the operator wrote. An unresolved token fails the
48
+ * predicate rather than producing a URL with a hole in it.
49
+ */
50
+ function interpolate(template, result) {
51
+ const source = withParsedBody(result);
52
+ return template.replace(TOKEN, (_match, path) => {
53
+ const value = readResultPath(source, path);
54
+ if (value === undefined || value === null || typeof value === "object") {
55
+ throw new Error(`verification_token_unresolved:${path}`);
56
+ }
57
+ return encodeURIComponent(String(value));
58
+ });
59
+ }
60
+ const resultEquals = {
61
+ type: "result_equals",
62
+ async check(predicate, result) {
63
+ const passed = Object.is(readResultPath(result, predicate.path), predicate.value);
64
+ return { passed, summary: `${predicate.path} ${passed ? "matched" : "did not match"} expected value` };
65
+ },
66
+ };
67
+ const resultContains = {
68
+ type: "result_contains",
69
+ async check(predicate, result) {
70
+ const observed = readResultPath(result, predicate.path);
71
+ const passed = typeof observed === "string" && observed.includes(predicate.value);
72
+ return { passed, summary: `${predicate.path} ${passed ? "contained" : "did not contain"} expected text` };
73
+ },
74
+ };
75
+ const exitCode = {
76
+ type: "exit_code",
77
+ async check(predicate, result) {
78
+ const passed = result.exitCode === predicate.value;
79
+ return { passed, summary: `exit code ${passed ? "matched" : "did not match"} ${predicate.value}` };
80
+ },
81
+ };
82
+ const urlMatches = {
83
+ type: "url_matches",
84
+ async check(predicate, result) {
85
+ const observed = result.url;
86
+ const passed = typeof observed === "string" && wildcardMatches(observed, predicate.pattern);
87
+ return { passed, summary: `final URL ${passed ? "matched" : "did not match"} expected pattern` };
88
+ },
89
+ };
90
+ const pageContains = {
91
+ type: "page_contains",
92
+ async check(predicate, result) {
93
+ const observed = result.text;
94
+ const passed = typeof observed === "string" && observed.includes(predicate.text);
95
+ return { passed, summary: `page ${passed ? "contained" : "did not contain"} expected text` };
96
+ },
97
+ };
98
+ const fileExists = {
99
+ type: "file_exists",
100
+ async check(predicate, _result, context) {
101
+ const path = await context.workspacePath(predicate.path);
102
+ const metadata = await stat(path);
103
+ const passed = metadata.isFile() || metadata.isDirectory();
104
+ return {
105
+ passed,
106
+ summary: `workspace path ${passed ? "exists" : "does not exist"}`,
107
+ source: context.relative(path),
108
+ };
109
+ },
110
+ };
111
+ const fileAbsent = {
112
+ type: "file_absent",
113
+ async check(predicate, _result, context) {
114
+ const path = await context.workspacePath(predicate.path, { mayBeAbsent: true });
115
+ let passed = false;
116
+ try {
117
+ await lstat(path);
118
+ }
119
+ catch (error) {
120
+ passed = error instanceof Error && "code" in error && error.code === "ENOENT";
121
+ if (!passed)
122
+ throw error;
123
+ }
124
+ return {
125
+ passed,
126
+ summary: `workspace path ${passed ? "is absent" : "still exists"}`,
127
+ source: context.relative(path),
128
+ };
129
+ },
130
+ };
131
+ const fileHash = {
132
+ type: "file_hash",
133
+ async check(predicate, _result, context) {
134
+ const path = await context.workspacePath(predicate.path);
135
+ const digest = createHash("sha256").update(await readFile(path)).digest("hex");
136
+ const passed = digest === predicate.sha256;
137
+ return {
138
+ passed,
139
+ summary: `file hash ${passed ? "matched" : "did not match"}`,
140
+ source: context.relative(path),
141
+ digest,
142
+ };
143
+ },
144
+ };
145
+ const httpResourceMatches = {
146
+ type: "http_resource_matches",
147
+ async check(predicate, result, context) {
148
+ if (context.probe === undefined) {
149
+ // Fails, never passes. A predicate the runtime cannot evaluate is an
150
+ // unanswered question, and treating it as satisfied would make the
151
+ // strongest evidence type the easiest one to claim.
152
+ throw new Error("verification_probe_unavailable");
153
+ }
154
+ const url = interpolate(predicate.url, result);
155
+ // Caught here rather than by the caller so a transport failure is not
156
+ // filed as the provider saying no. Both are `passed: false`; only this one
157
+ // is `inconclusive`, and that is what lets an unreachable provider leave a
158
+ // mutation `recovery_required` instead of `failed`. The interpolate above
159
+ // stays outside: an unresolved token is a caller error, and the provider
160
+ // is not implicated in it.
161
+ let observed;
162
+ try {
163
+ observed = withParsedBody(await context.probe({ url, method: predicate.method, timeoutMs: predicate.timeoutMs }));
164
+ }
165
+ catch (error) {
166
+ return {
167
+ passed: false,
168
+ inconclusive: true,
169
+ summary: `independent read unavailable: ${error instanceof Error ? error.message : String(error)}`,
170
+ source: url,
171
+ };
172
+ }
173
+ const passed = Object.is(readResultPath(observed, predicate.path), predicate.value);
174
+ return {
175
+ passed,
176
+ summary: `independent read of ${predicate.path} ${passed ? "matched" : "did not match"} expected value`,
177
+ source: url,
178
+ };
179
+ },
180
+ };
181
+ const BUILT_IN = [
182
+ resultEquals,
183
+ resultContains,
184
+ exitCode,
185
+ urlMatches,
186
+ pageContains,
187
+ fileExists,
188
+ fileAbsent,
189
+ fileHash,
190
+ httpResourceMatches,
191
+ ];
192
+ const BUILT_IN_TYPES = new Set(BUILT_IN.map((verifier) => verifier.type));
23
193
  export class Verifier {
24
194
  root;
25
- constructor(root) {
195
+ probe;
196
+ verifiers = new Map();
197
+ constructor(root, probe, extra) {
26
198
  this.root = root;
199
+ this.probe = probe;
200
+ for (const verifier of BUILT_IN)
201
+ this.verifiers.set(verifier.type, verifier);
202
+ for (const verifier of extra) {
203
+ // `custom` is the request-side wrapper, not a type a verifier can own.
204
+ if (this.verifiers.has(verifier.type) || verifier.type === "custom") {
205
+ throw new Error(`verifier_type_taken:${verifier.type}`);
206
+ }
207
+ // The name a `custom` predicate in a request must be able to carry.
208
+ if (!/^[a-z][a-z0-9_.-]{0,63}$/.test(verifier.type)) {
209
+ throw new Error(`verifier_name_invalid:${verifier.type}`);
210
+ }
211
+ this.verifiers.set(verifier.type, verifier);
212
+ }
213
+ }
214
+ /** Names of the registered verifiers the kernel does not ship. */
215
+ customVerifiers() {
216
+ return [...this.verifiers.keys()].filter((type) => !BUILT_IN_TYPES.has(type));
27
217
  }
28
- static async create(root) {
29
- return new Verifier(await realpath(root));
218
+ /** Whether a verifier is registered for this predicate; planning asks first. */
219
+ supports(predicate) {
220
+ return this.resolve(predicate).verifier !== undefined;
221
+ }
222
+ /**
223
+ * The verifier for a predicate, the evidence type to stamp, and what `check`
224
+ * receives. A request's `{ type: "custom", verifier, params }` reaches only a
225
+ * registered custom verifier, never a built-in: a built-in's fields are
226
+ * validated by its own schema arm, and `custom` must not be a way round it.
227
+ */
228
+ resolve(predicate) {
229
+ if (predicate.type !== "custom") {
230
+ return { verifier: this.verifiers.get(predicate.type), type: predicate.type, input: predicate };
231
+ }
232
+ const name = String(predicate.verifier);
233
+ const params = predicate.params ?? {};
234
+ return {
235
+ verifier: BUILT_IN_TYPES.has(name) ? undefined : this.verifiers.get(name),
236
+ type: `custom:${name}`,
237
+ input: { ...params, type: name },
238
+ };
239
+ }
240
+ static async create(root, options = {}) {
241
+ return new Verifier(await realpath(root), options.probe, options.verifiers ?? []);
30
242
  }
31
243
  async filePath(input) {
32
244
  const candidate = resolve(this.root, input);
@@ -66,115 +278,27 @@ export class Verifier {
66
278
  }
67
279
  }
68
280
  }
69
- async verify(predicates, result) {
281
+ async verify(
282
+ // A built-in predicate, or one a registered verifier understands.
283
+ predicates, result) {
284
+ const context = {
285
+ workspacePath: (input, options) => options?.mayBeAbsent === true ? this.potentiallyAbsentFilePath(input) : this.filePath(input),
286
+ relative: (path) => relative(this.root, path),
287
+ ...(this.probe === undefined ? {} : { probe: this.probe }),
288
+ };
70
289
  const evidence = [];
71
290
  for (const predicate of predicates) {
291
+ const { verifier, type, input } = this.resolve(predicate);
72
292
  try {
73
- switch (predicate.type) {
74
- case "result_equals": {
75
- const observed = readResultPath(result, predicate.path);
76
- const passed = Object.is(observed, predicate.value);
77
- evidence.push({
78
- type: predicate.type,
79
- passed,
80
- summary: `${predicate.path} ${passed ? "matched" : "did not match"} expected value`,
81
- });
82
- break;
83
- }
84
- case "result_contains": {
85
- const observed = readResultPath(result, predicate.path);
86
- const passed = typeof observed === "string" && observed.includes(predicate.value);
87
- evidence.push({
88
- type: predicate.type,
89
- passed,
90
- summary: `${predicate.path} ${passed ? "contained" : "did not contain"} expected text`,
91
- });
92
- break;
93
- }
94
- case "exit_code": {
95
- const passed = result.exitCode === predicate.value;
96
- evidence.push({
97
- type: predicate.type,
98
- passed,
99
- summary: `exit code ${passed ? "matched" : "did not match"} ${predicate.value}`,
100
- });
101
- break;
102
- }
103
- case "url_matches": {
104
- const observed = result.url;
105
- const passed = typeof observed === "string" &&
106
- wildcardMatches(observed, predicate.pattern);
107
- evidence.push({
108
- type: predicate.type,
109
- passed,
110
- summary: `final URL ${passed ? "matched" : "did not match"} expected pattern`,
111
- });
112
- break;
113
- }
114
- case "page_contains": {
115
- const observed = result.text;
116
- const passed = typeof observed === "string" && observed.includes(predicate.text);
117
- evidence.push({
118
- type: predicate.type,
119
- passed,
120
- summary: `page ${passed ? "contained" : "did not contain"} expected text`,
121
- });
122
- break;
123
- }
124
- case "file_exists": {
125
- const path = await this.filePath(predicate.path);
126
- const metadata = await stat(path);
127
- const passed = metadata.isFile() || metadata.isDirectory();
128
- evidence.push({
129
- type: predicate.type,
130
- passed,
131
- summary: `workspace path ${passed ? "exists" : "does not exist"}`,
132
- source: relative(this.root, path),
133
- });
134
- break;
135
- }
136
- case "file_absent": {
137
- const path = await this.potentiallyAbsentFilePath(predicate.path);
138
- let passed = false;
139
- try {
140
- await lstat(path);
141
- }
142
- catch (error) {
143
- passed =
144
- error instanceof Error &&
145
- "code" in error &&
146
- error.code === "ENOENT";
147
- if (!passed)
148
- throw error;
149
- }
150
- evidence.push({
151
- type: predicate.type,
152
- passed,
153
- summary: `workspace path ${passed ? "is absent" : "still exists"}`,
154
- source: relative(this.root, path),
155
- });
156
- break;
157
- }
158
- case "file_hash": {
159
- const path = await this.filePath(predicate.path);
160
- const digest = createHash("sha256")
161
- .update(await readFile(path))
162
- .digest("hex");
163
- const passed = digest === predicate.sha256;
164
- evidence.push({
165
- type: predicate.type,
166
- passed,
167
- summary: `file hash ${passed ? "matched" : "did not match"}`,
168
- source: relative(this.root, path),
169
- digest,
170
- });
171
- break;
172
- }
173
- }
293
+ // An unregistered type is a question nobody here can answer: it fails.
294
+ if (verifier === undefined)
295
+ throw new Error(`verification_unsupported:${type}`);
296
+ const found = await verifier.check(input, result, context);
297
+ evidence.push({ ...found, type });
174
298
  }
175
299
  catch (error) {
176
300
  evidence.push({
177
- type: predicate.type,
301
+ type,
178
302
  passed: false,
179
303
  summary: error instanceof Error ? error.message : String(error),
180
304
  });
@@ -182,7 +306,14 @@ export class Verifier {
182
306
  }
183
307
  return {
184
308
  verified: evidence.every((item) => item.passed),
185
- evidence,
309
+ // Stamped once here, after every verifier has run, and over whatever a
310
+ // verifier returned: strength is a property of the predicate type, so an
311
+ // unrecognised type reads as the weakest claim and no verifier can raise
312
+ // its own.
313
+ evidence: evidence.map((item) => ({
314
+ ...item,
315
+ strength: evidenceStrength(item.type),
316
+ })),
186
317
  };
187
318
  }
188
319
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,sCAAsC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAIxE,SAAS,MAAM,CAAC,IAAY,EAAE,SAAiB;IAC7C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACtC,OAAO,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AACzF,CAAC;AAED,SAAS,cAAc,CACrB,MAA+B,EAC/B,IAAY;IAEZ,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAU,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;QAC1D,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QACtE,OAAQ,OAAmC,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC,EAAE,MAAM,CAAC,CAAC;AACb,CAAC;AAED,SAAS,eAAe,CAAC,KAAa,EAAE,OAAe;IACrD,MAAM,OAAO,GAAG,OAAO;SACpB,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC;SACtC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3B,OAAO,IAAI,MAAM,CAAC,IAAI,OAAO,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,OAAO,QAAQ;IACU;IAA7B,YAA6B,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAE7C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAY;QAC9B,OAAO,IAAI,QAAQ,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5C,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,KAAa;QAClC,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,SAAS,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,KAAK,CAAC,yBAAyB,CAAC,KAAa;QACnD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,SAAS,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,KAAK,GAAG,SAAS,CAAC;QACtB,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACrC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;oBAC/B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;gBACzD,CAAC;gBACD,OAAO,SAAS,CAAC;YACnB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IACE,KAAK,YAAY,KAAK;oBACtB,KAAK,CAAC,OAAO,KAAK,qCAAqC,EACvD,CAAC;oBACD,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC9B,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;oBACrB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;gBACzD,CAAC;gBACD,KAAK,GAAG,MAAM,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CACV,UAA+B,EAC/B,MAA+B;QAE/B,MAAM,QAAQ,GAAmB,EAAE,CAAC;QACpC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;oBACvB,KAAK,eAAe,CAAC,CAAC,CAAC;wBACrB,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;wBACxD,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;wBACpD,QAAQ,CAAC,IAAI,CAAC;4BACZ,IAAI,EAAE,SAAS,CAAC,IAAI;4BACpB,MAAM;4BACN,OAAO,EAAE,GAAG,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,iBAAiB;yBACpF,CAAC,CAAC;wBACH,MAAM;oBACR,CAAC;oBACD,KAAK,iBAAiB,CAAC,CAAC,CAAC;wBACvB,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;wBACxD,MAAM,MAAM,GACV,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;wBACrE,QAAQ,CAAC,IAAI,CAAC;4BACZ,IAAI,EAAE,SAAS,CAAC,IAAI;4BACpB,MAAM;4BACN,OAAO,EAAE,GAAG,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,gBAAgB;yBACvF,CAAC,CAAC;wBACH,MAAM;oBACR,CAAC;oBACD,KAAK,WAAW,CAAC,CAAC,CAAC;wBACjB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,KAAK,CAAC;wBACnD,QAAQ,CAAC,IAAI,CAAC;4BACZ,IAAI,EAAE,SAAS,CAAC,IAAI;4BACpB,MAAM;4BACN,OAAO,EAAE,aAAa,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,IAAI,SAAS,CAAC,KAAK,EAAE;yBAChF,CAAC,CAAC;wBACH,MAAM;oBACR,CAAC;oBACD,KAAK,aAAa,CAAC,CAAC,CAAC;wBACnB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC;wBAC5B,MAAM,MAAM,GACV,OAAO,QAAQ,KAAK,QAAQ;4BAC5B,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;wBAC/C,QAAQ,CAAC,IAAI,CAAC;4BACZ,IAAI,EAAE,SAAS,CAAC,IAAI;4BACpB,MAAM;4BACN,OAAO,EAAE,aAAa,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,mBAAmB;yBAC9E,CAAC,CAAC;wBACH,MAAM;oBACR,CAAC;oBACD,KAAK,eAAe,CAAC,CAAC,CAAC;wBACrB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;wBAC7B,MAAM,MAAM,GACV,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;wBACpE,QAAQ,CAAC,IAAI,CAAC;4BACZ,IAAI,EAAE,SAAS,CAAC,IAAI;4BACpB,MAAM;4BACN,OAAO,EAAE,QAAQ,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,gBAAgB;yBAC1E,CAAC,CAAC;wBACH,MAAM;oBACR,CAAC;oBACD,KAAK,aAAa,CAAC,CAAC,CAAC;wBACnB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;wBACjD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;wBAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;wBAC3D,QAAQ,CAAC,IAAI,CAAC;4BACZ,IAAI,EAAE,SAAS,CAAC,IAAI;4BACpB,MAAM;4BACN,OAAO,EAAE,kBAAkB,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,EAAE;4BACjE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;yBAClC,CAAC,CAAC;wBACH,MAAM;oBACR,CAAC;oBACD,KAAK,aAAa,CAAC,CAAC,CAAC;wBACnB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,yBAAyB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;wBAClE,IAAI,MAAM,GAAG,KAAK,CAAC;wBACnB,IAAI,CAAC;4BACH,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;wBACpB,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM;gCACJ,KAAK,YAAY,KAAK;oCACtB,MAAM,IAAI,KAAK;oCACf,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;4BAC1B,IAAI,CAAC,MAAM;gCAAE,MAAM,KAAK,CAAC;wBAC3B,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC;4BACZ,IAAI,EAAE,SAAS,CAAC,IAAI;4BACpB,MAAM;4BACN,OAAO,EAAE,kBAAkB,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,EAAE;4BAClE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;yBAClC,CAAC,CAAC;wBACH,MAAM;oBACR,CAAC;oBACD,KAAK,WAAW,CAAC,CAAC,CAAC;wBACjB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;wBACjD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC;6BAChC,MAAM,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;6BAC5B,MAAM,CAAC,KAAK,CAAC,CAAC;wBACjB,MAAM,MAAM,GAAG,MAAM,KAAK,SAAS,CAAC,MAAM,CAAC;wBAC3C,QAAQ,CAAC,IAAI,CAAC;4BACZ,IAAI,EAAE,SAAS,CAAC,IAAI;4BACpB,MAAM;4BACN,OAAO,EAAE,aAAa,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,EAAE;4BAC5D,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;4BACjC,MAAM;yBACP,CAAC,CAAC;wBACH,MAAM;oBACR,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,SAAS,CAAC,IAAI;oBACpB,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAChE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO;YACL,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;YAC/C,QAAQ;SACT,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,sCAAsC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAExE,OAAO,EAAE,gBAAgB,EAAqB,MAAM,uBAAuB,CAAC;AAE5E,SAAS,MAAM,CAAC,IAAY,EAAE,SAAiB;IAC7C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACtC,OAAO,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AACzF,CAAC;AAED,SAAS,cAAc,CACrB,MAA+B,EAC/B,IAAY;IAEZ,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAU,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;QAC1D,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QACtE,OAAQ,OAAmC,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC,EAAE,MAAM,CAAC,CAAC;AACb,CAAC;AAED,SAAS,eAAe,CAAC,KAAa,EAAE,OAAe;IACrD,MAAM,OAAO,GAAG,OAAO;SACpB,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC;SACtC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3B,OAAO,IAAI,MAAM,CAAC,IAAI,OAAO,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACrD,CAAC;AAeD;;;;;GAKG;AACH,SAAS,cAAc,CACrB,MAA+B;IAE/B,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IACtD,IAAI,CAAC;QACH,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,KAAK,GAAG,iCAAiC,CAAC;AAEhD;;;;;;;;GAQG;AACH,SAAS,WAAW,CAAC,QAAgB,EAAE,MAA+B;IACpE,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACtC,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAY,EAAE,EAAE;QACtD,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvE,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,OAAO,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC;AA8CD,MAAM,YAAY,GAA2B;IAC3C,IAAI,EAAE,eAAe;IACrB,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM;QAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;QAClF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,iBAAiB,EAAE,CAAC;IACzG,CAAC;CACF,CAAC;AAEF,MAAM,cAAc,GAA6B;IAC/C,IAAI,EAAE,iBAAiB;IACvB,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM;QAC3B,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAClF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,gBAAgB,EAAE,CAAC;IAC5G,CAAC;CACF,CAAC;AAEF,MAAM,QAAQ,GAAuB;IACnC,IAAI,EAAE,WAAW;IACjB,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM;QAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,KAAK,CAAC;QACnD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,IAAI,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;IACrG,CAAC;CACF,CAAC;AAEF,MAAM,UAAU,GAAyB;IACvC,IAAI,EAAE,aAAa;IACnB,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM;QAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC;QAC5B,MAAM,MAAM,GAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QAC5F,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,mBAAmB,EAAE,CAAC;IACnG,CAAC;CACF,CAAC;AAEF,MAAM,YAAY,GAA2B;IAC3C,IAAI,EAAE,eAAe;IACrB,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM;QAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;QAC7B,MAAM,MAAM,GAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACjF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,gBAAgB,EAAE,CAAC;IAC/F,CAAC;CACF,CAAC;AAEF,MAAM,UAAU,GAAyB;IACvC,IAAI,EAAE,aAAa;IACnB,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO;QACrC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACzD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC3D,OAAO;YACL,MAAM;YACN,OAAO,EAAE,kBAAkB,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,EAAE;YACjE,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;SAC/B,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,UAAU,GAAyB;IACvC,IAAI,EAAE,aAAa;IACnB,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO;QACrC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAChF,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;YAC9E,IAAI,CAAC,MAAM;gBAAE,MAAM,KAAK,CAAC;QAC3B,CAAC;QACD,OAAO;YACL,MAAM;YACN,OAAO,EAAE,kBAAkB,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,EAAE;YAClE,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;SAC/B,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,QAAQ,GAAuB;IACnC,IAAI,EAAE,WAAW;IACjB,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO;QACrC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,MAAM,KAAK,SAAS,CAAC,MAAM,CAAC;QAC3C,OAAO;YACL,MAAM;YACN,OAAO,EAAE,aAAa,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,EAAE;YAC5D,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAC9B,MAAM;SACP,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,mBAAmB,GAAmC;IAC1D,IAAI,EAAE,uBAAuB;IAC7B,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO;QACpC,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAChC,qEAAqE;YACrE,mEAAmE;YACnE,oDAAoD;YACpD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QACD,MAAM,GAAG,GAAG,WAAW,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC/C,sEAAsE;QACtE,2EAA2E;QAC3E,2EAA2E;QAC3E,0EAA0E;QAC1E,yEAAyE;QACzE,2BAA2B;QAC3B,IAAI,QAAiC,CAAC;QACtC,IAAI,CAAC;YACH,QAAQ,GAAG,cAAc,CACvB,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,CAAC,CACvF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,YAAY,EAAE,IAAI;gBAClB,OAAO,EAAE,iCAAiC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBAClG,MAAM,EAAE,GAAG;aACZ,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;QACpF,OAAO;YACL,MAAM;YACN,OAAO,EAAE,uBAAuB,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,iBAAiB;YACvG,MAAM,EAAE,GAAG;SACZ,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,QAAQ,GAAsC;IAClD,YAAY;IACZ,cAAc;IACd,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,UAAU;IACV,UAAU;IACV,QAAQ;IACR,mBAAmB;CACpB,CAAC;AACF,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAa/F,MAAM,OAAO,QAAQ;IAIR;IACQ;IAJF,SAAS,GAAG,IAAI,GAAG,EAA8B,CAAC;IAEnE,YACW,IAAY,EACJ,KAAgC,EACjD,KAAwC;QAF/B,SAAI,GAAJ,IAAI,CAAQ;QACJ,UAAK,GAAL,KAAK,CAA2B;QAGjD,KAAK,MAAM,QAAQ,IAAI,QAAQ;YAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC7E,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;YAC7B,uEAAuE;YACvE,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACpE,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1D,CAAC;YACD,oEAAoE;YACpE,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpD,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,kEAAkE;IAClE,eAAe;QACb,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,gFAAgF;IAChF,QAAQ,CAAC,SAAyE;QAChF,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC;IACxD,CAAC;IAED;;;;;OAKG;IACK,OAAO,CAAC,SAAyE;QAKvF,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAClG,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAE,SAAoC,CAAC,QAAQ,CAAC,CAAC;QACpE,MAAM,MAAM,GAAI,SAAkD,CAAC,MAAM,IAAI,EAAE,CAAC;QAChF,OAAO;YACL,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YACzE,IAAI,EAAE,UAAU,IAAI,EAAE;YACtB,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE;SACjC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,MAAM,CACjB,IAAY,EACZ,UAA2B,EAAE;QAE7B,OAAO,IAAI,QAAQ,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IACpF,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,KAAa;QAClC,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,SAAS,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,KAAK,CAAC,yBAAyB,CAAC,KAAa;QACnD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,SAAS,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,KAAK,GAAG,SAAS,CAAC;QACtB,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACrC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;oBAC/B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;gBACzD,CAAC;gBACD,OAAO,SAAS,CAAC;YACnB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IACE,KAAK,YAAY,KAAK;oBACtB,KAAK,CAAC,OAAO,KAAK,qCAAqC,EACvD,CAAC;oBACD,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC9B,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;oBACrB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;gBACzD,CAAC;gBACD,KAAK,GAAG,MAAM,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM;IACV,kEAAkE;IAClE,UAAyF,EACzF,MAA+B;QAE/B,MAAM,OAAO,GAAwB;YACnC,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAChC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC9F,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;YAC7C,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;SAC3D,CAAC;QACF,MAAM,QAAQ,GAAmB,EAAE,CAAC;QACpC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC1D,IAAI,CAAC;gBACH,uEAAuE;gBACvE,IAAI,QAAQ,KAAK,SAAS;oBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC;gBAChF,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAc,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;gBACpE,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACpC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI;oBACJ,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAChE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO;YACL,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;YAC/C,uEAAuE;YACvE,yEAAyE;YACzE,yEAAyE;YACzE,WAAW;YACX,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAChC,GAAG,IAAI;gBACP,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;aACtC,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@melra/verifier-core",
3
- "version": "0.3.0-alpha.10",
3
+ "version": "0.3.0-alpha.12",
4
4
  "description": "Deterministic evidence predicates and result verification for MELRA.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -21,13 +21,13 @@
21
21
  "dist"
22
22
  ],
23
23
  "dependencies": {
24
- "@melra/protocol": "0.3.0-alpha.10",
25
- "@melra/receipt-schema": "0.3.0-alpha.10"
24
+ "@melra/protocol": "0.3.0-alpha.12",
25
+ "@melra/receipt-schema": "0.3.0-alpha.12"
26
26
  },
27
27
  "scripts": {
28
28
  "build": "tsc -p tsconfig.json",
29
29
  "clean": "rm -rf dist",
30
30
  "test": "vitest run",
31
- "typecheck": "tsc -p tsconfig.json --noEmit"
31
+ "typecheck": "tsc -p tsconfig.test.json"
32
32
  }
33
33
  }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -1,49 +0,0 @@
1
- // Copyright 2026 XAGI Labs Private Limited
2
- // SPDX-License-Identifier: Apache-2.0
3
- import { createHash } from "node:crypto";
4
- import { mkdtemp, rm, writeFile } from "node:fs/promises";
5
- import { tmpdir } from "node:os";
6
- import { join } from "node:path";
7
- import { afterEach, describe, expect, it } from "vitest";
8
- import { Verifier } from "./index.js";
9
- const roots = [];
10
- afterEach(async () => {
11
- await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
12
- });
13
- describe("Verifier", () => {
14
- it("checks structured fields and file effects", async () => {
15
- const root = await mkdtemp(join(tmpdir(), "melra-verifier-"));
16
- roots.push(root);
17
- await writeFile(join(root, "result.txt"), "verified");
18
- const verifier = await Verifier.create(root);
19
- const result = await verifier.verify([
20
- { type: "result_equals", path: "written", value: true },
21
- { type: "file_exists", path: "result.txt" },
22
- {
23
- type: "file_hash",
24
- path: "result.txt",
25
- sha256: createHash("sha256").update("verified").digest("hex"),
26
- },
27
- ], { written: true });
28
- expect(result.verified).toBe(true);
29
- expect(result.evidence.every((item) => item.passed)).toBe(true);
30
- });
31
- it("does not treat a mismatched predicate as success", async () => {
32
- const root = await mkdtemp(join(tmpdir(), "melra-verifier-"));
33
- roots.push(root);
34
- const verifier = await Verifier.create(root);
35
- const result = await verifier.verify([{ type: "result_contains", path: "stdout", value: "expected" }], { stdout: "different" });
36
- expect(result.verified).toBe(false);
37
- });
38
- it("verifies absence without allowing an escaping parent symlink", async () => {
39
- const root = await mkdtemp(join(tmpdir(), "melra-verifier-"));
40
- roots.push(root);
41
- const verifier = await Verifier.create(root);
42
- const absent = await verifier.verify([{ type: "file_absent", path: "deleted.txt" }], {});
43
- expect(absent.verified).toBe(true);
44
- const escaped = await verifier.verify([{ type: "file_absent", path: "../outside.txt" }], {});
45
- expect(escaped.verified).toBe(false);
46
- expect(escaped.evidence[0]?.summary).toBe("verification_path_outside_workspace");
47
- });
48
- });
49
- //# sourceMappingURL=index.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}