eval-quality 0.1.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/LICENSE +190 -0
- package/README.md +355 -0
- package/corpus/dev/README.md +36 -0
- package/corpus/dev/compile-seal-example/brief.json +1 -0
- package/corpus/dev/compile-seal-example/contract.json +1 -0
- package/corpus/dev/contracts/absent-collection-locations.json +1 -0
- package/corpus/dev/contracts/absent-sibling-groups.json +1 -0
- package/corpus/dev/contracts/absent-success-indicator.json +1 -0
- package/corpus/dev/contracts/empty-channel-roles.json +1 -0
- package/corpus/dev/contracts/empty-collection-locations.json +1 -0
- package/corpus/dev/contracts/empty-request-shapes.json +1 -0
- package/corpus/dev/contracts/empty-sibling-groups.json +1 -0
- package/corpus/dev/contracts/no-collection-quantifier.json +1 -0
- package/corpus/dev/contracts/no-operation-inventory.json +1 -0
- package/corpus/dev/contracts/no-read-back-relation.json +1 -0
- package/corpus/dev/contracts/no-state-change-marker.json +1 -0
- package/corpus/dev/contracts/no-type-violating-step.json +1 -0
- package/corpus/dev/contracts/per-key-split-oracles.json +1 -0
- package/corpus/dev/contracts/satisfied-declarations.json +1 -0
- package/corpus/dev/contracts/single-required-response-key.json +1 -0
- package/corpus/dev/contracts/split-indicator-oracle.json +1 -0
- package/corpus/dev/contracts/unaddressed-parameter-sibling.json +1 -0
- package/corpus/dev/contracts/unnamed-reference-set.json +1 -0
- package/corpus/dev/contracts/wrong-cardinality-form.json +1 -0
- package/corpus/dev/index.json +1 -0
- package/dist/adapters/index.d.ts +12 -0
- package/dist/adapters/index.js +3 -0
- package/dist/adapters/local-corpus-adapter.d.ts +7 -0
- package/dist/adapters/local-corpus-adapter.js +78 -0
- package/dist/adapters/node-file-system-adapter.d.ts +7 -0
- package/dist/adapters/node-file-system-adapter.js +39 -0
- package/dist/adapters/port-boundary.d.ts +18 -0
- package/dist/adapters/port-boundary.js +83 -0
- package/dist/adapters/system-clock-adapter.d.ts +10 -0
- package/dist/adapters/system-clock-adapter.js +18 -0
- package/dist/application/compile.d.ts +4 -0
- package/dist/application/compile.js +24 -0
- package/dist/application/diagnostics.d.ts +22 -0
- package/dist/application/diagnostics.js +18 -0
- package/dist/application/index.d.ts +23 -0
- package/dist/application/index.js +17 -0
- package/dist/application/invoke-port.d.ts +2 -0
- package/dist/application/invoke-port.js +45 -0
- package/dist/application/preflight.d.ts +27 -0
- package/dist/application/preflight.js +131 -0
- package/dist/application/seal.d.ts +4 -0
- package/dist/application/seal.js +28 -0
- package/dist/application/serialize.d.ts +6 -0
- package/dist/application/serialize.js +9 -0
- package/dist/cli/arguments.d.ts +28 -0
- package/dist/cli/arguments.js +167 -0
- package/dist/cli/exit-codes.d.ts +36 -0
- package/dist/cli/exit-codes.js +39 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +143 -0
- package/dist/cli/render.d.ts +26 -0
- package/dist/cli/render.js +53 -0
- package/dist/cli/run.d.ts +41 -0
- package/dist/cli/run.js +203 -0
- package/dist/core/canonical/canonicalize.d.ts +1 -0
- package/dist/core/canonical/canonicalize.js +113 -0
- package/dist/core/canonical/digest.d.ts +7 -0
- package/dist/core/canonical/digest.js +81 -0
- package/dist/core/canonical/scan-json.d.ts +1 -0
- package/dist/core/canonical/scan-json.js +298 -0
- package/dist/core/canonical/value-domain.d.ts +4 -0
- package/dist/core/canonical/value-domain.js +113 -0
- package/dist/core/compile/compile.d.ts +24 -0
- package/dist/core/compile/compile.js +67 -0
- package/dist/core/compile/declarations.d.ts +5 -0
- package/dist/core/compile/declarations.js +22 -0
- package/dist/core/compile/expression-legality.d.ts +14 -0
- package/dist/core/compile/expression-legality.js +346 -0
- package/dist/core/compile/forbidden-inputs.d.ts +5 -0
- package/dist/core/compile/forbidden-inputs.js +19 -0
- package/dist/core/compile/interface-inventory.d.ts +10 -0
- package/dist/core/compile/interface-inventory.js +55 -0
- package/dist/core/compile/oracle-alignment.d.ts +14 -0
- package/dist/core/compile/oracle-alignment.js +93 -0
- package/dist/core/compile/reachability.d.ts +17 -0
- package/dist/core/compile/reachability.js +177 -0
- package/dist/core/compile/rubrics.d.ts +55 -0
- package/dist/core/compile/rubrics.js +198 -0
- package/dist/core/compile/scripting-bound.d.ts +5 -0
- package/dist/core/compile/scripting-bound.js +151 -0
- package/dist/core/compile/sensitivity-witness.d.ts +73 -0
- package/dist/core/compile/sensitivity-witness.js +232 -0
- package/dist/core/compile/waivers.d.ts +3 -0
- package/dist/core/compile/waivers.js +21 -0
- package/dist/core/coverage/coverage.d.ts +18 -0
- package/dist/core/coverage/coverage.js +47 -0
- package/dist/core/coverage/relevance.d.ts +75 -0
- package/dist/core/coverage/relevance.js +186 -0
- package/dist/core/coverage/rules.d.ts +7 -0
- package/dist/core/coverage/rules.js +18 -0
- package/dist/core/coverage/satisfaction.d.ts +107 -0
- package/dist/core/coverage/satisfaction.js +415 -0
- package/dist/core/coverage/table.d.ts +26 -0
- package/dist/core/coverage/table.js +222 -0
- package/dist/core/declared-inputs.d.ts +16 -0
- package/dist/core/declared-inputs.js +18 -0
- package/dist/core/evaluate/evidence-resolution.d.ts +54 -0
- package/dist/core/evaluate/evidence-resolution.js +153 -0
- package/dist/core/evaluate/operators.d.ts +87 -0
- package/dist/core/evaluate/operators.js +350 -0
- package/dist/core/evaluate/resolution.d.ts +40 -0
- package/dist/core/evaluate/resolution.js +336 -0
- package/dist/core/evaluate/resolved-value.d.ts +9 -0
- package/dist/core/evaluate/resolved-value.js +6 -0
- package/dist/core/failure-codes.d.ts +18 -0
- package/dist/core/failure-codes.js +50 -0
- package/dist/core/lineage/chain.d.ts +49 -0
- package/dist/core/lineage/chain.js +210 -0
- package/dist/core/lineage/freeze.d.ts +12 -0
- package/dist/core/lineage/freeze.js +35 -0
- package/dist/core/lineage/stage-table.d.ts +43 -0
- package/dist/core/lineage/stage-table.js +106 -0
- package/dist/core/preflight/plan.d.ts +67 -0
- package/dist/core/preflight/plan.js +313 -0
- package/dist/core/preflight/projection.d.ts +40 -0
- package/dist/core/preflight/projection.js +96 -0
- package/dist/core/preflight/reduce.d.ts +8 -0
- package/dist/core/preflight/reduce.js +180 -0
- package/dist/core/preflight/witness-evidence.d.ts +42 -0
- package/dist/core/preflight/witness-evidence.js +88 -0
- package/dist/core/probe/target-policy.d.ts +63 -0
- package/dist/core/probe/target-policy.js +328 -0
- package/dist/core/schemas/artifact-reference.d.ts +19 -0
- package/dist/core/schemas/artifact-reference.js +30 -0
- package/dist/core/schemas/artifact.d.ts +1153 -0
- package/dist/core/schemas/artifact.js +84 -0
- package/dist/core/schemas/constraint-ledger.d.ts +57 -0
- package/dist/core/schemas/constraint-ledger.js +143 -0
- package/dist/core/schemas/eval-contract.d.ts +402 -0
- package/dist/core/schemas/eval-contract.js +147 -0
- package/dist/core/schemas/evaluator-configuration.d.ts +37 -0
- package/dist/core/schemas/evaluator-configuration.js +43 -0
- package/dist/core/schemas/evidence-artifact.d.ts +471 -0
- package/dist/core/schemas/evidence-artifact.js +232 -0
- package/dist/core/schemas/expression.d.ts +197 -0
- package/dist/core/schemas/expression.js +284 -0
- package/dist/core/schemas/faults.d.ts +9 -0
- package/dist/core/schemas/faults.js +32 -0
- package/dist/core/schemas/interface.d.ts +417 -0
- package/dist/core/schemas/interface.js +115 -0
- package/dist/core/schemas/isolation-manifest.d.ts +136 -0
- package/dist/core/schemas/isolation-manifest.js +92 -0
- package/dist/core/schemas/lineage.d.ts +21 -0
- package/dist/core/schemas/lineage.js +28 -0
- package/dist/core/schemas/oracle.d.ts +72 -0
- package/dist/core/schemas/oracle.js +35 -0
- package/dist/core/schemas/plan.d.ts +115 -0
- package/dist/core/schemas/plan.js +58 -0
- package/dist/core/schemas/pointer.d.ts +63 -0
- package/dist/core/schemas/pointer.js +94 -0
- package/dist/core/schemas/port-messages.d.ts +103 -0
- package/dist/core/schemas/port-messages.js +90 -0
- package/dist/core/schemas/preflight-verdict.d.ts +60 -0
- package/dist/core/schemas/preflight-verdict.js +38 -0
- package/dist/core/schemas/primitives.d.ts +78 -0
- package/dist/core/schemas/primitives.js +121 -0
- package/dist/core/schemas/private-artifact-manifest.d.ts +56 -0
- package/dist/core/schemas/private-artifact-manifest.js +46 -0
- package/dist/core/schemas/probe-body.d.ts +25 -0
- package/dist/core/schemas/probe-body.js +23 -0
- package/dist/core/schemas/probe-policy.d.ts +76 -0
- package/dist/core/schemas/probe-policy.js +33 -0
- package/dist/core/schemas/probe.d.ts +189 -0
- package/dist/core/schemas/probe.js +82 -0
- package/dist/core/schemas/publish.d.ts +30 -0
- package/dist/core/schemas/publish.js +135 -0
- package/dist/core/schemas/reference-set.d.ts +18 -0
- package/dist/core/schemas/reference-set.js +27 -0
- package/dist/core/schemas/rubric.d.ts +62 -0
- package/dist/core/schemas/rubric.js +68 -0
- package/dist/core/schemas/scoring-policy.d.ts +28 -0
- package/dist/core/schemas/scoring-policy.js +51 -0
- package/dist/core/schemas/sealed-evaluator-brief.d.ts +80 -0
- package/dist/core/schemas/sealed-evaluator-brief.js +59 -0
- package/dist/core/schemas/sealed-run-record.d.ts +382 -0
- package/dist/core/schemas/sealed-run-record.js +215 -0
- package/dist/core/schemas/sensitivity-witness.d.ts +138 -0
- package/dist/core/schemas/sensitivity-witness.js +86 -0
- package/dist/core/schemas/verdict.d.ts +25 -0
- package/dist/core/schemas/verdict.js +20 -0
- package/dist/core/schemas/waiver.d.ts +17 -0
- package/dist/core/schemas/waiver.js +24 -0
- package/dist/core/seal/derived-reference.d.ts +36 -0
- package/dist/core/seal/derived-reference.js +383 -0
- package/dist/core/seal/direction-prose.d.ts +13 -0
- package/dist/core/seal/direction-prose.js +120 -0
- package/dist/core/seal/plan-index.d.ts +63 -0
- package/dist/core/seal/plan-index.js +155 -0
- package/dist/core/seal/scripting-audit.d.ts +15 -0
- package/dist/core/seal/scripting-audit.js +51 -0
- package/dist/core/seal/seal.d.ts +18 -0
- package/dist/core/seal/seal.js +155 -0
- package/dist/core/stage-contracts.d.ts +30 -0
- package/dist/core/stage-contracts.js +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +22 -0
- package/dist/ports/clock-port.d.ts +13 -0
- package/dist/ports/clock-port.js +7 -0
- package/dist/ports/corpus-port.d.ts +16 -0
- package/dist/ports/corpus-port.js +7 -0
- package/dist/ports/environment-probe-port.d.ts +76 -0
- package/dist/ports/environment-probe-port.js +32 -0
- package/dist/ports/file-system-port.d.ts +27 -0
- package/dist/ports/file-system-port.js +11 -0
- package/dist/ports/port.d.ts +33 -0
- package/dist/ports/port.js +14 -0
- package/dist/testing/conformance.d.ts +88 -0
- package/dist/testing/conformance.js +281 -0
- package/dist/testing/index.d.ts +26 -0
- package/dist/testing/index.js +18 -0
- package/dist/testing/probe-conformance.d.ts +45 -0
- package/dist/testing/probe-conformance.js +186 -0
- package/package.json +130 -0
- package/schemas/artifact-reference.schema.json +64 -0
- package/schemas/eval-contract.schema.json +2145 -0
- package/schemas/evaluator-configuration.schema.json +199 -0
- package/schemas/evidence-artifact.schema.json +1229 -0
- package/schemas/isolation-manifest.schema.json +394 -0
- package/schemas/preflight-verdict.schema.json +114 -0
- package/schemas/private-artifact-manifest.schema.json +103 -0
- package/schemas/probe.schema.json +1151 -0
- package/schemas/rubric.schema.json +148 -0
- package/schemas/scoring-policy.schema.json +90 -0
- package/schemas/sealed-evaluator-brief.schema.json +268 -0
- package/schemas/sealed-run-record.schema.json +875 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/** the per-run isolation audit, and the forbidden-input accounting AD-16 adds. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { FORBIDDEN_INPUT_FLOOR } from './eval-contract.js';
|
|
4
|
+
import { lineageFields } from './lineage.js';
|
|
5
|
+
import { Digest, Identifier, PositiveDecimalString, UnsignedDecimalString, } from './primitives.js';
|
|
6
|
+
/**
|
|
7
|
+
* The harness's record of what it actually enforced, deliberately not
|
|
8
|
+
* `Budgets`: `Budgets` is the contract's three-key declared ceiling that AD-16
|
|
9
|
+
* puts on the brief so the caller knows what it may spend, while this carries
|
|
10
|
+
* the two token counts the contract never declares. One shape for both would
|
|
11
|
+
* conflate a declaration with an observation.
|
|
12
|
+
*/
|
|
13
|
+
export const ResourceCeilings = z.strictObject({
|
|
14
|
+
maxToolCalls: z.int().min(1),
|
|
15
|
+
maxInputTokens: z.int().min(1),
|
|
16
|
+
maxOutputTokens: z.int().min(1),
|
|
17
|
+
maxWallClockMinutes: z
|
|
18
|
+
.number()
|
|
19
|
+
.gt(0)
|
|
20
|
+
.describe("The prior art's `exclusiveMinimum: 0`, kept. A ceiling of zero minutes is not a ceiling, it is a run that may not happen, and the manifest records what the harness actually enforced."),
|
|
21
|
+
maxCostUsd: PositiveDecimalString.describe("Money, so AD-36 carries it as a string. The prior art's number does not survive; an AD-24 divergence, and the reason AD-36's exact-decimal rule reaches the manifest as well as the run record. The retyping keeps the prior art's `exclusiveMinimum: 0` rather than dropping it: `UnsignedDecimalString` would admit \"0\", which is the bound the prior art spent a keyword excluding."),
|
|
22
|
+
});
|
|
23
|
+
/** the prior art's five-member actual-use record, with money as a string. */
|
|
24
|
+
export const ActualResourceUse = z.strictObject({
|
|
25
|
+
toolCalls: z.int().min(0),
|
|
26
|
+
inputTokens: z.int().min(0),
|
|
27
|
+
outputTokens: z.int().min(0),
|
|
28
|
+
wallClockSeconds: z.number().min(0),
|
|
29
|
+
costUsd: UnsignedDecimalString,
|
|
30
|
+
});
|
|
31
|
+
/**
|
|
32
|
+
* AD-16 requires the manifest to "account for each forbidden input by name".
|
|
33
|
+
* `withheld: false` must parse: a prohibited input is an invalidating condition
|
|
34
|
+
* at ingest, never a parse failure.
|
|
35
|
+
*/
|
|
36
|
+
export const ForbiddenInputAccounting = z.strictObject({
|
|
37
|
+
withheld: z.boolean(),
|
|
38
|
+
note: z.string().nullable(),
|
|
39
|
+
});
|
|
40
|
+
// Generated from FORBIDDEN_INPUT_FLOOR, the same reason the constraint ledger
|
|
41
|
+
// generates its arity entries from TUPLE_ARITY: a hand-written second list is
|
|
42
|
+
// drift waiting to happen, and AD-16 makes an incomplete floor a coded
|
|
43
|
+
// compile-time failure because the list has one home.
|
|
44
|
+
//
|
|
45
|
+
// Declared after the shape it references and cast so the seven literal keys
|
|
46
|
+
// survive into `z.infer`: `Object.fromEntries` alone widens to an index
|
|
47
|
+
// signature, which would stop a typed accept fixture from catching a missing
|
|
48
|
+
// member.
|
|
49
|
+
const accountingShape = Object.fromEntries(FORBIDDEN_INPUT_FLOOR.map((member) => [member, ForbiddenInputAccounting]));
|
|
50
|
+
/**
|
|
51
|
+
* A strict object rather than `z.record(ForbiddenInput, …)`: the record does
|
|
52
|
+
* demand every enum member at parse time, but only as TypeScript behaviour.
|
|
53
|
+
* Its export carries `propertyNames` plus a schema-valued
|
|
54
|
+
* `additionalProperties` but never a `required` array, so the constraint
|
|
55
|
+
* would be invisible to the non-TypeScript consumer AD-13 protects, the same
|
|
56
|
+
* reasoning behind `RequestShape`'s four-key object.
|
|
57
|
+
*/
|
|
58
|
+
export const ForbiddenInputAccountingMap = z.strictObject(accountingShape);
|
|
59
|
+
export const IsolationManifest = z
|
|
60
|
+
.strictObject({
|
|
61
|
+
...lineageFields,
|
|
62
|
+
runId: z.string().min(1),
|
|
63
|
+
contractId: Identifier.describe('The prior art\'s `taskId`, renamed. "Task" is experiment vocabulary with no product meaning, and the manifest keeps an identifier because it is the artifact `core/ingest` matches against a run; the run record and the probe pin what they describe by digest instead.'),
|
|
64
|
+
conditionArm: z
|
|
65
|
+
.string()
|
|
66
|
+
.min(1)
|
|
67
|
+
.describe("An opaque caller label with no product semantics, per AD-24. The prior art's three-member enum does not survive, on the same reasoning as the run record's."),
|
|
68
|
+
modelSnapshot: z.string().min(1),
|
|
69
|
+
systemPromptDigest: Digest,
|
|
70
|
+
contractDigest: Digest,
|
|
71
|
+
evaluatorConfigurationDigest: Digest.describe('Added here and absent from the prior art. AD-32 requires this digest to agree between the manifest and the run record, which was previously an agreement rule asserted over two fields that did not exist. Required and non-nullable on both, which is what makes the substitution cost two contradictions rather than one omission. The agreement itself is a cross-artifact rule no schema can see.'),
|
|
72
|
+
workspaceIdentity: z.string().min(1),
|
|
73
|
+
allowedMounts: z.array(z.string()),
|
|
74
|
+
observedMounts: z
|
|
75
|
+
.array(z.string())
|
|
76
|
+
.describe('Observed mounts, network targets, and tool calls exceeding their allowlist is a violation AD-16 has `core/ingest` record; it is a cross-field rule with no AD-5 code and the schema admits it.'),
|
|
77
|
+
networkAllowlist: z.array(z.string()),
|
|
78
|
+
observedNetworkTargets: z.array(z.string()),
|
|
79
|
+
toolAllowlist: z.array(z.string()),
|
|
80
|
+
observedToolCalls: z.array(z.string()),
|
|
81
|
+
resourceCeilings: ResourceCeilings,
|
|
82
|
+
actualResourceUse: ActualResourceUse,
|
|
83
|
+
forbiddenInputAccounting: ForbiddenInputAccountingMap.describe('The field AD-16 adds and the prior art lacks: "the isolation manifest\'s required fields … account for each forbidden input by name". Seven keys, generated from `FORBIDDEN_INPUT_FLOOR` so the floor has one home.'),
|
|
84
|
+
violation: z
|
|
85
|
+
.string()
|
|
86
|
+
.nullable()
|
|
87
|
+
.describe("The sixteenth of the prior art's sixteen required members, and the one that is not a description of the run: a non-null violation invalidates it. AD-16 says the schema is \"seeded from the prior art's fifteen\"; the prior art's `required` array has sixteen. Settled by construction: the fifteen are the fields describing the run and this is the invalidation outcome. All sixteen are carried."),
|
|
88
|
+
})
|
|
89
|
+
.meta({
|
|
90
|
+
id: 'IsolationManifest',
|
|
91
|
+
description: "The per-run isolation audit. Succeeds the prior-art `isolation-manifest` schema per AD-24, carrying all sixteen of its required members plus `evaluatorConfigurationDigest`, `forbiddenInputAccounting`, and AD-29's lineage; `taskId` becomes `contractId`, `condition` is demoted to an opaque `conditionArm`, and money in both resource shapes becomes a decimal string. An absent, unparseable, incomplete, or violating manifest invalidates the run under AD-16 and never downgrades a verdict; a schema rejection is the correct expression of unparseable and incomplete, so nothing is admitted for their sake, and the violating case is `core/ingest`'s.",
|
|
92
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** AD-11's schema version and AD-29's lineage pair, spelled once. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* The three fields every lineage-bearing artifact carries, lifted here so
|
|
5
|
+
* eleven artifacts spread it instead of respelling it (the drift the
|
|
6
|
+
* Consistency Conventions warn against).
|
|
7
|
+
*
|
|
8
|
+
* This module imports only zod and primitives.ts: `artifact.ts` imports all
|
|
9
|
+
* twelve schema modules including this one, so importing `artifact.ts` back
|
|
10
|
+
* from here would close a circular import.
|
|
11
|
+
*
|
|
12
|
+
* Spread rather than nested, so `EvalContract`'s shape and the reject
|
|
13
|
+
* fixtures naming `['schemaVersion']`/`['parentDigest']` stay unchanged; the
|
|
14
|
+
* two discriminated-union artifacts (`Probe`, `EvidenceArtifact`) spread it
|
|
15
|
+
* inside every branch instead, since a union has no root property bag.
|
|
16
|
+
*/
|
|
17
|
+
export declare const lineageFields: {
|
|
18
|
+
schemaVersion: z.ZodInt;
|
|
19
|
+
parentDigest: z.ZodNullable<z.ZodString>;
|
|
20
|
+
revisionCount: z.ZodInt;
|
|
21
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** AD-11's schema version and AD-29's lineage pair, spelled once. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { Digest } from './primitives.js';
|
|
4
|
+
/**
|
|
5
|
+
* The three fields every lineage-bearing artifact carries, lifted here so
|
|
6
|
+
* eleven artifacts spread it instead of respelling it (the drift the
|
|
7
|
+
* Consistency Conventions warn against).
|
|
8
|
+
*
|
|
9
|
+
* This module imports only zod and primitives.ts: `artifact.ts` imports all
|
|
10
|
+
* twelve schema modules including this one, so importing `artifact.ts` back
|
|
11
|
+
* from here would close a circular import.
|
|
12
|
+
*
|
|
13
|
+
* Spread rather than nested, so `EvalContract`'s shape and the reject
|
|
14
|
+
* fixtures naming `['schemaVersion']`/`['parentDigest']` stay unchanged; the
|
|
15
|
+
* two discriminated-union artifacts (`Probe`, `EvidenceArtifact`) spread it
|
|
16
|
+
* inside every branch instead, since a union has no root property bag.
|
|
17
|
+
*/
|
|
18
|
+
export const lineageFields = {
|
|
19
|
+
schemaVersion: z
|
|
20
|
+
.int()
|
|
21
|
+
.min(1)
|
|
22
|
+
.describe('AD-11 requires an integer under this exact name. Deliberately not `z.literal(1)`: the literal exports as `{"type":"number","const":1}`, losing `integer` for a non-TypeScript consumer, and it would turn a version-2 artifact into an anonymous schema-parse failure instead of AD-28\'s dedicated `schema-version-mismatch` fault. Version equality belongs to the reader that throws that fault.'),
|
|
23
|
+
parentDigest: Digest.nullable().describe('AD-29 lineage. `null` if and only if `revisionCount` is 0. That biconditional is stated here rather than refined: a refinement is silently dropped from the published schema, so a non-TypeScript consumer would never see it, and the constraint ledger records it as not expressible.'),
|
|
24
|
+
revisionCount: z
|
|
25
|
+
.int()
|
|
26
|
+
.min(0)
|
|
27
|
+
.describe("AD-29: one greater than the parent artifact's."),
|
|
28
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** an oracle: a structured direction and an enforceable check. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { Expression } from './expression.ts';
|
|
4
|
+
/**
|
|
5
|
+
* AD-3's five direction fields: the channel the sealed evaluator reads,
|
|
6
|
+
* generated into prose by `seal`. Structured rather than free prose because
|
|
7
|
+
* alignment against `check` is a computation over two declared structures.
|
|
8
|
+
*/
|
|
9
|
+
export declare const Direction: z.ZodObject<{
|
|
10
|
+
evidenceTargets: z.ZodArray<z.ZodString>;
|
|
11
|
+
relation: z.ZodEnum<{
|
|
12
|
+
absence: "absence";
|
|
13
|
+
all: "all";
|
|
14
|
+
any: "any";
|
|
15
|
+
containment: "containment";
|
|
16
|
+
"count-tolerance": "count-tolerance";
|
|
17
|
+
"covers-by-key": "covers-by-key";
|
|
18
|
+
"deep-equality": "deep-equality";
|
|
19
|
+
equality: "equality";
|
|
20
|
+
existence: "existence";
|
|
21
|
+
"for-all": "for-all";
|
|
22
|
+
"for-any": "for-any";
|
|
23
|
+
not: "not";
|
|
24
|
+
ordering: "ordering";
|
|
25
|
+
regex: "regex";
|
|
26
|
+
"set-membership": "set-membership";
|
|
27
|
+
shape: "shape";
|
|
28
|
+
}>;
|
|
29
|
+
polarity: z.ZodEnum<{
|
|
30
|
+
"expects-hold": "expects-hold";
|
|
31
|
+
"expects-violation": "expects-violation";
|
|
32
|
+
}>;
|
|
33
|
+
scope: z.ZodNullable<z.ZodString>;
|
|
34
|
+
negativeDomain: z.ZodNullable<z.ZodString>;
|
|
35
|
+
}, z.core.$strict>;
|
|
36
|
+
export type Direction = z.infer<typeof Direction>;
|
|
37
|
+
export declare const Oracle: z.ZodObject<{
|
|
38
|
+
id: z.ZodString;
|
|
39
|
+
direction: z.ZodNullable<z.ZodObject<{
|
|
40
|
+
evidenceTargets: z.ZodArray<z.ZodString>;
|
|
41
|
+
relation: z.ZodEnum<{
|
|
42
|
+
absence: "absence";
|
|
43
|
+
all: "all";
|
|
44
|
+
any: "any";
|
|
45
|
+
containment: "containment";
|
|
46
|
+
"count-tolerance": "count-tolerance";
|
|
47
|
+
"covers-by-key": "covers-by-key";
|
|
48
|
+
"deep-equality": "deep-equality";
|
|
49
|
+
equality: "equality";
|
|
50
|
+
existence: "existence";
|
|
51
|
+
"for-all": "for-all";
|
|
52
|
+
"for-any": "for-any";
|
|
53
|
+
not: "not";
|
|
54
|
+
ordering: "ordering";
|
|
55
|
+
regex: "regex";
|
|
56
|
+
"set-membership": "set-membership";
|
|
57
|
+
shape: "shape";
|
|
58
|
+
}>;
|
|
59
|
+
polarity: z.ZodEnum<{
|
|
60
|
+
"expects-hold": "expects-hold";
|
|
61
|
+
"expects-violation": "expects-violation";
|
|
62
|
+
}>;
|
|
63
|
+
scope: z.ZodNullable<z.ZodString>;
|
|
64
|
+
negativeDomain: z.ZodNullable<z.ZodString>;
|
|
65
|
+
}, z.core.$strict>>;
|
|
66
|
+
check: z.ZodNullable<z.ZodType<Expression, unknown, z.core.$ZodTypeInternals<Expression, unknown>>>;
|
|
67
|
+
polarity: z.ZodEnum<{
|
|
68
|
+
"expects-hold": "expects-hold";
|
|
69
|
+
"expects-violation": "expects-violation";
|
|
70
|
+
}>;
|
|
71
|
+
commentary: z.ZodNullable<z.ZodString>;
|
|
72
|
+
}, z.core.$strict>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** an oracle: a structured direction and an enforceable check. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { Expression, Polarity, Relation } from './expression.js';
|
|
4
|
+
import { InteractionPointer } from './pointer.js';
|
|
5
|
+
import { OracleId } from './primitives.js';
|
|
6
|
+
/**
|
|
7
|
+
* AD-3's five direction fields: the channel the sealed evaluator reads,
|
|
8
|
+
* generated into prose by `seal`. Structured rather than free prose because
|
|
9
|
+
* alignment against `check` is a computation over two declared structures.
|
|
10
|
+
*/
|
|
11
|
+
export const Direction = z.strictObject({
|
|
12
|
+
evidenceTargets: z
|
|
13
|
+
.array(InteractionPointer)
|
|
14
|
+
.describe('Interaction-rooted pointers only. AD-3 computes containment after quantifier substitution, so a target is always fully rooted and the bound-element spelling never appears here.'),
|
|
15
|
+
relation: Relation.describe("Drawn from AD-4's full sixteen-member vocabulary — eleven operators, three connectives, two quantifiers — not the operators alone."),
|
|
16
|
+
polarity: Polarity.describe('Coin flip (a), settled: polarity is declared twice, here and on the oracle. AD-3 names it as one of the three axes the alignment predicate binds and AD-33 gives every check one, so declaring it once makes the alignment predicate vacuous on a third of its content. Duplication is what makes drift detectable, and the drift is deliberately not refined away: `direction-check-misaligned` needs the disagreement to stay representable.'),
|
|
17
|
+
scope: z
|
|
18
|
+
.string()
|
|
19
|
+
.nullable()
|
|
20
|
+
.describe('Evaluator-facing, and exempt from the alignment predicate, which binds evidence targets, relation, and polarity only.'),
|
|
21
|
+
negativeDomain: z
|
|
22
|
+
.string()
|
|
23
|
+
.nullable()
|
|
24
|
+
.describe('Evaluator-facing and exempt from alignment. `seal` renders it as an unordered set so the brief is byte-identical under reordering.'),
|
|
25
|
+
});
|
|
26
|
+
export const Oracle = z.strictObject({
|
|
27
|
+
id: OracleId,
|
|
28
|
+
direction: Direction.nullable().describe('`null` is half of what `oracle-missing-channel` fires on, so it must parse.'),
|
|
29
|
+
check: Expression.nullable().describe('`null` is the other half of `oracle-missing-channel`.'),
|
|
30
|
+
polarity: Polarity.describe('AD-33: every check declares one polarity, and it lives at oracle level rather than inside the expression tree. Required and explicit rather than defaulted to `expects-hold`: a Zod default diverges input and output mode and the explicit-null convention forbids implicit absence.'),
|
|
31
|
+
commentary: z
|
|
32
|
+
.string()
|
|
33
|
+
.nullable()
|
|
34
|
+
.describe("AD-3's author documentation. No predicate reads it and `seal` never emits it, because a channel the evaluator reads and no predicate audits is the free-prose channel AD-3 exists to close."),
|
|
35
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/** the interaction plan: steps as selectors over observations. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { JsonValue } from './primitives.ts';
|
|
4
|
+
/**
|
|
5
|
+
* AD-39: input-binding values are tagged and never share a value space. The
|
|
6
|
+
* untagged spelling let `{ "title": "type-violating" }` mean the matcher to
|
|
7
|
+
* one implementation and the literal string to another, and flipped a witness
|
|
8
|
+
* match between `caught` and `missed` on one record; that form is
|
|
9
|
+
* unrepresentable here.
|
|
10
|
+
*/
|
|
11
|
+
export declare const BindingValue: z.ZodUnion<readonly [z.ZodObject<{
|
|
12
|
+
literal: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
13
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
14
|
+
matcher: z.ZodEnum<{
|
|
15
|
+
any: "any";
|
|
16
|
+
"type-violating": "type-violating";
|
|
17
|
+
}>;
|
|
18
|
+
}, z.core.$strict>]>;
|
|
19
|
+
/** the constraint identifier the ledger carries for the check below. */
|
|
20
|
+
export declare const BINDING_CHANNEL_NON_EMPTY = "binding-channel-non-empty";
|
|
21
|
+
export declare const BindingChannel: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
22
|
+
literal: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
23
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
24
|
+
matcher: z.ZodEnum<{
|
|
25
|
+
any: "any";
|
|
26
|
+
"type-violating": "type-violating";
|
|
27
|
+
}>;
|
|
28
|
+
}, z.core.$strict>]>>>;
|
|
29
|
+
/**
|
|
30
|
+
* A four-key strict object with each channel nullable, not a record over the
|
|
31
|
+
* channel enum. Verified on the pin: a record over a four-member enum key
|
|
32
|
+
* requires every member at parse time and fails five of the Gate C fixture's
|
|
33
|
+
* six steps, all of which bind a subset of the channels.
|
|
34
|
+
*/
|
|
35
|
+
export declare const InputBinding: z.ZodObject<{
|
|
36
|
+
path: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
37
|
+
literal: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
38
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
39
|
+
matcher: z.ZodEnum<{
|
|
40
|
+
any: "any";
|
|
41
|
+
"type-violating": "type-violating";
|
|
42
|
+
}>;
|
|
43
|
+
}, z.core.$strict>]>>>;
|
|
44
|
+
query: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
45
|
+
literal: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
46
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
47
|
+
matcher: z.ZodEnum<{
|
|
48
|
+
any: "any";
|
|
49
|
+
"type-violating": "type-violating";
|
|
50
|
+
}>;
|
|
51
|
+
}, z.core.$strict>]>>>;
|
|
52
|
+
header: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
53
|
+
literal: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
54
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
55
|
+
matcher: z.ZodEnum<{
|
|
56
|
+
any: "any";
|
|
57
|
+
"type-violating": "type-violating";
|
|
58
|
+
}>;
|
|
59
|
+
}, z.core.$strict>]>>>;
|
|
60
|
+
body: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
61
|
+
literal: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
62
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
63
|
+
matcher: z.ZodEnum<{
|
|
64
|
+
any: "any";
|
|
65
|
+
"type-violating": "type-violating";
|
|
66
|
+
}>;
|
|
67
|
+
}, z.core.$strict>]>>>;
|
|
68
|
+
}, z.core.$strict>;
|
|
69
|
+
/**
|
|
70
|
+
* AD-39: a step is a selector over observations the evaluator produced, never
|
|
71
|
+
* an instruction. Its selection predicate is spelled as its two members, the
|
|
72
|
+
* input binding and the temporal clause, directly on the step itself,
|
|
73
|
+
* matching the only hand-authored contract rather than nesting them under a
|
|
74
|
+
* further key.
|
|
75
|
+
*/
|
|
76
|
+
export declare const InteractionStep: z.ZodObject<{
|
|
77
|
+
stepId: z.ZodString;
|
|
78
|
+
operationId: z.ZodString;
|
|
79
|
+
inputBinding: z.ZodObject<{
|
|
80
|
+
path: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
81
|
+
literal: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
82
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
83
|
+
matcher: z.ZodEnum<{
|
|
84
|
+
any: "any";
|
|
85
|
+
"type-violating": "type-violating";
|
|
86
|
+
}>;
|
|
87
|
+
}, z.core.$strict>]>>>;
|
|
88
|
+
query: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
89
|
+
literal: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
90
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
91
|
+
matcher: z.ZodEnum<{
|
|
92
|
+
any: "any";
|
|
93
|
+
"type-violating": "type-violating";
|
|
94
|
+
}>;
|
|
95
|
+
}, z.core.$strict>]>>>;
|
|
96
|
+
header: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
97
|
+
literal: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
98
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
99
|
+
matcher: z.ZodEnum<{
|
|
100
|
+
any: "any";
|
|
101
|
+
"type-violating": "type-violating";
|
|
102
|
+
}>;
|
|
103
|
+
}, z.core.$strict>]>>>;
|
|
104
|
+
body: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
105
|
+
literal: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
106
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
107
|
+
matcher: z.ZodEnum<{
|
|
108
|
+
any: "any";
|
|
109
|
+
"type-violating": "type-violating";
|
|
110
|
+
}>;
|
|
111
|
+
}, z.core.$strict>]>>>;
|
|
112
|
+
}, z.core.$strict>;
|
|
113
|
+
after: z.ZodNullable<z.ZodString>;
|
|
114
|
+
}, z.core.$strict>;
|
|
115
|
+
export type InteractionStep = z.infer<typeof InteractionStep>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** the interaction plan: steps as selectors over observations. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { Identifier, JsonValue, KeyName } from './primitives.js';
|
|
4
|
+
/**
|
|
5
|
+
* AD-39: input-binding values are tagged and never share a value space. The
|
|
6
|
+
* untagged spelling let `{ "title": "type-violating" }` mean the matcher to
|
|
7
|
+
* one implementation and the literal string to another, and flipped a witness
|
|
8
|
+
* match between `caught` and `missed` on one record; that form is
|
|
9
|
+
* unrepresentable here.
|
|
10
|
+
*/
|
|
11
|
+
export const BindingValue = z.union([
|
|
12
|
+
z.strictObject({ literal: JsonValue }),
|
|
13
|
+
z.strictObject({ matcher: z.enum(['any', 'type-violating']) }),
|
|
14
|
+
]);
|
|
15
|
+
/** the constraint identifier the ledger carries for the check below. */
|
|
16
|
+
export const BINDING_CHANNEL_NON_EMPTY = 'binding-channel-non-empty';
|
|
17
|
+
// Caller-keyed: the keys are the author's own parameter names. `{}` is
|
|
18
|
+
// rejected because a binding channel has exactly one spelling for "binds
|
|
19
|
+
// nothing" (`null`), unlike a request-shape channel's empty triple, which
|
|
20
|
+
// means "declared, no keys." No AD-5 code fires on an empty binding map, so
|
|
21
|
+
// the schema is the enforcement point, under the admit-rule's second clause.
|
|
22
|
+
const BindingChannelMap = z
|
|
23
|
+
.record(KeyName, BindingValue)
|
|
24
|
+
.refine((entries) => Object.keys(entries).length > 0, {
|
|
25
|
+
error: 'an input-binding channel names at least one parameter; an unbound channel is null',
|
|
26
|
+
});
|
|
27
|
+
// Named so the constraint ledger has one stable address for the non-empty
|
|
28
|
+
// check rather than a path through four sibling channels, and so the export
|
|
29
|
+
// injects `minProperties` once on the shared definition.
|
|
30
|
+
export const BindingChannel = BindingChannelMap.nullable().meta({
|
|
31
|
+
id: 'InputBindingChannel',
|
|
32
|
+
description: 'A parameter-name-to-binding-value map, or `null` for a channel this step binds nothing in. An empty map is rejected: `null` is the only spelling for unbound. That rejection is a Zod check and does not survive the export, so the constraint ledger carries it for injection on the object branch.',
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* A four-key strict object with each channel nullable, not a record over the
|
|
36
|
+
* channel enum. Verified on the pin: a record over a four-member enum key
|
|
37
|
+
* requires every member at parse time and fails five of the Gate C fixture's
|
|
38
|
+
* six steps, all of which bind a subset of the channels.
|
|
39
|
+
*/
|
|
40
|
+
export const InputBinding = z.strictObject({
|
|
41
|
+
path: BindingChannel,
|
|
42
|
+
query: BindingChannel,
|
|
43
|
+
header: BindingChannel,
|
|
44
|
+
body: BindingChannel,
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* AD-39: a step is a selector over observations the evaluator produced, never
|
|
48
|
+
* an instruction. Its selection predicate is spelled as its two members, the
|
|
49
|
+
* input binding and the temporal clause, directly on the step itself,
|
|
50
|
+
* matching the only hand-authored contract rather than nesting them under a
|
|
51
|
+
* further key.
|
|
52
|
+
*/
|
|
53
|
+
export const InteractionStep = z.strictObject({
|
|
54
|
+
stepId: Identifier,
|
|
55
|
+
operationId: Identifier,
|
|
56
|
+
inputBinding: InputBinding,
|
|
57
|
+
after: Identifier.nullable().describe("The temporal clause: the identifier of an earlier step, or `null`. That the named step carries no clause of its own is AD-39's one-level bound, which fires `nested-temporal-clause` at compile time and is deliberately not enforced here, so the code keeps a shape to fire on."),
|
|
58
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** the three pointer spellings and the consumers each is assigned to. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* AD-26's closed channel vocabulary, in AD-26's own order: order matters
|
|
5
|
+
* because enum order lands in the export, and the published-schema drift
|
|
6
|
+
* check pins whatever ships. These were once private regex fragments; they
|
|
7
|
+
* are exported here because the Sealed Run Record's quoted evidence needs to
|
|
8
|
+
* name a channel by one shared spelling.
|
|
9
|
+
*/
|
|
10
|
+
export declare const EVIDENCE_CHANNELS: readonly ['response-body', 'response-headers', 'response-status', 'call-inputs', 'stdout', 'stderr', 'exit-code'];
|
|
11
|
+
export type EvidenceChannelName = (typeof EVIDENCE_CHANNELS)[number];
|
|
12
|
+
export declare const EvidenceChannel: z.ZodEnum<{
|
|
13
|
+
"call-inputs": "call-inputs";
|
|
14
|
+
"exit-code": "exit-code";
|
|
15
|
+
"response-body": "response-body";
|
|
16
|
+
"response-headers": "response-headers";
|
|
17
|
+
"response-status": "response-status";
|
|
18
|
+
stderr: "stderr";
|
|
19
|
+
stdout: "stdout";
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* AD-19's four transport channels. `call-inputs` alone has no declared
|
|
23
|
+
* structure to resolve against (the defect AD-26 revision 3 records), so a
|
|
24
|
+
* transport channel is mandatory immediately after it.
|
|
25
|
+
*/
|
|
26
|
+
export declare const TRANSPORT_CHANNELS: readonly ['path', 'query', 'header', 'body'];
|
|
27
|
+
export type TransportChannelName = (typeof TRANSPORT_CHANNELS)[number];
|
|
28
|
+
export declare const TransportChannel: z.ZodEnum<{
|
|
29
|
+
body: "body";
|
|
30
|
+
header: "header";
|
|
31
|
+
path: "path";
|
|
32
|
+
query: "query";
|
|
33
|
+
}>;
|
|
34
|
+
export declare const TAIL_BEARING_CHANNELS: readonly ["response-body", "response-headers", "stdout", "stderr"];
|
|
35
|
+
export declare const SCALAR_CHANNELS: readonly ["response-status", "exit-code"];
|
|
36
|
+
export declare const TRANSPORT_ROOTED_CHANNEL: "call-inputs";
|
|
37
|
+
export declare const INTERACTION_POINTER_PATTERN: RegExp;
|
|
38
|
+
export declare const BOUND_ELEMENT_POINTER_PATTERN: RegExp;
|
|
39
|
+
export declare const DESCRIPTOR_POINTER_PATTERN: RegExp;
|
|
40
|
+
/**
|
|
41
|
+
* Spelling 1, interaction-rooted. Consumers: `{ pointer }` operands, a
|
|
42
|
+
* direction's evidence targets, and a rubric criterion's evidence.
|
|
43
|
+
*/
|
|
44
|
+
export declare const InteractionPointer: z.ZodString;
|
|
45
|
+
/**
|
|
46
|
+
* Spelling 2, bound-element relative. Consumer: a `{ pointer }` operand inside
|
|
47
|
+
* a quantifier predicate. Never an evidence target, because AD-3 computes
|
|
48
|
+
* containment after quantifier substitution, by which point every target is
|
|
49
|
+
* fully rooted.
|
|
50
|
+
*/
|
|
51
|
+
export declare const BoundElementPointer: z.ZodString;
|
|
52
|
+
/**
|
|
53
|
+
* Spelling 3, descriptor-relative. Consumers: a nominated success indicator,
|
|
54
|
+
* every channel-role key, a collection location's pointer, and volatile
|
|
55
|
+
* pointers. Gate C authoring point 7 fixed this spelling's scope and never gave
|
|
56
|
+
* it a syntax; this is the syntax.
|
|
57
|
+
*/
|
|
58
|
+
export declare const DescriptorPointer: z.ZodString;
|
|
59
|
+
/**
|
|
60
|
+
* The pointer form an operand may carry: rooted at an interaction, or relative
|
|
61
|
+
* to a quantifier's bound element.
|
|
62
|
+
*/
|
|
63
|
+
export declare const EvidencePointer: z.ZodUnion<readonly [z.ZodString, z.ZodString]>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** the three pointer spellings and the consumers each is assigned to. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { IDENTIFIER_CHARSET_SOURCE } from './primitives.js';
|
|
4
|
+
/**
|
|
5
|
+
* AD-26's closed channel vocabulary, in AD-26's own order: order matters
|
|
6
|
+
* because enum order lands in the export, and the published-schema drift
|
|
7
|
+
* check pins whatever ships. These were once private regex fragments; they
|
|
8
|
+
* are exported here because the Sealed Run Record's quoted evidence needs to
|
|
9
|
+
* name a channel by one shared spelling.
|
|
10
|
+
*/
|
|
11
|
+
export const EVIDENCE_CHANNELS = [
|
|
12
|
+
'response-body',
|
|
13
|
+
'response-headers',
|
|
14
|
+
'response-status',
|
|
15
|
+
'call-inputs',
|
|
16
|
+
'stdout',
|
|
17
|
+
'stderr',
|
|
18
|
+
'exit-code',
|
|
19
|
+
];
|
|
20
|
+
export const EvidenceChannel = z.enum(EVIDENCE_CHANNELS).meta({
|
|
21
|
+
id: 'EvidenceChannel',
|
|
22
|
+
description: "AD-26's closed evidence channel vocabulary. The same seven the interaction-rooted pointer addresses; a channel outside this set is a syntax error rather than an unreachable-evidence finding.",
|
|
23
|
+
});
|
|
24
|
+
/**
|
|
25
|
+
* AD-19's four transport channels. `call-inputs` alone has no declared
|
|
26
|
+
* structure to resolve against (the defect AD-26 revision 3 records), so a
|
|
27
|
+
* transport channel is mandatory immediately after it.
|
|
28
|
+
*/
|
|
29
|
+
export const TRANSPORT_CHANNELS = ['path', 'query', 'header', 'body'];
|
|
30
|
+
export const TransportChannel = z.enum(TRANSPORT_CHANNELS).meta({
|
|
31
|
+
id: 'TransportChannel',
|
|
32
|
+
description: "AD-19's four transport channels. They are the segment `call-inputs` takes before its tail, and the four keys an observation's recorded call inputs are keyed by.",
|
|
33
|
+
});
|
|
34
|
+
// The three-way partition (tail-bearing, scalar, transport-rooted) is spelled
|
|
35
|
+
// out and typed against the enum rather than rebuilt from it, so a typo fails
|
|
36
|
+
// the typecheck; a test asserts it stays disjoint and exhaustive. A status or
|
|
37
|
+
// exit code is scalar, so a pointer into one is a syntax error rather than an
|
|
38
|
+
// unreachable-evidence finding.
|
|
39
|
+
export const TAIL_BEARING_CHANNELS = [
|
|
40
|
+
'response-body',
|
|
41
|
+
'response-headers',
|
|
42
|
+
'stdout',
|
|
43
|
+
'stderr',
|
|
44
|
+
];
|
|
45
|
+
export const SCALAR_CHANNELS = [
|
|
46
|
+
'response-status',
|
|
47
|
+
'exit-code',
|
|
48
|
+
];
|
|
49
|
+
export const TRANSPORT_ROOTED_CHANNEL = 'call-inputs';
|
|
50
|
+
// An RFC 6901 reference token: any character but "/" and "~", plus the two
|
|
51
|
+
// escapes. A token may be empty, which is RFC 6901's spelling for a key that is
|
|
52
|
+
// the empty string.
|
|
53
|
+
const TOKEN = '(?:[^/~]|~[01])*';
|
|
54
|
+
const TAIL = `(?:/${TOKEN})*`;
|
|
55
|
+
const alternation = (members) => members.join('|');
|
|
56
|
+
export const INTERACTION_POINTER_PATTERN = new RegExp(`^/interactions/${IDENTIFIER_CHARSET_SOURCE}/(?:(?:${alternation(TAIL_BEARING_CHANNELS)})${TAIL}|(?:${alternation(SCALAR_CHANNELS)})|${TRANSPORT_ROOTED_CHANNEL}/(?:${alternation(TRANSPORT_CHANNELS)})${TAIL})$`);
|
|
57
|
+
export const BOUND_ELEMENT_POINTER_PATTERN = new RegExp(`^@(?:/${TOKEN})+$`);
|
|
58
|
+
export const DESCRIPTOR_POINTER_PATTERN = new RegExp(`^(?:/${TOKEN})*$`);
|
|
59
|
+
/**
|
|
60
|
+
* Spelling 1, interaction-rooted. Consumers: `{ pointer }` operands, a
|
|
61
|
+
* direction's evidence targets, and a rubric criterion's evidence.
|
|
62
|
+
*/
|
|
63
|
+
export const InteractionPointer = z
|
|
64
|
+
.string()
|
|
65
|
+
.regex(INTERACTION_POINTER_PATTERN)
|
|
66
|
+
.describe('AD-26 interaction-rooted pointer: "/interactions/{stepId}/" followed by one channel of the closed vocabulary. `call-inputs` takes one of the four transport channels as its next segment; `response-status` and `exit-code` take no tail. Syntax only: whether the step exists and whether the evidence is reachable are compile-time checks, not schema checks.');
|
|
67
|
+
/**
|
|
68
|
+
* Spelling 2, bound-element relative. Consumer: a `{ pointer }` operand inside
|
|
69
|
+
* a quantifier predicate. Never an evidence target, because AD-3 computes
|
|
70
|
+
* containment after quantifier substitution, by which point every target is
|
|
71
|
+
* fully rooted.
|
|
72
|
+
*/
|
|
73
|
+
export const BoundElementPointer = z
|
|
74
|
+
.string()
|
|
75
|
+
.regex(BOUND_ELEMENT_POINTER_PATTERN)
|
|
76
|
+
.describe('AD-26 bound-element pointer: "@/" plus an RFC 6901 tail, addressing the element a quantifier binds. Bare "@/" addresses the element itself. That it appears only inside a quantifier is a compile-time check, not a schema check.');
|
|
77
|
+
/**
|
|
78
|
+
* Spelling 3, descriptor-relative. Consumers: a nominated success indicator,
|
|
79
|
+
* every channel-role key, a collection location's pointer, and volatile
|
|
80
|
+
* pointers. Gate C authoring point 7 fixed this spelling's scope and never gave
|
|
81
|
+
* it a syntax; this is the syntax.
|
|
82
|
+
*/
|
|
83
|
+
export const DescriptorPointer = z
|
|
84
|
+
.string()
|
|
85
|
+
.regex(DESCRIPTOR_POINTER_PATTERN)
|
|
86
|
+
.describe("A plain RFC 6901 pointer into one operation's response descriptor. It resolves through the operation an interaction step names, never through the interaction root. A request or response shape's descriptor keys are plain key names rather than pointers, so this spelling does not apply there. The empty string is admitted and carries RFC 6901's own meaning, the whole document: as a nominated success indicator it says success is visible in the response taken as a whole rather than at any one key, and as a channel-role key it assigns a role to the whole body.");
|
|
87
|
+
/**
|
|
88
|
+
* The pointer form an operand may carry: rooted at an interaction, or relative
|
|
89
|
+
* to a quantifier's bound element.
|
|
90
|
+
*/
|
|
91
|
+
export const EvidencePointer = z.union([
|
|
92
|
+
InteractionPointer,
|
|
93
|
+
BoundElementPointer,
|
|
94
|
+
]);
|