@sanning/proof 0.12.0 → 0.13.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 +25 -12
- package/dist/agent-proof.d.ts +2 -2
- package/dist/agent-proof.js +4 -4
- package/dist/case-file.d.ts +126 -0
- package/dist/case-file.js +349 -0
- package/dist/case.d.ts +173 -26
- package/dist/case.js +469 -123
- package/dist/cli.d.ts +38 -5
- package/dist/cli.js +557 -208
- package/dist/crypto.d.ts +1 -1
- package/dist/crypto.js +5 -1
- package/dist/declaration.d.ts +58 -52
- package/dist/declaration.js +256 -33
- package/dist/evidence.d.ts +2 -0
- package/dist/evidence.js +134 -19
- package/dist/exit-codes.d.ts +17 -0
- package/dist/exit-codes.js +50 -0
- package/dist/grading.d.ts +28 -13
- package/dist/grading.js +90 -31
- package/dist/index.d.ts +10 -7
- package/dist/index.js +13 -6
- package/dist/message-parts.d.ts +11 -9
- package/dist/message-parts.js +11 -9
- package/dist/types.d.ts +1 -0
- package/dist/verifier.d.ts +9 -2
- package/dist/verifier.js +28 -12
- package/dist/zip-reader.d.ts +50 -0
- package/dist/zip-reader.js +220 -0
- package/package.json +2 -2
- package/src/agent-proof.ts +4 -4
- package/src/case-file.ts +419 -0
- package/src/case.ts +586 -132
- package/src/cli.ts +651 -206
- package/src/crypto.ts +5 -1
- package/src/declaration.ts +248 -52
- package/src/evidence.ts +142 -21
- package/src/exit-codes.ts +54 -0
- package/src/grading.ts +109 -52
- package/src/index.ts +58 -2
- package/src/message-parts.ts +11 -9
- package/src/types.ts +5 -0
- package/src/verifier.ts +35 -13
- package/src/zip-reader.ts +229 -0
- package/vectors/README.md +23 -5
- package/vectors/case-file-index.json +668 -0
- package/vectors/case-split.json +218 -9
- package/vectors/pack-grading.json +68 -4
- package/vectors/stamp-on-chain.json +3 -3
package/dist/crypto.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare function isHexField(value: unknown, nibbles: number, lower?: bool
|
|
|
4
4
|
export declare function utf8(s: string): Uint8Array;
|
|
5
5
|
export declare function sha256Bytes(bytes: Uint8Array): Promise<Uint8Array>;
|
|
6
6
|
export declare function sha256Hex(bytes: Uint8Array): Promise<string>;
|
|
7
|
-
export declare function ed25519Verify(
|
|
7
|
+
export declare function ed25519Verify(message: Uint8Array, signatureHex: string, publicKeyHex: string): Promise<boolean>;
|
|
8
8
|
export declare function ed25519Sign(message: Uint8Array, privateKeyHex: string): Promise<string>;
|
|
9
9
|
export declare function ed25519PublicKey(privateKeyHex: string): Promise<string>;
|
|
10
10
|
export declare function verifyRsaPssSha256(payloadBytes: Uint8Array, signatureHex: string, publicKey: {
|
package/dist/crypto.js
CHANGED
|
@@ -74,7 +74,11 @@ export async function sha256Hex(bytes) {
|
|
|
74
74
|
// appear in the envelope; message is raw bytes. Never throws — a malformed
|
|
75
75
|
// signature or key is "not verified," not an exception, so a hostile envelope
|
|
76
76
|
// can't crash the checker.
|
|
77
|
-
|
|
77
|
+
// Arguments in the Python twin's order, `ed25519_verify(message,
|
|
78
|
+
// signature_hex, public_key_hex)` (P-03, 0.13.0). The message came second
|
|
79
|
+
// until 0.13.0; a caller that still passes the signature first gets a compile
|
|
80
|
+
// error, because a string is not a Uint8Array.
|
|
81
|
+
export async function ed25519Verify(message, signatureHex, publicKeyHex) {
|
|
78
82
|
try {
|
|
79
83
|
// zip215:false → strict RFC-8032 verification, matching the Go agent's
|
|
80
84
|
// crypto/ed25519 exactly (noble defaults to the more lenient zip215:true).
|
package/dist/declaration.d.ts
CHANGED
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
import { type HandoffRecord } from "./handoff.js";
|
|
2
2
|
import { type SideContentMap } from "./side-content.js";
|
|
3
|
-
/** The declaration schema
|
|
3
|
+
/** The first declaration schema, which every earlier reader knows. */
|
|
4
4
|
export declare const DECLARATION_VERSION = "sanning.declaration/v1";
|
|
5
|
-
/** The three states a declaration check can reach, from the §3 vocabulary. */
|
|
6
|
-
export type DeclarationVerdict = "verified" | "failed" | "partial";
|
|
7
|
-
export type DeclarationDeviationKind =
|
|
8
|
-
/** The declaration is written to this version and is not readable as one. */
|
|
9
|
-
"declaration-malformed"
|
|
10
|
-
/** A record the declaration expects is not in the pack. */
|
|
11
|
-
| "declared-absent"
|
|
12
|
-
/** A record in the pack the declaration never expected. */
|
|
13
|
-
| "undeclared-present"
|
|
14
5
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
6
|
+
* v1 plus a signed `records[].role` on every record (evidence-bundle.md
|
|
7
|
+
* 5.4.1 v1.20, A21). A reader that knows only v1 reads a v2 declaration as one
|
|
8
|
+
* it cannot read, which is the safe direction.
|
|
17
9
|
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
/** A claimed hand-off names a record the declaration does not declare. */
|
|
22
|
-
| "pair-record-undeclared"
|
|
10
|
+
export declare const DECLARATION_VERSION_V2 = "sanning.declaration/v2";
|
|
11
|
+
/** Every declaration schema this reader knows, in the order they were added. */
|
|
12
|
+
export declare const DECLARATION_VERSIONS: readonly ["sanning.declaration/v1", "sanning.declaration/v2"];
|
|
23
13
|
/**
|
|
24
|
-
*
|
|
25
|
-
* record
|
|
14
|
+
* What a v2 declaration may sign a record IS, compared exactly: `handoff`, a
|
|
15
|
+
* record 4.1 governs that the pack claims as a side in `handoffs[]`, or
|
|
16
|
+
* `step`, any other record.
|
|
26
17
|
*/
|
|
27
|
-
|
|
18
|
+
export declare const DECLARATION_ROLES: readonly ["handoff", "step"];
|
|
19
|
+
export type DeclarationRole = (typeof DECLARATION_ROLES)[number];
|
|
20
|
+
/** The three states a declaration check can reach, from the §3 vocabulary. */
|
|
21
|
+
export declare const DECLARATION_VERDICTS: readonly ["verified", "failed", "partial"];
|
|
22
|
+
export type DeclarationVerdict = (typeof DECLARATION_VERDICTS)[number];
|
|
23
|
+
export declare const DECLARATION_DEVIATION_KINDS: readonly ["declaration_malformed", "declared_absent", "undeclared_present", "withheld_but_disclosed", "duplicate_event_id", "pair_record_undeclared", "pair_record_not_a_handoff", "role_handoff_unclaimed", "role_step_claimed", "role_step_governed", "role_step_unreadable"];
|
|
24
|
+
export type DeclarationDeviationKind = (typeof DECLARATION_DEVIATION_KINDS)[number];
|
|
28
25
|
/**
|
|
29
26
|
* Every way a pack and the UNSIGNED content handed in beside it fail to line
|
|
30
27
|
* up, as a closed set. Neither of these is a deviation, and neither of them
|
|
@@ -51,22 +48,8 @@ export type DeclarationDeviationKind =
|
|
|
51
48
|
* legal and grades `verified`, which is strictly better than the `incomplete`
|
|
52
49
|
* these carry.
|
|
53
50
|
*/
|
|
54
|
-
export
|
|
55
|
-
|
|
56
|
-
* A record declared `disclosed` whose bytes reached this reader from
|
|
57
|
-
* neither channel. ALWAYS content-dependent: 5.4.1 lets those bytes travel
|
|
58
|
-
* beside the pack as `logs/<event_id>.json`, so "no bytes arrived" is a
|
|
59
|
-
* fact about what the READER was handed and never a fact about what the
|
|
60
|
-
* holder supplied. No signature covers the absence of a file nobody signed.
|
|
61
|
-
*/
|
|
62
|
-
"content-dependent-withholding"
|
|
63
|
-
/**
|
|
64
|
-
* A record declared `content_withheld` whose bytes reached this reader ONLY
|
|
65
|
-
* from the unsigned side-content map. The pack's own body supplies none, so
|
|
66
|
-
* the holder committed to no such disclosure. The in-body half of the same
|
|
67
|
-
* rule is the `withheld-but-disclosed` DEVIATION and still fails.
|
|
68
|
-
*/
|
|
69
|
-
| "content-dependent-disclosure";
|
|
51
|
+
export declare const DECLARATION_CONTENT_KINDS: readonly ["content_dependent_withholding", "content_dependent_disclosure"];
|
|
52
|
+
export type DeclarationContentKind = (typeof DECLARATION_CONTENT_KINDS)[number];
|
|
70
53
|
/**
|
|
71
54
|
* One way the pack and the unsigned content beside it do not line up. Named
|
|
72
55
|
* like a deviation and weighed like an absence.
|
|
@@ -77,18 +60,8 @@ export interface DeclarationContentFinding {
|
|
|
77
60
|
eventId?: string;
|
|
78
61
|
}
|
|
79
62
|
/** Everything this check reports that is NOT a deviation, as a closed set. */
|
|
80
|
-
export
|
|
81
|
-
|
|
82
|
-
* Every record declared `disclosed` supplied no bytes, so nothing was
|
|
83
|
-
* selected: the bytes did not travel with the pack.
|
|
84
|
-
*/
|
|
85
|
-
"disclosure-did-not-travel"
|
|
86
|
-
/**
|
|
87
|
-
* A claimed hand-off side whose `event_bytes` the pack withholds. The reader
|
|
88
|
-
* cannot see what the record is either way, so it is neither a conformant
|
|
89
|
-
* hand-off record nor a non-conformant one.
|
|
90
|
-
*/
|
|
91
|
-
| "pair-record-withheld";
|
|
63
|
+
export declare const DECLARATION_NOTE_KINDS: readonly ["disclosure_did_not_travel", "pair_record_withheld", "role_step_withheld"];
|
|
64
|
+
export type DeclarationNoteKind = (typeof DECLARATION_NOTE_KINDS)[number];
|
|
92
65
|
/**
|
|
93
66
|
* One named non-deviation finding, as data.
|
|
94
67
|
*
|
|
@@ -102,9 +75,9 @@ export interface DeclarationNote {
|
|
|
102
75
|
count?: number;
|
|
103
76
|
/** The record this is about, where it is about one. */
|
|
104
77
|
eventId?: string;
|
|
105
|
-
/** Which side of a claimed hand-off named it, for `
|
|
78
|
+
/** Which side of a claimed hand-off named it, for `pair_record_withheld`. */
|
|
106
79
|
side?: "sent" | "received";
|
|
107
|
-
/** Which claimed hand-off, by position, for `
|
|
80
|
+
/** Which claimed hand-off, by position, for `pair_record_withheld`. */
|
|
108
81
|
pairIndex?: number;
|
|
109
82
|
}
|
|
110
83
|
/** One deviation, as data. A surface renders its own prose or calls `renderDeviation`. */
|
|
@@ -116,8 +89,14 @@ export interface DeclarationDeviation {
|
|
|
116
89
|
side?: "sent" | "received";
|
|
117
90
|
/** Which claimed hand-off, by position, for the two `pair-record-` deviations. */
|
|
118
91
|
pairIndex?: number;
|
|
119
|
-
/** What is wrong with the declaration itself, for `
|
|
92
|
+
/** What is wrong with the declaration itself, for `declaration_malformed`. */
|
|
120
93
|
reason?: string;
|
|
94
|
+
/**
|
|
95
|
+
* The `declaration_version` the object claimed, for `declaration_malformed`,
|
|
96
|
+
* so the rendered sentence names the version the holder wrote to rather than
|
|
97
|
+
* the first one this reader learned.
|
|
98
|
+
*/
|
|
99
|
+
version?: string;
|
|
121
100
|
}
|
|
122
101
|
export interface DeclarationCheck {
|
|
123
102
|
verdict: DeclarationVerdict;
|
|
@@ -142,6 +121,22 @@ export interface DeclarationCheck {
|
|
|
142
121
|
declared: string[];
|
|
143
122
|
/** Of those, the ones declared withheld on purpose. */
|
|
144
123
|
declaredWithheld: string[];
|
|
124
|
+
/**
|
|
125
|
+
* The `declaration_version` this reader read the object as, one of
|
|
126
|
+
* `DECLARATION_VERSIONS`, or `null` where the body carries no declaration or
|
|
127
|
+
* one whose version this reader does not know. Set for a malformed object
|
|
128
|
+
* too: the version was read, the rest was not. Optional so a check a caller
|
|
129
|
+
* builds by hand, as rule version 5 adapters do, still type-checks.
|
|
130
|
+
*/
|
|
131
|
+
version?: string | null;
|
|
132
|
+
/**
|
|
133
|
+
* Every record a v2 declaration signs a role for, in declaration order.
|
|
134
|
+
* Empty for v1, and for anything this reader could not read.
|
|
135
|
+
*/
|
|
136
|
+
roles?: {
|
|
137
|
+
eventId: string;
|
|
138
|
+
role: DeclarationRole;
|
|
139
|
+
}[];
|
|
145
140
|
}
|
|
146
141
|
/**
|
|
147
142
|
* One of the pack's own records: the id, and whether the pack supplied its
|
|
@@ -242,7 +237,7 @@ export interface DeclarationClaims {
|
|
|
242
237
|
*/
|
|
243
238
|
present: boolean;
|
|
244
239
|
/**
|
|
245
|
-
* Whether this reader could read the claim as `
|
|
240
|
+
* Whether this reader could read the claim as one of `DECLARATION_VERSIONS` AND the
|
|
246
241
|
* object satisfies 5.4.1. `false` covers an absent declaration, an unknown
|
|
247
242
|
* version and a malformed object, and a case reader must not read any of the
|
|
248
243
|
* three as "the holder claimed nothing to check".
|
|
@@ -256,6 +251,17 @@ export interface DeclarationClaims {
|
|
|
256
251
|
* is legal and is exactly the shape a case reader has to name.
|
|
257
252
|
*/
|
|
258
253
|
claimedSides: string[];
|
|
254
|
+
/**
|
|
255
|
+
* The version the claim was read as, where `readable`; else `null`. The case
|
|
256
|
+
* reader's claim check is v1's alone (5.5.1 v1.20): a v2 pack's claim check
|
|
257
|
+
* is rule 9, which the declaration check already ran.
|
|
258
|
+
*/
|
|
259
|
+
version: string | null;
|
|
260
|
+
/** Every record a READABLE v2 declaration signs a role for. Empty for v1. */
|
|
261
|
+
roles: {
|
|
262
|
+
eventId: string;
|
|
263
|
+
role: DeclarationRole;
|
|
264
|
+
}[];
|
|
259
265
|
}
|
|
260
266
|
/**
|
|
261
267
|
* Read the claim a pack's declaration makes, without grading the pack.
|