@sanning/proof 0.18.0 → 0.19.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/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,
@@ -353,7 +363,10 @@ export type {
353
363
  // `vectors/chain-reading.json` beside the pack-grading table for the same
354
364
  // reason: a rule consumers must agree with needs a statement they can fetch.
355
365
  //
356
- // It returns FINDINGS, never a verdict, and it feeds no status. Chain links are
366
+ // It returns FINDINGS, never a verdict, and it feeds no status on its own: a
367
+ // pack's signed v3 declaration can claim a chain complete and in order, and
368
+ // `checkDeclaration` holds that claim to the links `readChainLinks` reads
369
+ // (evidence-bundle.md 5.4.2 rule 11). Chain links are
357
370
  // deletion/reorder-evidence for the events present and NOT a completeness proof
358
371
  // (`anchor/docs/profile-sanning.events-v2.md` §5), drop the last N events of a
359
372
  // chain and nothing dangles. `CHAIN_READING_SCOPE` is that sentence, exported so
@@ -362,12 +375,14 @@ export type {
362
375
  export {
363
376
  ADAPTER_CHAIN_NAMESPACES,
364
377
  CHAIN_READING_SCOPE,
378
+ readChainLinks,
365
379
  readChains,
366
380
  renderChainFinding,
367
381
  } from "./chain.js";
368
382
  export type {
369
383
  ChainFinding,
370
384
  ChainFindingKind,
385
+ ChainLink,
371
386
  ChainReading,
372
387
  ChainSource,
373
388
  ChainSummary,
@@ -385,10 +400,24 @@ export {
385
400
  EXIT_FAILED,
386
401
  EXIT_MALFORMED,
387
402
  EXIT_MIXED,
403
+ EXIT_SANDBOX,
388
404
  EXIT_UNDETERMINED,
389
405
  EXIT_VERIFIED,
390
406
  exitCodeFor,
407
+ sandboxExit,
391
408
  } from "./exit-codes.js";
409
+ // Sandbox evidence: the environment marker over the envelopes a pack or case
410
+ // holds (envelope-spec §2, the `environment_marker` MAY), and the headline and
411
+ // line both commands print for it. Additive.
412
+ export {
413
+ SANDBOX_HEADLINE,
414
+ SANDBOX_LINE,
415
+ SANDBOX_TITLE,
416
+ environmentMarker,
417
+ onlySimulatedUnsettled,
418
+ packEnvelopes,
419
+ } from "./environment.js";
420
+ export type { EnvironmentMarker } from "./environment.js";
392
421
  export { attestationSignatureToHex, composeExport } from "./compose.js";
393
422
  export type { ComposeExportOptions, ComposeExportResult, ExporterKey } from "./compose.js";
394
423
 
@@ -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
+ }