@certrev/cert-block 0.1.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 (99) hide show
  1. package/README.md +154 -0
  2. package/dist/components/CertBadge.d.ts +29 -0
  3. package/dist/components/CertBadge.d.ts.map +1 -0
  4. package/dist/components/CertBadge.js +36 -0
  5. package/dist/components/CertBadge.js.map +1 -0
  6. package/dist/components/CertJsonLd.d.ts +23 -0
  7. package/dist/components/CertJsonLd.d.ts.map +1 -0
  8. package/dist/components/CertJsonLd.js +10 -0
  9. package/dist/components/CertJsonLd.js.map +1 -0
  10. package/dist/components/CertRevBacklink.d.ts +18 -0
  11. package/dist/components/CertRevBacklink.d.ts.map +1 -0
  12. package/dist/components/CertRevBacklink.js +16 -0
  13. package/dist/components/CertRevBacklink.js.map +1 -0
  14. package/dist/components/CertReview.d.ts +23 -0
  15. package/dist/components/CertReview.d.ts.map +1 -0
  16. package/dist/components/CertReview.js +11 -0
  17. package/dist/components/CertReview.js.map +1 -0
  18. package/dist/components/ExpertBio.d.ts +17 -0
  19. package/dist/components/ExpertBio.d.ts.map +1 -0
  20. package/dist/components/ExpertBio.js +17 -0
  21. package/dist/components/ExpertBio.js.map +1 -0
  22. package/dist/components/escape.d.ts +36 -0
  23. package/dist/components/escape.d.ts.map +1 -0
  24. package/dist/components/escape.js +76 -0
  25. package/dist/components/escape.js.map +1 -0
  26. package/dist/components/format.d.ts +22 -0
  27. package/dist/components/format.d.ts.map +1 -0
  28. package/dist/components/format.js +42 -0
  29. package/dist/components/format.js.map +1 -0
  30. package/dist/contract/fixtures.d.ts +36 -0
  31. package/dist/contract/fixtures.d.ts.map +1 -0
  32. package/dist/contract/fixtures.js +87 -0
  33. package/dist/contract/fixtures.js.map +1 -0
  34. package/dist/contract/kernel-contract.d.ts +154 -0
  35. package/dist/contract/kernel-contract.d.ts.map +1 -0
  36. package/dist/contract/kernel-contract.js +35 -0
  37. package/dist/contract/kernel-contract.js.map +1 -0
  38. package/dist/contract/kernel-stub.d.ts +44 -0
  39. package/dist/contract/kernel-stub.d.ts.map +1 -0
  40. package/dist/contract/kernel-stub.js +163 -0
  41. package/dist/contract/kernel-stub.js.map +1 -0
  42. package/dist/contract/kernel.d.ts +20 -0
  43. package/dist/contract/kernel.d.ts.map +1 -0
  44. package/dist/contract/kernel.js +19 -0
  45. package/dist/contract/kernel.js.map +1 -0
  46. package/dist/contract/verdict-kernel.d.ts +34 -0
  47. package/dist/contract/verdict-kernel.d.ts.map +1 -0
  48. package/dist/contract/verdict-kernel.js +13 -0
  49. package/dist/contract/verdict-kernel.js.map +1 -0
  50. package/dist/index.d.ts +31 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +38 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/jsonld/project.d.ts +71 -0
  55. package/dist/jsonld/project.d.ts.map +1 -0
  56. package/dist/jsonld/project.js +183 -0
  57. package/dist/jsonld/project.js.map +1 -0
  58. package/dist/verify/cache.d.ts +56 -0
  59. package/dist/verify/cache.d.ts.map +1 -0
  60. package/dist/verify/cache.js +93 -0
  61. package/dist/verify/cache.js.map +1 -0
  62. package/dist/verify/get-verified-envelope.d.ts +65 -0
  63. package/dist/verify/get-verified-envelope.d.ts.map +1 -0
  64. package/dist/verify/get-verified-envelope.js +104 -0
  65. package/dist/verify/get-verified-envelope.js.map +1 -0
  66. package/dist/verify/resolve-kid.d.ts +38 -0
  67. package/dist/verify/resolve-kid.d.ts.map +1 -0
  68. package/dist/verify/resolve-kid.js +71 -0
  69. package/dist/verify/resolve-kid.js.map +1 -0
  70. package/dist/webcomponent/certrev-badge.d.ts +38 -0
  71. package/dist/webcomponent/certrev-badge.d.ts.map +1 -0
  72. package/dist/webcomponent/certrev-badge.js +98 -0
  73. package/dist/webcomponent/certrev-badge.js.map +1 -0
  74. package/dist/webcomponent/render-badge-html.d.ts +25 -0
  75. package/dist/webcomponent/render-badge-html.d.ts.map +1 -0
  76. package/dist/webcomponent/render-badge-html.js +81 -0
  77. package/dist/webcomponent/render-badge-html.js.map +1 -0
  78. package/package.json +70 -0
  79. package/src/__tests__/components.test.tsx +191 -0
  80. package/src/__tests__/project.test.ts +128 -0
  81. package/src/__tests__/verify.test.ts +203 -0
  82. package/src/__tests__/webcomponent.test.tsx +106 -0
  83. package/src/components/CertBadge.tsx +164 -0
  84. package/src/components/CertJsonLd.tsx +36 -0
  85. package/src/components/CertRevBacklink.tsx +63 -0
  86. package/src/components/CertReview.tsx +42 -0
  87. package/src/components/ExpertBio.tsx +77 -0
  88. package/src/components/escape.ts +72 -0
  89. package/src/components/format.ts +55 -0
  90. package/src/contract/fixtures.ts +107 -0
  91. package/src/contract/kernel.ts +20 -0
  92. package/src/contract/verdict-kernel.ts +47 -0
  93. package/src/index.ts +85 -0
  94. package/src/jsonld/project.ts +206 -0
  95. package/src/verify/cache.ts +116 -0
  96. package/src/verify/get-verified-envelope.ts +156 -0
  97. package/src/verify/resolve-kid.ts +103 -0
  98. package/src/webcomponent/certrev-badge.ts +100 -0
  99. package/src/webcomponent/render-badge-html.ts +106 -0
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Presentation helpers shared by the React components + Web Component. Pure, no DOM,
3
+ * no React — so the same formatting drives JSX and the hand-built Web Component string.
4
+ */
5
+ /** Default accent if the brand didn't pin one (CertREV teal). */
6
+ export const DEFAULT_ACCENT = '#0f766e';
7
+ /** Resolve the optional display config to concrete presentation flags + accent. */
8
+ export function resolveDisplay(display, accentOverride) {
9
+ return {
10
+ accentColor: accentOverride ?? display?.accentColor ?? DEFAULT_ACCENT,
11
+ showExpertPhoto: display?.showExpertPhoto ?? true,
12
+ showAuthor: display?.showAuthor ?? true,
13
+ showMemo: display?.showMemo ?? true,
14
+ badgeStyle: display?.badgeStyle ?? 'full',
15
+ };
16
+ }
17
+ /**
18
+ * Format an ISO-8601 instant to a stable, locale-independent date label ("Jun 21, 2026").
19
+ * We deliberately DON'T use `toLocaleDateString` — its output varies by runtime ICU data,
20
+ * which would make SSR output non-deterministic + cause hydration mismatches. Fixed
21
+ * English month abbreviations keep server + client byte-identical.
22
+ */
23
+ const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
24
+ export function formatDate(iso) {
25
+ if (!iso)
26
+ return null;
27
+ const ms = Date.parse(iso);
28
+ if (Number.isNaN(ms))
29
+ return null;
30
+ const d = new Date(ms);
31
+ return `${MONTHS[d.getUTCMonth()]} ${d.getUTCDate()}, ${d.getUTCFullYear()}`;
32
+ }
33
+ /** "PhD, RD" — the expert's credential abbreviations, comma-joined. */
34
+ export function credentialSuffix(content) {
35
+ return content.expert.credentials.map((c) => c.abbreviation).join(', ');
36
+ }
37
+ /** "Dr. Jane Doe, PhD, RD" — display name with credential suffix appended. */
38
+ export function expertNameWithCredentials(content) {
39
+ const suffix = credentialSuffix(content);
40
+ return suffix ? `${content.expert.displayName}, ${suffix}` : content.expert.displayName;
41
+ }
42
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/components/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,iEAAiE;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAA;AAUvC,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAAC,OAAsC,EAAE,cAAuB;IAC7F,OAAO;QACN,WAAW,EAAE,cAAc,IAAI,OAAO,EAAE,WAAW,IAAI,cAAc;QACrE,eAAe,EAAE,OAAO,EAAE,eAAe,IAAI,IAAI;QACjD,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,IAAI;QACvC,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,IAAI;QACnC,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,MAAM;KACzC,CAAA;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;AAEnG,MAAM,UAAU,UAAU,CAAC,GAA8B;IACxD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1B,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAA;IACjC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAA;IACtB,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,cAAc,EAAE,EAAE,CAAA;AAC7E,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,gBAAgB,CAAC,OAAoB;IACpD,OAAO,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACxE,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,yBAAyB,CAAC,OAAoB;IAC7D,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACxC,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAA;AACxF,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Mock facts + a SIGNED envelope fixture for unit tests + local dev.
3
+ *
4
+ * `makeMockPayload` returns a complete, well-formed `CertPayload` (override any field).
5
+ * `makeSignedEnvelope` generates an ephemeral Ed25519 keypair, signs the payload's RFC-
6
+ * 8785 canonical bytes, and returns `{ envelope, resolveKid, publicKey }` so a test can
7
+ * run the FULL kernel pipeline (real signature verification) against the fixture — no
8
+ * mocking of the crypto.
9
+ *
10
+ * These helpers depend on Node's `crypto` (for keygen + signing on the ISSUER side, which
11
+ * tests stand in for). The SDK's RUNTIME never signs — it only verifies — so this stays
12
+ * test/dev-only and is not part of the public render API.
13
+ *
14
+ * The fixture signs over `canonicalPayloadBytes` from `@certrev/cert-contract` (RFC 8785),
15
+ * the SAME bytes the real kernel recomputes on verify — so a fixture envelope verifies
16
+ * end-to-end under the production `verifyEnvelope`, not a stand-in canonicalizer.
17
+ */
18
+ import { type KeyObject } from 'node:crypto';
19
+ import { type CertDeliveryEnvelope, type CertPayload, type ResolvePublicKeyByKid } from '@certrev/cert-contract';
20
+ declare const FIXTURE_KID = "certrev-fixture-key-1";
21
+ /** Build a complete mock payload. Pass overrides to exercise specific render branches. */
22
+ export declare function makeMockPayload(overrides?: Partial<CertPayload>): CertPayload;
23
+ export interface SignedEnvelopeFixture {
24
+ readonly envelope: CertDeliveryEnvelope;
25
+ readonly resolveKid: ResolvePublicKeyByKid;
26
+ readonly publicKey: KeyObject;
27
+ readonly kid: string;
28
+ }
29
+ /**
30
+ * Generate a fresh keypair, sign the payload, and return everything a test needs to run
31
+ * the kernel against a genuinely-valid envelope. The returned `resolveKid` resolves only
32
+ * the fixture kid (any other kid → null → 'unknown_key').
33
+ */
34
+ export declare function makeSignedEnvelope(overrides?: Partial<CertPayload>, kid?: string): SignedEnvelopeFixture;
35
+ export { FIXTURE_KID };
36
+ //# sourceMappingURL=fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/contract/fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAuB,KAAK,SAAS,EAAoB,MAAM,aAAa,CAAA;AACnF,OAAO,EAEN,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAEhB,KAAK,qBAAqB,EAC1B,MAAM,wBAAwB,CAAA;AAE/B,QAAA,MAAM,WAAW,0BAA0B,CAAA;AAE3C,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CA4CjF;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAA;IACvC,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAA;IAC1C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACpB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,EAAE,GAAG,SAAc,GAAG,qBAAqB,CAgBjH;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Mock facts + a SIGNED envelope fixture for unit tests + local dev.
3
+ *
4
+ * `makeMockPayload` returns a complete, well-formed `CertPayload` (override any field).
5
+ * `makeSignedEnvelope` generates an ephemeral Ed25519 keypair, signs the payload's RFC-
6
+ * 8785 canonical bytes, and returns `{ envelope, resolveKid, publicKey }` so a test can
7
+ * run the FULL kernel pipeline (real signature verification) against the fixture — no
8
+ * mocking of the crypto.
9
+ *
10
+ * These helpers depend on Node's `crypto` (for keygen + signing on the ISSUER side, which
11
+ * tests stand in for). The SDK's RUNTIME never signs — it only verifies — so this stays
12
+ * test/dev-only and is not part of the public render API.
13
+ *
14
+ * The fixture signs over `canonicalPayloadBytes` from `@certrev/cert-contract` (RFC 8785),
15
+ * the SAME bytes the real kernel recomputes on verify — so a fixture envelope verifies
16
+ * end-to-end under the production `verifyEnvelope`, not a stand-in canonicalizer.
17
+ */
18
+ import { generateKeyPairSync, sign as nodeSign } from 'node:crypto';
19
+ import { canonicalPayloadBytes, } from '@certrev/cert-contract';
20
+ const FIXTURE_KID = 'certrev-fixture-key-1';
21
+ /** Build a complete mock payload. Pass overrides to exercise specific render branches. */
22
+ export function makeMockPayload(overrides = {}) {
23
+ const base = {
24
+ contractVersion: 1,
25
+ certId: 'cert_fixture_001',
26
+ subject: {
27
+ platform: 'shopify',
28
+ externalId: 'gid://shopify/Article/123456789',
29
+ logicalArticleId: 'art_logical_abc',
30
+ canonicalUrls: ['https://brand.example.com/blogs/skincare/retinol-guide'],
31
+ installationId: 'inst_shopify_42',
32
+ contentDigest: 'a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2',
33
+ },
34
+ content: {
35
+ expert: {
36
+ displayName: 'Dr. Jane Doe',
37
+ credentials: [
38
+ { abbreviation: 'MD', fullName: 'Doctor of Medicine' },
39
+ { abbreviation: 'FAAD', fullName: 'Fellow of the American Academy of Dermatology' },
40
+ ],
41
+ profileUrl: 'https://certrev.com/experts/jane-doe',
42
+ photoUrl: 'https://cdn.certrev.com/experts/jane-doe.jpg',
43
+ },
44
+ author: { name: 'Sam Writer', title: 'Senior Content Editor' },
45
+ memo: 'I reviewed the retinol claims against current dermatology guidance; the concentrations and usage cadence cited are accurate and safely framed.',
46
+ certifiedAt: '2026-06-21T15:30:00.000Z',
47
+ contentModifiedAt: '2026-06-20T09:00:00.000Z',
48
+ verifyUrl: 'https://certrev.com/verify/cert_fixture_001',
49
+ display: {
50
+ accentColor: '#7c3aed',
51
+ showExpertPhoto: true,
52
+ showAuthor: true,
53
+ showMemo: true,
54
+ badgeStyle: 'full',
55
+ },
56
+ },
57
+ lifecycle: {
58
+ issuedAt: '2026-06-21T15:30:00.000Z',
59
+ expiresAt: '2099-01-01T00:00:00.000Z',
60
+ revokedAt: null,
61
+ revision: 1,
62
+ },
63
+ ...overrides,
64
+ };
65
+ return base;
66
+ }
67
+ /**
68
+ * Generate a fresh keypair, sign the payload, and return everything a test needs to run
69
+ * the kernel against a genuinely-valid envelope. The returned `resolveKid` resolves only
70
+ * the fixture kid (any other kid → null → 'unknown_key').
71
+ */
72
+ export function makeSignedEnvelope(overrides = {}, kid = FIXTURE_KID) {
73
+ const { publicKey, privateKey } = generateKeyPairSync('ed25519');
74
+ const payload = makeMockPayload(overrides);
75
+ const bytes = canonicalPayloadBytes(payload);
76
+ const sig = nodeSign(null, bytes, privateKey).toString('base64url');
77
+ const envelope = {
78
+ payload,
79
+ signature: { alg: 'ed25519', kid, sig, signedAt: payload.lifecycle.issuedAt },
80
+ };
81
+ const spkiBase64 = publicKey.export({ format: 'der', type: 'spki' }).toString('base64');
82
+ const keyInput = { format: 'spki-base64', base64: spkiBase64 };
83
+ const resolveKid = (k) => (k === kid ? keyInput : null);
84
+ return { envelope, resolveKid, publicKey, kid };
85
+ }
86
+ export { FIXTURE_KID };
87
+ //# sourceMappingURL=fixtures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/contract/fixtures.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * ─────────────────────────────────────────────────────────────────────────────
3
+ * @certrev/cert-contract — INTERFACE STUB (delete on publish; see INTEGRATION below)
4
+ * ─────────────────────────────────────────────────────────────────────────────
5
+ *
6
+ * The shared `CertDeliveryEnvelope` types + the fail-closed `VerdictKernel` live in
7
+ * the published `@certrev/cert-contract` package. That package is not yet on a registry
8
+ * this workspace can `pnpm install` from (it ships `file:`/workspace-only today), so
9
+ * `@certrev/cert-block` imports the contract surface from THIS local interface module
10
+ * instead. The types here are a byte-for-byte mirror of `cert-contract`'s `types.ts`
11
+ * (the settled, panel-revised shape: structured FACTS, no rendered JSON-LD in the
12
+ * payload; `subject` carries `logicalArticleId`, `canonicalUrls[]`, `installationId`,
13
+ * `contentDigest`).
14
+ *
15
+ * INTEGRATION (when @certrev/cert-contract publishes — see README "Integration TODOs"):
16
+ * 1. Delete this file and `./kernel-stub.ts`.
17
+ * 2. Replace every `from '../contract/kernel-contract.js'` with
18
+ * `from '@certrev/cert-contract'`.
19
+ * 3. The exported names here are deliberately identical to cert-contract's exports
20
+ * (`CertDeliveryEnvelope`, `CertPayload`, `CertVerdict`, `verifyEnvelope`,
21
+ * `renderVerdict`, `verifySignatureOnly`, `ResolvePublicKeyByKid`, `RenderContext`,
22
+ * `Ed25519PublicKeyInput`), so the swap is a find-and-replace of the import
23
+ * specifier — no call-site churn.
24
+ *
25
+ * Because this is type-only for everything the SDK consumes at COMPILE time, swapping
26
+ * the import path is the only change; the runtime kernel comes from `./kernel-stub.ts`
27
+ * today and from `@certrev/cert-contract` after publish.
28
+ */
29
+ /** Bump on ANY breaking change to the payload shape or signing rules. */
30
+ export declare const CONTRACT_VERSION: 1;
31
+ export type ContractVersion = typeof CONTRACT_VERSION;
32
+ /** RFC 8785 JSON Canonicalization Scheme — the bytes that get signed/hashed. */
33
+ export declare const CANONICALIZATION: "RFC8785-JCS";
34
+ /** Ed25519 (PureEdDSA). */
35
+ export declare const SIGNATURE_ALG: "ed25519";
36
+ export type SignatureAlg = typeof SIGNATURE_ALG;
37
+ export interface CertSubject {
38
+ readonly platform: string;
39
+ readonly externalId: string;
40
+ readonly logicalArticleId: string;
41
+ readonly canonicalUrls: ReadonlyArray<string>;
42
+ readonly installationId: string | null;
43
+ readonly contentDigest: string | null;
44
+ }
45
+ export interface CertDisplayConfig {
46
+ readonly accentColor?: string | null;
47
+ readonly showExpertPhoto?: boolean;
48
+ readonly showAuthor?: boolean;
49
+ readonly showMemo?: boolean;
50
+ readonly badgeStyle?: 'full' | 'compact';
51
+ }
52
+ export interface CertCredential {
53
+ readonly abbreviation: string;
54
+ readonly fullName: string;
55
+ }
56
+ export interface CertContent {
57
+ readonly expert: {
58
+ readonly displayName: string;
59
+ readonly credentials: ReadonlyArray<CertCredential>;
60
+ readonly profileUrl: string | null;
61
+ readonly photoUrl: string | null;
62
+ };
63
+ readonly author: {
64
+ readonly name: string;
65
+ readonly title: string | null;
66
+ };
67
+ readonly memo: string | null;
68
+ readonly certifiedAt: string;
69
+ readonly contentModifiedAt: string | null;
70
+ readonly verifyUrl: string;
71
+ readonly display: CertDisplayConfig;
72
+ }
73
+ export interface CertLifecycle {
74
+ readonly issuedAt: string;
75
+ readonly expiresAt: string;
76
+ readonly revokedAt: string | null;
77
+ readonly revision: number;
78
+ }
79
+ export interface CertPayload {
80
+ readonly contractVersion: ContractVersion;
81
+ readonly certId: string;
82
+ readonly subject: CertSubject;
83
+ readonly content: CertContent;
84
+ readonly lifecycle: CertLifecycle;
85
+ }
86
+ export interface CertSignature {
87
+ readonly alg: SignatureAlg;
88
+ readonly kid: string;
89
+ readonly sig: string;
90
+ readonly signedAt: string;
91
+ }
92
+ export interface CertDeliveryEnvelope {
93
+ readonly payload: CertPayload;
94
+ readonly signature: CertSignature;
95
+ }
96
+ export type CertVerdict = {
97
+ readonly decision: 'render';
98
+ readonly payload: CertPayload;
99
+ } | {
100
+ readonly decision: 'suppress';
101
+ readonly reason: CertSuppressReason;
102
+ };
103
+ export type CertSuppressReason = 'unsupported_contract_version' | 'unsupported_alg' | 'unknown_key' | 'invalid_signature' | 'platform_mismatch' | 'subject_mismatch' | 'revoked' | 'expired' | 'content_drift';
104
+ /** The Ed25519 public-key encodings a kid resolver may hand the kernel. */
105
+ export type Ed25519PublicKeyInput = {
106
+ readonly format: 'spki-der';
107
+ readonly bytes: Uint8Array;
108
+ } | {
109
+ readonly format: 'spki-base64';
110
+ readonly base64: string;
111
+ } | {
112
+ readonly format: 'pem';
113
+ readonly pem: string;
114
+ } | {
115
+ readonly format: 'raw';
116
+ readonly bytes: Uint8Array;
117
+ };
118
+ /**
119
+ * A kid → public-key resolver. Returns a usable Ed25519 key for the given kid, or
120
+ * null/undefined when the kid is unknown (→ suppress 'unknown_key'). May be async so
121
+ * an edge can fetch + cache a published key set. The real kernel also accepts a Node
122
+ * KeyObject; we model only the SDK-relevant inputs here.
123
+ */
124
+ export type ResolvePublicKeyByKid = (kid: string) => Promise<Ed25519PublicKeyInput | null | undefined> | Ed25519PublicKeyInput | null | undefined;
125
+ /** Edge-supplied context for the policy phase. */
126
+ export interface RenderContext {
127
+ readonly platform: string;
128
+ readonly externalId: string;
129
+ readonly liveContentHash?: string | null;
130
+ readonly now?: Date;
131
+ }
132
+ /** Full kernel: verify signature, then apply subject/lifecycle/drift policy. */
133
+ export type VerifyEnvelope = (envelope: CertDeliveryEnvelope, resolveKid: ResolvePublicKeyByKid, ctx: RenderContext) => Promise<CertVerdict>;
134
+ /** Phase-2-only policy over an already-verified payload. */
135
+ export type RenderVerdict = (payload: CertPayload, ctx: RenderContext) => CertVerdict;
136
+ /** Phase-1-only cryptographic verification. */
137
+ export type VerifySignatureOnly = (envelope: CertDeliveryEnvelope, resolveKid: ResolvePublicKeyByKid) => Promise<{
138
+ ok: true;
139
+ } | {
140
+ ok: false;
141
+ reason: CertSuppressReason;
142
+ }>;
143
+ /**
144
+ * The kernel function set as a single named interface — what the SDK depends on at
145
+ * the value level. `@certrev/cert-contract` exposes these as free functions; the SDK
146
+ * binds them through `./kernel-stub` today and re-points to the real exports on
147
+ * publish.
148
+ */
149
+ export interface VerdictKernel {
150
+ readonly verifyEnvelope: VerifyEnvelope;
151
+ readonly renderVerdict: RenderVerdict;
152
+ readonly verifySignatureOnly: VerifySignatureOnly;
153
+ }
154
+ //# sourceMappingURL=kernel-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernel-contract.d.ts","sourceRoot":"","sources":["../../src/contract/kernel-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,EAAG,CAAU,CAAA;AAC1C,MAAM,MAAM,eAAe,GAAG,OAAO,gBAAgB,CAAA;AAErD,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,EAAG,aAAsB,CAAA;AAEtD,2BAA2B;AAC3B,eAAO,MAAM,aAAa,EAAG,SAAkB,CAAA;AAC/C,MAAM,MAAM,YAAY,GAAG,OAAO,aAAa,CAAA;AAG/C,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC7C,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CACrC;AAGD,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC;AAGD,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,MAAM,EAAE;QAChB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;QAC5B,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;QACnD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;QAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAChC,CAAA;IACD,QAAQ,CAAC,MAAM,EAAE;QAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;QACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAC7B,CAAA;IACD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAA;CACnC;AAGD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CACzB;AAGD,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAA;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAA;CACjC;AAGD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAA;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CACzB;AAGD,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAA;CACjC;AAGD,MAAM,MAAM,WAAW,GACpB;IAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,CAAA;AAEzE,MAAM,MAAM,kBAAkB,GAC3B,8BAA8B,GAC9B,iBAAiB,GACjB,aAAa,GACb,mBAAmB,GACnB,mBAAmB,GACnB,kBAAkB,GAClB,SAAS,GACT,SAAS,GACT,eAAe,CAAA;AAIlB,2EAA2E;AAC3E,MAAM,MAAM,qBAAqB,GAC9B;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAC3D;IAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAA;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,CACnC,GAAG,EAAE,MAAM,KACP,OAAO,CAAC,qBAAqB,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,qBAAqB,GAAG,IAAI,GAAG,SAAS,CAAA;AAEjG,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAA;CACnB;AAED,gFAAgF;AAChF,MAAM,MAAM,cAAc,GAAG,CAC5B,QAAQ,EAAE,oBAAoB,EAC9B,UAAU,EAAE,qBAAqB,EACjC,GAAG,EAAE,aAAa,KACd,OAAO,CAAC,WAAW,CAAC,CAAA;AAEzB,4DAA4D;AAC5D,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,aAAa,KAAK,WAAW,CAAA;AAErF,+CAA+C;AAC/C,MAAM,MAAM,mBAAmB,GAAG,CACjC,QAAQ,EAAE,oBAAoB,EAC9B,UAAU,EAAE,qBAAqB,KAC7B,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAAA;AAEtE;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAA;IACvC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAA;IACrC,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAA;CACjD"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * ─────────────────────────────────────────────────────────────────────────────
3
+ * @certrev/cert-contract — INTERFACE STUB (delete on publish; see INTEGRATION below)
4
+ * ─────────────────────────────────────────────────────────────────────────────
5
+ *
6
+ * The shared `CertDeliveryEnvelope` types + the fail-closed `VerdictKernel` live in
7
+ * the published `@certrev/cert-contract` package. That package is not yet on a registry
8
+ * this workspace can `pnpm install` from (it ships `file:`/workspace-only today), so
9
+ * `@certrev/cert-block` imports the contract surface from THIS local interface module
10
+ * instead. The types here are a byte-for-byte mirror of `cert-contract`'s `types.ts`
11
+ * (the settled, panel-revised shape: structured FACTS, no rendered JSON-LD in the
12
+ * payload; `subject` carries `logicalArticleId`, `canonicalUrls[]`, `installationId`,
13
+ * `contentDigest`).
14
+ *
15
+ * INTEGRATION (when @certrev/cert-contract publishes — see README "Integration TODOs"):
16
+ * 1. Delete this file and `./kernel-stub.ts`.
17
+ * 2. Replace every `from '../contract/kernel-contract.js'` with
18
+ * `from '@certrev/cert-contract'`.
19
+ * 3. The exported names here are deliberately identical to cert-contract's exports
20
+ * (`CertDeliveryEnvelope`, `CertPayload`, `CertVerdict`, `verifyEnvelope`,
21
+ * `renderVerdict`, `verifySignatureOnly`, `ResolvePublicKeyByKid`, `RenderContext`,
22
+ * `Ed25519PublicKeyInput`), so the swap is a find-and-replace of the import
23
+ * specifier — no call-site churn.
24
+ *
25
+ * Because this is type-only for everything the SDK consumes at COMPILE time, swapping
26
+ * the import path is the only change; the runtime kernel comes from `./kernel-stub.ts`
27
+ * today and from `@certrev/cert-contract` after publish.
28
+ */
29
+ /** Bump on ANY breaking change to the payload shape or signing rules. */
30
+ export const CONTRACT_VERSION = 1;
31
+ /** RFC 8785 JSON Canonicalization Scheme — the bytes that get signed/hashed. */
32
+ export const CANONICALIZATION = 'RFC8785-JCS';
33
+ /** Ed25519 (PureEdDSA). */
34
+ export const SIGNATURE_ALG = 'ed25519';
35
+ //# sourceMappingURL=kernel-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernel-contract.js","sourceRoot":"","sources":["../../src/contract/kernel-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAU,CAAA;AAG1C,gFAAgF;AAChF,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAsB,CAAA;AAEtD,2BAA2B;AAC3B,MAAM,CAAC,MAAM,aAAa,GAAG,SAAkB,CAAA"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * ─────────────────────────────────────────────────────────────────────────────
3
+ * VerdictKernel — LOCAL STUB (delete on publish; mirrors @certrev/cert-contract)
4
+ * ─────────────────────────────────────────────────────────────────────────────
5
+ *
6
+ * A faithful, self-contained implementation of the cert-contract VerdictKernel so the
7
+ * SDK's verify layer + tests run NOW, before `@certrev/cert-contract` publishes to a
8
+ * registry this workspace installs from. The behavior is identical to the real kernel:
9
+ * • Ed25519 detached signature verified over the RFC-8785 (JCS) canonical bytes of
10
+ * `payload` (lexicographic key order, minimal whitespace, UTF-8).
11
+ * • Fail-closed pipeline: shape → alg → kid → signature → platform → subject →
12
+ * revoked → expired → drift → render. Any failure short-circuits to `suppress`.
13
+ * • Never throws on a bad envelope — a malformed input / throwing resolver fails
14
+ * closed to `suppress`, not to an exception a caller might swallow into a render.
15
+ *
16
+ * The byte-identical canonicalization across PHP / Node is what makes the credential
17
+ * portable; here we hand-roll a deterministic JCS serializer (sufficient for the
18
+ * envelope's all-string/number/bool/array/object shape — no exotic numbers) so the SDK
19
+ * carries no production crypto-canonicalization of its own that could DRIFT from the
20
+ * contract. On publish, the real `canonicalize` (RFC 8785) from cert-contract is used.
21
+ *
22
+ * INTEGRATION: delete this file + `./kernel-contract.ts`; import `verifyEnvelope`,
23
+ * `renderVerdict`, `verifySignatureOnly`, `toEd25519PublicKey` from
24
+ * `@certrev/cert-contract`. See README "Integration TODOs".
25
+ */
26
+ import { type KeyObject } from 'node:crypto';
27
+ import type { CertDeliveryEnvelope, CertPayload, CertSuppressReason, CertVerdict, Ed25519PublicKeyInput, RenderContext, ResolvePublicKeyByKid } from './kernel-contract.js';
28
+ /** Mirror of cert-contract's `toEd25519PublicKey` for the input encodings the SDK uses. */
29
+ declare function toEd25519PublicKey(input: Ed25519PublicKeyInput): KeyObject;
30
+ type CryptoResult = {
31
+ ok: true;
32
+ } | {
33
+ ok: false;
34
+ reason: CertSuppressReason;
35
+ };
36
+ /** Phase-2-only policy verdict over an already-authentic payload. Pure + synchronous. */
37
+ export declare function renderVerdict(payload: CertPayload, ctx: RenderContext): CertVerdict;
38
+ /** Phase-1-only cryptographic verification. */
39
+ export declare function verifySignatureOnly(envelope: CertDeliveryEnvelope, resolveKid: ResolvePublicKeyByKid): Promise<CryptoResult>;
40
+ /** Full kernel: verify signature, then apply policy. Fail-closed, never throws. */
41
+ export declare function verifyEnvelope(envelope: CertDeliveryEnvelope, resolveKid: ResolvePublicKeyByKid, ctx: RenderContext): Promise<CertVerdict>;
42
+ /** Re-export for tests that need to build a public key from raw/spki bytes. */
43
+ export { toEd25519PublicKey };
44
+ //# sourceMappingURL=kernel-stub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernel-stub.d.ts","sourceRoot":"","sources":["../../src/contract/kernel-stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAmB,KAAK,SAAS,EAAwB,MAAM,aAAa,CAAA;AACnF,OAAO,KAAK,EACX,oBAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,MAAM,sBAAsB,CAAA;AA4C7B,2FAA2F;AAC3F,iBAAS,kBAAkB,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,CAkBnE;AAUD,KAAK,YAAY,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,CAAA;AA6B5E,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,aAAa,GAAG,WAAW,CAoBnF;AAED,+CAA+C;AAC/C,wBAAsB,mBAAmB,CACxC,QAAQ,EAAE,oBAAoB,EAC9B,UAAU,EAAE,qBAAqB,GAC/B,OAAO,CAAC,YAAY,CAAC,CAEvB;AAED,mFAAmF;AACnF,wBAAsB,cAAc,CACnC,QAAQ,EAAE,oBAAoB,EAC9B,UAAU,EAAE,qBAAqB,EACjC,GAAG,EAAE,aAAa,GAChB,OAAO,CAAC,WAAW,CAAC,CAWtB;AAED,+EAA+E;AAC/E,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * ─────────────────────────────────────────────────────────────────────────────
3
+ * VerdictKernel — LOCAL STUB (delete on publish; mirrors @certrev/cert-contract)
4
+ * ─────────────────────────────────────────────────────────────────────────────
5
+ *
6
+ * A faithful, self-contained implementation of the cert-contract VerdictKernel so the
7
+ * SDK's verify layer + tests run NOW, before `@certrev/cert-contract` publishes to a
8
+ * registry this workspace installs from. The behavior is identical to the real kernel:
9
+ * • Ed25519 detached signature verified over the RFC-8785 (JCS) canonical bytes of
10
+ * `payload` (lexicographic key order, minimal whitespace, UTF-8).
11
+ * • Fail-closed pipeline: shape → alg → kid → signature → platform → subject →
12
+ * revoked → expired → drift → render. Any failure short-circuits to `suppress`.
13
+ * • Never throws on a bad envelope — a malformed input / throwing resolver fails
14
+ * closed to `suppress`, not to an exception a caller might swallow into a render.
15
+ *
16
+ * The byte-identical canonicalization across PHP / Node is what makes the credential
17
+ * portable; here we hand-roll a deterministic JCS serializer (sufficient for the
18
+ * envelope's all-string/number/bool/array/object shape — no exotic numbers) so the SDK
19
+ * carries no production crypto-canonicalization of its own that could DRIFT from the
20
+ * contract. On publish, the real `canonicalize` (RFC 8785) from cert-contract is used.
21
+ *
22
+ * INTEGRATION: delete this file + `./kernel-contract.ts`; import `verifyEnvelope`,
23
+ * `renderVerdict`, `verifySignatureOnly`, `toEd25519PublicKey` from
24
+ * `@certrev/cert-contract`. See README "Integration TODOs".
25
+ */
26
+ import { createPublicKey, verify as nodeVerify } from 'node:crypto';
27
+ import { CONTRACT_VERSION, SIGNATURE_ALG } from './kernel-contract.js';
28
+ // ── RFC-8785 (JCS) canonicalization — minimal, deterministic, envelope-shaped ─────
29
+ /**
30
+ * Serialize a JSON value to its RFC-8785 canonical string form: object keys sorted by
31
+ * UTF-16 code unit, no insignificant whitespace, JSON string escaping. The payload is
32
+ * all strings / finite numbers / booleans / null / arrays / objects, so we do NOT need
33
+ * the full ECMAScript number-formatting machinery the production `canonicalize` package
34
+ * implements — integers + ISO strings serialize identically either way. This stub
35
+ * exists only so tests run; the published path uses cert-contract's vetted JCS.
36
+ */
37
+ function jcs(value) {
38
+ if (value === null)
39
+ return 'null';
40
+ const t = typeof value;
41
+ if (t === 'string')
42
+ return JSON.stringify(value);
43
+ if (t === 'number') {
44
+ if (!Number.isFinite(value))
45
+ throw new Error('jcs: non-finite number');
46
+ return JSON.stringify(value);
47
+ }
48
+ if (t === 'boolean')
49
+ return value ? 'true' : 'false';
50
+ if (Array.isArray(value)) {
51
+ return `[${value.map((v) => jcs(v)).join(',')}]`;
52
+ }
53
+ if (t === 'object') {
54
+ const obj = value;
55
+ const keys = Object.keys(obj)
56
+ .filter((k) => obj[k] !== undefined)
57
+ .sort();
58
+ return `{${keys.map((k) => `${JSON.stringify(k)}:${jcs(obj[k])}`).join(',')}}`;
59
+ }
60
+ throw new Error(`jcs: unsupported value type ${t}`);
61
+ }
62
+ function canonicalPayloadBytes(payload) {
63
+ return new TextEncoder().encode(jcs(payload));
64
+ }
65
+ function base64urlDecode(s) {
66
+ return new Uint8Array(Buffer.from(s, 'base64url'));
67
+ }
68
+ const RAW_SPKI_PREFIX = Uint8Array.from([0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, 0x00]);
69
+ /** Mirror of cert-contract's `toEd25519PublicKey` for the input encodings the SDK uses. */
70
+ function toEd25519PublicKey(input) {
71
+ switch (input.format) {
72
+ case 'pem':
73
+ return createPublicKey({ key: input.pem, format: 'pem' });
74
+ case 'spki-base64':
75
+ return createPublicKey({ key: Buffer.from(input.base64, 'base64'), format: 'der', type: 'spki' });
76
+ case 'spki-der':
77
+ return createPublicKey({ key: Buffer.from(input.bytes), format: 'der', type: 'spki' });
78
+ case 'raw': {
79
+ if (input.bytes.length !== 32) {
80
+ throw new Error(`ed25519 raw public key must be 32 bytes, got ${input.bytes.length}`);
81
+ }
82
+ const spki = new Uint8Array(RAW_SPKI_PREFIX.length + 32);
83
+ spki.set(RAW_SPKI_PREFIX, 0);
84
+ spki.set(input.bytes, RAW_SPKI_PREFIX.length);
85
+ return createPublicKey({ key: Buffer.from(spki), format: 'der', type: 'spki' });
86
+ }
87
+ }
88
+ }
89
+ function verifyDetached(payload, sigBase64url, publicKey) {
90
+ try {
91
+ return nodeVerify(null, canonicalPayloadBytes(payload), publicKey, base64urlDecode(sigBase64url));
92
+ }
93
+ catch {
94
+ return false;
95
+ }
96
+ }
97
+ async function verifyCryptographic(envelope, resolveKid) {
98
+ const { payload, signature } = envelope ?? {};
99
+ if (!payload || !signature || payload.contractVersion !== CONTRACT_VERSION) {
100
+ return { ok: false, reason: 'unsupported_contract_version' };
101
+ }
102
+ if (signature.alg !== SIGNATURE_ALG) {
103
+ return { ok: false, reason: 'unsupported_alg' };
104
+ }
105
+ const resolved = await resolveKid(signature.kid);
106
+ if (!resolved) {
107
+ return { ok: false, reason: 'unknown_key' };
108
+ }
109
+ let key;
110
+ try {
111
+ key = toEd25519PublicKey(resolved);
112
+ }
113
+ catch {
114
+ return { ok: false, reason: 'unknown_key' };
115
+ }
116
+ if (!verifyDetached(payload, signature.sig, key)) {
117
+ return { ok: false, reason: 'invalid_signature' };
118
+ }
119
+ return { ok: true };
120
+ }
121
+ /** Phase-2-only policy verdict over an already-authentic payload. Pure + synchronous. */
122
+ export function renderVerdict(payload, ctx) {
123
+ const now = ctx.now ?? new Date();
124
+ if (payload.subject.platform !== ctx.platform) {
125
+ return { decision: 'suppress', reason: 'platform_mismatch' };
126
+ }
127
+ if (payload.subject.externalId !== ctx.externalId) {
128
+ return { decision: 'suppress', reason: 'subject_mismatch' };
129
+ }
130
+ if (payload.lifecycle.revokedAt !== null) {
131
+ return { decision: 'suppress', reason: 'revoked' };
132
+ }
133
+ if (now.getTime() >= Date.parse(payload.lifecycle.expiresAt)) {
134
+ return { decision: 'suppress', reason: 'expired' };
135
+ }
136
+ const bound = payload.subject.contentDigest;
137
+ const live = ctx.liveContentHash;
138
+ if (bound !== null && live != null && bound !== live) {
139
+ return { decision: 'suppress', reason: 'content_drift' };
140
+ }
141
+ return { decision: 'render', payload };
142
+ }
143
+ /** Phase-1-only cryptographic verification. */
144
+ export async function verifySignatureOnly(envelope, resolveKid) {
145
+ return verifyCryptographic(envelope, resolveKid);
146
+ }
147
+ /** Full kernel: verify signature, then apply policy. Fail-closed, never throws. */
148
+ export async function verifyEnvelope(envelope, resolveKid, ctx) {
149
+ let crypto;
150
+ try {
151
+ crypto = await verifyCryptographic(envelope, resolveKid);
152
+ }
153
+ catch {
154
+ return { decision: 'suppress', reason: 'unknown_key' };
155
+ }
156
+ if (!crypto.ok) {
157
+ return { decision: 'suppress', reason: crypto.reason };
158
+ }
159
+ return renderVerdict(envelope.payload, ctx);
160
+ }
161
+ /** Re-export for tests that need to build a public key from raw/spki bytes. */
162
+ export { toEd25519PublicKey };
163
+ //# sourceMappingURL=kernel-stub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernel-stub.js","sourceRoot":"","sources":["../../src/contract/kernel-stub.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * ─────────────────────────────────────────────────────────────────────────────
3
+ * Contract binding point — the SDK's single import of @certrev/cert-contract
4
+ * ─────────────────────────────────────────────────────────────────────────────
5
+ *
6
+ * Every other SDK module imports the contract TYPES and the KERNEL functions from HERE,
7
+ * never directly from `@certrev/cert-contract`, so the whole SDK's dependency on the
8
+ * contract is funnelled through one module. The published package owns the envelope types
9
+ * (`CertDeliveryEnvelope`, `CertPayload`, `CertCredential`, …), the RFC-8785
10
+ * canonicalization (`canonicalPayloadBytes`), and the fail-closed kernel (`verifyEnvelope`,
11
+ * `renderVerdict`, `verifySignatureOnly`, `toEd25519PublicKey`).
12
+ *
13
+ * `VerdictKernel` is the ONE name NOT re-exported from the package: the contract exposes
14
+ * the kernel as free functions, and different edges bundle them with different key-resolver
15
+ * shapes (cert-block uses `Ed25519PublicKeyInput`; the portal Delivery API uses raw
16
+ * `Uint8Array`), so the bundled interface stays edge-local — see ./verdict-kernel.
17
+ */
18
+ export * from '@certrev/cert-contract';
19
+ export type { VerdictKernel } from './verdict-kernel.js';
20
+ //# sourceMappingURL=kernel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernel.d.ts","sourceRoot":"","sources":["../../src/contract/kernel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,cAAc,wBAAwB,CAAA;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA"}