eval-quality 0.1.0 → 0.3.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/README.md +142 -67
- package/corpus/dev/README.md +20 -13
- package/corpus/dev/compile-seal-example/brief.json +1 -1
- package/corpus/dev/compile-seal-example/contract.json +1 -1
- package/corpus/dev/contracts/absent-collection-locations.json +1 -1
- package/corpus/dev/contracts/absent-sibling-groups.json +1 -1
- package/corpus/dev/contracts/absent-success-indicator.json +1 -1
- package/corpus/dev/contracts/empty-channel-roles.json +1 -1
- package/corpus/dev/contracts/empty-collection-locations.json +1 -1
- package/corpus/dev/contracts/empty-request-shapes.json +1 -1
- package/corpus/dev/contracts/empty-sibling-groups.json +1 -1
- package/corpus/dev/contracts/fragment-selection.json +1 -0
- package/corpus/dev/contracts/no-collection-quantifier.json +1 -1
- package/corpus/dev/contracts/no-operation-inventory.json +1 -1
- package/corpus/dev/contracts/no-read-back-relation.json +1 -1
- package/corpus/dev/contracts/no-state-change-marker.json +1 -1
- package/corpus/dev/contracts/no-type-violating-step.json +1 -1
- package/corpus/dev/contracts/per-key-split-oracles.json +1 -1
- package/corpus/dev/contracts/review-corpus.json +1 -0
- package/corpus/dev/contracts/satisfied-declarations.json +1 -1
- package/corpus/dev/contracts/single-required-response-key.json +1 -1
- package/corpus/dev/contracts/split-indicator-oracle.json +1 -1
- package/corpus/dev/contracts/unaddressed-parameter-sibling.json +1 -1
- package/corpus/dev/contracts/unnamed-reference-set.json +1 -1
- package/corpus/dev/contracts/wrong-cardinality-form.json +1 -1
- package/corpus/dev/index.json +1 -1
- package/dist/application/index.d.ts +2 -0
- package/dist/application/index.js +1 -0
- package/dist/application/score.d.ts +48 -0
- package/dist/application/score.js +186 -0
- package/dist/cli/arguments.d.ts +7 -3
- package/dist/cli/arguments.js +73 -5
- package/dist/cli/exit-codes.d.ts +6 -2
- package/dist/cli/exit-codes.js +8 -9
- package/dist/cli/main.js +9 -0
- package/dist/cli/render.d.ts +3 -6
- package/dist/cli/render.js +57 -5
- package/dist/cli/run.d.ts +13 -3
- package/dist/cli/run.js +136 -16
- package/dist/core/canonical/canonicalize.d.ts +12 -0
- package/dist/core/canonical/canonicalize.js +18 -4
- package/dist/core/compile/bindings.d.ts +89 -0
- package/dist/core/compile/bindings.js +334 -0
- package/dist/core/compile/compile.d.ts +17 -0
- package/dist/core/compile/compile.js +37 -1
- package/dist/core/compile/excluded-content.d.ts +11 -0
- package/dist/core/compile/excluded-content.js +42 -0
- package/dist/core/compile/expression-legality.d.ts +49 -0
- package/dist/core/compile/expression-legality.js +158 -38
- package/dist/core/compile/forbidden-inputs.d.ts +8 -1
- package/dist/core/compile/forbidden-inputs.js +16 -3
- package/dist/core/compile/interface-inventory.d.ts +57 -2
- package/dist/core/compile/interface-inventory.js +119 -13
- package/dist/core/compile/reachability.d.ts +28 -1
- package/dist/core/compile/reachability.js +167 -35
- package/dist/core/compile/schema-version.d.ts +2 -0
- package/dist/core/compile/schema-version.js +25 -0
- package/dist/core/compile/sensitivity-witness.d.ts +31 -12
- package/dist/core/compile/sensitivity-witness.js +110 -23
- package/dist/core/compile/step-reference.d.ts +2 -0
- package/dist/core/compile/step-reference.js +49 -0
- package/dist/core/coverage/operations.d.ts +62 -0
- package/dist/core/coverage/operations.js +57 -0
- package/dist/core/coverage/relevance.d.ts +4 -2
- package/dist/core/coverage/relevance.js +22 -23
- package/dist/core/coverage/satisfaction.d.ts +2 -2
- package/dist/core/coverage/satisfaction.js +73 -48
- package/dist/core/declared-inputs.d.ts +83 -4
- package/dist/core/declared-inputs.js +105 -8
- package/dist/core/emit/emit.d.ts +9 -0
- package/dist/core/emit/emit.js +214 -0
- package/dist/core/emit/private-artifact-digest.d.ts +11 -0
- package/dist/core/emit/private-artifact-digest.js +31 -0
- package/dist/core/evaluate/evidence-resolution.d.ts +10 -3
- package/dist/core/evaluate/evidence-resolution.js +74 -11
- package/dist/core/evaluate/operators.d.ts +22 -0
- package/dist/core/evaluate/operators.js +17 -1
- package/dist/core/evaluate/resolution.d.ts +14 -3
- package/dist/core/evaluate/resolution.js +63 -3
- package/dist/core/excluded-content.d.ts +65 -0
- package/dist/core/excluded-content.js +113 -0
- package/dist/core/failure-codes.d.ts +2 -2
- package/dist/core/failure-codes.js +7 -2
- package/dist/core/ingest/conditions.d.ts +201 -0
- package/dist/core/ingest/conditions.js +48 -0
- package/dist/core/ingest/index.d.ts +13 -0
- package/dist/core/ingest/index.js +11 -0
- package/dist/core/ingest/ingest.d.ts +68 -0
- package/dist/core/ingest/ingest.js +318 -0
- package/dist/core/lineage/stage-table.d.ts +21 -4
- package/dist/core/lineage/stage-table.js +35 -3
- package/dist/core/preflight/plan.d.ts +7 -5
- package/dist/core/preflight/plan.js +75 -32
- package/dist/core/preflight/projection.d.ts +6 -3
- package/dist/core/preflight/projection.js +22 -2
- package/dist/core/preflight/reduce.js +47 -7
- package/dist/core/preflight/witness-evidence.d.ts +5 -5
- package/dist/core/preflight/witness-evidence.js +73 -20
- package/dist/core/schemas/artifact.d.ts +1049 -30
- package/dist/core/schemas/constraint-ledger.js +51 -0
- package/dist/core/schemas/defect-signature.d.ts +695 -0
- package/dist/core/schemas/defect-signature.js +175 -0
- package/dist/core/schemas/eval-contract.d.ts +550 -12
- package/dist/core/schemas/eval-contract.js +32 -2
- package/dist/core/schemas/evidence-artifact.d.ts +109 -19
- package/dist/core/schemas/evidence-artifact.js +64 -8
- package/dist/core/schemas/interface.d.ts +741 -13
- package/dist/core/schemas/interface.js +120 -7
- package/dist/core/schemas/isolation-manifest.js +16 -9
- package/dist/core/schemas/plan.d.ts +329 -3
- package/dist/core/schemas/plan.js +89 -3
- package/dist/core/schemas/pointer.d.ts +47 -1
- package/dist/core/schemas/pointer.js +89 -8
- package/dist/core/schemas/port-messages.d.ts +194 -10
- package/dist/core/schemas/port-messages.js +73 -6
- package/dist/core/schemas/probe-body.d.ts +18 -0
- package/dist/core/schemas/probe-body.js +13 -0
- package/dist/core/schemas/probe-qualification.d.ts +168 -0
- package/dist/core/schemas/probe-qualification.js +106 -0
- package/dist/core/schemas/probe.d.ts +431 -0
- package/dist/core/schemas/probe.js +6 -2
- package/dist/core/schemas/scoring-policy.d.ts +1 -0
- package/dist/core/schemas/scoring-policy.js +6 -1
- package/dist/core/schemas/sealed-evaluator-brief.d.ts +1 -0
- package/dist/core/schemas/sealed-evaluator-brief.js +4 -1
- package/dist/core/schemas/sealed-run-record.d.ts +161 -12
- package/dist/core/schemas/sealed-run-record.js +92 -15
- package/dist/core/schemas/sensitivity-witness.d.ts +108 -6
- package/dist/core/schemas/sensitivity-witness.js +61 -5
- package/dist/core/score/binding-order.d.ts +31 -0
- package/dist/core/score/binding-order.js +88 -0
- package/dist/core/score/bindings.d.ts +93 -0
- package/dist/core/score/bindings.js +309 -0
- package/dist/core/score/ladder-table.d.ts +23 -0
- package/dist/core/score/ladder-table.js +109 -0
- package/dist/core/score/ladder.d.ts +229 -0
- package/dist/core/score/ladder.js +464 -0
- package/dist/core/score/mode-agreement.d.ts +30 -0
- package/dist/core/score/mode-agreement.js +16 -0
- package/dist/core/score/outcome-table.d.ts +17 -0
- package/dist/core/score/outcome-table.js +172 -0
- package/dist/core/score/outcome.d.ts +466 -0
- package/dist/core/score/outcome.js +562 -0
- package/dist/core/score/qualification.d.ts +83 -0
- package/dist/core/score/qualification.js +645 -0
- package/dist/core/score/quotation.d.ts +56 -0
- package/dist/core/score/quotation.js +226 -0
- package/dist/core/score/reduce-trials.d.ts +80 -0
- package/dist/core/score/reduce-trials.js +90 -0
- package/dist/core/score/score.d.ts +72 -0
- package/dist/core/score/score.js +607 -0
- package/dist/core/score/selection.d.ts +80 -0
- package/dist/core/score/selection.js +98 -0
- package/dist/core/score/strength.d.ts +58 -0
- package/dist/core/score/strength.js +227 -0
- package/dist/core/score/witness.d.ts +138 -0
- package/dist/core/score/witness.js +320 -0
- package/dist/core/seal/derived-reference.d.ts +2 -9
- package/dist/core/seal/derived-reference.js +293 -46
- package/dist/core/seal/plan-index.d.ts +18 -3
- package/dist/core/seal/plan-index.js +44 -8
- package/dist/core/seal/seal.js +8 -3
- package/dist/core/stage-contracts.d.ts +62 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/ports/environment-probe-port.d.ts +60 -4
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +1 -0
- package/dist/testing/probe-conformance.d.ts +29 -0
- package/dist/testing/probe-conformance.js +34 -5
- package/package.json +12 -3
- package/schemas/eval-contract.schema.json +1787 -797
- package/schemas/evidence-artifact.schema.json +126 -9
- package/schemas/isolation-manifest.schema.json +17 -10
- package/schemas/probe.schema.json +636 -5
- package/schemas/rubric.schema.json +1 -1
- package/schemas/scoring-policy.schema.json +8 -1
- package/schemas/sealed-evaluator-brief.schema.json +11 -1
- package/schemas/sealed-run-record.schema.json +314 -40
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { HttpMethod, PathTemplate } from './interface.js';
|
|
4
4
|
import { Identifier, JsonValue, KeyName, Rfc3339Utc } from './primitives.js';
|
|
5
|
-
import { ProbeObservedBody, ProbeRequestBody } from './probe-body.js';
|
|
5
|
+
import { ProbeObservedBody, ProbeRequestBody, ProbeRequestStdin, } from './probe-body.js';
|
|
6
6
|
export { ProbeObservedBody, ProbeRequestBody } from './probe-body.js';
|
|
7
7
|
// AD-8: the corpus port resolves an opaque reference to bytes from a
|
|
8
8
|
// caller-owned location. It does not check the digest: AD-8 puts digest
|
|
@@ -52,10 +52,20 @@ export const FileWriteResponse = z.strictObject({
|
|
|
52
52
|
* authorization material is the adapter's, supplied by the same mapping that
|
|
53
53
|
* authorizes the target.
|
|
54
54
|
*/
|
|
55
|
-
|
|
55
|
+
const probeCorrelation = {
|
|
56
56
|
probeId: Identifier.describe('An opaque correlation label minted by the pre-flight plan and echoed unchanged on the observation. Two witnesses of one operation, and the three observations a state-reset differential needs, are otherwise distinguishable only by array position, which NFR9 forbids any stage from reading.'),
|
|
57
57
|
interfaceId: Identifier,
|
|
58
58
|
operationId: Identifier,
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* A request to an interface that speaks HTTP. Tagged on `kind` so an adapter
|
|
62
|
+
* knows what it is being asked to do before it reads anything else, and so the
|
|
63
|
+
* two shapes cannot be confused for one another by a field that happens to be
|
|
64
|
+
* absent.
|
|
65
|
+
*/
|
|
66
|
+
export const ApiProbeRequest = z.strictObject({
|
|
67
|
+
...probeCorrelation,
|
|
68
|
+
kind: z.literal('api'),
|
|
59
69
|
method: HttpMethod,
|
|
60
70
|
pathTemplate: PathTemplate,
|
|
61
71
|
channels: z.strictObject({
|
|
@@ -67,6 +77,38 @@ export const ProbeRequest = z.strictObject({
|
|
|
67
77
|
body: ProbeRequestBody,
|
|
68
78
|
}),
|
|
69
79
|
});
|
|
80
|
+
/**
|
|
81
|
+
* A request to run a command.
|
|
82
|
+
*
|
|
83
|
+
* AD-35's rule is that a contract names a logical identifier and the caller
|
|
84
|
+
* maps it, and the analogue for a command is exactly the same shape: the
|
|
85
|
+
* `executable` is the logical name the contract declared, and the adapter maps
|
|
86
|
+
* it to something runnable from configuration outside the contract. No
|
|
87
|
+
* filesystem path, no interpreter, no shell string. The adapter builds the
|
|
88
|
+
* argument vector; it is never handed one to execute.
|
|
89
|
+
*
|
|
90
|
+
* `environment` is string-valued for the reason `header` is, and carries no
|
|
91
|
+
* credential for the reason AD-18 gives: authorization material is the
|
|
92
|
+
* adapter's, supplied by the same mapping that authorizes the target.
|
|
93
|
+
*/
|
|
94
|
+
export const CommandProbeRequest = z.strictObject({
|
|
95
|
+
...probeCorrelation,
|
|
96
|
+
kind: z.literal('cli'),
|
|
97
|
+
executable: Identifier.describe('A logical executable name, never a filesystem path, a URL, a host, or a port (AD-35). The adapter maps it to an authorized target through configuration outside the contract.'),
|
|
98
|
+
subcommandPath: z.array(Identifier),
|
|
99
|
+
channels: z.strictObject({
|
|
100
|
+
argument: z.record(KeyName, JsonValue),
|
|
101
|
+
option: z.record(KeyName, JsonValue),
|
|
102
|
+
environment: z
|
|
103
|
+
.record(KeyName, z.string())
|
|
104
|
+
.describe('String-valued because an environment variable is a string to the process; the other channels carry the declared JSON value.'),
|
|
105
|
+
stdin: ProbeRequestStdin,
|
|
106
|
+
}),
|
|
107
|
+
});
|
|
108
|
+
export const ProbeRequest = z.discriminatedUnion('kind', [
|
|
109
|
+
ApiProbeRequest,
|
|
110
|
+
CommandProbeRequest,
|
|
111
|
+
]);
|
|
70
112
|
/**
|
|
71
113
|
* What the adapter observed. Deliberately response content only: no elapsed
|
|
72
114
|
* time, no redirect count, no retry count. AD-35's caps are safety limits, so
|
|
@@ -78,13 +120,38 @@ export const ProbeRequest = z.strictObject({
|
|
|
78
120
|
* policy denial, a cap, an abort, or a transport failure throws; a 500 is the
|
|
79
121
|
* payload AD-10's seeded-fault check reads, never an error.
|
|
80
122
|
*/
|
|
81
|
-
export const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
operationId: Identifier,
|
|
123
|
+
export const ApiProbeObservation = z.strictObject({
|
|
124
|
+
...probeCorrelation,
|
|
125
|
+
kind: z.literal('api'),
|
|
85
126
|
status: z.int().min(100).max(599),
|
|
86
127
|
headers: z
|
|
87
128
|
.record(KeyName, z.string())
|
|
88
129
|
.describe('Repeated headers are joined with ", " per RFC 9110 before they reach this shape. `set-cookie` is the one header that rule is wrong for, and it is dropped rather than mangled: nothing in AD-10 reads it, and a joined `set-cookie` is a value no consumer can split back.'),
|
|
89
130
|
body: ProbeObservedBody,
|
|
90
131
|
});
|
|
132
|
+
/**
|
|
133
|
+
* What the adapter observed of a command run: its two streams, its exit code,
|
|
134
|
+
* and the files it wrote.
|
|
135
|
+
*
|
|
136
|
+
* `exitCode` is signed, unlike an HTTP status, because a process terminated by
|
|
137
|
+
* a signal is conventionally reported as a negative code and this field records
|
|
138
|
+
* what happened rather than what is tidy. A non-zero exit is an observation
|
|
139
|
+
* exactly as a 500 is: only a policy denial, a cap, an abort, or a failure to
|
|
140
|
+
* start the process throws.
|
|
141
|
+
*
|
|
142
|
+
* `artifacts` is keyed by the identifier the operation declared, not by a
|
|
143
|
+
* filesystem path. Which path each identifier names is the adapter's mapping,
|
|
144
|
+
* the same disclosure boundary AD-35 draws around the executable itself.
|
|
145
|
+
*/
|
|
146
|
+
export const CommandProbeObservation = z.strictObject({
|
|
147
|
+
...probeCorrelation,
|
|
148
|
+
kind: z.literal('cli'),
|
|
149
|
+
exitCode: z.int(),
|
|
150
|
+
stdout: ProbeObservedBody,
|
|
151
|
+
stderr: ProbeObservedBody,
|
|
152
|
+
artifacts: z.record(Identifier, ProbeObservedBody),
|
|
153
|
+
});
|
|
154
|
+
export const ProbeObservation = z.discriminatedUnion('kind', [
|
|
155
|
+
ApiProbeObservation,
|
|
156
|
+
CommandProbeObservation,
|
|
157
|
+
]);
|
|
@@ -21,5 +21,23 @@ export declare const ProbeObservedBody: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
21
21
|
}, z.core.$strict>, z.ZodObject<{
|
|
22
22
|
kind: z.ZodLiteral<"absent">;
|
|
23
23
|
}, z.core.$strict>], "kind">;
|
|
24
|
+
/**
|
|
25
|
+
* What one leg writes to a command's standard input. Three arms, like the
|
|
26
|
+
* observed body rather than the request body: standard input is a byte stream,
|
|
27
|
+
* so a command that reads a prompt receives text that was never JSON, and
|
|
28
|
+
* routing it through the `json` arm as a JSON string would make the leg claim
|
|
29
|
+
* a serialisation the command never sees. `absent` is the leg that writes
|
|
30
|
+
* nothing and closes the stream.
|
|
31
|
+
*/
|
|
32
|
+
export declare const ProbeRequestStdin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
33
|
+
kind: z.ZodLiteral<"json">;
|
|
34
|
+
value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
35
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
36
|
+
kind: z.ZodLiteral<"text">;
|
|
37
|
+
value: z.ZodString;
|
|
38
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
39
|
+
kind: z.ZodLiteral<"absent">;
|
|
40
|
+
}, z.core.$strict>], "kind">;
|
|
24
41
|
export type ProbeRequestBody = z.infer<typeof ProbeRequestBody>;
|
|
25
42
|
export type ProbeObservedBody = z.infer<typeof ProbeObservedBody>;
|
|
43
|
+
export type ProbeRequestStdin = z.infer<typeof ProbeRequestStdin>;
|
|
@@ -21,3 +21,16 @@ export const ProbeObservedBody = z.discriminatedUnion('kind', [
|
|
|
21
21
|
z.strictObject({ kind: z.literal('text'), value: z.string() }),
|
|
22
22
|
z.strictObject({ kind: z.literal('absent') }),
|
|
23
23
|
]);
|
|
24
|
+
/**
|
|
25
|
+
* What one leg writes to a command's standard input. Three arms, like the
|
|
26
|
+
* observed body rather than the request body: standard input is a byte stream,
|
|
27
|
+
* so a command that reads a prompt receives text that was never JSON, and
|
|
28
|
+
* routing it through the `json` arm as a JSON string would make the leg claim
|
|
29
|
+
* a serialisation the command never sees. `absent` is the leg that writes
|
|
30
|
+
* nothing and closes the stream.
|
|
31
|
+
*/
|
|
32
|
+
export const ProbeRequestStdin = z.discriminatedUnion('kind', [
|
|
33
|
+
z.strictObject({ kind: z.literal('json'), value: JsonValue }),
|
|
34
|
+
z.strictObject({ kind: z.literal('text'), value: z.string() }),
|
|
35
|
+
z.strictObject({ kind: z.literal('absent') }),
|
|
36
|
+
]);
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/** AD-9's five qualification routes, one per way ground truth is earned. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* AD-9 spells a route for each of the five ways a probe earns ground truth. The
|
|
5
|
+
* order is AD-9's own: historical fix boundary, controlled mutation,
|
|
6
|
+
* gameability demonstration, canary, clean control.
|
|
7
|
+
*/
|
|
8
|
+
export declare const QUALIFICATION_ROUTES: readonly ['historical', 'controlled-mutation', 'gameability', 'canary', 'clean-control'];
|
|
9
|
+
export type QualificationRouteValue = (typeof QUALIFICATION_ROUTES)[number];
|
|
10
|
+
export declare const QualificationRoute: z.ZodEnum<{
|
|
11
|
+
canary: "canary";
|
|
12
|
+
"clean-control": "clean-control";
|
|
13
|
+
"controlled-mutation": "controlled-mutation";
|
|
14
|
+
gameability: "gameability";
|
|
15
|
+
historical: "historical";
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* AD-9's qualification record, as a tagged union on `route`.
|
|
19
|
+
*
|
|
20
|
+
* A union rather than one wide object with nullable fields: the five routes
|
|
21
|
+
* demand disjoint evidence, and a flat shape would make every route's evidence
|
|
22
|
+
* optional on every other route, which is the shape AD-9 was written against:
|
|
23
|
+
* "a mined fix commit being trusted when its own test already passed at the
|
|
24
|
+
* parent commit". Each branch names what its route must record and nothing
|
|
25
|
+
* else.
|
|
26
|
+
*
|
|
27
|
+
* Required on every probe, canaries included. AD-9 spells a route for all five
|
|
28
|
+
* kinds and closes with "an unqualified probe cannot enter a sealed set" with
|
|
29
|
+
* no exception, so exempting the canary would leave the route AD-9 writes for
|
|
30
|
+
* it with nothing to write it in. The exemption AD-9 does grant attaches to the
|
|
31
|
+
* defect signature, which is AD-40's field.
|
|
32
|
+
*
|
|
33
|
+
* Which route a probe may take is fixed by its class and its `expectedClean`
|
|
34
|
+
* flag, and that pairing is enforced by the corpus qualification gate rather
|
|
35
|
+
* than by a schema refinement: all combinations parse here, so an incompatible
|
|
36
|
+
* pairing stays a reason code carrying an artifact path rather than an
|
|
37
|
+
* anonymous parse failure.
|
|
38
|
+
*
|
|
39
|
+
* Inlined rather than given a `.meta({ id })`. Two `$defs` sharing an internal
|
|
40
|
+
* path are indistinguishable from a schema path alone, and every branch here
|
|
41
|
+
* carries an `ArtifactReference`, so a `$defs` entry would share def-relative
|
|
42
|
+
* suffixes with `Expression` and `ArtifactReference` and make the published
|
|
43
|
+
* keyword walk's stated no-collision premise false.
|
|
44
|
+
*/
|
|
45
|
+
export declare const ProbeQualification: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
46
|
+
route: z.ZodLiteral<"historical">;
|
|
47
|
+
failBeforeEvidence: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
48
|
+
storage: z.ZodLiteral<"public">;
|
|
49
|
+
path: z.ZodString;
|
|
50
|
+
privateRef: z.ZodNull;
|
|
51
|
+
digest: z.ZodString;
|
|
52
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
53
|
+
storage: z.ZodLiteral<"private">;
|
|
54
|
+
path: z.ZodNull;
|
|
55
|
+
privateRef: z.ZodString;
|
|
56
|
+
digest: z.ZodString;
|
|
57
|
+
}, z.core.$strict>], "storage">;
|
|
58
|
+
passAfterEvidence: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
59
|
+
storage: z.ZodLiteral<"public">;
|
|
60
|
+
path: z.ZodString;
|
|
61
|
+
privateRef: z.ZodNull;
|
|
62
|
+
digest: z.ZodString;
|
|
63
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
64
|
+
storage: z.ZodLiteral<"private">;
|
|
65
|
+
path: z.ZodNull;
|
|
66
|
+
privateRef: z.ZodString;
|
|
67
|
+
digest: z.ZodString;
|
|
68
|
+
}, z.core.$strict>], "storage">;
|
|
69
|
+
fixCommitDigest: z.ZodString;
|
|
70
|
+
oracleStableAcrossRevisions: z.ZodBoolean;
|
|
71
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
72
|
+
route: z.ZodLiteral<"controlled-mutation">;
|
|
73
|
+
mutationSource: z.ZodString;
|
|
74
|
+
mutationOperator: z.ZodString;
|
|
75
|
+
targetArtifact: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
76
|
+
storage: z.ZodLiteral<"public">;
|
|
77
|
+
path: z.ZodString;
|
|
78
|
+
privateRef: z.ZodNull;
|
|
79
|
+
digest: z.ZodString;
|
|
80
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
81
|
+
storage: z.ZodLiteral<"private">;
|
|
82
|
+
path: z.ZodNull;
|
|
83
|
+
privateRef: z.ZodString;
|
|
84
|
+
digest: z.ZodString;
|
|
85
|
+
}, z.core.$strict>], "storage">;
|
|
86
|
+
expectedObservableFailure: z.ZodString;
|
|
87
|
+
baselinePassEvidence: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
88
|
+
storage: z.ZodLiteral<"public">;
|
|
89
|
+
path: z.ZodString;
|
|
90
|
+
privateRef: z.ZodNull;
|
|
91
|
+
digest: z.ZodString;
|
|
92
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
93
|
+
storage: z.ZodLiteral<"private">;
|
|
94
|
+
path: z.ZodNull;
|
|
95
|
+
privateRef: z.ZodString;
|
|
96
|
+
digest: z.ZodString;
|
|
97
|
+
}, z.core.$strict>], "storage">;
|
|
98
|
+
mutatedFailEvidence: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
99
|
+
storage: z.ZodLiteral<"public">;
|
|
100
|
+
path: z.ZodString;
|
|
101
|
+
privateRef: z.ZodNull;
|
|
102
|
+
digest: z.ZodString;
|
|
103
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
104
|
+
storage: z.ZodLiteral<"private">;
|
|
105
|
+
path: z.ZodNull;
|
|
106
|
+
privateRef: z.ZodString;
|
|
107
|
+
digest: z.ZodString;
|
|
108
|
+
}, z.core.$strict>], "storage">;
|
|
109
|
+
rollbackVerified: z.ZodBoolean;
|
|
110
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
111
|
+
route: z.ZodLiteral<"gameability">;
|
|
112
|
+
degenerateResponse: z.ZodString;
|
|
113
|
+
naiveOracleSatisfiedEvidence: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
114
|
+
storage: z.ZodLiteral<"public">;
|
|
115
|
+
path: z.ZodString;
|
|
116
|
+
privateRef: z.ZodNull;
|
|
117
|
+
digest: z.ZodString;
|
|
118
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
119
|
+
storage: z.ZodLiteral<"private">;
|
|
120
|
+
path: z.ZodNull;
|
|
121
|
+
privateRef: z.ZodString;
|
|
122
|
+
digest: z.ZodString;
|
|
123
|
+
}, z.core.$strict>], "storage">;
|
|
124
|
+
disciplinedOracleRejectedEvidence: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
125
|
+
storage: z.ZodLiteral<"public">;
|
|
126
|
+
path: z.ZodString;
|
|
127
|
+
privateRef: z.ZodNull;
|
|
128
|
+
digest: z.ZodString;
|
|
129
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
130
|
+
storage: z.ZodLiteral<"private">;
|
|
131
|
+
path: z.ZodNull;
|
|
132
|
+
privateRef: z.ZodString;
|
|
133
|
+
digest: z.ZodString;
|
|
134
|
+
}, z.core.$strict>], "storage">;
|
|
135
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
136
|
+
route: z.ZodLiteral<"canary">;
|
|
137
|
+
indicts: z.ZodEnum<{
|
|
138
|
+
corpus: "corpus";
|
|
139
|
+
fixture: "fixture";
|
|
140
|
+
}>;
|
|
141
|
+
nonDetectionEvidence: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
142
|
+
storage: z.ZodLiteral<"public">;
|
|
143
|
+
path: z.ZodString;
|
|
144
|
+
privateRef: z.ZodNull;
|
|
145
|
+
digest: z.ZodString;
|
|
146
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
147
|
+
storage: z.ZodLiteral<"private">;
|
|
148
|
+
path: z.ZodNull;
|
|
149
|
+
privateRef: z.ZodString;
|
|
150
|
+
digest: z.ZodString;
|
|
151
|
+
}, z.core.$strict>], "storage">;
|
|
152
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
153
|
+
route: z.ZodLiteral<"clean-control">;
|
|
154
|
+
baselinePassEvidence: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
155
|
+
storage: z.ZodLiteral<"public">;
|
|
156
|
+
path: z.ZodString;
|
|
157
|
+
privateRef: z.ZodNull;
|
|
158
|
+
digest: z.ZodString;
|
|
159
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
160
|
+
storage: z.ZodLiteral<"private">;
|
|
161
|
+
path: z.ZodNull;
|
|
162
|
+
privateRef: z.ZodString;
|
|
163
|
+
digest: z.ZodString;
|
|
164
|
+
}, z.core.$strict>], "storage">;
|
|
165
|
+
revisionCommitDigest: z.ZodString;
|
|
166
|
+
noKnownDefectStatement: z.ZodString;
|
|
167
|
+
}, z.core.$strict>], "route">;
|
|
168
|
+
export type ProbeQualification = z.infer<typeof ProbeQualification>;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/** AD-9's five qualification routes, one per way ground truth is earned. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { ArtifactReference } from './artifact-reference.js';
|
|
4
|
+
import { Digest } from './primitives.js';
|
|
5
|
+
/**
|
|
6
|
+
* AD-9 spells a route for each of the five ways a probe earns ground truth. The
|
|
7
|
+
* order is AD-9's own: historical fix boundary, controlled mutation,
|
|
8
|
+
* gameability demonstration, canary, clean control.
|
|
9
|
+
*/
|
|
10
|
+
export const QUALIFICATION_ROUTES = [
|
|
11
|
+
'historical',
|
|
12
|
+
'controlled-mutation',
|
|
13
|
+
'gameability',
|
|
14
|
+
'canary',
|
|
15
|
+
'clean-control',
|
|
16
|
+
];
|
|
17
|
+
export const QualificationRoute = z.enum(QUALIFICATION_ROUTES);
|
|
18
|
+
/**
|
|
19
|
+
* AD-9's qualification record, as a tagged union on `route`.
|
|
20
|
+
*
|
|
21
|
+
* A union rather than one wide object with nullable fields: the five routes
|
|
22
|
+
* demand disjoint evidence, and a flat shape would make every route's evidence
|
|
23
|
+
* optional on every other route, which is the shape AD-9 was written against:
|
|
24
|
+
* "a mined fix commit being trusted when its own test already passed at the
|
|
25
|
+
* parent commit". Each branch names what its route must record and nothing
|
|
26
|
+
* else.
|
|
27
|
+
*
|
|
28
|
+
* Required on every probe, canaries included. AD-9 spells a route for all five
|
|
29
|
+
* kinds and closes with "an unqualified probe cannot enter a sealed set" with
|
|
30
|
+
* no exception, so exempting the canary would leave the route AD-9 writes for
|
|
31
|
+
* it with nothing to write it in. The exemption AD-9 does grant attaches to the
|
|
32
|
+
* defect signature, which is AD-40's field.
|
|
33
|
+
*
|
|
34
|
+
* Which route a probe may take is fixed by its class and its `expectedClean`
|
|
35
|
+
* flag, and that pairing is enforced by the corpus qualification gate rather
|
|
36
|
+
* than by a schema refinement: all combinations parse here, so an incompatible
|
|
37
|
+
* pairing stays a reason code carrying an artifact path rather than an
|
|
38
|
+
* anonymous parse failure.
|
|
39
|
+
*
|
|
40
|
+
* Inlined rather than given a `.meta({ id })`. Two `$defs` sharing an internal
|
|
41
|
+
* path are indistinguishable from a schema path alone, and every branch here
|
|
42
|
+
* carries an `ArtifactReference`, so a `$defs` entry would share def-relative
|
|
43
|
+
* suffixes with `Expression` and `ArtifactReference` and make the published
|
|
44
|
+
* keyword walk's stated no-collision premise false.
|
|
45
|
+
*/
|
|
46
|
+
export const ProbeQualification = z.discriminatedUnion('route', [
|
|
47
|
+
z
|
|
48
|
+
.strictObject({
|
|
49
|
+
route: z.literal('historical'),
|
|
50
|
+
failBeforeEvidence: ArtifactReference.describe('The recorded failure at the parent revision. AD-9 exists because 2 of 18 mined fix commits had a test that already passed at the parent, so this is the half that cannot be assumed.'),
|
|
51
|
+
passAfterEvidence: ArtifactReference,
|
|
52
|
+
fixCommitDigest: Digest.describe('The causally isolated fix boundary AD-9 requires the two evidence records to straddle.'),
|
|
53
|
+
oracleStableAcrossRevisions: z
|
|
54
|
+
.boolean()
|
|
55
|
+
.describe("AD-9 requires the oracle to be stable across both revisions. `false` parses and fails the gate: a route that cannot record its own unmet precondition cannot be audited, and the schema is not where AD-9's admission decision is made."),
|
|
56
|
+
})
|
|
57
|
+
.describe('A historical probe: a defect mined from a real fix boundary, seeded by reverting it.'),
|
|
58
|
+
z
|
|
59
|
+
.strictObject({
|
|
60
|
+
route: z.literal('controlled-mutation'),
|
|
61
|
+
mutationSource: z
|
|
62
|
+
.string()
|
|
63
|
+
.min(1)
|
|
64
|
+
.describe("Where the mutation came from, in the corpus author's own terms. An opaque caller string, unrelated to `Defect.source`'s two-member enum, which records whether the defect is natural or introduced."),
|
|
65
|
+
mutationOperator: z.string().min(1),
|
|
66
|
+
targetArtifact: ArtifactReference,
|
|
67
|
+
expectedObservableFailure: z.string().min(1),
|
|
68
|
+
baselinePassEvidence: ArtifactReference,
|
|
69
|
+
mutatedFailEvidence: ArtifactReference,
|
|
70
|
+
rollbackVerified: z
|
|
71
|
+
.boolean()
|
|
72
|
+
.describe("AD-9's verified rollback or cleanup. `false` parses and fails the gate, for the same reason `oracleStableAcrossRevisions` does."),
|
|
73
|
+
})
|
|
74
|
+
.describe('A controlled mutation: a defect introduced by a named operator against a named artifact.'),
|
|
75
|
+
z
|
|
76
|
+
.strictObject({
|
|
77
|
+
route: z.literal('gameability'),
|
|
78
|
+
degenerateResponse: z
|
|
79
|
+
.string()
|
|
80
|
+
.min(1)
|
|
81
|
+
.describe('The compliant-looking degenerate response, described rather than embedded: AD-8 forbids sealed-case content from entering any artifact.'),
|
|
82
|
+
naiveOracleSatisfiedEvidence: ArtifactReference,
|
|
83
|
+
disciplinedOracleRejectedEvidence: ArtifactReference,
|
|
84
|
+
})
|
|
85
|
+
.describe('A gameability probe: the demonstration that a degenerate response satisfies a naive oracle and is rejected by a disciplined one.'),
|
|
86
|
+
z
|
|
87
|
+
.strictObject({
|
|
88
|
+
route: z.literal('canary'),
|
|
89
|
+
indicts: z
|
|
90
|
+
.enum(['corpus', 'fixture'])
|
|
91
|
+
.describe("AD-9's canary qualifies by demonstrating that non-detection indicts one of these two rather than the contract. Which one it indicts is the demonstration's own result and is recorded rather than left to the reader."),
|
|
92
|
+
nonDetectionEvidence: ArtifactReference,
|
|
93
|
+
})
|
|
94
|
+
.describe('A canary: a probe whose non-detection is evidence about the instrument, never about the contract.'),
|
|
95
|
+
z
|
|
96
|
+
.strictObject({
|
|
97
|
+
route: z.literal('clean-control'),
|
|
98
|
+
baselinePassEvidence: ArtifactReference,
|
|
99
|
+
revisionCommitDigest: Digest,
|
|
100
|
+
noKnownDefectStatement: z
|
|
101
|
+
.string()
|
|
102
|
+
.min(1)
|
|
103
|
+
.describe('AD-9 qualifies a clean control at "a revision with no known defect in the probed interface". No field can prove an absence, so the statement is recorded as an attestation under AD-32 and read as trust rather than as a computed fact.'),
|
|
104
|
+
})
|
|
105
|
+
.describe('A known-clean control: recorded baseline-pass evidence at a revision with no known defect in the probed interface.'),
|
|
106
|
+
]);
|