@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 +43 -4
- package/dist/index.d.ts +80 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +238 -107
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -49
- package/dist/index.test.js.map +0 -1
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,
|
|
20
|
-
codes,
|
|
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.
|
|
27
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
}>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
-
|
|
29
|
-
|
|
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(
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
|
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
|
-
|
|
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":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@melra/verifier-core",
|
|
3
|
-
"version": "0.3.0-alpha.
|
|
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.
|
|
25
|
-
"@melra/receipt-schema": "0.3.0-alpha.
|
|
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
|
|
31
|
+
"typecheck": "tsc -p tsconfig.test.json"
|
|
32
32
|
}
|
|
33
33
|
}
|
package/dist/index.test.d.ts
DELETED
package/dist/index.test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
|
package/dist/index.test.js
DELETED
|
@@ -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
|
package/dist/index.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,sCAAsC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,KAAK,GAAa,EAAE,CAAC;AAE3B,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/F,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,UAAU,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAClC;YACE,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE;YACvD,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE;YAC3C;gBACE,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D;SACF,EACD,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAClC,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAChE,EAAE,MAAM,EAAE,WAAW,EAAE,CACxB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAClC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAC9C,EAAE,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEnC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CACnC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,EACjD,EAAE,CACH,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,CACvC,qCAAqC,CACtC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|