@sanning/proof 0.18.0 → 0.19.1

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/src/exit-codes.ts CHANGED
@@ -16,6 +16,14 @@ export const EXIT_FAILED = 1;
16
16
  export const EXIT_MALFORMED = 2;
17
17
  export const EXIT_UNDETERMINED = 3;
18
18
  export const EXIT_MIXED = 4;
19
+ /**
20
+ * Sandbox evidence (envelope-spec §2): a run that would exit 0 over a pack or
21
+ * case holding a record signed `environment: "dev"`, or a run over records
22
+ * that are ALL signed `dev` whose only unsettled witnesses are simulated.
23
+ * Not a verdict word: the verdict stays what the checks established
24
+ * (`sandboxExit`). No flag turns 5 into 0.
25
+ */
26
+ export const EXIT_SANDBOX = 5;
19
27
 
20
28
  /**
21
29
  * The exit code of each of the eight verdict words (`evidence-bundle.md` §3).
@@ -40,6 +48,7 @@ export const EXIT_CODES_HELP = [
40
48
  " 2 usage or malformed",
41
49
  " 3 undetermined: partial, pending, incomplete or not_found",
42
50
  " 4 mixed: more than one outcome, none failed; read the exceptions",
51
+ " 5 sandbox: a record is signed environment dev; would be 0, or only a simulated witness is unchecked",
43
52
  ].join("\n");
44
53
 
45
54
  /**
@@ -52,3 +61,22 @@ export function exitCodeFor(verdict: unknown): number {
52
61
  }
53
62
  return EXIT_MALFORMED;
54
63
  }
64
+
65
+ /**
66
+ * The code a verb exits with once the environment marker is read. 5 where the
67
+ * run would otherwise exit 0 and the pack or case holds a record signed `dev`;
68
+ * 5 where the run is undetermined only because a simulated witness could not
69
+ * be looked up (`onlySimulatedUnsettled`, which the caller works out) and
70
+ * EVERY record is signed `dev`, so a production or mixed pack carrying a
71
+ * simulated witness keeps 3; the code unchanged everywhere else. A failure
72
+ * stays 1, malformed 2 and mixed 4.
73
+ */
74
+ export function sandboxExit(
75
+ code: number,
76
+ environmentMarker: string | null,
77
+ onlySimulatedUnsettled = false,
78
+ ): number {
79
+ if (code === EXIT_VERIFIED && environmentMarker !== null) return EXIT_SANDBOX;
80
+ if (code === EXIT_UNDETERMINED && environmentMarker === "dev" && onlySimulatedUnsettled) return EXIT_SANDBOX;
81
+ return code;
82
+ }
package/src/index.ts CHANGED
@@ -25,6 +25,15 @@ export {
25
25
  specVersionSupported,
26
26
  verifyEnvelope,
27
27
  } from "./verifier.js";
28
+ // The strict reader of bytes that claim to be JCS, the twin of Python's public
29
+ // `canonicalize.jcs_loads`. The enclave attestation adapters read a token's
30
+ // JSON through it, so they refuse what the kernel refuses. Additive.
31
+ export { jcsParse } from "./verifier.js";
32
+ // The same reader within the enclave readers' limits (enclave-attestation
33
+ // section 2.1): depth checked on the bytes first, every number finite. The
34
+ // adapters read a token's header and claims and the manifest through it.
35
+ // Additive.
36
+ export { exceedsTextDepth, hasNonFiniteNumber, jcsParseWithinLimits, MAX_READ_DEPTH } from "./verifier.js";
28
37
  export {
29
38
  bytesToHex,
30
39
  deriveOperatorAddress,
@@ -175,6 +184,7 @@ export {
175
184
  DECLARATION_VERDICTS,
176
185
  DECLARATION_VERSION,
177
186
  DECLARATION_VERSION_V2,
187
+ DECLARATION_VERSION_V3,
178
188
  DECLARATION_VERSIONS,
179
189
  checkDeclaration,
180
190
  declarationClaims,
@@ -224,6 +234,7 @@ export {
224
234
  CASE_NOTE_KINDS,
225
235
  CASE_RELIANCE,
226
236
  CASE_RELIANCE_HANDOFF_CLAUSE,
237
+ CASE_RELIANCE_SANDBOX,
227
238
  CASE_VERDICTS,
228
239
  CONTENT_WITHHELD_BY_DECLARATION,
229
240
  CO_SIGNATURES_PRESENT,
@@ -353,7 +364,10 @@ export type {
353
364
  // `vectors/chain-reading.json` beside the pack-grading table for the same
354
365
  // reason: a rule consumers must agree with needs a statement they can fetch.
355
366
  //
356
- // It returns FINDINGS, never a verdict, and it feeds no status. Chain links are
367
+ // It returns FINDINGS, never a verdict, and it feeds no status on its own: a
368
+ // pack's signed v3 declaration can claim a chain complete and in order, and
369
+ // `checkDeclaration` holds that claim to the links `readChainLinks` reads
370
+ // (evidence-bundle.md 5.4.2 rule 11). Chain links are
357
371
  // deletion/reorder-evidence for the events present and NOT a completeness proof
358
372
  // (`anchor/docs/profile-sanning.events-v2.md` §5), drop the last N events of a
359
373
  // chain and nothing dangles. `CHAIN_READING_SCOPE` is that sentence, exported so
@@ -362,12 +376,14 @@ export type {
362
376
  export {
363
377
  ADAPTER_CHAIN_NAMESPACES,
364
378
  CHAIN_READING_SCOPE,
379
+ readChainLinks,
365
380
  readChains,
366
381
  renderChainFinding,
367
382
  } from "./chain.js";
368
383
  export type {
369
384
  ChainFinding,
370
385
  ChainFindingKind,
386
+ ChainLink,
371
387
  ChainReading,
372
388
  ChainSource,
373
389
  ChainSummary,
@@ -385,10 +401,24 @@ export {
385
401
  EXIT_FAILED,
386
402
  EXIT_MALFORMED,
387
403
  EXIT_MIXED,
404
+ EXIT_SANDBOX,
388
405
  EXIT_UNDETERMINED,
389
406
  EXIT_VERIFIED,
390
407
  exitCodeFor,
408
+ sandboxExit,
391
409
  } from "./exit-codes.js";
410
+ // Sandbox evidence: the environment marker over the envelopes a pack or case
411
+ // holds (envelope-spec §2, the `environment_marker` MAY), and the headline and
412
+ // line both commands print for it. Additive.
413
+ export {
414
+ SANDBOX_HEADLINE,
415
+ SANDBOX_LINE,
416
+ SANDBOX_TITLE,
417
+ environmentMarker,
418
+ onlySimulatedUnsettled,
419
+ packEnvelopes,
420
+ } from "./environment.js";
421
+ export type { EnvironmentMarker } from "./environment.js";
392
422
  export { attestationSignatureToHex, composeExport } from "./compose.js";
393
423
  export type { ComposeExportOptions, ComposeExportResult, ExporterKey } from "./compose.js";
394
424
 
@@ -0,0 +1,44 @@
1
+ // Loading the enclave attestation adapters a reader has installed. Kept out of
2
+ // `index.ts` on purpose: it imports packages by name, which a browser bundle
3
+ // cannot resolve, and only the command line needs it. `run.ts` imports nothing.
4
+ //
5
+ // The packages are named by `ADAPTER_MODULES` and by nothing else: a provider
6
+ // id read from a pack is never turned into a module name.
7
+
8
+ import { ADAPTER_MODULES, declaredKinds, type EnclaveAdapter } from "./run.js";
9
+
10
+ /** Import a module by name. A parameter so a test can watch what is asked for. */
11
+ export type Importer = (name: string) => Promise<unknown>;
12
+
13
+ const dynamicImport: Importer = (name) => import(/* @vite-ignore */ name);
14
+
15
+ /**
16
+ * The adapters this environment holds, loaded from `ADAPTER_MODULES` and
17
+ * nothing else. A module counts only when it exports the provider it was
18
+ * loaded for as `provider`, a `check` function, and the failure kinds it
19
+ * declares as `kinds` (`declaredKinds`).
20
+ */
21
+ export async function loadInstalledAdapters(
22
+ importer: Importer = dynamicImport,
23
+ ): Promise<Map<string, EnclaveAdapter>> {
24
+ const found = new Map<string, EnclaveAdapter>();
25
+ for (const [provider, name] of Object.entries(ADAPTER_MODULES)) {
26
+ let module: unknown;
27
+ try {
28
+ module = await importer(name);
29
+ } catch {
30
+ continue;
31
+ }
32
+ const m = module as Partial<EnclaveAdapter> | null;
33
+ if (
34
+ m !== null &&
35
+ typeof m === "object" &&
36
+ m.provider === provider &&
37
+ typeof m.check === "function" &&
38
+ declaredKinds(m) !== null
39
+ ) {
40
+ found.set(provider, m as EnclaveAdapter);
41
+ }
42
+ }
43
+ return found;
44
+ }