@hlos-ai/schemas 0.4.2

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/dist/index.js ADDED
@@ -0,0 +1,965 @@
1
+ import {
2
+ CorrelationIdSchema,
3
+ CrossingIdSchema,
4
+ IdempotencyKeySchema,
5
+ PassportIdSchema,
6
+ ReceiptIdSchema,
7
+ WalletIdSchema,
8
+ __require,
9
+ generateCrossingId,
10
+ generateId,
11
+ generatePassportId,
12
+ generateReceiptId,
13
+ generateWalletId
14
+ } from "./chunk-RQP6MVT3.js";
15
+
16
+ // src/surface.ts
17
+ import { z } from "zod";
18
+ var SurfaceSchema = z.enum([
19
+ "mcp",
20
+ // Model Context Protocol servers
21
+ "x402",
22
+ // x402 micropayment protocol
23
+ "events",
24
+ // events.hlos.ai
25
+ "cli",
26
+ // HLOS CLI
27
+ "web",
28
+ // hlos.ai web app
29
+ "acp",
30
+ // Agent Commerce Protocol
31
+ "api"
32
+ // Direct API calls (default for unspecified)
33
+ ]);
34
+ var SURFACES = SurfaceSchema.options;
35
+
36
+ // src/response.ts
37
+ import { z as z3 } from "zod";
38
+
39
+ // src/error-codes.ts
40
+ import { z as z2 } from "zod";
41
+ var KernelErrorCodeSchema = z2.enum([
42
+ // 4xx Client Errors
43
+ "INVALID_REQUEST",
44
+ // 400 - Malformed request body
45
+ "UNAUTHORIZED",
46
+ // 401 - Missing/invalid auth
47
+ "FORBIDDEN",
48
+ // 403 - Insufficient permissions
49
+ "NOT_FOUND",
50
+ // 404 - Resource doesn't exist
51
+ "CONFLICT",
52
+ // 409 - General conflict
53
+ "IDEMPOTENCY_CONFLICT",
54
+ // 409 - Same idem_key, different request
55
+ "INSUFFICIENT_BALANCE",
56
+ // 402 - Wallet lacks funds
57
+ "SPEND_CAP_EXCEEDED",
58
+ // 402 - Spend cap hit
59
+ "RATE_LIMITED",
60
+ // 429 - Too many requests
61
+ // 5xx Server Errors
62
+ "INTERNAL_ERROR",
63
+ // 500 - Server error
64
+ "SERVICE_UNAVAILABLE"
65
+ // 503 - Temporarily unavailable
66
+ ]);
67
+
68
+ // src/response.ts
69
+ function success(data, correlationId, requestId) {
70
+ return {
71
+ success: true,
72
+ data,
73
+ meta: {
74
+ correlation_id: correlationId,
75
+ ...requestId && { request_id: requestId }
76
+ }
77
+ };
78
+ }
79
+ function error(code, message, correlationId, details) {
80
+ return {
81
+ success: false,
82
+ error: {
83
+ code,
84
+ message,
85
+ correlation_id: correlationId,
86
+ ...details !== void 0 && { details }
87
+ }
88
+ };
89
+ }
90
+ var SuccessResponseSchema = (dataSchema) => z3.object({
91
+ success: z3.literal(true),
92
+ data: dataSchema,
93
+ meta: z3.object({
94
+ request_id: z3.string().optional(),
95
+ correlation_id: z3.string()
96
+ }).optional()
97
+ });
98
+ var ErrorResponseSchema = z3.object({
99
+ success: z3.literal(false),
100
+ error: z3.object({
101
+ code: KernelErrorCodeSchema,
102
+ message: z3.string(),
103
+ details: z3.unknown().optional(),
104
+ correlation_id: z3.string()
105
+ })
106
+ });
107
+
108
+ // src/receipt-v0.ts
109
+ import { z as z4 } from "zod";
110
+ var RECEIPT_TYPE_URI = "https://hlos.ai/schema/SignedReceiptV0";
111
+ var RECEIPT_VERSION = 0;
112
+ var CONTENT_HASH_LENGTH = 43;
113
+ var SIGNATURE_LENGTH = 86;
114
+ var SignedReceiptV0Schema = (contentSchema) => z4.object({
115
+ "@type": z4.literal(RECEIPT_TYPE_URI),
116
+ version: z4.literal(RECEIPT_VERSION),
117
+ receipt_id: z4.string(),
118
+ content: contentSchema,
119
+ // SHA-256 digest (32 bytes) = exactly 43 chars base64url
120
+ content_hash: z4.string().regex(
121
+ /^[A-Za-z0-9_-]{43}$/,
122
+ "content_hash must be 43-char base64url (32-byte SHA-256)"
123
+ ),
124
+ // Ed25519 signature (64 bytes) = exactly 86 chars base64url
125
+ signature: z4.string().regex(
126
+ /^[A-Za-z0-9_-]{86}$/,
127
+ "signature must be 86-char base64url (64-byte Ed25519)"
128
+ ),
129
+ key_id: z4.string().min(1),
130
+ issued_at: z4.string().datetime()
131
+ });
132
+ var SignedReceiptV0LooseSchema = SignedReceiptV0Schema(z4.unknown());
133
+ function isSignedReceiptV0(value) {
134
+ if (typeof value !== "object" || value === null) return false;
135
+ const obj = value;
136
+ return obj["@type"] === RECEIPT_TYPE_URI && obj["version"] === RECEIPT_VERSION && typeof obj["receipt_id"] === "string" && typeof obj["content_hash"] === "string" && typeof obj["signature"] === "string" && typeof obj["key_id"] === "string" && typeof obj["issued_at"] === "string";
137
+ }
138
+
139
+ // src/shared-contract.ts
140
+ import { z as z5 } from "zod";
141
+ var KernelErrorCodeSchema2 = z5.enum([
142
+ // Validation / Request errors
143
+ "VALIDATION_ERROR",
144
+ // 400 - Input validation failed
145
+ "INVALID_REQUEST",
146
+ // 400 - Malformed request
147
+ // Auth errors
148
+ "UNAUTHORIZED",
149
+ // 401 - Missing/invalid auth
150
+ "FORBIDDEN",
151
+ // 403 - Insufficient permissions
152
+ // Resource errors
153
+ "NOT_FOUND",
154
+ // 404 - Generic not found
155
+ "CROSSING_NOT_FOUND",
156
+ // 404 - Crossing not found
157
+ "STACK_NOT_FOUND",
158
+ // 404 - Stack not found
159
+ "STACK_CONNECTION_NOT_FOUND",
160
+ // 404 - Stack connection not found
161
+ // Conflict errors
162
+ "CONFLICT",
163
+ // 409 - Generic conflict
164
+ "INVALID_STATE_TRANSITION",
165
+ // 409 - State machine violation
166
+ "CROSSING_ALREADY_SETTLED",
167
+ // 409 - Crossing already settled
168
+ "IDEMPOTENCY_CONFLICT",
169
+ // 409 - Same key, different request
170
+ // Payment errors
171
+ "INSUFFICIENT_BALANCE",
172
+ // 402 - Wallet lacks funds
173
+ "SPEND_CAP_EXCEEDED",
174
+ // 402 - Spend cap hit
175
+ // Rate limiting
176
+ "RATE_LIMITED",
177
+ // 429 - Too many requests
178
+ // Server errors
179
+ "INTERNAL_ERROR",
180
+ // 500 - Server error
181
+ "SERVICE_UNAVAILABLE"
182
+ // 503 - Temporarily unavailable
183
+ ]);
184
+ var ERROR_CODE_STATUS = {
185
+ VALIDATION_ERROR: 400,
186
+ INVALID_REQUEST: 400,
187
+ UNAUTHORIZED: 401,
188
+ FORBIDDEN: 403,
189
+ NOT_FOUND: 404,
190
+ CROSSING_NOT_FOUND: 404,
191
+ STACK_NOT_FOUND: 404,
192
+ STACK_CONNECTION_NOT_FOUND: 404,
193
+ CONFLICT: 409,
194
+ INVALID_STATE_TRANSITION: 409,
195
+ CROSSING_ALREADY_SETTLED: 409,
196
+ IDEMPOTENCY_CONFLICT: 409,
197
+ INSUFFICIENT_BALANCE: 402,
198
+ SPEND_CAP_EXCEEDED: 402,
199
+ RATE_LIMITED: 429,
200
+ INTERNAL_ERROR: 500,
201
+ SERVICE_UNAVAILABLE: 503
202
+ };
203
+ var KernelOkSchema = (dataSchema) => z5.object({
204
+ ok: z5.literal(true),
205
+ status: z5.union([
206
+ z5.number().int().min(200).max(299),
207
+ z5.literal(304)
208
+ ]),
209
+ data: dataSchema
210
+ });
211
+ var KernelErrorSchema = z5.object({
212
+ ok: z5.literal(false),
213
+ status: z5.number().int().min(400).max(599),
214
+ error: z5.object({
215
+ code: KernelErrorCodeSchema2,
216
+ // P0 FIX: was z.string()
217
+ message: z5.string(),
218
+ details: z5.record(z5.unknown()).optional()
219
+ })
220
+ });
221
+ var CrossingIdFormatSchema = z5.string().regex(/^cross_[a-z0-9]{20,}$/i, "Invalid CrossingId format (expected: cross_...)");
222
+ var ReceiptIdFormatSchema = z5.string().regex(/^rcpt_[0-9A-HJKMNP-TV-Z]{26}$/i, "Invalid ReceiptId format (expected: rcpt_...)");
223
+ var PassportIdFormatSchema = z5.string().regex(/^passport_[a-z0-9]{20,}$/i, "Invalid PassportId format (expected: passport_...)");
224
+ var WalletIdFormatSchema = z5.string().regex(/^wallet_[a-z0-9]{20,}$/i, "Invalid WalletId format (expected: wallet_...)");
225
+ var FundingSourceSchema = z5.enum(["SPONSOR", "PLATFORM", "USER"]);
226
+ var CredentialSourceSchema = z5.enum([
227
+ "SPONSOR_KEY",
228
+ // Sponsor-provisioned key
229
+ "BYOK",
230
+ // Bring Your Own Key (user-provided)
231
+ "HLOS_FALLBACK"
232
+ // Platform fallback credential
233
+ ]);
234
+ function deriveFundingSource(credentialSource) {
235
+ switch (credentialSource) {
236
+ case "SPONSOR_KEY":
237
+ return "SPONSOR";
238
+ case "BYOK":
239
+ return "USER";
240
+ case "HLOS_FALLBACK":
241
+ return "PLATFORM";
242
+ }
243
+ }
244
+ var CrossingSnapshotV0Schema = z5.object({
245
+ crossingId: CrossingIdFormatSchema,
246
+ capabilityId: z5.string(),
247
+ passportId: PassportIdFormatSchema,
248
+ // Scoping
249
+ event_id: z5.string().nullable(),
250
+ access_window_id: z5.string().nullable(),
251
+ access_grant_id: z5.string().nullable(),
252
+ // Attribution
253
+ attribution_org_id: z5.string().nullable(),
254
+ funding_source: FundingSourceSchema.nullable(),
255
+ credential_source: CredentialSourceSchema
256
+ });
257
+ var CrossingHashInputV0Schema = z5.object({
258
+ v: z5.literal(0),
259
+ snapshot: CrossingSnapshotV0Schema,
260
+ attested_receipt_id: ReceiptIdFormatSchema
261
+ });
262
+ var SETTLEMENT_AUTHORITY = "hlos.ai";
263
+ var CrossingSettledReceiptSchema = z5.object({
264
+ type: z5.literal("CrossingSettled"),
265
+ crossingId: CrossingIdFormatSchema,
266
+ // Scoping (powers adoption + ROI views)
267
+ event_id: z5.string().nullable(),
268
+ access_window_id: z5.string().nullable(),
269
+ access_grant_id: z5.string().nullable(),
270
+ // Attribution
271
+ attribution_org_id: z5.string().nullable(),
272
+ funding_source: FundingSourceSchema.nullable(),
273
+ credential_source: CredentialSourceSchema,
274
+ // Authority (LITERAL)
275
+ settlement_authority: z5.literal(SETTLEMENT_AUTHORITY),
276
+ // Binding
277
+ crossing_hash: z5.string(),
278
+ // sha256 base64url of CrossingHashInputV0
279
+ attested_receipt_id: z5.string(),
280
+ // Timestamp
281
+ settled_at: z5.string().datetime()
282
+ });
283
+ var AvailabilityTypeSchema = z5.enum([
284
+ "EVENT_SPONSOR",
285
+ // Sponsor-funded for specific event
286
+ "EVERGREEN",
287
+ // Always available platform credit
288
+ "CATALOG"
289
+ // User-paid from catalog
290
+ ]);
291
+ var ProviderRoleSchema = z5.enum([
292
+ "AI",
293
+ // AI/LLM providers (Gemini, GPT, Claude)
294
+ "DATABASE",
295
+ // Database providers (MongoDB, Supabase)
296
+ "AUTH",
297
+ // Auth providers (Clerk, Auth0)
298
+ "DEPLOY",
299
+ // Deployment providers (Vercel, Cloudflare)
300
+ "STORAGE",
301
+ // Storage providers (S3, R2)
302
+ "SEARCH",
303
+ // Search providers (Algolia, Pinecone)
304
+ "PAYMENTS",
305
+ // Payment providers (Stripe)
306
+ "COMPUTE",
307
+ // Compute providers (Modal, Replicate)
308
+ "OTHER"
309
+ // Catch-all for new categories
310
+ ]);
311
+ var StackProviderSchema = z5.object({
312
+ provider_id: z5.string(),
313
+ role: ProviderRoleSchema,
314
+ // P1: Now a constrained enum
315
+ display_name: z5.string(),
316
+ budget_allocation: z5.number().nonnegative(),
317
+ sku_ids: z5.array(z5.string()),
318
+ availability_type: AvailabilityTypeSchema
319
+ });
320
+ var StackSchema = z5.object({
321
+ id: z5.string(),
322
+ slug: z5.string(),
323
+ name: z5.string(),
324
+ tagline: z5.string(),
325
+ icon: z5.string(),
326
+ providers: z5.array(StackProviderSchema),
327
+ github_template: z5.string().nullable(),
328
+ total_budget: z5.number().nonnegative(),
329
+ event_id: z5.string().nullable()
330
+ // null = evergreen
331
+ });
332
+ var StackConnectionSchema = z5.object({
333
+ id: z5.string(),
334
+ stack_id: z5.string(),
335
+ passport_id: z5.string(),
336
+ team_id: z5.string().nullable(),
337
+ environment_id: z5.string(),
338
+ connected_at: z5.string().datetime(),
339
+ connected_providers: z5.array(z5.string())
340
+ });
341
+ function kernelOk(data, status = 200) {
342
+ return { ok: true, status, data };
343
+ }
344
+ function kernelError(code, message, status, details) {
345
+ return {
346
+ ok: false,
347
+ status: status ?? ERROR_CODE_STATUS[code],
348
+ error: {
349
+ code,
350
+ message,
351
+ ...details && { details }
352
+ }
353
+ };
354
+ }
355
+ var GOLDEN_FIXTURES = {
356
+ /**
357
+ * Sample CrossingHashInputV0 for hash conformance.
358
+ */
359
+ crossingHashInput: {
360
+ v: 0,
361
+ snapshot: {
362
+ crossingId: "cross_test123abc456def789ghi",
363
+ capabilityId: "gemini.generate.v1",
364
+ passportId: "passport_user123abc456def789g",
365
+ event_id: "evt_hackathon2026",
366
+ access_window_id: "aw_sponsor_mongodb",
367
+ access_grant_id: "ag_team_001",
368
+ attribution_org_id: "mongodb",
369
+ funding_source: "SPONSOR",
370
+ credential_source: "SPONSOR_KEY"
371
+ },
372
+ attested_receipt_id: "rcpt_01HZABCDEF1234567890ABCDEF"
373
+ },
374
+ /**
375
+ * Expected crossing_hash for the above input (FROZEN).
376
+ * Compute: JCS canonicalize → SHA-256 → base64url (no padding)
377
+ *
378
+ * This is the golden vector. If your hash differs, your implementation
379
+ * is not conformant. DO NOT CHANGE unless crossingHashInput changes.
380
+ */
381
+ expectedCrossingHash_base64url_sha256_jcs_v0: "z8A2kCNck4rPL4ugNe-Fbxputdi3PkjkVpSrIBhojU0",
382
+ /**
383
+ * Sample CrossingSettledReceipt.
384
+ */
385
+ crossingSettledReceipt: {
386
+ type: "CrossingSettled",
387
+ crossingId: "cross_test123abc456def789ghi",
388
+ event_id: "evt_hackathon2026",
389
+ access_window_id: "aw_sponsor_mongodb",
390
+ access_grant_id: "ag_team_001",
391
+ attribution_org_id: "mongodb",
392
+ funding_source: "SPONSOR",
393
+ credential_source: "SPONSOR_KEY",
394
+ settlement_authority: "hlos.ai",
395
+ crossing_hash: "z8A2kCNck4rPL4ugNe-Fbxputdi3PkjkVpSrIBhojU0",
396
+ attested_receipt_id: "rcpt_01HZABCDEF1234567890ABCDEF",
397
+ settled_at: "2026-01-24T12:00:00.000Z"
398
+ }
399
+ };
400
+ function isCrossingHashInputV0(value) {
401
+ return CrossingHashInputV0Schema.safeParse(value).success;
402
+ }
403
+ function isCrossingSettledReceipt(value) {
404
+ return CrossingSettledReceiptSchema.safeParse(value).success;
405
+ }
406
+
407
+ // src/w.ts
408
+ import { z as z6 } from "zod";
409
+ var W_RPID_DOMAIN = new TextEncoder().encode("W:RPID:v1");
410
+ var W_TXCTX_DOMAIN = new TextEncoder().encode("W:TXCTX:v1");
411
+ var RFC3339_CAPTURING = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.(\d{1,9}))?(Z|([+-])(\d{2}):(\d{2}))$/;
412
+ function isLeapYear(year) {
413
+ return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
414
+ }
415
+ function daysInMonth(year, month) {
416
+ const days = [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
417
+ return days[month - 1] ?? 0;
418
+ }
419
+ function parseRfc3339StrictToMs(value) {
420
+ const match = RFC3339_CAPTURING.exec(value);
421
+ if (!match) {
422
+ throw new Error(
423
+ `Invalid epoch: "${value}" is not a valid RFC3339 datetime (requires time and timezone)`
424
+ );
425
+ }
426
+ const year = Number(match[1]);
427
+ const month = Number(match[2]);
428
+ const day = Number(match[3]);
429
+ const hour = Number(match[4]);
430
+ const minute = Number(match[5]);
431
+ const second = Number(match[6]);
432
+ const fraction = match[8] ?? "";
433
+ const tz = match[9];
434
+ if (month < 1 || month > 12) {
435
+ throw new Error("Invalid epoch: month out of range");
436
+ }
437
+ const maxDay = daysInMonth(year, month);
438
+ if (day < 1 || day > maxDay) {
439
+ throw new Error("Invalid epoch: day out of range");
440
+ }
441
+ if (hour > 23) {
442
+ throw new Error("Invalid epoch: hour out of range");
443
+ }
444
+ if (minute > 59) {
445
+ throw new Error("Invalid epoch: minute out of range");
446
+ }
447
+ if (second > 59) {
448
+ throw new Error("Invalid epoch: second out of range");
449
+ }
450
+ const msFraction = fraction.length ? Number((fraction + "000").slice(0, 3)) : 0;
451
+ const utcMs = Date.UTC(year, month - 1, day, hour, minute, second, msFraction);
452
+ let offsetMs = 0;
453
+ if (tz !== "Z") {
454
+ const sign = match[10] === "-" ? -1 : 1;
455
+ const offsetHour = Number(match[11]);
456
+ const offsetMinute = Number(match[12]);
457
+ if (offsetHour > 23) {
458
+ throw new Error("Invalid epoch: tz hour out of range");
459
+ }
460
+ if (offsetMinute > 59) {
461
+ throw new Error("Invalid epoch: tz minute out of range");
462
+ }
463
+ offsetMs = sign * (offsetHour * 60 + offsetMinute) * 6e4;
464
+ }
465
+ const ms = utcMs - offsetMs;
466
+ if (!Number.isFinite(ms) || ms < 0) {
467
+ throw new Error("Invalid epoch: must be a non-negative timestamp");
468
+ }
469
+ return ms;
470
+ }
471
+ function encodeEpoch(epoch) {
472
+ let ms;
473
+ if (typeof epoch === "string") {
474
+ ms = parseRfc3339StrictToMs(epoch);
475
+ } else {
476
+ if (!Number.isInteger(epoch) || epoch < 0) {
477
+ throw new Error(`Invalid epoch: ${epoch} must be a non-negative integer`);
478
+ }
479
+ ms = epoch;
480
+ }
481
+ const buf = new ArrayBuffer(8);
482
+ const view = new DataView(buf);
483
+ view.setBigUint64(0, BigInt(ms), false);
484
+ return new Uint8Array(buf);
485
+ }
486
+ var RelyingPartyIdSchema = z6.object({
487
+ /** RP domain (e.g., "merchant.example.com") */
488
+ domain: z6.string().min(1).max(253),
489
+ /** Audience URI (e.g., "https://merchant.example.com/verify") */
490
+ audience_uri: z6.string().url(),
491
+ /** SHA-256 hash of verifier's public key (hex, 64 chars) */
492
+ verifier_key_hash: z6.string().regex(/^[a-f0-9]{64}$/, "Must be 64-char lowercase hex")
493
+ });
494
+ var RotationEpochSchema = z6.union([
495
+ z6.number().int().nonnegative(),
496
+ z6.string().datetime({ offset: true })
497
+ // Requires timezone offset (RFC3339)
498
+ ]);
499
+ var RPIDSchema = z6.string().length(43, "RPID must be base64url-encoded 32 bytes (43 chars, no padding)").regex(/^[A-Za-z0-9_-]+$/, "Must be base64url (no padding)");
500
+ var TransactionContextSchema = z6.object({
501
+ // Required core (stable)
502
+ relying_party_id: RelyingPartyIdSchema,
503
+ /** sha256(JCS({ intent, request })) — see computeOperationHash() */
504
+ operation_hash: z6.string().regex(/^[a-f0-9]{64}$/, "Must be 64-char lowercase hex"),
505
+ /** Validity start (RFC3339) */
506
+ not_before: z6.string().datetime({ offset: true }),
507
+ /** Validity end (RFC3339) */
508
+ not_after: z6.string().datetime({ offset: true }),
509
+ // Optional (part of hash, must be consistent)
510
+ amount: z6.number().nonnegative().optional(),
511
+ currency: z6.string().length(3).optional(),
512
+ surface_id: z6.string().optional(),
513
+ channel_id: z6.string().optional()
514
+ });
515
+ var TransactionContextHashSchema = z6.string().regex(/^[a-f0-9]{64}$/, "Must be 64-char lowercase hex");
516
+ var W_GOLDEN_FIXTURES = {
517
+ /**
518
+ * encodeEpoch(1706486400000) = 2024-01-29T00:00:00.000Z
519
+ * Expected: 8 bytes, u64 big-endian
520
+ */
521
+ epochMs: 17064864e5,
522
+ expectedEpochBytes: new Uint8Array([0, 0, 1, 141, 82, 132, 4, 0]),
523
+ /**
524
+ * Sample RelyingPartyId for test vectors
525
+ */
526
+ sampleRpId: {
527
+ domain: "merchant.example.com",
528
+ audience_uri: "https://merchant.example.com/verify",
529
+ verifier_key_hash: "a".repeat(64)
530
+ },
531
+ /**
532
+ * Sample TransactionContext for test vectors
533
+ */
534
+ sampleTxContext: {
535
+ relying_party_id: {
536
+ domain: "merchant.example.com",
537
+ audience_uri: "https://merchant.example.com/verify",
538
+ verifier_key_hash: "a".repeat(64)
539
+ },
540
+ operation_hash: "b".repeat(64),
541
+ not_before: "2026-01-29T00:00:00Z",
542
+ not_after: "2026-01-29T00:05:00Z"
543
+ },
544
+ /**
545
+ * MAX_WINDOW_MS: Maximum allowed not_after - not_before (5 minutes)
546
+ */
547
+ MAX_WINDOW_MS: 5 * 60 * 1e3
548
+ };
549
+ function validateTimeWindow(context) {
550
+ let notBefore;
551
+ let notAfter;
552
+ try {
553
+ notBefore = parseRfc3339StrictToMs(context.not_before);
554
+ notAfter = parseRfc3339StrictToMs(context.not_after);
555
+ } catch {
556
+ throw new Error("Invalid timestamp: not_before/not_after must be RFC3339 with timezone");
557
+ }
558
+ if (notAfter <= notBefore) {
559
+ throw new Error("not_after must be greater than not_before");
560
+ }
561
+ const windowMs = notAfter - notBefore;
562
+ if (windowMs > W_GOLDEN_FIXTURES.MAX_WINDOW_MS) {
563
+ throw new Error(
564
+ `Time window ${windowMs}ms exceeds MAX_WINDOW_MS (${W_GOLDEN_FIXTURES.MAX_WINDOW_MS}ms)`
565
+ );
566
+ }
567
+ return true;
568
+ }
569
+
570
+ // src/agents.ts
571
+ import { z as z7 } from "zod";
572
+ var AgentStatusSchema = z7.enum(["ACTIVE", "PENDING", "SUSPENDED", "REVOKED"]).or(z7.string().min(1));
573
+ var AgentTypeSchema = z7.enum(["CUSTOM", "CLAUDE", "GPT", "GEMINI", "CURSOR", "COPILOT", "OTHER"]).or(z7.string().min(1));
574
+ var AgentListItemSchema = z7.object({
575
+ id: z7.string().min(1),
576
+ external_id: z7.string().min(1),
577
+ name: z7.string().min(1),
578
+ status: AgentStatusSchema,
579
+ agent_type: AgentTypeSchema,
580
+ trust_score: z7.number().int().min(0).max(1e3),
581
+ hosting_model: z7.null(),
582
+ declared_tier: z7.null(),
583
+ created_at: z7.string().datetime()
584
+ }).passthrough();
585
+ var AgentsListResponseSchema = z7.object({
586
+ agents: z7.array(AgentListItemSchema),
587
+ _meta: z7.object({
588
+ source: z7.literal("hlos")
589
+ })
590
+ }).passthrough();
591
+ var AgentPassportStubResponseSchema = z7.object({
592
+ passport_id: z7.null(),
593
+ agent_id: z7.string().min(1),
594
+ hosting_model: z7.null(),
595
+ declared_tier: z7.null(),
596
+ effective_tier: z7.null(),
597
+ finality_level: z7.null(),
598
+ graph: z7.object({
599
+ incoming_edges: z7.null(),
600
+ outgoing_edges: z7.null(),
601
+ active_visas: z7.null()
602
+ }).passthrough(),
603
+ links: z7.object({
604
+ passport_url: z7.string().startsWith("/agent-passport/agents/"),
605
+ docs_url: z7.literal("/agents/passport")
606
+ }).passthrough(),
607
+ _meta: z7.object({
608
+ source: z7.literal("stub")
609
+ })
610
+ }).passthrough();
611
+
612
+ // src/encoding.ts
613
+ import { z as z8 } from "zod";
614
+ function bytesToBase64url(bytes) {
615
+ let binary = "";
616
+ for (let i = 0; i < bytes.length; i++) {
617
+ binary += String.fromCharCode(bytes[i]);
618
+ }
619
+ const base64 = btoa(binary);
620
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
621
+ }
622
+ function base64urlToBytes(str) {
623
+ const base64 = str.replace(/-/g, "+").replace(/_/g, "/");
624
+ const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
625
+ const binary = atob(padded);
626
+ const bytes = new Uint8Array(binary.length);
627
+ for (let i = 0; i < binary.length; i++) {
628
+ bytes[i] = binary.charCodeAt(i);
629
+ }
630
+ return bytes;
631
+ }
632
+ var BASE64URL_SHA256_REGEX = /^[A-Za-z0-9_-]{43}$/;
633
+ var Base64urlSha256Schema = z8.string().regex(
634
+ BASE64URL_SHA256_REGEX,
635
+ "Must be 43-char base64url (32-byte SHA-256 digest)"
636
+ );
637
+ var Base64urlEd25519SigSchema = z8.string().regex(
638
+ /^[A-Za-z0-9_-]{86}$/,
639
+ "Must be 86-char base64url (64-byte Ed25519 signature)"
640
+ );
641
+
642
+ // src/receipt-hash.ts
643
+ var cachedSha256 = null;
644
+ function sortKeysDeep(value) {
645
+ if (Array.isArray(value)) return value.map(sortKeysDeep);
646
+ if (value !== null && typeof value === "object") {
647
+ const obj = value;
648
+ const out = {};
649
+ for (const key of Object.keys(obj).sort()) {
650
+ out[key] = sortKeysDeep(obj[key]);
651
+ }
652
+ return out;
653
+ }
654
+ return value;
655
+ }
656
+ function jcsCanonicalize(value) {
657
+ return JSON.stringify(sortKeysDeep(value), (_key, v) => {
658
+ if (v === void 0) throw new Error("JCS: undefined is not allowed");
659
+ if (typeof v === "function") throw new Error("JCS: function is not allowed");
660
+ if (typeof v === "symbol") throw new Error("JCS: symbol is not allowed");
661
+ if (typeof v === "bigint") throw new Error("JCS: bigint is not allowed");
662
+ if (typeof v === "number" && !Number.isFinite(v))
663
+ throw new Error("JCS: non-finite number is not allowed");
664
+ return v;
665
+ });
666
+ }
667
+ function computeReceiptHash(receipt) {
668
+ const sha256 = loadSha256();
669
+ const canonical = jcsCanonicalize(receipt);
670
+ const digest = sha256(new TextEncoder().encode(canonical));
671
+ return bytesToBase64url(digest);
672
+ }
673
+ function computeContentHash(content) {
674
+ const sha256 = loadSha256();
675
+ const canonical = jcsCanonicalize(content);
676
+ const digest = sha256(new TextEncoder().encode(canonical));
677
+ return bytesToBase64url(digest);
678
+ }
679
+ function loadSha256() {
680
+ if (cachedSha256) return cachedSha256;
681
+ let _require;
682
+ try {
683
+ const { createRequire } = __require("module");
684
+ _require = createRequire(import.meta.url);
685
+ } catch {
686
+ _require = __require;
687
+ }
688
+ let sha256;
689
+ try {
690
+ sha256 = _require("@noble/hashes/sha2.js").sha256;
691
+ } catch {
692
+ try {
693
+ sha256 = _require("@noble/hashes/sha2").sha256;
694
+ } catch {
695
+ throw new Error(
696
+ "computeReceiptHash/computeContentHash requires @noble/hashes as a peer dependency. Install it: npm install @noble/hashes"
697
+ );
698
+ }
699
+ }
700
+ cachedSha256 = sha256;
701
+ return sha256;
702
+ }
703
+ var ReceiptHashSchema = Base64urlSha256Schema.describe(
704
+ "receipt_hash: base64url(SHA-256(JCS(receipt)))"
705
+ );
706
+ var RECEIPT_HASH_GOLDEN_FIXTURE = {
707
+ receipt: {
708
+ "@type": "https://hlos.ai/schema/SignedReceiptV0",
709
+ version: 0,
710
+ receipt_id: "rcpt_01HZGOLDENTEST000000000000",
711
+ content: {
712
+ type: "CrossingSettled",
713
+ crossingId: "cross_test123abc456def789ghi",
714
+ settlement_authority: "hlos.ai"
715
+ },
716
+ // Placeholder bytes (NOT a valid cryptographic signature)
717
+ content_hash: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
718
+ signature: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
719
+ key_id: "hlos-v2-1",
720
+ issued_at: "2026-01-27T00:00:00.000Z"
721
+ },
722
+ /**
723
+ * Expected JCS canonical form of the receipt.
724
+ * Keys are lexicographically sorted at all levels.
725
+ */
726
+ expectedJcs: '{"@type":"https://hlos.ai/schema/SignedReceiptV0","content":{"crossingId":"cross_test123abc456def789ghi","settlement_authority":"hlos.ai","type":"CrossingSettled"},"content_hash":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","issued_at":"2026-01-27T00:00:00.000Z","key_id":"hlos-v2-1","receipt_id":"rcpt_01HZGOLDENTEST000000000000","signature":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","version":0}',
727
+ /**
728
+ * Expected receipt_hash (FROZEN).
729
+ * Compute: JCS canonicalize receipt → SHA-256 → base64url (no padding)
730
+ *
731
+ * DO NOT CHANGE unless the receipt fixture above changes.
732
+ */
733
+ expectedReceiptHash: "uLiQVUeVKcE35Rdje2fArZQfTcECDgwK6UbmQB_36Pg"
734
+ };
735
+
736
+ // src/finality.ts
737
+ import { z as z9 } from "zod";
738
+ var NA_ID_PREFIX = "na_";
739
+ var FinalityLevel = {
740
+ SOFT: "SOFT",
741
+ HARD: "HARD"
742
+ };
743
+ var NotaryAttestationIdFormatSchema = z9.string().regex(
744
+ /^na_[a-zA-Z0-9]{20,}$/,
745
+ "NA ID must match na_[a-zA-Z0-9]{20,}"
746
+ );
747
+ var LogInclusionProofSchema = z9.object({
748
+ /** Merkle root hash (base64url SHA-256) */
749
+ root: Base64urlSha256Schema,
750
+ /** Sibling hashes along the path (base64url SHA-256 each) */
751
+ proof: z9.array(Base64urlSha256Schema),
752
+ /** Leaf index in the log */
753
+ index: z9.number().int().nonnegative()
754
+ });
755
+ var NotaryAttestationSchema = z9.object({
756
+ // --- Required ---
757
+ /** Unique NA identifier */
758
+ na_id: NotaryAttestationIdFormatSchema,
759
+ /** The receipt_hash this NA attests to */
760
+ receipt_hash: Base64urlSha256Schema,
761
+ /** Notary service identifier (e.g. "staampid") */
762
+ notary_id: z9.string().min(1),
763
+ /** ISO 8601 timestamp when NA was issued */
764
+ issued_at: z9.string().datetime(),
765
+ /** Notary's countersignature (base64url encoded) */
766
+ signature: z9.string().min(1),
767
+ /** Signature algorithm (e.g. "EdDSA") */
768
+ signature_alg: z9.string().min(1),
769
+ // --- Optional (future-proof) ---
770
+ /** Receipt type being attested */
771
+ receipt_type: z9.string().optional(),
772
+ /** Receipt version being attested */
773
+ receipt_version: z9.number().int().nonnegative().optional(),
774
+ /** Settlement authority that issued the receipt (cross-check) */
775
+ settlement_authority: z9.string().optional(),
776
+ /** TTL in seconds for this attestation */
777
+ validity_window_seconds: z9.number().int().positive().optional(),
778
+ /** ISO 8601 expiry (derived from issued_at + validity_window_seconds) */
779
+ expires_at: z9.string().datetime().optional(),
780
+ /** Merkle proof for append-only log inclusion */
781
+ log_inclusion: LogInclusionProofSchema.optional()
782
+ });
783
+ var NotaryRequestSchema = z9.object({
784
+ /** receipt_hash to be attested (base64url SHA-256) */
785
+ receipt_hash: Base64urlSha256Schema,
786
+ /** Must be literal 'hlos.ai' */
787
+ settlement_authority: z9.literal(SETTLEMENT_AUTHORITY),
788
+ /** Crossing this receipt belongs to */
789
+ crossing_id: z9.string().min(1),
790
+ /** Type of the receipt being attested */
791
+ receipt_type: z9.string().min(1),
792
+ /** Version of the receipt being attested */
793
+ receipt_version: z9.number().int().nonnegative(),
794
+ /** ISO 8601 timestamp of the request */
795
+ timestamp: z9.string().datetime(),
796
+ /** Optional: requested validity window in seconds */
797
+ validity_window_seconds: z9.number().int().positive().optional()
798
+ });
799
+ var NotarizeStatusSchema = z9.enum([
800
+ "HARD",
801
+ // NA obtained, finality upgraded
802
+ "PENDING",
803
+ // Notarization in progress (async)
804
+ "FAILED",
805
+ // Notarization failed
806
+ "ALREADY_HARD"
807
+ // Receipt already has NA
808
+ ]);
809
+ var NotarizeResponseSchema = z9.object({
810
+ /** Finality status after this operation */
811
+ status: NotarizeStatusSchema,
812
+ /** The receipt_hash that was notarized */
813
+ receipt_hash: Base64urlSha256Schema,
814
+ /** Hash of the NA itself (optional, present when status is HARD) */
815
+ na_hash: Base64urlSha256Schema.optional(),
816
+ /** The full NA object (optional embed) */
817
+ na: NotaryAttestationSchema.optional(),
818
+ /** Notary service identifier */
819
+ notary: z9.string().min(1).optional(),
820
+ /** NA ID for retrieval */
821
+ notary_receipt_id: z9.string().optional(),
822
+ /** ISO 8601 timestamp */
823
+ timestamp: z9.string().datetime(),
824
+ /** Error details (present when status is FAILED) */
825
+ error: z9.string().optional()
826
+ });
827
+ function isNotaryAttestation(value) {
828
+ return NotaryAttestationSchema.safeParse(value).success;
829
+ }
830
+ function isNotaryRequest(value) {
831
+ return NotaryRequestSchema.safeParse(value).success;
832
+ }
833
+ var ArtifactRefSchema = z9.object({
834
+ /** Artifact type */
835
+ type: z9.enum(["CR", "LAT", "EGP", "SA", "SignedReceiptV0", "NA"]),
836
+ /** base64url SHA-256 hash of the artifact */
837
+ hash: Base64urlSha256Schema,
838
+ /** Issuer of the artifact */
839
+ issuer: z9.string().min(1),
840
+ /** Schema version */
841
+ version: z9.string().min(1),
842
+ /** Optional retrieval URI */
843
+ uri: z9.string().url().optional()
844
+ });
845
+ var FINALITY_GOLDEN_FIXTURES = {
846
+ /** Sample NotaryAttestation */
847
+ notaryAttestation: {
848
+ na_id: "na_01HZGOLDENNATEST00000000",
849
+ receipt_hash: "uLiQVUeVKcE35Rdje2fArZQfTcECDgwK6UbmQB_36Pg",
850
+ notary_id: "staampid",
851
+ issued_at: "2026-01-27T00:01:00.000Z",
852
+ signature: "dGVzdF9ub3Rhcnlfc2lnbmF0dXJlXzY0X2J5dGVzX3BhZGRlZF90b19maWxsXzg2X2NoYXJhY3RlcnNf",
853
+ signature_alg: "EdDSA",
854
+ receipt_type: "SignedReceiptV0",
855
+ receipt_version: 0,
856
+ settlement_authority: "hlos.ai"
857
+ },
858
+ /** Sample NotaryRequest */
859
+ notaryRequest: {
860
+ receipt_hash: "uLiQVUeVKcE35Rdje2fArZQfTcECDgwK6UbmQB_36Pg",
861
+ settlement_authority: "hlos.ai",
862
+ crossing_id: "cross_test123abc456def789ghi",
863
+ receipt_type: "SignedReceiptV0",
864
+ receipt_version: 0,
865
+ timestamp: "2026-01-27T00:00:30.000Z"
866
+ },
867
+ /** Sample successful notarize response */
868
+ notarizeResponseHard: {
869
+ status: "HARD",
870
+ receipt_hash: "uLiQVUeVKcE35Rdje2fArZQfTcECDgwK6UbmQB_36Pg",
871
+ na_hash: "_rkedsyWZhokzye55M9NRAvIKFTxFCYTHVOPjg9cAfU",
872
+ notary: "staampid",
873
+ notary_receipt_id: "na_01HZGOLDENNATEST00000000",
874
+ timestamp: "2026-01-27T00:01:00.000Z"
875
+ }
876
+ };
877
+ export {
878
+ AgentListItemSchema,
879
+ AgentPassportStubResponseSchema,
880
+ AgentStatusSchema,
881
+ AgentTypeSchema,
882
+ AgentsListResponseSchema,
883
+ ArtifactRefSchema,
884
+ AvailabilityTypeSchema,
885
+ BASE64URL_SHA256_REGEX,
886
+ Base64urlEd25519SigSchema,
887
+ Base64urlSha256Schema,
888
+ CONTENT_HASH_LENGTH,
889
+ CorrelationIdSchema,
890
+ CredentialSourceSchema,
891
+ CrossingHashInputV0Schema,
892
+ CrossingIdFormatSchema,
893
+ CrossingIdSchema,
894
+ CrossingSettledReceiptSchema,
895
+ CrossingSnapshotV0Schema,
896
+ ERROR_CODE_STATUS,
897
+ ErrorResponseSchema,
898
+ FINALITY_GOLDEN_FIXTURES,
899
+ FinalityLevel,
900
+ FundingSourceSchema,
901
+ GOLDEN_FIXTURES,
902
+ IdempotencyKeySchema,
903
+ KernelErrorCodeSchema2 as KernelErrorCodeSchema,
904
+ KernelErrorSchema,
905
+ KernelOkSchema,
906
+ LogInclusionProofSchema,
907
+ NA_ID_PREFIX,
908
+ NotarizeResponseSchema,
909
+ NotarizeStatusSchema,
910
+ NotaryAttestationIdFormatSchema,
911
+ NotaryAttestationSchema,
912
+ NotaryRequestSchema,
913
+ PassportIdFormatSchema,
914
+ PassportIdSchema,
915
+ ProviderRoleSchema,
916
+ RECEIPT_HASH_GOLDEN_FIXTURE,
917
+ RECEIPT_TYPE_URI,
918
+ RECEIPT_VERSION,
919
+ RPIDSchema,
920
+ ReceiptHashSchema,
921
+ ReceiptIdFormatSchema,
922
+ ReceiptIdSchema,
923
+ RelyingPartyIdSchema,
924
+ RotationEpochSchema,
925
+ SETTLEMENT_AUTHORITY,
926
+ SIGNATURE_LENGTH,
927
+ SURFACES,
928
+ SignedReceiptV0LooseSchema,
929
+ SignedReceiptV0Schema,
930
+ StackConnectionSchema,
931
+ StackProviderSchema,
932
+ StackSchema,
933
+ SuccessResponseSchema,
934
+ SurfaceSchema,
935
+ TransactionContextHashSchema,
936
+ TransactionContextSchema,
937
+ W_GOLDEN_FIXTURES,
938
+ W_RPID_DOMAIN,
939
+ W_TXCTX_DOMAIN,
940
+ WalletIdFormatSchema,
941
+ WalletIdSchema,
942
+ base64urlToBytes,
943
+ bytesToBase64url,
944
+ computeContentHash,
945
+ computeReceiptHash,
946
+ deriveFundingSource,
947
+ encodeEpoch,
948
+ error,
949
+ generateCrossingId,
950
+ generateId,
951
+ generatePassportId,
952
+ generateReceiptId,
953
+ generateWalletId,
954
+ isCrossingHashInputV0,
955
+ isCrossingSettledReceipt,
956
+ isNotaryAttestation,
957
+ isNotaryRequest,
958
+ isSignedReceiptV0,
959
+ jcsCanonicalize,
960
+ kernelError,
961
+ kernelOk,
962
+ success,
963
+ validateTimeWindow
964
+ };
965
+ //# sourceMappingURL=index.js.map