@melra/verifier-core 0.3.0-alpha.11 → 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 +61 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +194 -151
- 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 -63
- package/dist/index.test.js.map +0 -1
- package/dist/probe.test.d.ts +0 -2
- package/dist/probe.test.d.ts.map +0 -1
- package/dist/probe.test.js +0 -116
- package/dist/probe.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
|
@@ -12,18 +12,78 @@ export type EvidenceProbe = (request: {
|
|
|
12
12
|
method: "GET" | "HEAD";
|
|
13
13
|
timeoutMs: number;
|
|
14
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
|
+
}
|
|
15
52
|
export interface VerifierOptions {
|
|
16
53
|
/** Absent means `http_resource_matches` fails rather than passes. */
|
|
17
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>;
|
|
18
60
|
}
|
|
19
61
|
export declare class Verifier {
|
|
20
62
|
readonly root: string;
|
|
21
63
|
private readonly probe;
|
|
64
|
+
private readonly verifiers;
|
|
22
65
|
private constructor();
|
|
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;
|
|
23
80
|
static create(root: string, options?: VerifierOptions): Promise<Verifier>;
|
|
24
81
|
private filePath;
|
|
25
82
|
private potentiallyAbsentFilePath;
|
|
26
|
-
verify(predicates: EvidencePredicate
|
|
83
|
+
verify(predicates: ReadonlyArray<EvidencePredicate | {
|
|
84
|
+
type: string;
|
|
85
|
+
[field: string]: unknown;
|
|
86
|
+
}>, result: Record<string, unknown>): Promise<{
|
|
27
87
|
verified: boolean;
|
|
28
88
|
evidence: EvidenceItem[];
|
|
29
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,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,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,KAAK,CAAC,EAAE,aAAa,CAAC;
|
|
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
|
@@ -57,15 +57,188 @@ function interpolate(template, result) {
|
|
|
57
57
|
return encodeURIComponent(String(value));
|
|
58
58
|
});
|
|
59
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));
|
|
60
193
|
export class Verifier {
|
|
61
194
|
root;
|
|
62
195
|
probe;
|
|
63
|
-
|
|
196
|
+
verifiers = new Map();
|
|
197
|
+
constructor(root, probe, extra) {
|
|
64
198
|
this.root = root;
|
|
65
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));
|
|
217
|
+
}
|
|
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
|
+
};
|
|
66
239
|
}
|
|
67
240
|
static async create(root, options = {}) {
|
|
68
|
-
return new Verifier(await realpath(root), options.probe);
|
|
241
|
+
return new Verifier(await realpath(root), options.probe, options.verifiers ?? []);
|
|
69
242
|
}
|
|
70
243
|
async filePath(input) {
|
|
71
244
|
const candidate = resolve(this.root, input);
|
|
@@ -105,158 +278,27 @@ export class Verifier {
|
|
|
105
278
|
}
|
|
106
279
|
}
|
|
107
280
|
}
|
|
108
|
-
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
|
+
};
|
|
109
289
|
const evidence = [];
|
|
110
290
|
for (const predicate of predicates) {
|
|
291
|
+
const { verifier, type, input } = this.resolve(predicate);
|
|
111
292
|
try {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
type: predicate.type,
|
|
118
|
-
passed,
|
|
119
|
-
summary: `${predicate.path} ${passed ? "matched" : "did not match"} expected value`,
|
|
120
|
-
});
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
case "result_contains": {
|
|
124
|
-
const observed = readResultPath(result, predicate.path);
|
|
125
|
-
const passed = typeof observed === "string" && observed.includes(predicate.value);
|
|
126
|
-
evidence.push({
|
|
127
|
-
type: predicate.type,
|
|
128
|
-
passed,
|
|
129
|
-
summary: `${predicate.path} ${passed ? "contained" : "did not contain"} expected text`,
|
|
130
|
-
});
|
|
131
|
-
break;
|
|
132
|
-
}
|
|
133
|
-
case "exit_code": {
|
|
134
|
-
const passed = result.exitCode === predicate.value;
|
|
135
|
-
evidence.push({
|
|
136
|
-
type: predicate.type,
|
|
137
|
-
passed,
|
|
138
|
-
summary: `exit code ${passed ? "matched" : "did not match"} ${predicate.value}`,
|
|
139
|
-
});
|
|
140
|
-
break;
|
|
141
|
-
}
|
|
142
|
-
case "url_matches": {
|
|
143
|
-
const observed = result.url;
|
|
144
|
-
const passed = typeof observed === "string" &&
|
|
145
|
-
wildcardMatches(observed, predicate.pattern);
|
|
146
|
-
evidence.push({
|
|
147
|
-
type: predicate.type,
|
|
148
|
-
passed,
|
|
149
|
-
summary: `final URL ${passed ? "matched" : "did not match"} expected pattern`,
|
|
150
|
-
});
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
case "page_contains": {
|
|
154
|
-
const observed = result.text;
|
|
155
|
-
const passed = typeof observed === "string" && observed.includes(predicate.text);
|
|
156
|
-
evidence.push({
|
|
157
|
-
type: predicate.type,
|
|
158
|
-
passed,
|
|
159
|
-
summary: `page ${passed ? "contained" : "did not contain"} expected text`,
|
|
160
|
-
});
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
case "file_exists": {
|
|
164
|
-
const path = await this.filePath(predicate.path);
|
|
165
|
-
const metadata = await stat(path);
|
|
166
|
-
const passed = metadata.isFile() || metadata.isDirectory();
|
|
167
|
-
evidence.push({
|
|
168
|
-
type: predicate.type,
|
|
169
|
-
passed,
|
|
170
|
-
summary: `workspace path ${passed ? "exists" : "does not exist"}`,
|
|
171
|
-
source: relative(this.root, path),
|
|
172
|
-
});
|
|
173
|
-
break;
|
|
174
|
-
}
|
|
175
|
-
case "file_absent": {
|
|
176
|
-
const path = await this.potentiallyAbsentFilePath(predicate.path);
|
|
177
|
-
let passed = false;
|
|
178
|
-
try {
|
|
179
|
-
await lstat(path);
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
passed =
|
|
183
|
-
error instanceof Error &&
|
|
184
|
-
"code" in error &&
|
|
185
|
-
error.code === "ENOENT";
|
|
186
|
-
if (!passed)
|
|
187
|
-
throw error;
|
|
188
|
-
}
|
|
189
|
-
evidence.push({
|
|
190
|
-
type: predicate.type,
|
|
191
|
-
passed,
|
|
192
|
-
summary: `workspace path ${passed ? "is absent" : "still exists"}`,
|
|
193
|
-
source: relative(this.root, path),
|
|
194
|
-
});
|
|
195
|
-
break;
|
|
196
|
-
}
|
|
197
|
-
case "file_hash": {
|
|
198
|
-
const path = await this.filePath(predicate.path);
|
|
199
|
-
const digest = createHash("sha256")
|
|
200
|
-
.update(await readFile(path))
|
|
201
|
-
.digest("hex");
|
|
202
|
-
const passed = digest === predicate.sha256;
|
|
203
|
-
evidence.push({
|
|
204
|
-
type: predicate.type,
|
|
205
|
-
passed,
|
|
206
|
-
summary: `file hash ${passed ? "matched" : "did not match"}`,
|
|
207
|
-
source: relative(this.root, path),
|
|
208
|
-
digest,
|
|
209
|
-
});
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
case "http_resource_matches": {
|
|
213
|
-
if (this.probe === undefined) {
|
|
214
|
-
// Fails, never passes. A predicate the runtime cannot evaluate is
|
|
215
|
-
// an unanswered question, and treating it as satisfied would make
|
|
216
|
-
// the strongest evidence type the easiest one to claim.
|
|
217
|
-
throw new Error("verification_probe_unavailable");
|
|
218
|
-
}
|
|
219
|
-
const url = interpolate(predicate.url, result);
|
|
220
|
-
// Caught here rather than by the outer handler so a transport
|
|
221
|
-
// failure is not filed as the provider saying no. Both are
|
|
222
|
-
// `passed: false`; only this one is `inconclusive`, and that is
|
|
223
|
-
// what lets an unreachable provider leave a mutation
|
|
224
|
-
// `recovery_required` instead of `failed`. The interpolate above
|
|
225
|
-
// stays outside: an unresolved token is a caller error, and the
|
|
226
|
-
// provider is not implicated in it.
|
|
227
|
-
let observed;
|
|
228
|
-
try {
|
|
229
|
-
observed = withParsedBody(await this.probe({
|
|
230
|
-
url,
|
|
231
|
-
method: predicate.method,
|
|
232
|
-
timeoutMs: predicate.timeoutMs,
|
|
233
|
-
}));
|
|
234
|
-
}
|
|
235
|
-
catch (error) {
|
|
236
|
-
evidence.push({
|
|
237
|
-
type: predicate.type,
|
|
238
|
-
passed: false,
|
|
239
|
-
inconclusive: true,
|
|
240
|
-
summary: `independent read unavailable: ${error instanceof Error ? error.message : String(error)}`,
|
|
241
|
-
source: url,
|
|
242
|
-
});
|
|
243
|
-
break;
|
|
244
|
-
}
|
|
245
|
-
const value = readResultPath(observed, predicate.path);
|
|
246
|
-
const passed = Object.is(value, predicate.value);
|
|
247
|
-
evidence.push({
|
|
248
|
-
type: predicate.type,
|
|
249
|
-
passed,
|
|
250
|
-
summary: `independent read of ${predicate.path} ${passed ? "matched" : "did not match"} expected value`,
|
|
251
|
-
source: url,
|
|
252
|
-
});
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
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 });
|
|
256
298
|
}
|
|
257
299
|
catch (error) {
|
|
258
300
|
evidence.push({
|
|
259
|
-
type
|
|
301
|
+
type,
|
|
260
302
|
passed: false,
|
|
261
303
|
summary: error instanceof Error ? error.message : String(error),
|
|
262
304
|
});
|
|
@@ -264,9 +306,10 @@ export class Verifier {
|
|
|
264
306
|
}
|
|
265
307
|
return {
|
|
266
308
|
verified: evidence.every((item) => item.passed),
|
|
267
|
-
// Stamped once here
|
|
268
|
-
// property of the predicate type, so
|
|
269
|
-
//
|
|
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.
|
|
270
313
|
evidence: evidence.map((item) => ({
|
|
271
314
|
...item,
|
|
272
315
|
strength: evidenceStrength(item.type),
|
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,63 +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
|
-
it("stamps each item with how it was established", async () => {
|
|
49
|
-
const root = await mkdtemp(join(tmpdir(), "melra-verifier-"));
|
|
50
|
-
roots.push(root);
|
|
51
|
-
await writeFile(join(root, "present.txt"), "content");
|
|
52
|
-
const verifier = await Verifier.create(root);
|
|
53
|
-
const { evidence } = await verifier.verify([
|
|
54
|
-
{ type: "file_exists", path: "present.txt" },
|
|
55
|
-
{ type: "result_equals", path: "ok", value: true },
|
|
56
|
-
], { ok: true });
|
|
57
|
-
// Same receipt, two different claims: one re-read the disk, the other only
|
|
58
|
-
// re-read what the adapter handed back.
|
|
59
|
-
expect(evidence[0]?.strength).toBe("state");
|
|
60
|
-
expect(evidence[1]?.strength).toBe("execution");
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
//# 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":"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"}
|
package/dist/probe.test.d.ts
DELETED
package/dist/probe.test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"probe.test.d.ts","sourceRoot":"","sources":["../src/probe.test.ts"],"names":[],"mappings":""}
|
package/dist/probe.test.js
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 XAGI Labs Private Limited
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
// The independent-channel predicate, with the probe stubbed.
|
|
4
|
-
//
|
|
5
|
-
// What is worth pinning here is not that a match passes — it is what the URL
|
|
6
|
-
// is allowed to be built out of, and what happens when the channel is missing.
|
|
7
|
-
import { mkdtemp, rm } from "node:fs/promises";
|
|
8
|
-
import { tmpdir } from "node:os";
|
|
9
|
-
import { join } from "node:path";
|
|
10
|
-
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
11
|
-
import { EvidencePredicateSchema } from "@melra/protocol";
|
|
12
|
-
import { Verifier } from "./index.js";
|
|
13
|
-
let root;
|
|
14
|
-
/** Every URL the probe was asked for, in order. */
|
|
15
|
-
let asked;
|
|
16
|
-
beforeAll(async () => {
|
|
17
|
-
root = await mkdtemp(join(tmpdir(), "melra-probe-"));
|
|
18
|
-
});
|
|
19
|
-
afterAll(async () => {
|
|
20
|
-
await rm(root, { recursive: true, force: true });
|
|
21
|
-
});
|
|
22
|
-
const probeReturning = (body, status = 200) => {
|
|
23
|
-
asked = [];
|
|
24
|
-
return async (request) => {
|
|
25
|
-
asked.push(request.url);
|
|
26
|
-
return { success: status < 300, status, content: JSON.stringify(body) };
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
const predicate = (over = {}) => EvidencePredicateSchema.parse({
|
|
30
|
-
type: "http_resource_matches",
|
|
31
|
-
url: "https://api.example.com/refunds/{{json.id}}",
|
|
32
|
-
path: "json.state",
|
|
33
|
-
value: "succeeded",
|
|
34
|
-
...over,
|
|
35
|
-
});
|
|
36
|
-
/** What the operation being verified returned: a refund was created. */
|
|
37
|
-
const created = { status: 201, content: JSON.stringify({ id: "rf_123" }) };
|
|
38
|
-
describe("verification through a channel that did not act", () => {
|
|
39
|
-
it("re-reads the resource the effect named and compares provider state", async () => {
|
|
40
|
-
const verifier = await Verifier.create(root, {
|
|
41
|
-
probe: probeReturning({ state: "succeeded" }),
|
|
42
|
-
});
|
|
43
|
-
const { verified, evidence } = await verifier.verify([predicate()], created);
|
|
44
|
-
expect(verified).toBe(true);
|
|
45
|
-
expect(asked).toEqual(["https://api.example.com/refunds/rf_123"]);
|
|
46
|
-
// The point of the whole predicate: this is the one item a caller can rank
|
|
47
|
-
// above the acting channel's own word.
|
|
48
|
-
expect(evidence[0]?.strength).toBe("independent");
|
|
49
|
-
});
|
|
50
|
-
it("fails when the provider never got there, even though the call succeeded", async () => {
|
|
51
|
-
const verifier = await Verifier.create(root, {
|
|
52
|
-
probe: probeReturning({ state: "pending" }),
|
|
53
|
-
});
|
|
54
|
-
const { verified } = await verifier.verify([predicate()], created);
|
|
55
|
-
expect(verified).toBe(false);
|
|
56
|
-
});
|
|
57
|
-
it("fails rather than passes when there is no channel to ask", async () => {
|
|
58
|
-
const verifier = await Verifier.create(root);
|
|
59
|
-
const { verified, evidence } = await verifier.verify([predicate()], created);
|
|
60
|
-
expect(verified).toBe(false);
|
|
61
|
-
expect(evidence[0]?.summary).toBe("verification_probe_unavailable");
|
|
62
|
-
});
|
|
63
|
-
it("percent-encodes what it splices, so a response cannot rewrite the path", async () => {
|
|
64
|
-
const verifier = await Verifier.create(root, {
|
|
65
|
-
probe: probeReturning({ state: "succeeded" }),
|
|
66
|
-
});
|
|
67
|
-
await verifier.verify([predicate()], {
|
|
68
|
-
status: 201,
|
|
69
|
-
content: JSON.stringify({ id: "../../admin?all=1" }),
|
|
70
|
-
});
|
|
71
|
-
expect(asked).toEqual([
|
|
72
|
-
"https://api.example.com/refunds/..%2F..%2Fadmin%3Fall%3D1",
|
|
73
|
-
]);
|
|
74
|
-
});
|
|
75
|
-
it("fails when the token names nothing in the result", async () => {
|
|
76
|
-
const verifier = await Verifier.create(root, {
|
|
77
|
-
probe: probeReturning({ state: "succeeded" }),
|
|
78
|
-
});
|
|
79
|
-
const { verified, evidence } = await verifier.verify([predicate()], {
|
|
80
|
-
status: 201,
|
|
81
|
-
content: JSON.stringify({ reference: "rf_123" }),
|
|
82
|
-
});
|
|
83
|
-
expect(verified).toBe(false);
|
|
84
|
-
expect(evidence[0]?.summary).toBe("verification_token_unresolved:json.id");
|
|
85
|
-
// Nothing was fetched: a URL with a hole in it is not a destination.
|
|
86
|
-
expect(asked).toEqual([]);
|
|
87
|
-
});
|
|
88
|
-
it("only reads — the schema has no verb that could change anything", () => {
|
|
89
|
-
expect(() => predicate({ method: "DELETE" })).toThrow();
|
|
90
|
-
});
|
|
91
|
-
it("separates a provider that answered no from one that did not answer", async () => {
|
|
92
|
-
const verifier = await Verifier.create(root, {
|
|
93
|
-
probe: async () => {
|
|
94
|
-
throw new Error("ECONNREFUSED");
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
const { verified, evidence } = await verifier.verify([predicate()], created);
|
|
98
|
-
// Unproven is not proven, so the task still does not verify — but "no such
|
|
99
|
-
// refund" and "could not ask" are different facts, and only the first is
|
|
100
|
-
// grounds to call the effect failed.
|
|
101
|
-
expect(verified).toBe(false);
|
|
102
|
-
expect(evidence[0]).toMatchObject({
|
|
103
|
-
passed: false,
|
|
104
|
-
inconclusive: true,
|
|
105
|
-
source: "https://api.example.com/refunds/rf_123",
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
it("does not call a value mismatch inconclusive", async () => {
|
|
109
|
-
const verifier = await Verifier.create(root, {
|
|
110
|
-
probe: probeReturning({ state: "pending" }),
|
|
111
|
-
});
|
|
112
|
-
const { evidence } = await verifier.verify([predicate()], created);
|
|
113
|
-
expect(evidence[0]?.inconclusive).toBeUndefined();
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
//# sourceMappingURL=probe.test.js.map
|
package/dist/probe.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"probe.test.js","sourceRoot":"","sources":["../src/probe.test.ts"],"names":[],"mappings":"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"}
|