eval-quality 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/index.d.ts +2 -0
- package/dist/application/index.js +1 -0
- package/dist/application/score.d.ts +12 -0
- package/dist/application/score.js +10 -2
- package/dist/cli/render.d.ts +9 -1
- package/dist/cli/render.js +12 -1
- package/dist/cli/run.js +9 -1
- package/dist/core/evaluate/operators.d.ts +9 -5
- package/dist/core/evaluate/operators.js +9 -5
- package/dist/core/evaluate/resolution.js +36 -27
- package/dist/core/preflight/reduce.js +85 -0
- package/dist/core/schemas/artifact.d.ts +45 -6
- package/dist/core/schemas/eval-contract.d.ts +15 -2
- package/dist/core/schemas/probe.d.ts +45 -6
- package/dist/core/schemas/sensitivity-witness.d.ts +41 -4
- package/dist/core/schemas/sensitivity-witness.js +13 -2
- package/dist/core/score/score.d.ts +8 -1
- package/dist/core/score/score.js +14 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/schemas/eval-contract.schema.json +96 -1
- package/schemas/probe.schema.json +192 -2
|
@@ -15,6 +15,8 @@ export type { RuntimeFaultCode } from '../core/schemas/faults.ts';
|
|
|
15
15
|
export { RUNTIME_FAULT_CODES, RuntimeFault } from '../core/schemas/faults.ts';
|
|
16
16
|
export type { EvaluatorRecommendation, Verdict, } from '../core/schemas/verdict.ts';
|
|
17
17
|
export { EVALUATOR_RECOMMENDATIONS, VERDICTS, } from '../core/schemas/verdict.ts';
|
|
18
|
+
export type { QualificationFailure, QualificationFailureCode, QualificationResult, } from '../core/score/qualification.ts';
|
|
19
|
+
export { QUALIFICATION_FAILURES } from '../core/score/qualification.ts';
|
|
18
20
|
export { compile } from './compile.ts';
|
|
19
21
|
export type { Diagnostic, DiagnosticSink } from './diagnostics.ts';
|
|
20
22
|
export type { PreflightFromObservationsOptions, RunPreflightOptions, } from './preflight.ts';
|
|
@@ -11,6 +11,7 @@ export { validateLineageChain } from '../core/lineage/chain.js';
|
|
|
11
11
|
export { INTERCHANGE_ARTIFACT_KEYS } from '../core/schemas/artifact.js';
|
|
12
12
|
export { RUNTIME_FAULT_CODES, RuntimeFault } from '../core/schemas/faults.js';
|
|
13
13
|
export { EVALUATOR_RECOMMENDATIONS, VERDICTS, } from '../core/schemas/verdict.js';
|
|
14
|
+
export { QUALIFICATION_FAILURES } from '../core/score/qualification.js';
|
|
14
15
|
export { compile } from './compile.js';
|
|
15
16
|
export { preflightFromObservations, runPreflight } from './preflight.js';
|
|
16
17
|
export { runScore } from './score.js';
|
|
@@ -8,6 +8,7 @@ import { Probe } from '../core/schemas/probe.ts';
|
|
|
8
8
|
import { ScoringPolicy } from '../core/schemas/scoring-policy.ts';
|
|
9
9
|
import { SealedRunRecord } from '../core/schemas/sealed-run-record.ts';
|
|
10
10
|
import type { LadderResolution } from '../core/score/ladder.ts';
|
|
11
|
+
import type { QualificationResult } from '../core/score/qualification.ts';
|
|
11
12
|
import { type CorpusPort } from '../ports/corpus-port.ts';
|
|
12
13
|
export type RunScoreOptions = {
|
|
13
14
|
readonly record: SealedRunRecord;
|
|
@@ -44,5 +45,16 @@ export type RunScoreResult = {
|
|
|
44
45
|
*/
|
|
45
46
|
readonly artifact: EvidenceArtifact | null;
|
|
46
47
|
readonly ladder: LadderResolution;
|
|
48
|
+
/**
|
|
49
|
+
* AD-9's gate over `options.probe`, carried out of `score` unchanged. A
|
|
50
|
+
* rejected probe resolves an oracle to `infrastructure-error` wherever no
|
|
51
|
+
* higher-precedence AD-33 row already resolved it, and any of those states
|
|
52
|
+
* lands the run on the Invalid rung, where `artifact` is `null` and there
|
|
53
|
+
* is no artifact field for the reason to travel in. A contract declaring no
|
|
54
|
+
* oracles resolves no outcome at all: that run mints an artifact carrying
|
|
55
|
+
* no trace of the rejection. `failures` is the reason in both cases, in the
|
|
56
|
+
* closed `QualificationFailureCode` vocabulary.
|
|
57
|
+
*/
|
|
58
|
+
readonly qualification: QualificationResult;
|
|
47
59
|
};
|
|
48
60
|
export declare function runScore(options: RunScoreOptions): Promise<RunScoreResult>;
|
|
@@ -176,11 +176,19 @@ export async function runScore(options) {
|
|
|
176
176
|
// identical gap.
|
|
177
177
|
'none', false);
|
|
178
178
|
if (scored.ladder.verdict === null) {
|
|
179
|
-
return {
|
|
179
|
+
return {
|
|
180
|
+
artifact: null,
|
|
181
|
+
ladder: scored.ladder,
|
|
182
|
+
qualification: scored.probeQualification,
|
|
183
|
+
};
|
|
180
184
|
}
|
|
181
185
|
const artifact = emit(scored, corpusDigest,
|
|
182
186
|
// AD-11 names the same fixture digest `PreflightVerdict.fixtureDigest`
|
|
183
187
|
// already carries: restated, never re-derived.
|
|
184
188
|
preflightVerdict.fixtureDigest, record.evaluatorConfigurationDigest);
|
|
185
|
-
return {
|
|
189
|
+
return {
|
|
190
|
+
artifact,
|
|
191
|
+
ladder: scored.ladder,
|
|
192
|
+
qualification: scored.probeQualification,
|
|
193
|
+
};
|
|
186
194
|
}
|
package/dist/cli/render.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Diagnostic } from '../application/index.ts';
|
|
1
|
+
import { type Diagnostic, type QualificationFailure } from '../application/index.ts';
|
|
2
2
|
/**
|
|
3
3
|
* Delegates to `serializeArtifact`; the canonical bytes are not re-derived
|
|
4
4
|
* here, so the text written to stdout is the text `digestArtifact` hashes.
|
|
@@ -14,6 +14,14 @@ export declare function renderDiagnostic(diagnostic: Diagnostic): string;
|
|
|
14
14
|
* own code looks like from outside.
|
|
15
15
|
*/
|
|
16
16
|
export declare function renderError(error: unknown): string;
|
|
17
|
+
/**
|
|
18
|
+
* One AD-9 qualification failure, in the same
|
|
19
|
+
* `<code>: <artifactPath>: <detail>` shape `renderError` uses. An unqualified
|
|
20
|
+
* probe is a domain outcome the ladder resolves to Invalid, so no
|
|
21
|
+
* `StructuralFailure` and no `RuntimeFault` carries it. It reads like one on
|
|
22
|
+
* stderr because the reader's question is the same.
|
|
23
|
+
*/
|
|
24
|
+
export declare function renderQualificationFailure(failure: QualificationFailure): string;
|
|
17
25
|
/**
|
|
18
26
|
* AD-21's seven exit codes, one line each. The `--help` output and the README
|
|
19
27
|
* table are this text, so the two cannot drift.
|
package/dist/cli/render.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The four shapes the binary writes, and the exit-code table two documents
|
|
3
3
|
* share. Every line the CLI emits is produced here, so a format change is one
|
|
4
|
-
* file.
|
|
4
|
+
* file. Five renderers over the four shapes: a qualification failure and an
|
|
5
|
+
* error both print `<code>: <artifactPath>: <detail>`.
|
|
5
6
|
*/
|
|
6
7
|
import { z } from 'zod';
|
|
7
8
|
import { RuntimeFault, StructuralFailure, serializeArtifact, } from '../application/index.js';
|
|
@@ -81,6 +82,16 @@ export function renderError(error) {
|
|
|
81
82
|
}
|
|
82
83
|
return `${PREFIX}: ${String(error)}`;
|
|
83
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* One AD-9 qualification failure, in the same
|
|
87
|
+
* `<code>: <artifactPath>: <detail>` shape `renderError` uses. An unqualified
|
|
88
|
+
* probe is a domain outcome the ladder resolves to Invalid, so no
|
|
89
|
+
* `StructuralFailure` and no `RuntimeFault` carries it. It reads like one on
|
|
90
|
+
* stderr because the reader's question is the same.
|
|
91
|
+
*/
|
|
92
|
+
export function renderQualificationFailure(failure) {
|
|
93
|
+
return `${PREFIX}: ${failure.code}: ${failure.artifactPath}: ${failure.detail}`;
|
|
94
|
+
}
|
|
84
95
|
/**
|
|
85
96
|
* AD-21's seven exit codes, one line each. The `--help` output and the README
|
|
86
97
|
* table are this text, so the two cannot drift.
|
package/dist/cli/run.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* run in memory.
|
|
7
7
|
*/
|
|
8
8
|
import { compile, preflightFromObservations, RuntimeFault, runScore, StructuralFailure, seal, } from '../application/index.js';
|
|
9
|
-
import { EXIT_CODE_TABLE, renderArtifact, renderDiagnostic, renderError, renderUsage, } from './render.js';
|
|
9
|
+
import { EXIT_CODE_TABLE, renderArtifact, renderDiagnostic, renderError, renderQualificationFailure, renderUsage, } from './render.js';
|
|
10
10
|
export const APPLICATION = {
|
|
11
11
|
compile,
|
|
12
12
|
seal,
|
|
@@ -316,6 +316,14 @@ async function runScoreCommand(invocation, environment, application, target) {
|
|
|
316
316
|
port: corpusRoot === null ? undefined : environment.corpusPort(corpusRoot),
|
|
317
317
|
signal: environment.signal,
|
|
318
318
|
});
|
|
319
|
+
// A rejected probe resolves an oracle to `infrastructure-error` wherever no
|
|
320
|
+
// higher-precedence AD-33 row already resolved it, and no artifact field
|
|
321
|
+
// carries the reason on any rung. Written whatever the rung, since the gate
|
|
322
|
+
// also runs on a probe the ladder never invalidated, a contract declaring
|
|
323
|
+
// no oracles above all: the reasons are the same either way.
|
|
324
|
+
for (const failure of result.qualification.failures) {
|
|
325
|
+
environment.writeDiagnostic(renderQualificationFailure(failure));
|
|
326
|
+
}
|
|
319
327
|
if (result.artifact !== null) {
|
|
320
328
|
await emitArtifact(environment, result.artifact, 'score', target);
|
|
321
329
|
}
|
|
@@ -59,11 +59,15 @@ export declare function regexMatch(value: ResolvedValue, pattern: string, matchS
|
|
|
59
59
|
*/
|
|
60
60
|
export declare function ordering(collection: ResolvedValue, key: string, order: 'ascending' | 'descending', _artifactPath: string): boolean;
|
|
61
61
|
/**
|
|
62
|
-
* An empty array is a legitimate zero count, never special-cased
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
62
|
+
* An empty array is a legitimate zero count, never special-cased, and this
|
|
63
|
+
* function is called with one. `count-tolerance` reads the collection's
|
|
64
|
+
* cardinality, so `resolution.ts` marks it `total` over a collection observed
|
|
65
|
+
* to be present and empty and hands the `[]` straight through; the guard below
|
|
66
|
+
* is load-bearing on `collection.length === 0`. A collection-typed pointer
|
|
67
|
+
* that resolved `absent` is still intercepted there and never reaches here.
|
|
68
|
+
* The allowed deviation is compared unrounded: `actual` is an integer, so `<=`
|
|
69
|
+
* against a fractional deviation is already exact, and rounding either
|
|
70
|
+
* direction would move the declared boundary.
|
|
67
71
|
*/
|
|
68
72
|
export declare function countTolerance(collection: ResolvedValue, expected: number, tolerance: number, relative: boolean, _artifactPath: string): boolean;
|
|
69
73
|
/**
|
|
@@ -249,11 +249,15 @@ export function ordering(collection, key, order, _artifactPath) {
|
|
|
249
249
|
return true;
|
|
250
250
|
}
|
|
251
251
|
/**
|
|
252
|
-
* An empty array is a legitimate zero count, never special-cased
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
252
|
+
* An empty array is a legitimate zero count, never special-cased, and this
|
|
253
|
+
* function is called with one. `count-tolerance` reads the collection's
|
|
254
|
+
* cardinality, so `resolution.ts` marks it `total` over a collection observed
|
|
255
|
+
* to be present and empty and hands the `[]` straight through; the guard below
|
|
256
|
+
* is load-bearing on `collection.length === 0`. A collection-typed pointer
|
|
257
|
+
* that resolved `absent` is still intercepted there and never reaches here.
|
|
258
|
+
* The allowed deviation is compared unrounded: `actual` is an integer, so `<=`
|
|
259
|
+
* against a fractional deviation is already exact, and rounding either
|
|
260
|
+
* direction would move the declared boundary.
|
|
257
261
|
*/
|
|
258
262
|
export function countTolerance(collection, expected, tolerance, relative, _artifactPath) {
|
|
259
263
|
if (collection === ABSENT || !Array.isArray(collection))
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import { absence, containment, countTolerance, coversByKey, deepEquality, equality, existence, keyValueOf, ordering, regexMatch, setMembership, shape, } from './operators.js';
|
|
2
2
|
import { ABSENT } from './resolved-value.js';
|
|
3
3
|
/**
|
|
4
|
-
* AD-4's one closed introduction condition, checked per operand
|
|
5
|
-
*
|
|
4
|
+
* AD-4's one closed introduction condition, checked per operand. Two inputs
|
|
5
|
+
* decide it: what the operand resolved to, and whether the operator can answer
|
|
6
|
+
* from an empty collection.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* An operand that resolved to a present, empty array reached an evidence
|
|
9
|
+
* channel that worked and had nothing in it. That stops a `needs-a-member`
|
|
10
|
+
* operator, which would otherwise report a vacuous truth over no elements.
|
|
11
|
+
* A `total` operator has its answer: the cardinality is zero, the value is
|
|
12
|
+
* present. AD-4's own rule keeps a detected defect a detection, and that is
|
|
13
|
+
* what makes the second case a resolution.
|
|
14
|
+
*
|
|
15
|
+
* The `absent` branch does not vary. A collection-typed pointer that did not
|
|
16
|
+
* resolve is the missing page AD-4 folds into this condition to close the
|
|
17
|
+
* soft-delete fail-open, and no operator gets to read a missing collection as
|
|
18
|
+
* an empty one.
|
|
13
19
|
*/
|
|
14
|
-
function operandDenotesEmptyCollection(resolved, operand, pointerDenotesCollection) {
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return
|
|
20
|
+
function operandDenotesEmptyCollection(resolved, operand, pointerDenotesCollection, totality) {
|
|
21
|
+
if (resolved !== ABSENT) {
|
|
22
|
+
if (totality === 'total')
|
|
23
|
+
return false;
|
|
24
|
+
return Array.isArray(resolved) && resolved.length === 0;
|
|
25
|
+
}
|
|
19
26
|
// Only a `{ pointer }` operand can carry a declared collection type.
|
|
20
27
|
// `{ literal }` never resolves ABSENT, and an ABSENT `{ referenceSet }`
|
|
21
28
|
// means `unresolved-reference-set` slipped past compilation, which this
|
|
@@ -38,8 +45,8 @@ function booleanResult(result) {
|
|
|
38
45
|
}
|
|
39
46
|
// Checked across every operand before any operator runs, so the interception
|
|
40
47
|
// replaces a leaf's own two-valued answer outright.
|
|
41
|
-
function anyOperandEmpty(pairs, pointerDenotesCollection) {
|
|
42
|
-
return pairs.some(({ operand, resolved }) => operandDenotesEmptyCollection(resolved, operand, pointerDenotesCollection));
|
|
48
|
+
function anyOperandEmpty(pairs, pointerDenotesCollection, totality) {
|
|
49
|
+
return pairs.some(({ operand, resolved }) => operandDenotesEmptyCollection(resolved, operand, pointerDenotesCollection, totality));
|
|
43
50
|
}
|
|
44
51
|
/** `not(insufficient-evidence)` is terminal under both polarities (AD-4). */
|
|
45
52
|
function notOf(child) {
|
|
@@ -107,10 +114,12 @@ function resolveQuantifier(op, collectionOperand, predicate, boundElement, ctx)
|
|
|
107
114
|
};
|
|
108
115
|
}
|
|
109
116
|
// Shared by the six single-operand leaves: resolve, intercept on the
|
|
110
|
-
// empty-collection condition, otherwise hand the value to the operator.
|
|
111
|
-
|
|
117
|
+
// empty-collection condition, otherwise hand the value to the operator. Each
|
|
118
|
+
// caller declares its own totality, since that is the one thing the six
|
|
119
|
+
// disagree on.
|
|
120
|
+
function resolveSingleOperand(operand, boundElement, ctx, totality, evaluate) {
|
|
112
121
|
const resolved = ctx.resolveOperand(operand, boundElement, ctx.artifactPath);
|
|
113
|
-
if (anyOperandEmpty([{ operand, resolved }], ctx.pointerDenotesCollection)) {
|
|
122
|
+
if (anyOperandEmpty([{ operand, resolved }], ctx.pointerDenotesCollection, totality)) {
|
|
114
123
|
return emptyCollectionResult();
|
|
115
124
|
}
|
|
116
125
|
return booleanResult(evaluate(resolved));
|
|
@@ -124,7 +133,7 @@ function resolveEqualityLike(operands, evaluate, boundElement, ctx) {
|
|
|
124
133
|
if (anyOperandEmpty([
|
|
125
134
|
{ operand: aOperand, resolved: a },
|
|
126
135
|
{ operand: bOperand, resolved: b },
|
|
127
|
-
], ctx.pointerDenotesCollection)) {
|
|
136
|
+
], ctx.pointerDenotesCollection, 'needs-a-member')) {
|
|
128
137
|
return emptyCollectionResult();
|
|
129
138
|
}
|
|
130
139
|
return booleanResult(evaluate(a, b, ctx.artifactPath));
|
|
@@ -212,7 +221,7 @@ function resolveContainmentNode(expression, boundElement, ctx) {
|
|
|
212
221
|
if (anyOperandEmpty([
|
|
213
222
|
{ operand: containerOperand, resolved: container },
|
|
214
223
|
{ operand: candidateOperand, resolved: candidate },
|
|
215
|
-
], ctx.pointerDenotesCollection)) {
|
|
224
|
+
], ctx.pointerDenotesCollection, 'needs-a-member')) {
|
|
216
225
|
return emptyCollectionResult();
|
|
217
226
|
}
|
|
218
227
|
// The array-narrowing guard applies only to a `{ referenceSet }` candidate.
|
|
@@ -231,16 +240,16 @@ function resolveContainmentNode(expression, boundElement, ctx) {
|
|
|
231
240
|
}
|
|
232
241
|
function resolveExistenceNode(expression, boundElement, ctx) {
|
|
233
242
|
const [operand] = expression.operands;
|
|
234
|
-
return resolveSingleOperand(operand, boundElement, ctx, (resolved) => existence(resolved, ctx.artifactPath));
|
|
243
|
+
return resolveSingleOperand(operand, boundElement, ctx, 'total', (resolved) => existence(resolved, ctx.artifactPath));
|
|
235
244
|
}
|
|
236
245
|
function resolveAbsenceNode(expression, boundElement, ctx) {
|
|
237
246
|
const [operand] = expression.operands;
|
|
238
|
-
return resolveSingleOperand(operand, boundElement, ctx, (resolved) => absence(resolved, ctx.artifactPath));
|
|
247
|
+
return resolveSingleOperand(operand, boundElement, ctx, 'total', (resolved) => absence(resolved, ctx.artifactPath));
|
|
239
248
|
}
|
|
240
249
|
function resolveRegexNode(expression, boundElement, ctx) {
|
|
241
250
|
const [operand] = expression.operands;
|
|
242
251
|
const { pattern } = expression;
|
|
243
|
-
return resolveSingleOperand(operand, boundElement, ctx, (resolved) => regexMatch(resolved, pattern, ctx.regexMatchStepBudget, ctx.artifactPath));
|
|
252
|
+
return resolveSingleOperand(operand, boundElement, ctx, 'needs-a-member', (resolved) => regexMatch(resolved, pattern, ctx.regexMatchStepBudget, ctx.artifactPath));
|
|
244
253
|
}
|
|
245
254
|
/**
|
|
246
255
|
* Reads the single declared key off each member of a `{ referenceSet }` set
|
|
@@ -308,7 +317,7 @@ function resolveSetMembershipNode(expression, boundElement, ctx) {
|
|
|
308
317
|
if (anyOperandEmpty([
|
|
309
318
|
{ operand: valueOperand, resolved: value },
|
|
310
319
|
{ operand: setOperand, resolved: resolvedSet },
|
|
311
|
-
], ctx.pointerDenotesCollection)) {
|
|
320
|
+
], ctx.pointerDenotesCollection, 'needs-a-member')) {
|
|
312
321
|
return emptyCollectionResult();
|
|
313
322
|
}
|
|
314
323
|
// The set position needs the `JsonValue[]` the schema already guarantees
|
|
@@ -326,17 +335,17 @@ function resolveSetMembershipNode(expression, boundElement, ctx) {
|
|
|
326
335
|
function resolveOrderingNode(expression, boundElement, ctx) {
|
|
327
336
|
const [operand] = expression.operands;
|
|
328
337
|
const { key, order } = expression;
|
|
329
|
-
return resolveSingleOperand(operand, boundElement, ctx, (resolved) => ordering(resolved, key, order, ctx.artifactPath));
|
|
338
|
+
return resolveSingleOperand(operand, boundElement, ctx, 'needs-a-member', (resolved) => ordering(resolved, key, order, ctx.artifactPath));
|
|
330
339
|
}
|
|
331
340
|
function resolveCountToleranceNode(expression, boundElement, ctx) {
|
|
332
341
|
const [operand] = expression.operands;
|
|
333
342
|
const { expected, tolerance, relative } = expression;
|
|
334
|
-
return resolveSingleOperand(operand, boundElement, ctx, (resolved) => countTolerance(resolved, expected, tolerance, relative, ctx.artifactPath));
|
|
343
|
+
return resolveSingleOperand(operand, boundElement, ctx, 'total', (resolved) => countTolerance(resolved, expected, tolerance, relative, ctx.artifactPath));
|
|
335
344
|
}
|
|
336
345
|
function resolveShapeNode(expression, boundElement, ctx) {
|
|
337
346
|
const [operand] = expression.operands;
|
|
338
347
|
const { descriptor } = expression;
|
|
339
|
-
return resolveSingleOperand(operand, boundElement, ctx, (resolved) => shape(resolved, descriptor, ctx.artifactPath));
|
|
348
|
+
return resolveSingleOperand(operand, boundElement, ctx, 'needs-a-member', (resolved) => shape(resolved, descriptor, ctx.artifactPath));
|
|
340
349
|
}
|
|
341
350
|
// One entry per `Expression['op']`; the mapped type below fails to compile if
|
|
342
351
|
// an op is missing or misassigned, since each key demands the handler typed
|
|
@@ -65,6 +65,62 @@ const sameFixtureState = (left, right) => {
|
|
|
65
65
|
return (digestArtifact(state(left), PREFLIGHT_ARTIFACT_PATH) ===
|
|
66
66
|
digestArtifact(state(right), PREFLIGHT_ARTIFACT_PATH));
|
|
67
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* The canonical digest of one value, or `null` where the value holds something
|
|
70
|
+
* RFC 8785 cannot serialise. `JsonValue` admits an integer outside the safe
|
|
71
|
+
* range and a lone surrogate, and a 64-bit identifier in a query parameter is
|
|
72
|
+
* ordinary, so this is reachable from a contract that parses. A verdict is what
|
|
73
|
+
* this stage owes its caller, and `null` compares equal to nothing, so a value
|
|
74
|
+
* that cannot be digested leaves the two sides distinguishable and the check
|
|
75
|
+
* still reads the leg.
|
|
76
|
+
*/
|
|
77
|
+
const digestOrNull = (value) => {
|
|
78
|
+
try {
|
|
79
|
+
return digestArtifact(value, PREFLIGHT_ARTIFACT_PATH);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (error instanceof RuntimeFault)
|
|
83
|
+
return null;
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Whether two legs issued one request and received one answer, which makes them
|
|
89
|
+
* one probe under two labels. A manifestation witness firing on such a leg is
|
|
90
|
+
* the fault leg's own manifestation read a second time, and it establishes
|
|
91
|
+
* nothing about where the defect is scoped.
|
|
92
|
+
*
|
|
93
|
+
* Both halves are required. Answers alone would drop AD-10's own worked example,
|
|
94
|
+
* two distinct nonexistent identifiers both returning 404: those legs ask
|
|
95
|
+
* different questions and are exactly the legs this check exists to read.
|
|
96
|
+
* Requests alone are what the plan can see, and identical requests can still be
|
|
97
|
+
* answered differently, which is why the comparison lives here where the
|
|
98
|
+
* answers are in hand.
|
|
99
|
+
*
|
|
100
|
+
* The answer half compares the evidence, which is everything a relation can
|
|
101
|
+
* address: two legs with equal evidence resolve one relation to one value. It
|
|
102
|
+
* carries AD-11's projected body, so a field the operation declares volatile is
|
|
103
|
+
* already out of it and a server-minted identifier stops being a difference,
|
|
104
|
+
* which is what makes the same request to a mutating operation comparable at
|
|
105
|
+
* all. The raw observation is the wrong side of this comparison for that exact
|
|
106
|
+
* reason: two writes to one collection differ on a minted id by design, and
|
|
107
|
+
* reading that as a difference puts the false failure this check just lost back
|
|
108
|
+
* one stage over.
|
|
109
|
+
*
|
|
110
|
+
* The correlation identifiers are neutralised on both sides, since they are the
|
|
111
|
+
* leg id and differ by construction. A digest that comes back `null` matches
|
|
112
|
+
* nothing, so a pair that cannot be compared stays a pair the check reads.
|
|
113
|
+
*/
|
|
114
|
+
const answeredAlike = (left, right) => {
|
|
115
|
+
const request = (state) => digestOrNull({ ...state.leg.request, probeId: '' });
|
|
116
|
+
const answer = (state) => digestOrNull({ ...state.evidence, observationId: '' });
|
|
117
|
+
const leftRequest = request(left);
|
|
118
|
+
const leftAnswer = answer(left);
|
|
119
|
+
return (leftRequest !== null &&
|
|
120
|
+
leftAnswer !== null &&
|
|
121
|
+
leftRequest === request(right) &&
|
|
122
|
+
leftAnswer === answer(right));
|
|
123
|
+
};
|
|
68
124
|
/**
|
|
69
125
|
* Resolves a manifestation witness against one leg. Returns `null` when that
|
|
70
126
|
* leg produced no observation, which the two seeded-fault rows read
|
|
@@ -175,7 +231,36 @@ export const reducePreflight = (plan, { observations }) => {
|
|
|
175
231
|
}
|
|
176
232
|
case 'seeded-faults-scoped': {
|
|
177
233
|
const { witness, defectId } = planned;
|
|
234
|
+
const fault = states.get(witness.legId);
|
|
235
|
+
// The legs that answered a different question than the fault leg's, and
|
|
236
|
+
// the legs dropped for answering the same one.
|
|
237
|
+
const examined = [];
|
|
238
|
+
const dropped = [];
|
|
178
239
|
for (const legId of planned.cleanLegIds) {
|
|
240
|
+
const state = states.get(legId);
|
|
241
|
+
if (state !== undefined &&
|
|
242
|
+
fault !== undefined &&
|
|
243
|
+
answeredAlike(state, fault)) {
|
|
244
|
+
dropped.push(legId);
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
examined.push(legId);
|
|
248
|
+
}
|
|
249
|
+
// Emptiness is tested on what survived the drop. A check over no clean
|
|
250
|
+
// leg examined nothing, and a check that examined nothing has
|
|
251
|
+
// established nothing, which is the rule the `input-sensitivity` row
|
|
252
|
+
// above already runs on. Satisfied here would certify scoping from zero
|
|
253
|
+
// evidence on the three contracts least able to afford it: one whose
|
|
254
|
+
// defect names the only leg its operation has, one whose every other leg
|
|
255
|
+
// repeats the fault leg's probe, and one where the plan named legs and
|
|
256
|
+
// the drop took all of them. The note says which.
|
|
257
|
+
if (examined.length === 0) {
|
|
258
|
+
const named = dropped.map((legId) => `"${legId}"`).join(', ');
|
|
259
|
+
return check(planned.kind, witness.operationId, 'failed', dropped.length === 0
|
|
260
|
+
? `${defectId}: the operation has no leg besides the fault leg, so nothing here establishes that the defect is scoped to it`
|
|
261
|
+
: `${defectId}: every other leg of the operation issued the fault leg's own request and received its answer (${named}), so nothing here establishes that the defect is scoped to it`);
|
|
262
|
+
}
|
|
263
|
+
for (const legId of examined) {
|
|
179
264
|
const resolved = resolveAgainst(witness, states.get(legId), plan, PREFLIGHT_ARTIFACT_PATH);
|
|
180
265
|
if (resolved === 'true')
|
|
181
266
|
return check(planned.kind, witness.operationId, 'failed', `${defectId}: the manifestation witness fires on clean leg "${legId}"`);
|
|
@@ -828,7 +828,7 @@ export declare const INTERCHANGE_ARTIFACTS: {
|
|
|
828
828
|
legId: z.ZodString;
|
|
829
829
|
interfaceId: z.ZodString;
|
|
830
830
|
operationId: z.ZodString;
|
|
831
|
-
inputs: z.ZodObject<{
|
|
831
|
+
inputs: z.ZodUnion<readonly [z.ZodObject<{
|
|
832
832
|
path: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
833
833
|
query: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
834
834
|
header: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -838,7 +838,20 @@ export declare const INTERCHANGE_ARTIFACTS: {
|
|
|
838
838
|
}, z.core.$strict>, z.ZodObject<{
|
|
839
839
|
kind: z.ZodLiteral<"absent">;
|
|
840
840
|
}, z.core.$strict>], "kind">;
|
|
841
|
-
}, z.core.$strict
|
|
841
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
842
|
+
argument: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
843
|
+
option: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
844
|
+
environment: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
845
|
+
stdin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
846
|
+
kind: z.ZodLiteral<"json">;
|
|
847
|
+
value: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
|
|
848
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
849
|
+
kind: z.ZodLiteral<"text">;
|
|
850
|
+
value: z.ZodString;
|
|
851
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
852
|
+
kind: z.ZodLiteral<"absent">;
|
|
853
|
+
}, z.core.$strict>], "kind">;
|
|
854
|
+
}, z.core.$strict>]>;
|
|
842
855
|
}, z.core.$strict>>;
|
|
843
856
|
}, z.core.$strict>;
|
|
844
857
|
readonly priorArt: 'eval-contract';
|
|
@@ -1404,7 +1417,7 @@ export declare const INTERCHANGE_ARTIFACTS: {
|
|
|
1404
1417
|
legId: z.ZodString;
|
|
1405
1418
|
interfaceId: z.ZodString;
|
|
1406
1419
|
operationId: z.ZodString;
|
|
1407
|
-
inputs: z.ZodObject<{
|
|
1420
|
+
inputs: z.ZodUnion<readonly [z.ZodObject<{
|
|
1408
1421
|
path: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
1409
1422
|
query: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
1410
1423
|
header: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -1414,7 +1427,20 @@ export declare const INTERCHANGE_ARTIFACTS: {
|
|
|
1414
1427
|
}, z.core.$strict>, z.ZodObject<{
|
|
1415
1428
|
kind: z.ZodLiteral<"absent">;
|
|
1416
1429
|
}, z.core.$strict>], "kind">;
|
|
1417
|
-
}, z.core.$strict
|
|
1430
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1431
|
+
argument: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
1432
|
+
option: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
1433
|
+
environment: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1434
|
+
stdin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1435
|
+
kind: z.ZodLiteral<"json">;
|
|
1436
|
+
value: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
|
|
1437
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1438
|
+
kind: z.ZodLiteral<"text">;
|
|
1439
|
+
value: z.ZodString;
|
|
1440
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1441
|
+
kind: z.ZodLiteral<"absent">;
|
|
1442
|
+
}, z.core.$strict>], "kind">;
|
|
1443
|
+
}, z.core.$strict>]>;
|
|
1418
1444
|
relation: z.ZodType<import("./expression.ts").Expression, unknown, z.core.$ZodTypeInternals<import("./expression.ts").Expression, unknown>>;
|
|
1419
1445
|
}, z.core.$strict>>;
|
|
1420
1446
|
}, z.core.$strict>>;
|
|
@@ -1587,7 +1613,7 @@ export declare const INTERCHANGE_ARTIFACTS: {
|
|
|
1587
1613
|
legId: z.ZodString;
|
|
1588
1614
|
interfaceId: z.ZodString;
|
|
1589
1615
|
operationId: z.ZodString;
|
|
1590
|
-
inputs: z.ZodObject<{
|
|
1616
|
+
inputs: z.ZodUnion<readonly [z.ZodObject<{
|
|
1591
1617
|
path: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
1592
1618
|
query: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
1593
1619
|
header: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -1597,7 +1623,20 @@ export declare const INTERCHANGE_ARTIFACTS: {
|
|
|
1597
1623
|
}, z.core.$strict>, z.ZodObject<{
|
|
1598
1624
|
kind: z.ZodLiteral<"absent">;
|
|
1599
1625
|
}, z.core.$strict>], "kind">;
|
|
1600
|
-
}, z.core.$strict
|
|
1626
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1627
|
+
argument: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
1628
|
+
option: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
1629
|
+
environment: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1630
|
+
stdin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1631
|
+
kind: z.ZodLiteral<"json">;
|
|
1632
|
+
value: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
|
|
1633
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1634
|
+
kind: z.ZodLiteral<"text">;
|
|
1635
|
+
value: z.ZodString;
|
|
1636
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1637
|
+
kind: z.ZodLiteral<"absent">;
|
|
1638
|
+
}, z.core.$strict>], "kind">;
|
|
1639
|
+
}, z.core.$strict>]>;
|
|
1601
1640
|
relation: z.ZodType<import("./expression.ts").Expression, unknown, z.core.$ZodTypeInternals<import("./expression.ts").Expression, unknown>>;
|
|
1602
1641
|
}, z.core.$strict>>;
|
|
1603
1642
|
}, z.core.$strict>>;
|
|
@@ -924,7 +924,7 @@ export declare const EvalContract: z.ZodObject<{
|
|
|
924
924
|
legId: z.ZodString;
|
|
925
925
|
interfaceId: z.ZodString;
|
|
926
926
|
operationId: z.ZodString;
|
|
927
|
-
inputs: z.ZodObject<{
|
|
927
|
+
inputs: z.ZodUnion<readonly [z.ZodObject<{
|
|
928
928
|
path: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
929
929
|
query: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
930
930
|
header: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -934,7 +934,20 @@ export declare const EvalContract: z.ZodObject<{
|
|
|
934
934
|
}, z.core.$strict>, z.ZodObject<{
|
|
935
935
|
kind: z.ZodLiteral<"absent">;
|
|
936
936
|
}, z.core.$strict>], "kind">;
|
|
937
|
-
}, z.core.$strict
|
|
937
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
938
|
+
argument: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
939
|
+
option: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
940
|
+
environment: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
941
|
+
stdin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
942
|
+
kind: z.ZodLiteral<"json">;
|
|
943
|
+
value: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
|
|
944
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
945
|
+
kind: z.ZodLiteral<"text">;
|
|
946
|
+
value: z.ZodString;
|
|
947
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
948
|
+
kind: z.ZodLiteral<"absent">;
|
|
949
|
+
}, z.core.$strict>], "kind">;
|
|
950
|
+
}, z.core.$strict>]>;
|
|
938
951
|
}, z.core.$strict>>;
|
|
939
952
|
}, z.core.$strict>;
|
|
940
953
|
export type EvalContract = z.infer<typeof EvalContract>;
|
|
@@ -42,7 +42,7 @@ export declare const Defect: z.ZodObject<{
|
|
|
42
42
|
legId: z.ZodString;
|
|
43
43
|
interfaceId: z.ZodString;
|
|
44
44
|
operationId: z.ZodString;
|
|
45
|
-
inputs: z.ZodObject<{
|
|
45
|
+
inputs: z.ZodUnion<readonly [z.ZodObject<{
|
|
46
46
|
path: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
47
47
|
query: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
48
48
|
header: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -52,7 +52,20 @@ export declare const Defect: z.ZodObject<{
|
|
|
52
52
|
}, z.core.$strict>, z.ZodObject<{
|
|
53
53
|
kind: z.ZodLiteral<"absent">;
|
|
54
54
|
}, z.core.$strict>], "kind">;
|
|
55
|
-
}, z.core.$strict
|
|
55
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
56
|
+
argument: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
57
|
+
option: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
58
|
+
environment: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
59
|
+
stdin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
60
|
+
kind: z.ZodLiteral<"json">;
|
|
61
|
+
value: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
|
|
62
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
63
|
+
kind: z.ZodLiteral<"text">;
|
|
64
|
+
value: z.ZodString;
|
|
65
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
66
|
+
kind: z.ZodLiteral<"absent">;
|
|
67
|
+
}, z.core.$strict>], "kind">;
|
|
68
|
+
}, z.core.$strict>]>;
|
|
56
69
|
relation: z.ZodType<import("./expression.ts").Expression, unknown, z.core.$ZodTypeInternals<import("./expression.ts").Expression, unknown>>;
|
|
57
70
|
}, z.core.$strict>>;
|
|
58
71
|
}, z.core.$strict>;
|
|
@@ -234,7 +247,7 @@ export declare const Probe: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
234
247
|
legId: z.ZodString;
|
|
235
248
|
interfaceId: z.ZodString;
|
|
236
249
|
operationId: z.ZodString;
|
|
237
|
-
inputs: z.ZodObject<{
|
|
250
|
+
inputs: z.ZodUnion<readonly [z.ZodObject<{
|
|
238
251
|
path: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
239
252
|
query: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
240
253
|
header: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -244,7 +257,20 @@ export declare const Probe: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
244
257
|
}, z.core.$strict>, z.ZodObject<{
|
|
245
258
|
kind: z.ZodLiteral<"absent">;
|
|
246
259
|
}, z.core.$strict>], "kind">;
|
|
247
|
-
}, z.core.$strict
|
|
260
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
261
|
+
argument: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
262
|
+
option: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
263
|
+
environment: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
264
|
+
stdin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
265
|
+
kind: z.ZodLiteral<"json">;
|
|
266
|
+
value: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
|
|
267
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
268
|
+
kind: z.ZodLiteral<"text">;
|
|
269
|
+
value: z.ZodString;
|
|
270
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
271
|
+
kind: z.ZodLiteral<"absent">;
|
|
272
|
+
}, z.core.$strict>], "kind">;
|
|
273
|
+
}, z.core.$strict>]>;
|
|
248
274
|
relation: z.ZodType<import("./expression.ts").Expression, unknown, z.core.$ZodTypeInternals<import("./expression.ts").Expression, unknown>>;
|
|
249
275
|
}, z.core.$strict>>;
|
|
250
276
|
}, z.core.$strict>>;
|
|
@@ -417,7 +443,7 @@ export declare const Probe: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
417
443
|
legId: z.ZodString;
|
|
418
444
|
interfaceId: z.ZodString;
|
|
419
445
|
operationId: z.ZodString;
|
|
420
|
-
inputs: z.ZodObject<{
|
|
446
|
+
inputs: z.ZodUnion<readonly [z.ZodObject<{
|
|
421
447
|
path: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
422
448
|
query: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
423
449
|
header: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -427,7 +453,20 @@ export declare const Probe: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
427
453
|
}, z.core.$strict>, z.ZodObject<{
|
|
428
454
|
kind: z.ZodLiteral<"absent">;
|
|
429
455
|
}, z.core.$strict>], "kind">;
|
|
430
|
-
}, z.core.$strict
|
|
456
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
457
|
+
argument: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
458
|
+
option: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
459
|
+
environment: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
460
|
+
stdin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
461
|
+
kind: z.ZodLiteral<"json">;
|
|
462
|
+
value: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
|
|
463
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
464
|
+
kind: z.ZodLiteral<"text">;
|
|
465
|
+
value: z.ZodString;
|
|
466
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
467
|
+
kind: z.ZodLiteral<"absent">;
|
|
468
|
+
}, z.core.$strict>], "kind">;
|
|
469
|
+
}, z.core.$strict>]>;
|
|
431
470
|
relation: z.ZodType<import("./expression.ts").Expression, unknown, z.core.$ZodTypeInternals<import("./expression.ts").Expression, unknown>>;
|
|
432
471
|
}, z.core.$strict>>;
|
|
433
472
|
}, z.core.$strict>>;
|
|
@@ -197,12 +197,23 @@ export type SensitivityWitness = z.infer<typeof SensitivityWitness>;
|
|
|
197
197
|
* A different mechanism from AD-40's DEFECT SIGNATURE, which matches a
|
|
198
198
|
* scoring-side finding against an observation. This one never enters a score; it
|
|
199
199
|
* makes "every declared seeded fault observed to fire" decidable at pre-flight.
|
|
200
|
+
*
|
|
201
|
+
* `inputs` is the same union a sensitivity leg takes. It was `ApiWitnessInputs`
|
|
202
|
+
* alone, which made a seeded defect against a command-line system under test
|
|
203
|
+
* unrepresentable in both directions: command channels failed the `Probe`
|
|
204
|
+
* parse, and transport channels reached `requestOf` and threw
|
|
205
|
+
* `undeclared-mandatory-input` for supplying transport channels to an operation
|
|
206
|
+
* that runs behind a command. A `null` witness parses, so the only way through
|
|
207
|
+
* was to declare the defect unobservable, which pre-flight records as a failed
|
|
208
|
+
* `seeded-fault-fired` check. Every `defect` and `zero-action` probe against a
|
|
209
|
+
* command was therefore unscoreable. 0.3.0 widened the contract side and left
|
|
210
|
+
* this one and `FixtureReset` behind.
|
|
200
211
|
*/
|
|
201
212
|
export declare const ManifestationWitness: z.ZodObject<{
|
|
202
213
|
legId: z.ZodString;
|
|
203
214
|
interfaceId: z.ZodString;
|
|
204
215
|
operationId: z.ZodString;
|
|
205
|
-
inputs: z.ZodObject<{
|
|
216
|
+
inputs: z.ZodUnion<readonly [z.ZodObject<{
|
|
206
217
|
path: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
207
218
|
query: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
208
219
|
header: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -212,7 +223,20 @@ export declare const ManifestationWitness: z.ZodObject<{
|
|
|
212
223
|
}, z.core.$strict>, z.ZodObject<{
|
|
213
224
|
kind: z.ZodLiteral<"absent">;
|
|
214
225
|
}, z.core.$strict>], "kind">;
|
|
215
|
-
}, z.core.$strict
|
|
226
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
227
|
+
argument: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
228
|
+
option: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
229
|
+
environment: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
230
|
+
stdin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
231
|
+
kind: z.ZodLiteral<"json">;
|
|
232
|
+
value: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
|
|
233
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
234
|
+
kind: z.ZodLiteral<"text">;
|
|
235
|
+
value: z.ZodString;
|
|
236
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
237
|
+
kind: z.ZodLiteral<"absent">;
|
|
238
|
+
}, z.core.$strict>], "kind">;
|
|
239
|
+
}, z.core.$strict>]>;
|
|
216
240
|
relation: z.ZodType<Expression, unknown, z.core.$ZodTypeInternals<Expression, unknown>>;
|
|
217
241
|
}, z.core.$strict>;
|
|
218
242
|
export type ManifestationWitness = z.infer<typeof ManifestationWitness>;
|
|
@@ -225,7 +249,7 @@ export declare const FixtureReset: z.ZodObject<{
|
|
|
225
249
|
legId: z.ZodString;
|
|
226
250
|
interfaceId: z.ZodString;
|
|
227
251
|
operationId: z.ZodString;
|
|
228
|
-
inputs: z.ZodObject<{
|
|
252
|
+
inputs: z.ZodUnion<readonly [z.ZodObject<{
|
|
229
253
|
path: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
230
254
|
query: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
231
255
|
header: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -235,6 +259,19 @@ export declare const FixtureReset: z.ZodObject<{
|
|
|
235
259
|
}, z.core.$strict>, z.ZodObject<{
|
|
236
260
|
kind: z.ZodLiteral<"absent">;
|
|
237
261
|
}, z.core.$strict>], "kind">;
|
|
238
|
-
}, z.core.$strict
|
|
262
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
263
|
+
argument: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
264
|
+
option: z.ZodType<import("./primitives.ts").JsonObject, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonObject, unknown>>;
|
|
265
|
+
environment: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
266
|
+
stdin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
267
|
+
kind: z.ZodLiteral<"json">;
|
|
268
|
+
value: z.ZodType<import("./primitives.ts").JsonValue, unknown, z.core.$ZodTypeInternals<import("./primitives.ts").JsonValue, unknown>>;
|
|
269
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
270
|
+
kind: z.ZodLiteral<"text">;
|
|
271
|
+
value: z.ZodString;
|
|
272
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
273
|
+
kind: z.ZodLiteral<"absent">;
|
|
274
|
+
}, z.core.$strict>], "kind">;
|
|
275
|
+
}, z.core.$strict>]>;
|
|
239
276
|
}, z.core.$strict>;
|
|
240
277
|
export type FixtureReset = z.infer<typeof FixtureReset>;
|
|
@@ -121,12 +121,23 @@ export const SensitivityWitness = z.strictObject({
|
|
|
121
121
|
* A different mechanism from AD-40's DEFECT SIGNATURE, which matches a
|
|
122
122
|
* scoring-side finding against an observation. This one never enters a score; it
|
|
123
123
|
* makes "every declared seeded fault observed to fire" decidable at pre-flight.
|
|
124
|
+
*
|
|
125
|
+
* `inputs` is the same union a sensitivity leg takes. It was `ApiWitnessInputs`
|
|
126
|
+
* alone, which made a seeded defect against a command-line system under test
|
|
127
|
+
* unrepresentable in both directions: command channels failed the `Probe`
|
|
128
|
+
* parse, and transport channels reached `requestOf` and threw
|
|
129
|
+
* `undeclared-mandatory-input` for supplying transport channels to an operation
|
|
130
|
+
* that runs behind a command. A `null` witness parses, so the only way through
|
|
131
|
+
* was to declare the defect unobservable, which pre-flight records as a failed
|
|
132
|
+
* `seeded-fault-fired` check. Every `defect` and `zero-action` probe against a
|
|
133
|
+
* command was therefore unscoreable. 0.3.0 widened the contract side and left
|
|
134
|
+
* this one and `FixtureReset` behind.
|
|
124
135
|
*/
|
|
125
136
|
export const ManifestationWitness = z.strictObject({
|
|
126
137
|
legId: Identifier,
|
|
127
138
|
interfaceId: Identifier,
|
|
128
139
|
operationId: Identifier,
|
|
129
|
-
inputs:
|
|
140
|
+
inputs: WitnessInputs,
|
|
130
141
|
relation: Expression,
|
|
131
142
|
});
|
|
132
143
|
/**
|
|
@@ -138,5 +149,5 @@ export const FixtureReset = z.strictObject({
|
|
|
138
149
|
legId: Identifier,
|
|
139
150
|
interfaceId: Identifier,
|
|
140
151
|
operationId: Identifier,
|
|
141
|
-
inputs:
|
|
152
|
+
inputs: WitnessInputs,
|
|
142
153
|
});
|
|
@@ -35,7 +35,7 @@ import type { Probe } from '../schemas/probe.ts';
|
|
|
35
35
|
import type { ScoringPolicy } from '../schemas/scoring-policy.ts';
|
|
36
36
|
import type { ScoreStage } from '../stage-contracts.ts';
|
|
37
37
|
import type { ContractAssessment, LadderResolution, ProductionAssessment } from './ladder.ts';
|
|
38
|
-
import { type SealedProbeSet } from './qualification.ts';
|
|
38
|
+
import { type QualificationResult, type SealedProbeSet } from './qualification.ts';
|
|
39
39
|
import { type TrialSetResult } from './reduce-trials.ts';
|
|
40
40
|
/**
|
|
41
41
|
* `score`'s owned product: the assessment/ladder pairing AD-24 names, "the
|
|
@@ -56,6 +56,13 @@ export type ScoredOutcomesAndVerdict = {
|
|
|
56
56
|
readonly policy: ScoringPolicy;
|
|
57
57
|
readonly probe: Probe;
|
|
58
58
|
readonly sealedProbes: SealedProbeSet;
|
|
59
|
+
/**
|
|
60
|
+
* The one probe's own qualification result, lifted out of `sealedProbes`
|
|
61
|
+
* so a caller reading a run's product holds the closed reason set that
|
|
62
|
+
* decided it. `emit` mints no field from this: AD-9's reasons stay off the
|
|
63
|
+
* `EvidenceArtifact` and travel the return path.
|
|
64
|
+
*/
|
|
65
|
+
readonly probeQualification: QualificationResult;
|
|
59
66
|
/** this probe's own AD-7 trial-set fold, keyed by `emit` under `probe.probeId` to build the strength vector. */
|
|
60
67
|
readonly trialSetResult: TrialSetResult;
|
|
61
68
|
/** the full `EvidenceArtifact.outcomes` shape, a parallel array to `ScoredOutcome[]` above: `ScoredOutcome` carries `resolution` but not `disposition` or the raw `CheckResolution` tree this shape needs, so the two are not reconstructible from one another. */
|
package/dist/core/score/score.js
CHANGED
|
@@ -37,7 +37,7 @@ import { buildPlanIndex } from '../seal/plan-index.js';
|
|
|
37
37
|
import { resolveCapturedBindings, selectWithBindings } from './bindings.js';
|
|
38
38
|
import { resolveContractVerdict, resolveProductionVerdict } from './ladder.js';
|
|
39
39
|
import { FINDING_BUCKETS, resolveOutcome, uncitedDefectFindingGaps, uncitedFindingIds, } from './outcome.js';
|
|
40
|
-
import { resolveHomeOperation, sealProbeSet, } from './qualification.js';
|
|
40
|
+
import { qualifyProbe, resolveHomeOperation, sealProbeSet, } from './qualification.js';
|
|
41
41
|
import { reduceTrialSet, TRIAL_VOTE_STATES, } from './reduce-trials.js';
|
|
42
42
|
import { mapFindings, matchProbeWitness } from './witness.js';
|
|
43
43
|
/** A mutable copy of the two record-shaped arrays every witness/finding function this stage calls wants, since `ValidatedObservations`' own arrays are `readonly`. */
|
|
@@ -245,8 +245,17 @@ export const score = (contract, trials, probe, preflightVerdict, policy, waiver,
|
|
|
245
245
|
? null
|
|
246
246
|
: resolveHomeOperation(candidate.defectSignature, contract.permittedInterfaces);
|
|
247
247
|
const sealedProbes = sealProbeSet([probe], homeOperationOf);
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
// `sealProbeSet` over a one-probe array puts that probe in exactly one
|
|
249
|
+
// bucket, so the third branch is unreachable. It re-runs the gate rather
|
|
250
|
+
// than composing a result here: `qualifyProbe` holds
|
|
251
|
+
// `qualified === (failures.length === 0)`, and a hand-built
|
|
252
|
+
// `{ qualified: false, failures: [] }` would hand a consumer a rejection
|
|
253
|
+
// with no code to route on, which is the silent state this field removes.
|
|
254
|
+
// The gate is pure, so a second call over the same probe answers the same.
|
|
255
|
+
const probeQualification = sealedProbes.admitted[0]?.result ??
|
|
256
|
+
sealedProbes.rejected[0]?.result ??
|
|
257
|
+
qualifyProbe(probe, homeOperationOf(probe));
|
|
258
|
+
const probeQualified = probeQualification.qualified;
|
|
250
259
|
const signedProbe = signedProbeOf(probe);
|
|
251
260
|
const designatedOracleId = designatedOracleIdOf(probe, contract);
|
|
252
261
|
const probeSigned = !probe.expectedClean && probe.defectSignature !== null;
|
|
@@ -578,6 +587,7 @@ export const score = (contract, trials, probe, preflightVerdict, policy, waiver,
|
|
|
578
587
|
policy,
|
|
579
588
|
probe,
|
|
580
589
|
sealedProbes,
|
|
590
|
+
probeQualification,
|
|
581
591
|
trialSetResult: reduced,
|
|
582
592
|
outcomes,
|
|
583
593
|
uncitedFindings,
|
|
@@ -600,6 +610,7 @@ export const score = (contract, trials, probe, preflightVerdict, policy, waiver,
|
|
|
600
610
|
policy,
|
|
601
611
|
probe,
|
|
602
612
|
sealedProbes,
|
|
613
|
+
probeQualification,
|
|
603
614
|
trialSetResult: reduced,
|
|
604
615
|
outcomes,
|
|
605
616
|
uncitedFindings,
|
package/dist/index.d.ts
CHANGED
|
@@ -12,4 +12,4 @@ export type { ScoringPolicy } from './core/schemas/scoring-policy.ts';
|
|
|
12
12
|
export type { SealedEvaluatorBrief } from './core/schemas/sealed-evaluator-brief.ts';
|
|
13
13
|
export type { SealedRunRecord } from './core/schemas/sealed-run-record.ts';
|
|
14
14
|
export type { FixtureReset, ManifestationWitness, SensitivityWitness, SensitivityWitnessLeg, WitnessChannel, WitnessInputs, } from './core/schemas/sensitivity-witness.ts';
|
|
15
|
-
export declare const VERSION = "1.
|
|
15
|
+
export declare const VERSION = "1.4.0";
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1566,7 +1566,102 @@
|
|
|
1566
1566
|
"description": "A kebab-case slug. Excludes \"/\" and \"~\" so an identifier can be embedded in an interaction-rooted pointer without escaping."
|
|
1567
1567
|
},
|
|
1568
1568
|
"inputs": {
|
|
1569
|
-
"
|
|
1569
|
+
"anyOf": [
|
|
1570
|
+
{
|
|
1571
|
+
"$ref": "#/$defs/WitnessInputs"
|
|
1572
|
+
},
|
|
1573
|
+
{
|
|
1574
|
+
"type": "object",
|
|
1575
|
+
"properties": {
|
|
1576
|
+
"argument": {
|
|
1577
|
+
"type": "object",
|
|
1578
|
+
"propertyNames": {
|
|
1579
|
+
"type": "string"
|
|
1580
|
+
},
|
|
1581
|
+
"additionalProperties": {
|
|
1582
|
+
"$ref": "#/$defs/JsonValue"
|
|
1583
|
+
}
|
|
1584
|
+
},
|
|
1585
|
+
"option": {
|
|
1586
|
+
"type": "object",
|
|
1587
|
+
"propertyNames": {
|
|
1588
|
+
"type": "string"
|
|
1589
|
+
},
|
|
1590
|
+
"additionalProperties": {
|
|
1591
|
+
"$ref": "#/$defs/JsonValue"
|
|
1592
|
+
}
|
|
1593
|
+
},
|
|
1594
|
+
"environment": {
|
|
1595
|
+
"type": "object",
|
|
1596
|
+
"propertyNames": {
|
|
1597
|
+
"type": "string",
|
|
1598
|
+
"minLength": 1
|
|
1599
|
+
},
|
|
1600
|
+
"additionalProperties": {
|
|
1601
|
+
"type": "string"
|
|
1602
|
+
}
|
|
1603
|
+
},
|
|
1604
|
+
"stdin": {
|
|
1605
|
+
"oneOf": [
|
|
1606
|
+
{
|
|
1607
|
+
"type": "object",
|
|
1608
|
+
"properties": {
|
|
1609
|
+
"kind": {
|
|
1610
|
+
"type": "string",
|
|
1611
|
+
"const": "json"
|
|
1612
|
+
},
|
|
1613
|
+
"value": {
|
|
1614
|
+
"$ref": "#/$defs/JsonValue"
|
|
1615
|
+
}
|
|
1616
|
+
},
|
|
1617
|
+
"required": [
|
|
1618
|
+
"kind",
|
|
1619
|
+
"value"
|
|
1620
|
+
],
|
|
1621
|
+
"additionalProperties": false
|
|
1622
|
+
},
|
|
1623
|
+
{
|
|
1624
|
+
"type": "object",
|
|
1625
|
+
"properties": {
|
|
1626
|
+
"kind": {
|
|
1627
|
+
"type": "string",
|
|
1628
|
+
"const": "text"
|
|
1629
|
+
},
|
|
1630
|
+
"value": {
|
|
1631
|
+
"type": "string"
|
|
1632
|
+
}
|
|
1633
|
+
},
|
|
1634
|
+
"required": [
|
|
1635
|
+
"kind",
|
|
1636
|
+
"value"
|
|
1637
|
+
],
|
|
1638
|
+
"additionalProperties": false
|
|
1639
|
+
},
|
|
1640
|
+
{
|
|
1641
|
+
"type": "object",
|
|
1642
|
+
"properties": {
|
|
1643
|
+
"kind": {
|
|
1644
|
+
"type": "string",
|
|
1645
|
+
"const": "absent"
|
|
1646
|
+
}
|
|
1647
|
+
},
|
|
1648
|
+
"required": [
|
|
1649
|
+
"kind"
|
|
1650
|
+
],
|
|
1651
|
+
"additionalProperties": false
|
|
1652
|
+
}
|
|
1653
|
+
]
|
|
1654
|
+
}
|
|
1655
|
+
},
|
|
1656
|
+
"required": [
|
|
1657
|
+
"argument",
|
|
1658
|
+
"option",
|
|
1659
|
+
"environment",
|
|
1660
|
+
"stdin"
|
|
1661
|
+
],
|
|
1662
|
+
"additionalProperties": false
|
|
1663
|
+
}
|
|
1664
|
+
]
|
|
1570
1665
|
}
|
|
1571
1666
|
},
|
|
1572
1667
|
"required": [
|
|
@@ -308,7 +308,102 @@
|
|
|
308
308
|
"description": "A kebab-case slug. Excludes \"/\" and \"~\" so an identifier can be embedded in an interaction-rooted pointer without escaping."
|
|
309
309
|
},
|
|
310
310
|
"inputs": {
|
|
311
|
-
"
|
|
311
|
+
"anyOf": [
|
|
312
|
+
{
|
|
313
|
+
"$ref": "#/$defs/WitnessInputs"
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
"type": "object",
|
|
317
|
+
"properties": {
|
|
318
|
+
"argument": {
|
|
319
|
+
"type": "object",
|
|
320
|
+
"propertyNames": {
|
|
321
|
+
"type": "string"
|
|
322
|
+
},
|
|
323
|
+
"additionalProperties": {
|
|
324
|
+
"$ref": "#/$defs/JsonValue"
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
"option": {
|
|
328
|
+
"type": "object",
|
|
329
|
+
"propertyNames": {
|
|
330
|
+
"type": "string"
|
|
331
|
+
},
|
|
332
|
+
"additionalProperties": {
|
|
333
|
+
"$ref": "#/$defs/JsonValue"
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
"environment": {
|
|
337
|
+
"type": "object",
|
|
338
|
+
"propertyNames": {
|
|
339
|
+
"type": "string",
|
|
340
|
+
"minLength": 1
|
|
341
|
+
},
|
|
342
|
+
"additionalProperties": {
|
|
343
|
+
"type": "string"
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
"stdin": {
|
|
347
|
+
"oneOf": [
|
|
348
|
+
{
|
|
349
|
+
"type": "object",
|
|
350
|
+
"properties": {
|
|
351
|
+
"kind": {
|
|
352
|
+
"type": "string",
|
|
353
|
+
"const": "json"
|
|
354
|
+
},
|
|
355
|
+
"value": {
|
|
356
|
+
"$ref": "#/$defs/JsonValue"
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
"required": [
|
|
360
|
+
"kind",
|
|
361
|
+
"value"
|
|
362
|
+
],
|
|
363
|
+
"additionalProperties": false
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
"type": "object",
|
|
367
|
+
"properties": {
|
|
368
|
+
"kind": {
|
|
369
|
+
"type": "string",
|
|
370
|
+
"const": "text"
|
|
371
|
+
},
|
|
372
|
+
"value": {
|
|
373
|
+
"type": "string"
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
"required": [
|
|
377
|
+
"kind",
|
|
378
|
+
"value"
|
|
379
|
+
],
|
|
380
|
+
"additionalProperties": false
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
"type": "object",
|
|
384
|
+
"properties": {
|
|
385
|
+
"kind": {
|
|
386
|
+
"type": "string",
|
|
387
|
+
"const": "absent"
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
"required": [
|
|
391
|
+
"kind"
|
|
392
|
+
],
|
|
393
|
+
"additionalProperties": false
|
|
394
|
+
}
|
|
395
|
+
]
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
"required": [
|
|
399
|
+
"argument",
|
|
400
|
+
"option",
|
|
401
|
+
"environment",
|
|
402
|
+
"stdin"
|
|
403
|
+
],
|
|
404
|
+
"additionalProperties": false
|
|
405
|
+
}
|
|
406
|
+
]
|
|
312
407
|
},
|
|
313
408
|
"relation": {
|
|
314
409
|
"$ref": "#/$defs/Expression"
|
|
@@ -668,7 +763,102 @@
|
|
|
668
763
|
"description": "A kebab-case slug. Excludes \"/\" and \"~\" so an identifier can be embedded in an interaction-rooted pointer without escaping."
|
|
669
764
|
},
|
|
670
765
|
"inputs": {
|
|
671
|
-
"
|
|
766
|
+
"anyOf": [
|
|
767
|
+
{
|
|
768
|
+
"$ref": "#/$defs/WitnessInputs"
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
"type": "object",
|
|
772
|
+
"properties": {
|
|
773
|
+
"argument": {
|
|
774
|
+
"type": "object",
|
|
775
|
+
"propertyNames": {
|
|
776
|
+
"type": "string"
|
|
777
|
+
},
|
|
778
|
+
"additionalProperties": {
|
|
779
|
+
"$ref": "#/$defs/JsonValue"
|
|
780
|
+
}
|
|
781
|
+
},
|
|
782
|
+
"option": {
|
|
783
|
+
"type": "object",
|
|
784
|
+
"propertyNames": {
|
|
785
|
+
"type": "string"
|
|
786
|
+
},
|
|
787
|
+
"additionalProperties": {
|
|
788
|
+
"$ref": "#/$defs/JsonValue"
|
|
789
|
+
}
|
|
790
|
+
},
|
|
791
|
+
"environment": {
|
|
792
|
+
"type": "object",
|
|
793
|
+
"propertyNames": {
|
|
794
|
+
"type": "string",
|
|
795
|
+
"minLength": 1
|
|
796
|
+
},
|
|
797
|
+
"additionalProperties": {
|
|
798
|
+
"type": "string"
|
|
799
|
+
}
|
|
800
|
+
},
|
|
801
|
+
"stdin": {
|
|
802
|
+
"oneOf": [
|
|
803
|
+
{
|
|
804
|
+
"type": "object",
|
|
805
|
+
"properties": {
|
|
806
|
+
"kind": {
|
|
807
|
+
"type": "string",
|
|
808
|
+
"const": "json"
|
|
809
|
+
},
|
|
810
|
+
"value": {
|
|
811
|
+
"$ref": "#/$defs/JsonValue"
|
|
812
|
+
}
|
|
813
|
+
},
|
|
814
|
+
"required": [
|
|
815
|
+
"kind",
|
|
816
|
+
"value"
|
|
817
|
+
],
|
|
818
|
+
"additionalProperties": false
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
"type": "object",
|
|
822
|
+
"properties": {
|
|
823
|
+
"kind": {
|
|
824
|
+
"type": "string",
|
|
825
|
+
"const": "text"
|
|
826
|
+
},
|
|
827
|
+
"value": {
|
|
828
|
+
"type": "string"
|
|
829
|
+
}
|
|
830
|
+
},
|
|
831
|
+
"required": [
|
|
832
|
+
"kind",
|
|
833
|
+
"value"
|
|
834
|
+
],
|
|
835
|
+
"additionalProperties": false
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
"type": "object",
|
|
839
|
+
"properties": {
|
|
840
|
+
"kind": {
|
|
841
|
+
"type": "string",
|
|
842
|
+
"const": "absent"
|
|
843
|
+
}
|
|
844
|
+
},
|
|
845
|
+
"required": [
|
|
846
|
+
"kind"
|
|
847
|
+
],
|
|
848
|
+
"additionalProperties": false
|
|
849
|
+
}
|
|
850
|
+
]
|
|
851
|
+
}
|
|
852
|
+
},
|
|
853
|
+
"required": [
|
|
854
|
+
"argument",
|
|
855
|
+
"option",
|
|
856
|
+
"environment",
|
|
857
|
+
"stdin"
|
|
858
|
+
],
|
|
859
|
+
"additionalProperties": false
|
|
860
|
+
}
|
|
861
|
+
]
|
|
672
862
|
},
|
|
673
863
|
"relation": {
|
|
674
864
|
"$ref": "#/$defs/Expression"
|