@zanii/certify 0.0.0-stage → 0.5.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.
Files changed (133) hide show
  1. package/LICENSE +159 -0
  2. package/README.md +112 -2
  3. package/dist/appliance-execution.d.ts +18 -0
  4. package/dist/appliance-execution.js +12 -0
  5. package/dist/appliance.d.ts +135 -0
  6. package/dist/appliance.js +253 -0
  7. package/dist/assurance-status.d.ts +58 -0
  8. package/dist/assurance-status.js +86 -0
  9. package/dist/audit-renewal.d.ts +39 -0
  10. package/dist/audit-renewal.js +62 -0
  11. package/dist/audit.d.ts +69 -0
  12. package/dist/audit.js +112 -0
  13. package/dist/beacon-client.d.ts +38 -0
  14. package/dist/beacon-client.js +52 -0
  15. package/dist/beacon.d.ts +84 -0
  16. package/dist/beacon.js +106 -0
  17. package/dist/bitstring-status.d.ts +56 -0
  18. package/dist/bitstring-status.js +135 -0
  19. package/dist/board.d.ts +218 -0
  20. package/dist/board.js +428 -0
  21. package/dist/bundle.d.ts +92 -0
  22. package/dist/bundle.js +109 -0
  23. package/dist/certificate.d.ts +161 -0
  24. package/dist/certificate.js +345 -0
  25. package/dist/cli-messages.json +148 -0
  26. package/dist/cli.d.ts +16 -0
  27. package/dist/cli.js +369 -0
  28. package/dist/current-issuer-vc.d.ts +20 -0
  29. package/dist/current-issuer-vc.js +60 -0
  30. package/dist/evidence-share.d.ts +89 -0
  31. package/dist/evidence-share.js +479 -0
  32. package/dist/federation.d.ts +103 -0
  33. package/dist/federation.js +240 -0
  34. package/dist/feed-snapshot.d.ts +97 -0
  35. package/dist/feed-snapshot.js +186 -0
  36. package/dist/fingerprint.d.ts +23 -0
  37. package/dist/fingerprint.js +48 -0
  38. package/dist/formats/status-v2.schema.json +31 -0
  39. package/dist/governance.d.ts +242 -0
  40. package/dist/governance.js +411 -0
  41. package/dist/identity.d.ts +79 -0
  42. package/dist/identity.js +146 -0
  43. package/dist/impartiality.d.ts +47 -0
  44. package/dist/impartiality.js +85 -0
  45. package/dist/index.d.ts +58 -0
  46. package/dist/index.js +59 -0
  47. package/dist/issuer-authorization.d.ts +4 -0
  48. package/dist/issuer-authorization.js +52 -0
  49. package/dist/issuer-resolution.d.ts +25 -0
  50. package/dist/issuer-resolution.js +89 -0
  51. package/dist/licence-owner-entry.d.ts +20 -0
  52. package/dist/licence-owner-entry.js +33 -0
  53. package/dist/licence-owner.d.ts +67 -0
  54. package/dist/licence-owner.js +180 -0
  55. package/dist/licence.d.ts +174 -0
  56. package/dist/licence.js +400 -0
  57. package/dist/live-evidence.d.ts +135 -0
  58. package/dist/live-evidence.js +210 -0
  59. package/dist/nitro-roots.d.ts +3 -0
  60. package/dist/nitro-roots.js +20 -0
  61. package/dist/nitro-x509.d.ts +16 -0
  62. package/dist/nitro-x509.js +141 -0
  63. package/dist/nitro.d.ts +74 -0
  64. package/dist/nitro.js +329 -0
  65. package/dist/normalization.d.ts +8 -0
  66. package/dist/normalization.js +10 -0
  67. package/dist/pq.d.ts +32 -0
  68. package/dist/pq.js +69 -0
  69. package/dist/profile.d.ts +20 -0
  70. package/dist/profile.js +161 -0
  71. package/dist/register.d.ts +79 -0
  72. package/dist/register.js +134 -0
  73. package/dist/rotation.d.ts +49 -0
  74. package/dist/rotation.js +124 -0
  75. package/dist/royalty-reconciliation.d.ts +24 -0
  76. package/dist/royalty-reconciliation.js +88 -0
  77. package/dist/runtime-client.d.ts +38 -0
  78. package/dist/runtime-client.js +185 -0
  79. package/dist/runtime-gateway.d.ts +24 -0
  80. package/dist/runtime-gateway.js +167 -0
  81. package/dist/runtime-knowledge.d.ts +28 -0
  82. package/dist/runtime-knowledge.js +75 -0
  83. package/dist/runtime-nitro.d.ts +30 -0
  84. package/dist/runtime-nitro.js +57 -0
  85. package/dist/runtime.d.ts +226 -0
  86. package/dist/runtime.js +254 -0
  87. package/dist/sandbox-delegation.d.ts +38 -0
  88. package/dist/sandbox-delegation.js +61 -0
  89. package/dist/schema-dialect.d.ts +1 -0
  90. package/dist/schema-dialect.js +97 -0
  91. package/dist/schemas/clause-map.schema.json +52 -0
  92. package/dist/schemas/profile.schema.json +80 -0
  93. package/dist/schemas/scenarios.schema.json +573 -0
  94. package/dist/schemas/suite.schema.json +138 -0
  95. package/dist/scheme-authority.d.ts +5 -0
  96. package/dist/scheme-authority.js +15 -0
  97. package/dist/scheme-entry.d.ts +25 -0
  98. package/dist/scheme-entry.js +85 -0
  99. package/dist/scheme-history.d.ts +5 -0
  100. package/dist/scheme-history.js +87 -0
  101. package/dist/scheme-log.d.ts +98 -0
  102. package/dist/scheme-log.js +266 -0
  103. package/dist/scheme-merkle.d.ts +2 -0
  104. package/dist/scheme-merkle.js +20 -0
  105. package/dist/scheme-text.d.ts +25 -0
  106. package/dist/scheme-text.js +46 -0
  107. package/dist/scheme-timing.d.ts +16 -0
  108. package/dist/scheme-timing.js +22 -0
  109. package/dist/scheme-transition.d.ts +47 -0
  110. package/dist/scheme-transition.js +101 -0
  111. package/dist/scoring.d.ts +35 -0
  112. package/dist/scoring.js +50 -0
  113. package/dist/shared.d.ts +16 -0
  114. package/dist/shared.js +20 -0
  115. package/dist/signer.d.ts +18 -0
  116. package/dist/signer.js +49 -0
  117. package/dist/signing-identity.d.ts +1 -0
  118. package/dist/signing-identity.js +11 -0
  119. package/dist/status.d.ts +113 -0
  120. package/dist/status.js +204 -0
  121. package/dist/succession.d.ts +21 -0
  122. package/dist/succession.js +67 -0
  123. package/dist/suite.d.ts +257 -0
  124. package/dist/suite.js +441 -0
  125. package/dist/vc.d.ts +29 -0
  126. package/dist/vc.js +96 -0
  127. package/dist/verification-bounds.d.ts +5 -0
  128. package/dist/verification-bounds.js +76 -0
  129. package/dist/verification-policy.d.ts +32 -0
  130. package/dist/verification-policy.js +85 -0
  131. package/dist/witness.d.ts +19 -0
  132. package/dist/witness.js +80 -0
  133. package/package.json +57 -3
@@ -0,0 +1,92 @@
1
+ import { type Staff } from "./impartiality.ts";
2
+ import { type CategoryScore } from "./scoring.ts";
3
+ import { type ApplianceExecution, type ApplianceExportIdentity } from "./appliance-execution.ts";
4
+ export type { ApplianceExecution, ApplianceExportIdentity } from "./appliance-execution.ts";
5
+ export interface CategoryCount {
6
+ category: string;
7
+ trials: number;
8
+ passes: number;
9
+ threshold_ppm: number;
10
+ findings: readonly string[];
11
+ }
12
+ export interface CategoryResult extends CategoryScore {
13
+ category: string;
14
+ trials: number;
15
+ passes: number;
16
+ threshold_ppm: number;
17
+ findings: string[];
18
+ }
19
+ export interface Evidence {
20
+ case_id: string;
21
+ /** The hash-chain head of the case's recorded transcript. */
22
+ chain_head: string;
23
+ blackbox_session?: string;
24
+ }
25
+ export interface BundleInput {
26
+ execution?: ApplianceExecution | null;
27
+ profile: string;
28
+ level: number;
29
+ fingerprint: string;
30
+ plan: {
31
+ categories: readonly string[];
32
+ trials: number;
33
+ };
34
+ results: readonly CategoryCount[];
35
+ evidence: readonly Evidence[];
36
+ suite_snapshot: string;
37
+ staff: Staff;
38
+ started_at: string;
39
+ ended_at: string;
40
+ /** Default: pickScheme (0.1 for Levels 1 and 2, 0.2 for Level 3); the profile's scheme. */
41
+ scheme?: string;
42
+ /** Section 4: a partial re-test, and the bundle of the earlier passing run that covers the rest. */
43
+ partial?: {
44
+ covered_by: string;
45
+ } | null;
46
+ }
47
+ export interface ResultBundle {
48
+ execution?: ApplianceExecution;
49
+ v: 1;
50
+ type: "certify.result-bundle";
51
+ scheme: string;
52
+ profile: string;
53
+ level: number;
54
+ fingerprint: string;
55
+ plan: {
56
+ categories: string[];
57
+ trials: number;
58
+ };
59
+ results: CategoryResult[];
60
+ evidence: Evidence[];
61
+ suite_snapshot: string;
62
+ staff: {
63
+ testers: string[];
64
+ reviewer: string | null;
65
+ decider: string;
66
+ };
67
+ started_at: string;
68
+ ended_at: string;
69
+ partial?: {
70
+ covered_by: string;
71
+ };
72
+ }
73
+ export interface ApplianceExportBundle extends Omit<ResultBundle, "v" | "staff" | "execution" | "partial"> {
74
+ v: 2;
75
+ phase: "undecided";
76
+ staff: {
77
+ testers: string[];
78
+ reviewer: null;
79
+ decider: null;
80
+ };
81
+ execution: ApplianceExportIdentity;
82
+ }
83
+ export type ApplianceExportBundleInput = Omit<BundleInput, "staff" | "partial" | "execution"> & {
84
+ testers: readonly string[];
85
+ execution: ApplianceExportIdentity;
86
+ };
87
+ /** Existing v1 output is unchanged unless explicit verified appliance provenance is supplied. */
88
+ export declare function buildBundle(input: BundleInput): ResultBundle;
89
+ /** An appliance supplies execution evidence; it never occupies a human reviewer or decider role. */
90
+ export declare function buildApplianceExportBundle(input: ApplianceExportBundleInput): ApplianceExportBundle;
91
+ /** The bundle's identity: what the certificate's `claim.bundle` names. */
92
+ export declare const bundleHash: (bundle: ResultBundle | ApplianceExportBundle) => string;
package/dist/bundle.js ADDED
@@ -0,0 +1,109 @@
1
+ // spec/result-bundle.md: what a test run produced, hashed into the certificate. Never item text.
2
+ import { jcsHash } from "@zanii/core";
3
+ import { LEVELS, pickScheme } from "./certificate.js";
4
+ import { staffRefusals } from "./impartiality.js";
5
+ import { scoreCategory } from "./scoring.js";
6
+ import { isDid, isInt, isIso, isSha, ms, SLUG, sortedUnique } from "./shared.js";
7
+ import { applianceExecution, applianceExportIdentity } from "./appliance-execution.js";
8
+ const CATEGORY = /^[a-z][a-z0-9_]{0,63}$/;
9
+ const FINDING = /^[A-Z][A-Z0-9_]{0,63}$/;
10
+ const CASE_ID = /^[A-Za-z0-9._:-]{1,128}$/;
11
+ const PROFILE_REF = new RegExp(`^${SLUG.source.slice(1, -1)}/[1-9][0-9]*$`);
12
+ const byKey = (k) => (a, b) => k(a) < k(b) ? -1 : k(a) > k(b) ? 1 : 0;
13
+ function normalizedBundle(input, source) {
14
+ if (!PROFILE_REF.test(input.profile))
15
+ throw new Error("profile must be <slug>/<version>");
16
+ if (!LEVELS.includes(input.level))
17
+ throw new Error("level must be 1, 2 or 3");
18
+ const scheme = pickScheme(input.scheme, input.level);
19
+ if (!isSha(input.fingerprint))
20
+ throw new Error("fingerprint must be a fingerprint id");
21
+ if (!isSha(input.suite_snapshot))
22
+ throw new Error("suite_snapshot must be a sha256");
23
+ if (!isIso(input.started_at) || !isIso(input.ended_at) || ms(input.ended_at) < ms(input.started_at))
24
+ throw new Error("started_at and ended_at must be ISO UTC timestamps, in order");
25
+ const categories = sortedUnique(input.plan.categories);
26
+ if (!categories.length || categories.length !== input.plan.categories.length)
27
+ throw new Error("plan.categories must be distinct and not empty");
28
+ if (!categories.every((c) => CATEGORY.test(c)))
29
+ throw new Error("bad category id");
30
+ if (!isInt(input.plan.trials, 1, 1000))
31
+ throw new Error("plan.trials must be 1-1000");
32
+ const results = input.results.map((r) => {
33
+ const findings = sortedUnique(r.findings);
34
+ if (!findings.every((f) => FINDING.test(f)))
35
+ throw new Error(`bad finding code in ${r.category}`);
36
+ return {
37
+ category: r.category,
38
+ trials: r.trials,
39
+ passes: r.passes,
40
+ ...scoreCategory(r.passes, r.trials, r.threshold_ppm),
41
+ threshold_ppm: r.threshold_ppm,
42
+ findings,
43
+ };
44
+ });
45
+ results.sort(byKey((r) => r.category));
46
+ if (results.map((r) => r.category).join() !== categories.join())
47
+ throw new Error("results must have exactly one entry per planned category");
48
+ const evidence = input.evidence.map((e) => {
49
+ if (!CASE_ID.test(e.case_id) || !isSha(e.chain_head))
50
+ throw new Error("bad evidence entry");
51
+ const out = { case_id: e.case_id, chain_head: e.chain_head };
52
+ if (e.blackbox_session != null) {
53
+ if (!CASE_ID.test(e.blackbox_session))
54
+ throw new Error("bad blackbox_session");
55
+ out.blackbox_session = e.blackbox_session;
56
+ }
57
+ return out;
58
+ });
59
+ evidence.sort(byKey((e) => e.case_id));
60
+ if (new Set(evidence.map((e) => e.case_id)).size !== evidence.length)
61
+ throw new Error("evidence case_id values must be distinct");
62
+ const { testers, reviewer, decider } = input.staff;
63
+ if (!testers.length || !testers.every(isDid) || !source && !isDid(decider))
64
+ throw new Error("staff needs tester and decider DIDs");
65
+ if (!source && (reviewer === null ? input.level !== 1 : !isDid(reviewer)))
66
+ throw new Error("a reviewer DID is required above Level 1");
67
+ const refusals = source ? [] : staffRefusals({ testers: [...testers], reviewer, decider: decider }, []);
68
+ if (refusals.length)
69
+ throw new Error(`staffing refused: ${refusals.join(", ")}`);
70
+ const partial = input.partial ?? null;
71
+ if (partial !== null && (Object.keys(partial).length !== 1 || !isSha(partial.covered_by)))
72
+ throw new Error("partial must be {covered_by: <bundle hash>}");
73
+ const execution = input.execution == null ? undefined : applianceExecution(input.execution), machine = source?.appliance ?? execution?.appliance;
74
+ if (machine && [...testers, reviewer, decider].includes(machine))
75
+ throw new Error("an appliance cannot be recorded as human staff");
76
+ const bundle = {
77
+ v: 1,
78
+ type: "certify.result-bundle",
79
+ scheme,
80
+ profile: input.profile,
81
+ level: input.level,
82
+ fingerprint: input.fingerprint,
83
+ plan: { categories, trials: input.plan.trials },
84
+ results,
85
+ evidence,
86
+ suite_snapshot: input.suite_snapshot,
87
+ staff: { testers: sortedUnique(testers), reviewer, decider: decider },
88
+ started_at: input.started_at,
89
+ ended_at: input.ended_at,
90
+ ...(partial ? { partial: { covered_by: partial.covered_by } } : {}),
91
+ ...(execution ? { execution } : {}),
92
+ };
93
+ if (source) {
94
+ const { partial: ignored, ...base } = bundle;
95
+ return { ...base, v: 2, phase: "undecided", staff: { testers: sortedUnique(testers), reviewer: null, decider: null }, execution: source };
96
+ }
97
+ return bundle;
98
+ }
99
+ /** Existing v1 output is unchanged unless explicit verified appliance provenance is supplied. */
100
+ export function buildBundle(input) { return normalizedBundle(input); }
101
+ /** An appliance supplies execution evidence; it never occupies a human reviewer or decider role. */
102
+ export function buildApplianceExportBundle(input) {
103
+ if (!Array.isArray(input.testers) || input.testers.length > 64 || !Array.isArray(input.results) || input.results.length > 10000 || !Array.isArray(input.evidence) || input.evidence.length > 10000 || !Array.isArray(input.plan?.categories) || input.plan.categories.length > 10000)
104
+ throw new Error("appliance bundle exceeds its staff or result bounds");
105
+ const source = applianceExportIdentity(input.execution);
106
+ return normalizedBundle({ ...input, execution: null, partial: null, staff: { testers: input.testers, reviewer: null, decider: null } }, source);
107
+ }
108
+ /** The bundle's identity: what the certificate's `claim.bundle` names. */
109
+ export const bundleHash = (bundle) => jcsHash(bundle);
@@ -0,0 +1,161 @@
1
+ import { type Credential, type CredentialCheck, type IssuerResolver, type RevocationList } from "@zanii/credentials";
2
+ import { type PqBinding } from "@zanii/pq";
3
+ import { type AuditAttestation } from "./audit.ts";
4
+ import { type Fingerprint } from "./fingerprint.ts";
5
+ import { type Licence, type LicenceOptions } from "./licence.ts";
6
+ import { type PqCosignature } from "./pq.ts";
7
+ import { type BodyRegisterOptions } from "./register.ts";
8
+ import { type Signer } from "./signer.ts";
9
+ import { type StatusDocument, type StatusEntry, type StatusWitness } from "./status.ts";
10
+ import { type IssuerPolicy, type ReleaseVerificationPolicy } from "./verification-policy.ts";
11
+ import { type AuditRenewalPolicy } from "./audit-renewal.ts";
12
+ /** scheme.md section 8: every scheme version a certificate or bundle may name. */
13
+ export declare const SCHEMES: readonly ["zanii-certify/0.1", "zanii-certify/0.2", "zanii-certify/0.3"];
14
+ export type Scheme = (typeof SCHEMES)[number];
15
+ /** The current scheme. */
16
+ export declare const SCHEME: Scheme;
17
+ export declare const LEVELS: readonly [1, 2, 3];
18
+ export type Level = (typeof LEVELS)[number];
19
+ /** scheme.md section 2: the levels each scheme version issues. */
20
+ export declare const SCHEME_LEVELS: Record<Scheme, readonly Level[]>;
21
+ /**
22
+ * scheme.md section 8: the scheme a certificate or bundle is issued under. Given, it must issue
23
+ * `level` (and allow 0.2 features when `needs02`, 0.3 features when `needs03`); absent, 0.3 with a
24
+ * 0.3 feature (a licence), else 0.1 for Levels 1 and 2 without 0.2 features, else 0.2.
25
+ */
26
+ export declare function pickScheme(scheme: string | undefined, level: number, needs02?: boolean, needs03?: boolean): Scheme;
27
+ export declare const CONFLICTS: readonly ["blackbox_customer", "ledger_customer", "investor", "staff_link", "other"];
28
+ export type Conflict = (typeof CONFLICTS)[number];
29
+ /** scheme.md section 5: the default re-test interval per level. */
30
+ export declare const SURVEILLANCE: Record<Level, string>;
31
+ /** scheme.md section 4: validity is 365 days from issue. */
32
+ export declare const VALIDITY_DAYS = 365;
33
+ export declare const DOMAIN: RegExp;
34
+ export interface CertifyClaim {
35
+ scheme: Scheme;
36
+ profile: string;
37
+ level: Level;
38
+ fingerprint: string;
39
+ configuration: string;
40
+ bundle: string;
41
+ surveillance: string;
42
+ conflicts: Conflict[];
43
+ applicant: {
44
+ name: string;
45
+ country: string;
46
+ };
47
+ /** Level 3 only: jcsHash of the audit attestation (spec/audit.md). */
48
+ audit?: string;
49
+ /** When co-signed: bindingHash of the issuer's @zanii/pq binding (section 7). */
50
+ pq_binding?: string;
51
+ /** Scheme 0.3, issued by a licensee: jcsHash of its scheme licence (spec/licensing.md). */
52
+ licence?: string;
53
+ }
54
+ export interface CertificateInput {
55
+ issuerDomain: string;
56
+ /** The agent's did:key. */
57
+ holder: string;
58
+ profile: {
59
+ slug: string;
60
+ version: number;
61
+ };
62
+ level: Level;
63
+ fingerprint: Fingerprint;
64
+ /** The result bundle hash (spec/result-bundle.md). */
65
+ bundle: string;
66
+ conflicts: readonly Conflict[];
67
+ applicant: {
68
+ name: string;
69
+ country: string;
70
+ };
71
+ issuedAt: string;
72
+ /** Default: issuedAt plus 365 days. */
73
+ exp?: string;
74
+ /** Default: SURVEILLANCE[level]. */
75
+ surveillance?: string;
76
+ /** Default: pickScheme (0.1, or 0.2 for Level 3 or a pq binding). */
77
+ scheme?: string;
78
+ /** Level 3: the certification body's audit attestation (spec/audit.md). */
79
+ audit?: AuditAttestation;
80
+ /** The issuer's @zanii/pq binding, committed in the claim so the certificate can be co-signed. */
81
+ pqBinding?: PqBinding;
82
+ /** Scheme 0.3: the scheme licence the issuer certifies under (spec/licensing.md). */
83
+ licence?: Licence;
84
+ /** Scheme 0.3: the issuer's key lineage, oldest first: a licence naming an earlier key of it covers the signer. */
85
+ lineage?: readonly string[];
86
+ }
87
+ /** `certify.<profile slug>.l<level>` */
88
+ export declare const certificateScope: (slug: string, level: number) => string;
89
+ /** Issue a certificate, signed by `signer` (the lab issuer key, in a KMS or HSM). */
90
+ export declare function issueCertificate(input: CertificateInput, signer: Signer): Promise<Credential>;
91
+ export interface CertificateCheck {
92
+ ok: boolean;
93
+ reasons: string[];
94
+ /** This certificate's entry in the status document, when one was checked. */
95
+ status: StatusEntry | null;
96
+ /** Whether the supplied current fingerprint matches; null when none was supplied. */
97
+ fingerprint: "match" | "mismatch" | null;
98
+ credential: CredentialCheck;
99
+ /** Whether the certificate's post-quantum co-signature verified; null when not checked. */
100
+ pq: boolean | null;
101
+ /** The trusted witnesses that co-signed the status checkpoint, when a witness policy was given. */
102
+ witnesses: string[] | null;
103
+ /**
104
+ * With `issuerDoc` (section 7a): `required` when it says `require_pq` and the co-signatures were
105
+ * required, `opted_out` when the caller set `allowNoPq`, `not_required` otherwise.
106
+ */
107
+ pqPolicy?: PqPolicy;
108
+ /** Level 3 with `bodyRegister` or `trustedBodies`: which list of trusted bodies was used. */
109
+ bodies?: "register" | "local";
110
+ }
111
+ export type PqPolicy = "required" | "opted_out" | "not_required";
112
+ export interface CertificateVerifyOptions {
113
+ /** Independently known scheme owner; its key cannot sign issuer or status histories. */
114
+ schemeOwner?: string;
115
+ status?: StatusDocument;
116
+ revocationList?: RevocationList;
117
+ resolver?: IssuerResolver;
118
+ /** The agent's current fingerprint (from a beacon or the applicant). */
119
+ fingerprint?: Fingerprint;
120
+ now?: string;
121
+ /** The certificate's post-quantum co-signature (section 7). */
122
+ pq?: PqCosignature;
123
+ /** The status document's post-quantum co-signature (status.md section 5). */
124
+ statusPq?: PqCosignature;
125
+ /** Require both signatures on the certificate and (when supplied) on the status document. */
126
+ requirePq?: boolean;
127
+ /** Level 3: the audit attestation the claim references (spec/audit.md). */
128
+ audit?: AuditAttestation;
129
+ /** Versioned issuer endorsement of a replacement audit; the original certificate stays immutable. */
130
+ auditRenewal?: AuditRenewalPolicy;
131
+ /** Level 3: the did:keys of the certification bodies this verifier trusts. */
132
+ trustedBodies?: readonly string[];
133
+ /** Require the status document to be in a witnessed checkpoint (spec/witness.md). */
134
+ statusWitness?: StatusWitness;
135
+ /**
136
+ * The issuer document's `status_dids` (section 5): the DIDs that may sign status now. Given, the
137
+ * status document and revocation list must be signed by one of them; a DID other than the
138
+ * certificate's issuer is accepted only when it is listed here and the resolver resolves it.
139
+ */
140
+ statusDids?: readonly string[];
141
+ /** spec/licensing.md section 3: check the certificate was issued under a licence that covered it. */
142
+ licences?: LicenceOptions;
143
+ /** Section 7a: the issuer document; `require_pq: true` in it makes `requirePq` the default. */
144
+ issuerDoc?: unknown;
145
+ /** Section 7a: explicitly verify without the post-quantum co-signatures the issuer document requires (reported as `opted_out`). */
146
+ allowNoPq?: boolean;
147
+ /** Level 3 (spec/body-register.md): the board-signed register of trusted bodies, used instead of `trustedBodies`. */
148
+ bodyRegister?: BodyRegisterOptions;
149
+ /** Independently pinned identity/PQ policy; absent metadata or changed keys fails closed. */
150
+ issuerPolicy?: IssuerPolicy;
151
+ /** Require trusted profile/scheme releases at issuance; optional strict post-withdrawal refusal. */
152
+ releases?: ReleaseVerificationPolicy;
153
+ }
154
+ /** The certify claim's own rules (certificate.md section 2); empty when the claim is well formed. */
155
+ export declare function claimReasons(cert: Credential): string[];
156
+ /**
157
+ * Verify a certificate: the four @zanii/credentials checks, the certify claim, its live status in
158
+ * the signed status document, and (when supplied) that the agent's current fingerprint matches.
159
+ * Anything not checked is reported, never assumed.
160
+ */
161
+ export declare function verifyCertificate(cert: Credential, opts?: CertificateVerifyOptions): Promise<CertificateCheck>;