@colophon-claims/verify 0.0.0 → 0.2.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 +39 -0
- package/dist/admission/application.d.ts +18 -0
- package/dist/admission/application.js +53 -0
- package/dist/admission/contracts.d.ts +506 -0
- package/dist/admission/contracts.js +459 -0
- package/dist/admission/index.d.ts +5 -0
- package/dist/admission/index.js +5 -0
- package/dist/admission/intake.d.ts +75 -0
- package/dist/admission/intake.js +70 -0
- package/dist/admission/result-evaluation.d.ts +18 -0
- package/dist/admission/result-evaluation.js +71 -0
- package/dist/admission/screening-sample.d.ts +56 -0
- package/dist/admission/screening-sample.js +126 -0
- package/dist/admission/verification.d.ts +102 -0
- package/dist/admission/verification.js +844 -0
- package/dist/anchor/check.d.ts +95 -0
- package/dist/anchor/check.js +146 -0
- package/dist/anchor/ports.d.ts +6 -0
- package/dist/anchor/ports.js +354 -0
- package/dist/assets.d.ts +33 -0
- package/dist/assets.js +885 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +20 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.js +205 -0
- package/dist/comparison.d.ts +64 -0
- package/dist/comparison.js +235 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +23 -0
- package/dist/manifest.d.ts +54 -0
- package/dist/manifest.js +240 -0
- package/dist/materialize.d.ts +4 -0
- package/dist/materialize.js +13 -0
- package/dist/profile/admission-receipts.d.ts +11 -0
- package/dist/profile/admission-receipts.js +24 -0
- package/dist/profile/anchor-claims.d.ts +157 -0
- package/dist/profile/anchor-claims.js +330 -0
- package/dist/profile/artifacts.d.ts +261 -0
- package/dist/profile/artifacts.js +139 -0
- package/dist/profile/assembly-ports.d.ts +19 -0
- package/dist/profile/assembly-ports.js +42 -0
- package/dist/profile/binary-judge-manifest.d.ts +121 -0
- package/dist/profile/binary-judge-manifest.js +106 -0
- package/dist/profile/binary-qualification.d.ts +9 -0
- package/dist/profile/binary-qualification.js +58 -0
- package/dist/profile/branding-assets.d.ts +5 -0
- package/dist/profile/branding-assets.js +5 -0
- package/dist/profile/branding.d.ts +24 -0
- package/dist/profile/branding.js +14 -0
- package/dist/profile/claim-consistency.d.ts +26 -0
- package/dist/profile/claim-consistency.js +91 -0
- package/dist/profile/claim.d.ts +327 -0
- package/dist/profile/claim.js +742 -0
- package/dist/profile/errors.d.ts +49 -0
- package/dist/profile/errors.js +78 -0
- package/dist/profile/inspect-assurance.d.ts +16 -0
- package/dist/profile/inspect-assurance.js +30 -0
- package/dist/profile/inspect-disclosure.d.ts +28 -0
- package/dist/profile/inspect-disclosure.js +54 -0
- package/dist/profile/inspect-manifest.d.ts +706 -0
- package/dist/profile/inspect-manifest.js +397 -0
- package/dist/profile/isolation.d.ts +21 -0
- package/dist/profile/isolation.js +31 -0
- package/dist/profile/pinning-evidence.d.ts +41 -0
- package/dist/profile/pinning-evidence.js +43 -0
- package/dist/profile/ports.d.ts +3 -0
- package/dist/profile/ports.js +11 -0
- package/dist/profile/preview-log.d.ts +4 -0
- package/dist/profile/preview-log.js +3 -0
- package/dist/profile/run-results.d.ts +17 -0
- package/dist/profile/run-results.js +23 -0
- package/dist/profile/signing.d.ts +10 -0
- package/dist/profile/signing.js +46 -0
- package/dist/profile/trust.d.ts +13 -0
- package/dist/profile/trust.js +35 -0
- package/dist/profile/venue.d.ts +2 -0
- package/dist/profile/venue.js +2 -0
- package/dist/profile/verdict.d.ts +28 -0
- package/dist/profile/verdict.js +51 -0
- package/dist/reader-instructions.d.ts +41 -0
- package/dist/reader-instructions.js +52 -0
- package/dist/schema.d.ts +380 -0
- package/dist/schema.js +498 -0
- package/dist/verify.d.ts +72 -0
- package/dist/verify.js +1573 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +2 -0
- package/package.json +63 -3
- package/schemas/assembly-row.schema.json +194 -0
- package/schemas/bundle-manifest.schema.json +23 -0
- package/schemas/claim-package.schema.json +279 -0
- package/schemas/dsse-envelope.schema.json +25 -0
- package/schemas/evidence-catalog.schema.json +43 -0
- package/schemas/public-trust.schema.json +44 -0
- package/schemas/verdict-catalog.schema.json +27 -0
- package/scripts/external-verify.py +238 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { VERDICT_DSSE_PAYLOAD_TYPE } from "@jinn-network/task-execution-profiles";
|
|
4
|
+
import { parseExactDsseEnvelope } from "@jinn-network/trust-core";
|
|
5
|
+
const MeasurementValueSchema = z.union([z.string(), z.number(), z.boolean()]);
|
|
6
|
+
const VerdictStatementSchema = z.looseObject({
|
|
7
|
+
predicateType: z.string().min(1),
|
|
8
|
+
predicate: z.looseObject({
|
|
9
|
+
evaluator: z.looseObject({ id: z.string().min(1) }),
|
|
10
|
+
verdict: z.enum(["pass", "fail", "inconclusive"]),
|
|
11
|
+
evaluationSpecification: z.looseObject({
|
|
12
|
+
digest: z.looseObject({ sha256: z.string().regex(/^[a-f0-9]{64}$/u) }),
|
|
13
|
+
}),
|
|
14
|
+
evaluationMethod: z.looseObject({
|
|
15
|
+
name: z.string().min(1),
|
|
16
|
+
digest: z.looseObject({ sha256: z.string().regex(/^[a-f0-9]{64}$/u) }),
|
|
17
|
+
}).optional(),
|
|
18
|
+
measurements: z.array(z.looseObject({ name: z.string().min(1), value: MeasurementValueSchema })).optional(),
|
|
19
|
+
evidence: z.array(z.looseObject({
|
|
20
|
+
name: z.string().min(1),
|
|
21
|
+
digest: z.looseObject({ sha256: z.string().regex(/^[a-f0-9]{64}$/u) }),
|
|
22
|
+
mediaType: z.string().optional(),
|
|
23
|
+
})).optional(),
|
|
24
|
+
evaluatedAt: z.string().min(1),
|
|
25
|
+
limitations: z.array(z.string()).optional(),
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
28
|
+
function statement(envelopeBytes) {
|
|
29
|
+
const envelope = parseExactDsseEnvelope(envelopeBytes);
|
|
30
|
+
if (envelope.payloadType !== VERDICT_DSSE_PAYLOAD_TYPE)
|
|
31
|
+
throw new Error("wrong Result Evaluation payload type");
|
|
32
|
+
let json;
|
|
33
|
+
try {
|
|
34
|
+
json = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(envelope.payloadBytes));
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
throw new Error("Result Evaluation payload is not UTF-8 JSON");
|
|
38
|
+
}
|
|
39
|
+
const parsed = VerdictStatementSchema.safeParse(json);
|
|
40
|
+
if (!parsed.success)
|
|
41
|
+
throw new Error("Result Evaluation payload is outside the closed view");
|
|
42
|
+
return parsed.data;
|
|
43
|
+
}
|
|
44
|
+
export function readAdmissionVerdictEnvelope(envelopeBytes) {
|
|
45
|
+
const { predicate } = statement(envelopeBytes);
|
|
46
|
+
const measurements = {};
|
|
47
|
+
for (const measurement of predicate.measurements ?? [])
|
|
48
|
+
measurements[measurement.name] = measurement.value;
|
|
49
|
+
return {
|
|
50
|
+
evaluatorId: predicate.evaluator.id,
|
|
51
|
+
verdict: predicate.verdict,
|
|
52
|
+
evaluationSpecificationSha256: predicate.evaluationSpecification.digest.sha256,
|
|
53
|
+
measurements,
|
|
54
|
+
evaluatedAt: predicate.evaluatedAt,
|
|
55
|
+
...(predicate.evidence === undefined ? {} : {
|
|
56
|
+
evidence: predicate.evidence.map((entry) => ({
|
|
57
|
+
name: entry.name,
|
|
58
|
+
sha256: entry.digest.sha256,
|
|
59
|
+
...(entry.mediaType === undefined ? {} : { mediaType: entry.mediaType }),
|
|
60
|
+
})),
|
|
61
|
+
}),
|
|
62
|
+
...(predicate.limitations === undefined ? {} : { limitations: predicate.limitations }),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function readOrderedAdmissionVerdictMeasurements(envelopeBytes) {
|
|
66
|
+
const measurements = statement(envelopeBytes).predicate.measurements ?? [];
|
|
67
|
+
if (new Set(measurements.map((measurement) => measurement.name)).size !== measurements.length) {
|
|
68
|
+
throw new Error("Result Evaluation carries duplicate measurement names");
|
|
69
|
+
}
|
|
70
|
+
return measurements.map((measurement) => ({ name: measurement.name, value: measurement.value }));
|
|
71
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export declare class ScreeningSampleError extends Error {
|
|
2
|
+
readonly path: string;
|
|
3
|
+
constructor(path: string, detail: string);
|
|
4
|
+
}
|
|
5
|
+
export interface ScreeningSampleParams {
|
|
6
|
+
/** The table's `itemSha256` values -- the row identity set. Order is irrelevant; see R-4. */
|
|
7
|
+
readonly itemSha256s: readonly string[];
|
|
8
|
+
/** Non-empty seed string. Enters the HMAC key as literal UTF-8 text, concatenated with `poolDigest`. */
|
|
9
|
+
readonly sampleSeed: string;
|
|
10
|
+
/** Positive integer, `<= itemSha256s.length`. The sample is the first `sampleSize` of the full order. */
|
|
11
|
+
readonly sampleSize: number;
|
|
12
|
+
}
|
|
13
|
+
export interface ScreeningSampleResult {
|
|
14
|
+
/** `sha256:<64 lowercase hex>` -- the digest of the sorted, unique identity set alone. */
|
|
15
|
+
readonly poolDigest: string;
|
|
16
|
+
/** Every `itemSha256` in the pool, ascending by HMAC stream (unsigned byte order), ties by code-unit order. */
|
|
17
|
+
readonly order: readonly string[];
|
|
18
|
+
/** `order.slice(0, sampleSize)`. */
|
|
19
|
+
readonly sample: readonly string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* One entry in the HMAC-stream ordering: the value actually compared (`stream`) paired with the
|
|
23
|
+
* tie-break key (`itemSha256`). Exported so the sort itself is directly testable -- a real
|
|
24
|
+
* HMAC-SHA256 collision cannot be constructed to exercise the tie-break in an end-to-end call.
|
|
25
|
+
*/
|
|
26
|
+
export interface ScreeningStreamEntry {
|
|
27
|
+
readonly itemSha256: string;
|
|
28
|
+
readonly stream: Uint8Array;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* `stream` compared as 32 unsigned bytes ascending; ties broken by `itemSha256` code-unit order.
|
|
32
|
+
* `Uint8Array` indexing always yields an unsigned 0-255 number in JavaScript, so a direct numeric
|
|
33
|
+
* subtraction per element is already the unsigned comparison -- no bit-masking is needed, but it
|
|
34
|
+
* must not be replaced by a signed-view read (e.g. `Int8Array`) or by comparing a hex rendering.
|
|
35
|
+
*/
|
|
36
|
+
export declare function compareScreeningStreamEntries(left: ScreeningStreamEntry, right: ScreeningStreamEntry): number;
|
|
37
|
+
/**
|
|
38
|
+
* `sha256:` followed by the 64 lowercase hex digits of the SHA-256 of the canonical-JSON bytes of
|
|
39
|
+
* `itemSha256s`, code-unit sorted AND deduplicated, so the digest depends on the identity SET and
|
|
40
|
+
* not on input order or on repetition. §6.5 says "sorted and unique" and this function is the one
|
|
41
|
+
* that has to mean it: `computeScreeningSample` refuses duplicates before it ever calls here, so
|
|
42
|
+
* the dedupe is a no-op on every in-repo path and moves no digest, but this is exported precisely
|
|
43
|
+
* so a cross-language implementer can check `poolDigest` in ISOLATION, and in isolation "sorted"
|
|
44
|
+
* alone would have silently accepted a duplicated identity and produced a digest no other
|
|
45
|
+
* implementation reproduces. Otherwise does not validate its input; `computeScreeningSample`
|
|
46
|
+
* owns that.
|
|
47
|
+
*/
|
|
48
|
+
export declare function computeScreeningPoolDigest(itemSha256s: readonly string[]): string;
|
|
49
|
+
/**
|
|
50
|
+
* Procedure `screening-sample/1` (§6.5). Refuses (throws `ScreeningSampleError`) when:
|
|
51
|
+
* - `itemSha256s` is empty, contains a duplicate, or contains an entry not matching
|
|
52
|
+
* `^sha256:[0-9a-f]{64}$`;
|
|
53
|
+
* - `sampleSeed` is empty;
|
|
54
|
+
* - `sampleSize` is not a positive integer, or exceeds `itemSha256s.length`.
|
|
55
|
+
*/
|
|
56
|
+
export declare function computeScreeningSample(params: ScreeningSampleParams): ScreeningSampleResult;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* `screening-sample/1` -- the verifier's independent recomputation of binary-judgment human-review
|
|
4
|
+
* sample membership (judge-path program packet P6, spec
|
|
5
|
+
* `docs/superpowers/specs/2026-08-19-judge-path-delta-contracts.md` §6.5 "(1) Sample membership").
|
|
6
|
+
*
|
|
7
|
+
* The verifier does not execute the operator's sealed sampling script; it recomputes membership
|
|
8
|
+
* from this specified procedure instead, and the recomputation wins on disagreement. That only
|
|
9
|
+
* works if the procedure is reimplementable in any language from the spec paragraph alone (R-4), so
|
|
10
|
+
* every encoding choice below is spelled out rather than left to convention:
|
|
11
|
+
*
|
|
12
|
+
* - **`poolDigest` binds the row *identity* set, never the rows.** It is `sha256:` followed by the
|
|
13
|
+
* 64 lowercase hex digits of the SHA-256 of the canonical-JSON bytes of the `itemSha256` values
|
|
14
|
+
* alone, code-unit sorted and unique -- not the rows themselves. Binding the rows is circular and
|
|
15
|
+
* uncomputable: a row carries `handChecked`, which rows carry it depends on the sample, and the
|
|
16
|
+
* sample depends on the digest. Binding the identity set breaks the cycle, because `itemSha256` is
|
|
17
|
+
* exactly the part of a row hand-checking never touches.
|
|
18
|
+
* - **The key is text, not raw digest bytes.** The HMAC key is `utf8(sampleSeed || poolDigest)`,
|
|
19
|
+
* where `poolDigest` enters in its `sha256:`-prefixed lowercase-hex string form -- the exact
|
|
20
|
+
* 64-hex-digit string, concatenated onto `sampleSeed`, then UTF-8 encoded. Keying on the digest's
|
|
21
|
+
* 32 raw bytes instead would introduce the only binary-versus-text distinction in an otherwise
|
|
22
|
+
* all-text procedure, which is exactly the kind of thing a second implementer gets wrong.
|
|
23
|
+
* - **No delimiter separates `sampleSeed` and `poolDigest`.** `poolDigest` is a fixed 71-character
|
|
24
|
+
* suffix (`sha256:` + 64 hex digits), so a delimiter would just be a second convention to get
|
|
25
|
+
* wrong.
|
|
26
|
+
* - **The HMAC message is `utf8(itemSha256)`**, the same `sha256:`-prefixed lowercase-hex string
|
|
27
|
+
* used everywhere else in the spec -- never raw digest bytes.
|
|
28
|
+
* - **Stream comparison is over 32 *unsigned* bytes.** `Uint8Array` elements are unsigned by
|
|
29
|
+
* construction in JavaScript (0-255), so a plain per-element numeric comparison is correct; the
|
|
30
|
+
* classic bug is reading the same bytes through a signed 8-bit view (where 0x80 becomes -128)
|
|
31
|
+
* or via a hex-string shortcut that doesn't preserve this. Ties are broken by `itemSha256` in
|
|
32
|
+
* code-unit order (never `localeCompare`, which is locale-dependent).
|
|
33
|
+
*
|
|
34
|
+
* This module does no filesystem or network I/O, throws `ScreeningSampleError` on any invalid
|
|
35
|
+
* input, and owns exactly its own input validity -- not the four other §6.5 checks (coverage,
|
|
36
|
+
* required hand checks, agreement rate, per-row admission), which read the recomputed sample but
|
|
37
|
+
* live elsewhere in this package.
|
|
38
|
+
*/
|
|
39
|
+
import { createHash, createHmac } from "node:crypto";
|
|
40
|
+
import { canonicalJsonBytes, compareCodeUnitStrings } from "@jinn-network/task-execution-profiles";
|
|
41
|
+
const SHA256_DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/;
|
|
42
|
+
export class ScreeningSampleError extends Error {
|
|
43
|
+
path;
|
|
44
|
+
constructor(path, detail) {
|
|
45
|
+
super(`${path}: ${detail}`);
|
|
46
|
+
this.name = "ScreeningSampleError";
|
|
47
|
+
this.path = path;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function fail(path, detail) {
|
|
51
|
+
throw new ScreeningSampleError(path, detail);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* `stream` compared as 32 unsigned bytes ascending; ties broken by `itemSha256` code-unit order.
|
|
55
|
+
* `Uint8Array` indexing always yields an unsigned 0-255 number in JavaScript, so a direct numeric
|
|
56
|
+
* subtraction per element is already the unsigned comparison -- no bit-masking is needed, but it
|
|
57
|
+
* must not be replaced by a signed-view read (e.g. `Int8Array`) or by comparing a hex rendering.
|
|
58
|
+
*/
|
|
59
|
+
export function compareScreeningStreamEntries(left, right) {
|
|
60
|
+
const length = Math.min(left.stream.length, right.stream.length);
|
|
61
|
+
for (let index = 0; index < length; index += 1) {
|
|
62
|
+
const delta = left.stream[index] - right.stream[index];
|
|
63
|
+
if (delta !== 0)
|
|
64
|
+
return delta;
|
|
65
|
+
}
|
|
66
|
+
if (left.stream.length !== right.stream.length)
|
|
67
|
+
return left.stream.length - right.stream.length;
|
|
68
|
+
return compareCodeUnitStrings(left.itemSha256, right.itemSha256);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* `sha256:` followed by the 64 lowercase hex digits of the SHA-256 of the canonical-JSON bytes of
|
|
72
|
+
* `itemSha256s`, code-unit sorted AND deduplicated, so the digest depends on the identity SET and
|
|
73
|
+
* not on input order or on repetition. §6.5 says "sorted and unique" and this function is the one
|
|
74
|
+
* that has to mean it: `computeScreeningSample` refuses duplicates before it ever calls here, so
|
|
75
|
+
* the dedupe is a no-op on every in-repo path and moves no digest, but this is exported precisely
|
|
76
|
+
* so a cross-language implementer can check `poolDigest` in ISOLATION, and in isolation "sorted"
|
|
77
|
+
* alone would have silently accepted a duplicated identity and produced a digest no other
|
|
78
|
+
* implementation reproduces. Otherwise does not validate its input; `computeScreeningSample`
|
|
79
|
+
* owns that.
|
|
80
|
+
*/
|
|
81
|
+
export function computeScreeningPoolDigest(itemSha256s) {
|
|
82
|
+
const sorted = [...new Set(itemSha256s)].sort(compareCodeUnitStrings);
|
|
83
|
+
const bytes = canonicalJsonBytes(sorted);
|
|
84
|
+
const hex = createHash("sha256").update(bytes).digest("hex");
|
|
85
|
+
return `sha256:${hex}`;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Procedure `screening-sample/1` (§6.5). Refuses (throws `ScreeningSampleError`) when:
|
|
89
|
+
* - `itemSha256s` is empty, contains a duplicate, or contains an entry not matching
|
|
90
|
+
* `^sha256:[0-9a-f]{64}$`;
|
|
91
|
+
* - `sampleSeed` is empty;
|
|
92
|
+
* - `sampleSize` is not a positive integer, or exceeds `itemSha256s.length`.
|
|
93
|
+
*/
|
|
94
|
+
export function computeScreeningSample(params) {
|
|
95
|
+
const { itemSha256s, sampleSeed, sampleSize } = params;
|
|
96
|
+
itemSha256s.forEach((itemSha256, index) => {
|
|
97
|
+
if (!SHA256_DIGEST_PATTERN.test(itemSha256)) {
|
|
98
|
+
fail(`itemSha256s[${index}]`, `must match ^sha256:[0-9a-f]{64}$, got ${JSON.stringify(itemSha256)}`);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
if (itemSha256s.length === 0)
|
|
102
|
+
fail("itemSha256s", "identity set must be non-empty");
|
|
103
|
+
if (new Set(itemSha256s).size !== itemSha256s.length) {
|
|
104
|
+
fail("itemSha256s", "identity set must not contain duplicate itemSha256 values");
|
|
105
|
+
}
|
|
106
|
+
if (sampleSeed.length === 0)
|
|
107
|
+
fail("sampleSeed", "must be non-empty");
|
|
108
|
+
if (!Number.isInteger(sampleSize) || sampleSize <= 0) {
|
|
109
|
+
fail("sampleSize", `must be a positive integer, got ${JSON.stringify(sampleSize)}`);
|
|
110
|
+
}
|
|
111
|
+
if (sampleSize > itemSha256s.length) {
|
|
112
|
+
fail("sampleSize", `must not exceed the pool size (${itemSha256s.length}), got ${sampleSize}`);
|
|
113
|
+
}
|
|
114
|
+
const poolDigest = computeScreeningPoolDigest(itemSha256s);
|
|
115
|
+
const key = Buffer.from(`${sampleSeed}${poolDigest}`, "utf8");
|
|
116
|
+
const entries = itemSha256s.map((itemSha256) => ({
|
|
117
|
+
itemSha256,
|
|
118
|
+
stream: new Uint8Array(createHmac("sha256", key).update(Buffer.from(itemSha256, "utf8")).digest()),
|
|
119
|
+
}));
|
|
120
|
+
const order = [...entries].sort(compareScreeningStreamEntries).map((entry) => entry.itemSha256);
|
|
121
|
+
return {
|
|
122
|
+
poolDigest,
|
|
123
|
+
order,
|
|
124
|
+
sample: order.slice(0, sampleSize),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { PROMPTED_SCREENING_PROFILE, type BinaryJudgmentAdmissionManifest, type HumanReviewReplacementLedger } from "./contracts.js";
|
|
2
|
+
export type AdmissionSha256 = `sha256:${string}`;
|
|
3
|
+
export declare const BINARY_JUDGMENT_ADMISSION_RECORD_ROLES: readonly ["admission-manifest", "replacement-ledger", "source-item", "label-resolution", "analysis-context", "human-review-evaluation-spec", "human-review-form", "human-review-packet", "human-review-response", "human-review-verdict", "reviewer-roster", "review-visibility-receipt", "review-reveal-receipt", "operator-assertion", "screening-table", "screening-reveal-receipt", "screening-instrument", "screening-sampling-script", "screening-raw-outputs", "screening-prompt", "screening-procedure", "screening-pool", "screening-sample-commitment", "screening-transcript"];
|
|
4
|
+
export type BinaryJudgmentAdmissionRecordRole = (typeof BINARY_JUDGMENT_ADMISSION_RECORD_ROLES)[number];
|
|
5
|
+
export type AdmissionAuthorityRole = "roster-attestor" | "truth-reveal-attestor" | "operator-truth-attestor";
|
|
6
|
+
export interface BinaryJudgmentAdmissionClosurePorts {
|
|
7
|
+
/** Resolve immutable bytes by their prefixed digest. The verifier re-hashes every result. */
|
|
8
|
+
resolveExactRecord(digest: AdmissionSha256): Uint8Array;
|
|
9
|
+
/** Verify the one reviewer signature against the evaluator/key binding trusted by the caller. */
|
|
10
|
+
verifyReviewerSignature(input: {
|
|
11
|
+
readonly envelopeBytes: Uint8Array;
|
|
12
|
+
readonly evaluatorId: string;
|
|
13
|
+
readonly keyId: string;
|
|
14
|
+
}): boolean;
|
|
15
|
+
/** Verify the one product-authority signature under its payload-declared, separated role. */
|
|
16
|
+
verifyAuthoritySignature(input: {
|
|
17
|
+
readonly envelopeBytes: Uint8Array;
|
|
18
|
+
readonly keyId: string;
|
|
19
|
+
readonly role: AdmissionAuthorityRole;
|
|
20
|
+
}): boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface VerifyBinaryJudgmentAdmissionClosureInput {
|
|
23
|
+
readonly admissionManifestSha256: AdmissionSha256;
|
|
24
|
+
readonly expectedDraftId: string;
|
|
25
|
+
}
|
|
26
|
+
export interface VerifiedBinaryJudgmentAdmissionItem {
|
|
27
|
+
readonly itemSha256: AdmissionSha256;
|
|
28
|
+
readonly itemId: string;
|
|
29
|
+
readonly truthLabel: "CORRECT" | "WRONG";
|
|
30
|
+
readonly candidateClass: string;
|
|
31
|
+
readonly stratum: string;
|
|
32
|
+
readonly truthAdmission: "two-human-unanimous" | "operator-only" | "screened-operator-sampled";
|
|
33
|
+
readonly labelResolutionSha256: AdmissionSha256;
|
|
34
|
+
readonly analysisContextSha256: AdmissionSha256;
|
|
35
|
+
}
|
|
36
|
+
export interface VerifiedBinaryJudgmentAdmissionExclusion {
|
|
37
|
+
readonly itemSha256: AdmissionSha256;
|
|
38
|
+
readonly itemId: string;
|
|
39
|
+
readonly candidateClass: string;
|
|
40
|
+
readonly stratum: string;
|
|
41
|
+
readonly reason: "review-disagreement" | "review-indeterminate" | "review-incomplete" | "screening-disagreement" | "screening-indeterminate" | "screening-hand-excluded";
|
|
42
|
+
readonly replacementItemSha256: AdmissionSha256;
|
|
43
|
+
}
|
|
44
|
+
export interface VerifiedBinaryJudgmentAdmissionClosure {
|
|
45
|
+
readonly manifestSha256: AdmissionSha256;
|
|
46
|
+
readonly manifest: BinaryJudgmentAdmissionManifest;
|
|
47
|
+
readonly replacementLedger: HumanReviewReplacementLedger;
|
|
48
|
+
readonly publicationGrade: boolean;
|
|
49
|
+
readonly classes: readonly string[];
|
|
50
|
+
readonly strata: readonly string[];
|
|
51
|
+
readonly accepted: readonly VerifiedBinaryJudgmentAdmissionItem[];
|
|
52
|
+
readonly excluded: readonly VerifiedBinaryJudgmentAdmissionExclusion[];
|
|
53
|
+
/** Complete, sorted digest inventory reachable from the manifest closure. */
|
|
54
|
+
readonly reachableSha256s: readonly AdmissionSha256[];
|
|
55
|
+
/** Same closure with semantic roles assigned by the exact traversal that authenticated it. */
|
|
56
|
+
readonly reachableRecords: readonly {
|
|
57
|
+
readonly sha256: AdmissionSha256;
|
|
58
|
+
readonly roles: readonly BinaryJudgmentAdmissionRecordRole[];
|
|
59
|
+
}[];
|
|
60
|
+
/** Present for the legacy screening-table/v1 method (spec §6.5 check (3)). */
|
|
61
|
+
readonly screening?: {
|
|
62
|
+
readonly sampleAgreementRate: number;
|
|
63
|
+
readonly instrumentSha256: AdmissionSha256;
|
|
64
|
+
};
|
|
65
|
+
/** Present for screening-table/v2; kept separate so the legacy v1 result shape stays source-compatible. */
|
|
66
|
+
readonly promptedScreening?: {
|
|
67
|
+
readonly sampleAgreementRate: number;
|
|
68
|
+
readonly procedureSha256: AdmissionSha256;
|
|
69
|
+
readonly profile: typeof PROMPTED_SCREENING_PROFILE;
|
|
70
|
+
readonly capabilityBoundary: PromptedScreeningCapabilityBoundary;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export declare const PROMPTED_SCREENING_CAPABILITY_BOUNDARY: {
|
|
74
|
+
readonly status: "not-machine-verified";
|
|
75
|
+
readonly machineVerified: readonly ["sealed-pool", "sealed-sample", "signed-table", "operator-decisions", "artifact-integrity"];
|
|
76
|
+
readonly notMachineVerified: readonly ["prompt-compliance-not-machine-verified", "provider-execution-not-machine-verified", "transcript-provenance-not-machine-verified", "mutable-model-alias-weights-not-machine-verified"];
|
|
77
|
+
};
|
|
78
|
+
export type PromptedScreeningCapabilityBoundary = typeof PROMPTED_SCREENING_CAPABILITY_BOUNDARY;
|
|
79
|
+
export declare class BinaryJudgmentAdmissionClosureError extends Error {
|
|
80
|
+
readonly path: string;
|
|
81
|
+
constructor(path: string, detail: string, options?: ErrorOptions);
|
|
82
|
+
}
|
|
83
|
+
export interface VerifiedBinaryJudgmentReviewerResult {
|
|
84
|
+
readonly evaluatorId: string;
|
|
85
|
+
readonly keyId: string;
|
|
86
|
+
readonly label: "CORRECT" | "WRONG" | "indeterminate";
|
|
87
|
+
readonly complete: boolean;
|
|
88
|
+
readonly completedAt: string;
|
|
89
|
+
readonly itemId: string;
|
|
90
|
+
readonly packetSha256: AdmissionSha256;
|
|
91
|
+
readonly visibilityReceiptSha256: AdmissionSha256;
|
|
92
|
+
}
|
|
93
|
+
/** The reviewer Result Evaluation verifier shared by admission construction and closure replay. */
|
|
94
|
+
export declare function verifyBinaryJudgmentReviewerResult(input: {
|
|
95
|
+
readonly verdictSha256: AdmissionSha256;
|
|
96
|
+
readonly expectedItemSha256: AdmissionSha256;
|
|
97
|
+
}, ports: BinaryJudgmentAdmissionClosurePorts): VerifiedBinaryJudgmentReviewerResult;
|
|
98
|
+
/**
|
|
99
|
+
* Portable, fail-closed replay of the entire binary-judgment admission graph. The caller supplies
|
|
100
|
+
* immutable record resolution and role-separated trust; no candidate truth is caller-authored.
|
|
101
|
+
*/
|
|
102
|
+
export declare function verifyBinaryJudgmentAdmissionClosure(input: VerifyBinaryJudgmentAdmissionClosureInput, ports: BinaryJudgmentAdmissionClosurePorts): VerifiedBinaryJudgmentAdmissionClosure;
|