@treeseed/sdk 0.13.0-rc.55 → 0.13.0-rc.56

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 (33) hide show
  1. package/dist/agent-capacity/contracts/capacity/providers/supply-policy.d.ts +0 -2
  2. package/dist/agent-capacity/validation/activity-profile.js +18 -9
  3. package/dist/agent-capacity/validation/agent-definition-schema.d.ts +540 -618
  4. package/dist/agent-capacity/validation/agent-definition-schema.js +8 -28
  5. package/dist/agent-capacity/validation/agent-lab-forensics-schema.d.ts +11 -11
  6. package/dist/capacity-provider/capability-ontology.d.ts +1211 -0
  7. package/dist/capacity-provider/capability-ontology.js +200 -0
  8. package/dist/capacity-provider/contracts/governance.d.ts +37 -2
  9. package/dist/capacity-provider/core-capability-catalog.d.ts +47 -0
  10. package/dist/capacity-provider/core-capability-catalog.js +63 -0
  11. package/dist/capacity-provider/environment-catalog.d.ts +877 -0
  12. package/dist/capacity-provider/environment-catalog.js +116 -0
  13. package/dist/capacity-provider/index.d.ts +3 -0
  14. package/dist/capacity-provider/index.js +3 -0
  15. package/dist/capacity-provider/sandbox-contracts.d.ts +147 -26
  16. package/dist/capacity-provider/sandbox-contracts.js +16 -1
  17. package/dist/capacity-provider/validation.d.ts +2 -1
  18. package/dist/capacity-provider/validation.js +34 -1
  19. package/dist/content/validation/content-model-schemas.d.ts +985 -1128
  20. package/dist/content/validation/portable-content-data.d.ts +90 -103
  21. package/dist/deployment/schemas.d.ts +17 -17
  22. package/dist/deployment/schemas.js +1 -1
  23. package/dist/operator-contracts/canonical-command-tree.js +6 -0
  24. package/dist/operator-contracts/catalog/capability-ontology-operations.d.ts +164 -0
  25. package/dist/operator-contracts/catalog/capability-ontology-operations.js +24 -0
  26. package/dist/operator-contracts/catalog/control-plane-catalog.d.ts +6 -0
  27. package/dist/operator-contracts/catalog/control-plane-catalog.js +18 -0
  28. package/dist/operator-contracts/control-plane-operations.d.ts +510 -342
  29. package/dist/operator-contracts/control-plane-operations.js +7 -10
  30. package/dist/operator-contracts/index.d.ts +1 -0
  31. package/dist/operator-contracts/index.js +1 -0
  32. package/dist/types/agents/agent-activity-profile.d.ts +15 -33
  33. package/package.json +1 -1
@@ -0,0 +1,116 @@
1
+ import { createHash, createPublicKey, verify } from "node:crypto";
2
+ import { z } from "zod";
3
+ const identifier = z.string().regex(/^[a-z][a-z0-9._-]{0,127}$/u);
4
+ const digest = z.string().regex(/^sha256:[a-f0-9]{64}$/u);
5
+ const version = z.string().regex(/^\d+\.\d+\.\d+$/u);
6
+ const sandboxEnvironmentContractSchema = z.object({
7
+ id: identifier,
8
+ version,
9
+ digest,
10
+ capabilities: z.array(identifier)
11
+ }).strict();
12
+ const provenance = z.object({
13
+ sourceRepository: z.string().url(),
14
+ sourceRevision: z.union([z.string().regex(/^[a-f0-9]{40}$/u), digest]),
15
+ buildRecipeDigest: digest,
16
+ sbomDigest: digest,
17
+ signature: z.object({ keyId: identifier, algorithm: z.enum(["Ed25519", "cosign"]), value: z.string().min(1) }).strict()
18
+ }).strict();
19
+ const sandboxEnvironmentCatalogEntrySchema = z.object({
20
+ id: identifier,
21
+ version,
22
+ kind: z.enum(["base", "extension"]),
23
+ contract: sandboxEnvironmentContractSchema,
24
+ image: z.object({ reference: z.string().min(1), digest, architectures: z.array(z.enum(["amd64", "arm64"])).min(1), operatingSystem: z.literal("linux") }).strict(),
25
+ derivedFrom: z.array(z.object({ entryId: identifier, version, imageDigest: digest }).strict()).min(1).nullable(),
26
+ provenance,
27
+ qualification: z.object({ suiteId: identifier, suiteVersion: version, evidenceDigest: digest, status: z.literal("passed"), completedAt: z.string().datetime() }).strict(),
28
+ status: z.enum(["active", "deprecated", "revoked"]),
29
+ createdAt: z.string().datetime()
30
+ }).strict().superRefine((entry, context) => {
31
+ if (new Set(entry.image.architectures).size !== entry.image.architectures.length) context.addIssue({ code: z.ZodIssueCode.custom, path: ["image", "architectures"], message: "Image architectures must be unique." });
32
+ if (entry.kind === "base" && entry.derivedFrom !== null) context.addIssue({ code: z.ZodIssueCode.custom, path: ["derivedFrom"], message: "Base environments cannot derive from another catalog entry." });
33
+ if (entry.kind === "extension" && entry.derivedFrom === null) context.addIssue({ code: z.ZodIssueCode.custom, path: ["derivedFrom"], message: "Extended environments require exact catalog bases." });
34
+ });
35
+ const sandboxEnvironmentCatalogSchema = z.object({
36
+ schemaVersion: z.literal("treeseed.sandbox-environment-catalog/v1"),
37
+ generation: z.number().int().positive(),
38
+ catalogDigest: digest,
39
+ rootPolicy: z.object({ allowedBaseImageDigests: z.array(digest).min(1) }).strict(),
40
+ entries: z.array(sandboxEnvironmentCatalogEntrySchema),
41
+ createdAt: z.string().datetime(),
42
+ signature: z.object({ keyId: identifier, algorithm: z.literal("Ed25519"), value: z.string().min(1) }).strict()
43
+ }).strict().superRefine((catalog, context) => {
44
+ const entries = new Map(catalog.entries.map((entry) => [`${entry.id}@${entry.version}`, entry]));
45
+ for (const [index, entry] of catalog.entries.entries()) {
46
+ if (entry.kind === "base" && !catalog.rootPolicy.allowedBaseImageDigests.includes(entry.image.digest)) context.addIssue({ code: z.ZodIssueCode.custom, path: ["entries", index, "image", "digest"], message: "Base image is not an allowed catalog root." });
47
+ if (entry.kind !== "extension" || !entry.derivedFrom) continue;
48
+ const parentArchitectures = /* @__PURE__ */ new Set();
49
+ for (const [parentIndex, reference] of entry.derivedFrom.entries()) {
50
+ const parent = entries.get(`${reference.entryId}@${reference.version}`);
51
+ if (!parent || parent.image.digest !== reference.imageDigest) {
52
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["entries", index, "derivedFrom", parentIndex], message: "Environment extension does not bind an exact entry in this catalog." });
53
+ continue;
54
+ }
55
+ const pending = [parent], seen = /* @__PURE__ */ new Set(), roots = [];
56
+ while (pending.length) {
57
+ const current = pending.pop(), key = `${current.id}@${current.version}`;
58
+ if (seen.has(key)) {
59
+ roots.length = 0;
60
+ break;
61
+ }
62
+ seen.add(key);
63
+ if (current.kind === "base") {
64
+ roots.push(current);
65
+ continue;
66
+ }
67
+ for (const ancestor of current.derivedFrom ?? []) {
68
+ const resolved = entries.get(`${ancestor.entryId}@${ancestor.version}`);
69
+ if (!resolved || resolved.image.digest !== ancestor.imageDigest) {
70
+ roots.length = 0;
71
+ pending.length = 0;
72
+ break;
73
+ }
74
+ pending.push(resolved);
75
+ }
76
+ }
77
+ if (!roots.length || roots.some((root) => !catalog.rootPolicy.allowedBaseImageDigests.includes(root.image.digest))) context.addIssue({ code: z.ZodIssueCode.custom, path: ["entries", index, "derivedFrom", parentIndex], message: "Environment extension does not resolve to an allowed catalog root." });
78
+ else for (const root of roots) for (const architecture of root.image.architectures) parentArchitectures.add(architecture);
79
+ }
80
+ for (const architecture of entry.image.architectures) if (!parentArchitectures.has(architecture)) context.addIssue({ code: z.ZodIssueCode.custom, path: ["entries", index, "derivedFrom"], message: `Environment extension has no allowed ${architecture} base.` });
81
+ }
82
+ });
83
+ const providerSandboxEnvironmentAvailabilitySchema = z.object({
84
+ schemaVersion: z.literal("treeseed.provider-sandbox-environments/v1"),
85
+ providerId: z.string().min(1),
86
+ catalogGeneration: z.number().int().positive(),
87
+ catalogDigest: digest,
88
+ entries: z.array(z.object({ entryId: identifier, version, contractDigest: digest, imageDigest: digest, status: z.enum(["pulling", "ready", "failed", "quarantined"]), checkedAt: z.string().datetime(), reason: z.string().min(1).nullable() }).strict())
89
+ }).strict();
90
+ function canonical(value) {
91
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
92
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
93
+ return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`).join(",")}}`;
94
+ }
95
+ function sandboxEnvironmentCatalogDigest(value) {
96
+ return `sha256:${createHash("sha256").update(canonical(value)).digest("hex")}`;
97
+ }
98
+ function sandboxEnvironmentCatalogSigningBytes(value) {
99
+ return Buffer.from(canonical({ ...value, signature: { ...value.signature, value: "" } }));
100
+ }
101
+ function verifySandboxEnvironmentCatalog(value, publicJwk) {
102
+ const catalog = sandboxEnvironmentCatalogSchema.parse(value);
103
+ const { catalogDigest, signature: _signature, ...material } = catalog;
104
+ if (sandboxEnvironmentCatalogDigest(material) !== catalogDigest) throw new Error("Sandbox environment catalog digest does not match its canonical content.");
105
+ if (!verify(null, sandboxEnvironmentCatalogSigningBytes(catalog), createPublicKey({ key: publicJwk, format: "jwk" }), Buffer.from(catalog.signature.value, "base64url"))) throw new Error("Sandbox environment catalog signature is invalid.");
106
+ return catalog;
107
+ }
108
+ export {
109
+ providerSandboxEnvironmentAvailabilitySchema,
110
+ sandboxEnvironmentCatalogDigest,
111
+ sandboxEnvironmentCatalogEntrySchema,
112
+ sandboxEnvironmentCatalogSchema,
113
+ sandboxEnvironmentCatalogSigningBytes,
114
+ sandboxEnvironmentContractSchema,
115
+ verifySandboxEnvironmentCatalog
116
+ };
@@ -2,3 +2,6 @@ export * from './client.js';
2
2
  export * from './contracts/index.js';
3
3
  export * from './validation.js';
4
4
  export * from './sandbox-contracts.js';
5
+ export * from './environment-catalog.js';
6
+ export * from './capability-ontology.js';
7
+ export * from './core-capability-catalog.js';
@@ -2,3 +2,6 @@ export * from "./client.js";
2
2
  export * from "./contracts/index.js";
3
3
  export * from "./validation.js";
4
4
  export * from "./sandbox-contracts.js";
5
+ export * from "./environment-catalog.js";
6
+ export * from "./capability-ontology.js";
7
+ export * from "./core-capability-catalog.js";
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- declare const sandboxProfile: z.ZodEnum<["read", "unit", "integration", "platform", "connected"]>;
2
+ declare const sandboxProfile: z.ZodString;
3
3
  export declare const sandboxAssignmentSchema: z.ZodObject<{
4
4
  schemaVersion: z.ZodLiteral<"treeseed.sandbox-assignment/v1">;
5
5
  assignmentId: z.ZodString;
@@ -8,7 +8,23 @@ export declare const sandboxAssignmentSchema: z.ZodObject<{
8
8
  providerId: z.ZodString;
9
9
  teamId: z.ZodString;
10
10
  projectId: z.ZodString;
11
- profile: z.ZodEnum<["read", "unit", "integration", "platform", "connected"]>;
11
+ profile: z.ZodString;
12
+ environmentContract: z.ZodOptional<z.ZodObject<{
13
+ id: z.ZodString;
14
+ version: z.ZodString;
15
+ digest: z.ZodString;
16
+ capabilities: z.ZodArray<z.ZodString, "many">;
17
+ }, "strict", z.ZodTypeAny, {
18
+ id: string;
19
+ digest: string;
20
+ version: string;
21
+ capabilities: string[];
22
+ }, {
23
+ id: string;
24
+ digest: string;
25
+ version: string;
26
+ capabilities: string[];
27
+ }>>;
12
28
  guestImage: z.ZodString;
13
29
  guestImageDigest: z.ZodString;
14
30
  identityManifestDigest: z.ZodString;
@@ -158,7 +174,7 @@ export declare const sandboxAssignmentSchema: z.ZodObject<{
158
174
  outputBytes: number;
159
175
  };
160
176
  projectId: string;
161
- profile: "read" | "unit" | "integration" | "platform" | "connected";
177
+ profile: string;
162
178
  network: {
163
179
  defaultDeny: true;
164
180
  relayUrl: string;
@@ -169,10 +185,6 @@ export declare const sandboxAssignmentSchema: z.ZodObject<{
169
185
  guestImageDigest: string;
170
186
  providerId: string;
171
187
  runnerId: string;
172
- leaseExpiresAt: string;
173
- attempt: number;
174
- identityManifestDigest: string;
175
- contextManifestDigest: string;
176
188
  inputs: {
177
189
  id: string;
178
190
  mediaType: string;
@@ -181,6 +193,15 @@ export declare const sandboxAssignmentSchema: z.ZodObject<{
181
193
  disposition: "read-only" | "copy-on-write";
182
194
  targetPath: string;
183
195
  }[];
196
+ signature: {
197
+ value: string;
198
+ algorithm: "Ed25519";
199
+ keyId: string;
200
+ };
201
+ leaseExpiresAt: string;
202
+ attempt: number;
203
+ identityManifestDigest: string;
204
+ contextManifestDigest: string;
184
205
  modelPolicy: {
185
206
  provider: string;
186
207
  capabilities: string[];
@@ -195,11 +216,12 @@ export declare const sandboxAssignmentSchema: z.ZodObject<{
195
216
  revealAllowed: false;
196
217
  }[];
197
218
  treeDxHandleIds: string[];
198
- signature: {
199
- value: string;
200
- algorithm: "Ed25519";
201
- keyId: string;
202
- };
219
+ environmentContract?: {
220
+ id: string;
221
+ digest: string;
222
+ version: string;
223
+ capabilities: string[];
224
+ } | undefined;
203
225
  }, {
204
226
  teamId: string;
205
227
  assignmentId: string;
@@ -219,7 +241,7 @@ export declare const sandboxAssignmentSchema: z.ZodObject<{
219
241
  outputBytes: number;
220
242
  };
221
243
  projectId: string;
222
- profile: "read" | "unit" | "integration" | "platform" | "connected";
244
+ profile: string;
223
245
  network: {
224
246
  defaultDeny: true;
225
247
  relayUrl: string;
@@ -230,10 +252,6 @@ export declare const sandboxAssignmentSchema: z.ZodObject<{
230
252
  guestImageDigest: string;
231
253
  providerId: string;
232
254
  runnerId: string;
233
- leaseExpiresAt: string;
234
- attempt: number;
235
- identityManifestDigest: string;
236
- contextManifestDigest: string;
237
255
  inputs: {
238
256
  id: string;
239
257
  mediaType: string;
@@ -242,6 +260,15 @@ export declare const sandboxAssignmentSchema: z.ZodObject<{
242
260
  disposition: "read-only" | "copy-on-write";
243
261
  targetPath: string;
244
262
  }[];
263
+ signature: {
264
+ value: string;
265
+ algorithm: "Ed25519";
266
+ keyId: string;
267
+ };
268
+ leaseExpiresAt: string;
269
+ attempt: number;
270
+ identityManifestDigest: string;
271
+ contextManifestDigest: string;
245
272
  modelPolicy: {
246
273
  provider: string;
247
274
  capabilities: string[];
@@ -256,11 +283,12 @@ export declare const sandboxAssignmentSchema: z.ZodObject<{
256
283
  revealAllowed: false;
257
284
  }[];
258
285
  treeDxHandleIds: string[];
259
- signature: {
260
- value: string;
261
- algorithm: "Ed25519";
262
- keyId: string;
263
- };
286
+ environmentContract?: {
287
+ id: string;
288
+ digest: string;
289
+ version: string;
290
+ capabilities: string[];
291
+ } | undefined;
264
292
  }>;
265
293
  export declare const sandboxEventSchema: z.ZodObject<{
266
294
  schemaVersion: z.ZodLiteral<"treeseed.sandbox-event/v1">;
@@ -313,26 +341,26 @@ export declare const sandboxLeaseRenewalSchema: z.ZodObject<{
313
341
  assignmentId: string;
314
342
  schemaVersion: "treeseed.sandbox-lease-renewal/v1";
315
343
  providerId: string;
316
- leaseExpiresAt: string;
317
- issuedAt: string;
318
344
  signature: {
319
345
  value: string;
320
346
  algorithm: "Ed25519";
321
347
  keyId: string;
322
348
  };
349
+ issuedAt: string;
350
+ leaseExpiresAt: string;
323
351
  sandboxId: string;
324
352
  }, {
325
353
  teamId: string;
326
354
  assignmentId: string;
327
355
  schemaVersion: "treeseed.sandbox-lease-renewal/v1";
328
356
  providerId: string;
329
- leaseExpiresAt: string;
330
- issuedAt: string;
331
357
  signature: {
332
358
  value: string;
333
359
  algorithm: "Ed25519";
334
360
  keyId: string;
335
361
  };
362
+ issuedAt: string;
363
+ leaseExpiresAt: string;
336
364
  sandboxId: string;
337
365
  }>;
338
366
  export declare const sandboxResultSchema: z.ZodObject<{
@@ -414,9 +442,102 @@ export declare const sandboxResultSchema: z.ZodObject<{
414
442
  diagnostics?: Record<string, unknown> | undefined;
415
443
  responseMarkdown?: string | undefined;
416
444
  }>;
445
+ export declare const providerEnvironmentReceiptSchema: z.ZodObject<{
446
+ schemaVersion: z.ZodLiteral<"treeseed.provider-environment-receipt/v1">;
447
+ assignmentId: z.ZodString;
448
+ offerId: z.ZodString;
449
+ providerId: z.ZodString;
450
+ imageDigest: z.ZodString;
451
+ baseLineage: z.ZodObject<{
452
+ baseImageDigest: z.ZodString;
453
+ provenanceDigest: z.ZodString;
454
+ architectures: z.ZodArray<z.ZodEnum<["amd64", "arm64"]>, "many">;
455
+ }, "strict", z.ZodTypeAny, {
456
+ baseImageDigest: string;
457
+ provenanceDigest: string;
458
+ architectures: ("amd64" | "arm64")[];
459
+ }, {
460
+ baseImageDigest: string;
461
+ provenanceDigest: string;
462
+ architectures: ("amd64" | "arm64")[];
463
+ }>;
464
+ securityAttestationDigest: z.ZodString;
465
+ brokerVersion: z.ZodString;
466
+ teardown: z.ZodObject<{
467
+ verified: z.ZodBoolean;
468
+ completedAt: z.ZodNullable<z.ZodString>;
469
+ }, "strict", z.ZodTypeAny, {
470
+ completedAt: string | null;
471
+ verified: boolean;
472
+ }, {
473
+ completedAt: string | null;
474
+ verified: boolean;
475
+ }>;
476
+ createdAt: z.ZodString;
477
+ signature: z.ZodObject<{
478
+ keyId: z.ZodString;
479
+ algorithm: z.ZodLiteral<"Ed25519">;
480
+ value: z.ZodString;
481
+ }, "strict", z.ZodTypeAny, {
482
+ value: string;
483
+ algorithm: "Ed25519";
484
+ keyId: string;
485
+ }, {
486
+ value: string;
487
+ algorithm: "Ed25519";
488
+ keyId: string;
489
+ }>;
490
+ }, "strict", z.ZodTypeAny, {
491
+ assignmentId: string;
492
+ schemaVersion: "treeseed.provider-environment-receipt/v1";
493
+ createdAt: string;
494
+ providerId: string;
495
+ signature: {
496
+ value: string;
497
+ algorithm: "Ed25519";
498
+ keyId: string;
499
+ };
500
+ offerId: string;
501
+ teardown: {
502
+ completedAt: string | null;
503
+ verified: boolean;
504
+ };
505
+ imageDigest: string;
506
+ baseLineage: {
507
+ baseImageDigest: string;
508
+ provenanceDigest: string;
509
+ architectures: ("amd64" | "arm64")[];
510
+ };
511
+ securityAttestationDigest: string;
512
+ brokerVersion: string;
513
+ }, {
514
+ assignmentId: string;
515
+ schemaVersion: "treeseed.provider-environment-receipt/v1";
516
+ createdAt: string;
517
+ providerId: string;
518
+ signature: {
519
+ value: string;
520
+ algorithm: "Ed25519";
521
+ keyId: string;
522
+ };
523
+ offerId: string;
524
+ teardown: {
525
+ completedAt: string | null;
526
+ verified: boolean;
527
+ };
528
+ imageDigest: string;
529
+ baseLineage: {
530
+ baseImageDigest: string;
531
+ provenanceDigest: string;
532
+ architectures: ("amd64" | "arm64")[];
533
+ };
534
+ securityAttestationDigest: string;
535
+ brokerVersion: string;
536
+ }>;
417
537
  export type SandboxAssignment = z.infer<typeof sandboxAssignmentSchema>;
418
538
  export type SandboxEvent = z.infer<typeof sandboxEventSchema>;
419
539
  export type SandboxLeaseRenewal = z.infer<typeof sandboxLeaseRenewalSchema>;
420
540
  export type SandboxResult = z.infer<typeof sandboxResultSchema>;
541
+ export type ProviderEnvironmentReceipt = z.infer<typeof providerEnvironmentReceiptSchema>;
421
542
  export type SandboxEnvironmentProfile = z.infer<typeof sandboxProfile>;
422
543
  export {};
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  const identifier = z.string().regex(/^[a-z][a-z0-9._-]{0,127}$/u);
3
3
  const digest = z.string().regex(/^sha256:[a-f0-9]{64}$/u);
4
- const sandboxProfile = z.enum(["read", "unit", "integration", "platform", "connected"]);
4
+ const sandboxProfile = identifier;
5
5
  const sandboxAssignmentSchema = z.object({
6
6
  schemaVersion: z.literal("treeseed.sandbox-assignment/v1"),
7
7
  assignmentId: z.string().min(1),
@@ -11,6 +11,7 @@ const sandboxAssignmentSchema = z.object({
11
11
  teamId: z.string().min(1),
12
12
  projectId: z.string().min(1),
13
13
  profile: sandboxProfile,
14
+ environmentContract: z.object({ id: identifier, version: z.string().regex(/^\d+\.\d+\.\d+$/u), digest, capabilities: z.array(identifier) }).strict().optional(),
14
15
  guestImage: z.string().min(1),
15
16
  guestImageDigest: digest,
16
17
  identityManifestDigest: digest,
@@ -63,7 +64,21 @@ const sandboxResultSchema = z.object({
63
64
  diagnostics: z.record(z.unknown()).default({}),
64
65
  teardown: z.object({ verified: z.boolean(), completedAt: z.string().datetime().nullable() }).strict()
65
66
  }).strict();
67
+ const providerEnvironmentReceiptSchema = z.object({
68
+ schemaVersion: z.literal("treeseed.provider-environment-receipt/v1"),
69
+ assignmentId: z.string().min(1),
70
+ offerId: identifier,
71
+ providerId: z.string().min(1),
72
+ imageDigest: digest,
73
+ baseLineage: z.object({ baseImageDigest: digest, provenanceDigest: digest, architectures: z.array(z.enum(["amd64", "arm64"])).min(1) }).strict(),
74
+ securityAttestationDigest: digest,
75
+ brokerVersion: z.string().min(1),
76
+ teardown: z.object({ verified: z.boolean(), completedAt: z.string().datetime().nullable() }).strict(),
77
+ createdAt: z.string().datetime(),
78
+ signature: z.object({ keyId: identifier, algorithm: z.literal("Ed25519"), value: z.string().min(1) }).strict()
79
+ }).strict();
66
80
  export {
81
+ providerEnvironmentReceiptSchema,
67
82
  sandboxAssignmentSchema,
68
83
  sandboxEventSchema,
69
84
  sandboxLeaseRenewalSchema,
@@ -1,4 +1,4 @@
1
- import { type CapacityProviderManifestV3, type CapacityProviderManifestV4, type CapacityProviderProofPayload, type CapacityProviderPublicJwk, type ProviderSupplyOffer } from './contracts/index.js';
1
+ import { type CapacityProviderManifestV3, type CapacityProviderManifestV4, type CapacityProviderManifestV5, type CapacityProviderProofPayload, type CapacityProviderPublicJwk, type ProviderSupplyOffer } from './contracts/index.js';
2
2
  export interface CapacityProviderContractDiagnostic {
3
3
  code: string;
4
4
  path: string;
@@ -21,6 +21,7 @@ export declare function validateCapacityProviderProofPayload(payload: CapacityPr
21
21
  export declare function validateProviderSupplyOffer(offer: ProviderSupplyOffer, path?: string): CapacityProviderContractValidation;
22
22
  export declare function validateCapacityProviderManifestV3(manifest: CapacityProviderManifestV3): CapacityProviderContractValidation;
23
23
  export declare function validateCapacityProviderManifestV4(manifest: CapacityProviderManifestV4): CapacityProviderContractValidation;
24
+ export declare function validateCapacityProviderManifestV5(manifest: CapacityProviderManifestV5): CapacityProviderContractValidation;
24
25
  export declare function capacityProviderSecurityDefaults(): {
25
26
  proofTtlSeconds: number;
26
27
  accessTokenTtlSeconds: number;
@@ -187,13 +187,45 @@ function validateCapacityProviderManifestV4(manifest) {
187
187
  if (!manifest.sandbox?.brokerSocket?.startsWith("/run/treeseed/")) add(diagnostics, "provider_sandbox_socket_invalid", "sandbox.brokerSocket", "Sandbox broker socket must remain under /run/treeseed.");
188
188
  const profiles = new Set((manifest.sandbox?.profiles ?? []).map((profile) => profile.id));
189
189
  for (const [index, profile] of (manifest.sandbox?.profiles ?? []).entries()) {
190
- if (!["read", "unit", "integration", "platform", "connected"].includes(profile.id)) add(diagnostics, "provider_sandbox_profile_invalid", `sandbox.profiles[${index}].id`, "Sandbox profile must be one of read, unit, integration, platform, or connected.");
190
+ if (!/^[a-z][a-z0-9._-]{0,127}$/u.test(profile.id)) add(diagnostics, "provider_sandbox_profile_invalid", `sandbox.profiles[${index}].id`, "Sandbox profile id must be a provider-local identifier.");
191
+ if (profile.contract) {
192
+ if (!/^[a-z][a-z0-9._-]{0,127}$/u.test(profile.contract.id) || !/^\d+\.\d+\.\d+$/u.test(profile.contract.version) || !/^sha256:[a-f0-9]{64}$/u.test(profile.contract.digest)) add(diagnostics, "provider_sandbox_contract_invalid", `sandbox.profiles[${index}].contract`, "Portable sandbox contracts require an id, exact semantic version, and immutable digest.");
193
+ if (!Array.isArray(profile.contract.capabilities) || profile.contract.capabilities.some((capability) => !/^[a-z][a-z0-9._-]{0,127}$/u.test(capability))) add(diagnostics, "provider_sandbox_contract_capabilities_invalid", `sandbox.profiles[${index}].contract.capabilities`, "Sandbox contract capabilities must be portable identifiers.");
194
+ }
191
195
  if (!/^sha256:[a-f0-9]{64}$/u.test(profile.guestImageDigest)) add(diagnostics, "provider_sandbox_image_digest_invalid", `sandbox.profiles[${index}].guestImageDigest`, "Guest images require an immutable SHA-256 digest.");
192
196
  if (profile.defaultDenyNetwork !== true) add(diagnostics, "provider_sandbox_network_policy_invalid", `sandbox.profiles[${index}].defaultDenyNetwork`, "Sandbox networking must default deny.");
193
197
  }
194
198
  for (const [index, adapter] of manifest.adapters.entries()) {
195
199
  if (adapter.isolation !== "microvm") add(diagnostics, "provider_v4_microvm_required", `adapters[${index}].isolation`, "Manifest v4 adapters must use microvm isolation.");
196
200
  for (const profile of adapter.sandboxProfileIds ?? []) if (!profiles.has(profile)) add(diagnostics, "provider_sandbox_profile_unknown", `adapters[${index}].sandboxProfileIds`, `Unknown sandbox profile ${profile}.`);
201
+ for (const [purpose, profile] of Object.entries(adapter.defaultSandboxProfiles ?? {})) if (!profiles.has(profile)) add(diagnostics, "provider_sandbox_default_unknown", `adapters[${index}].defaultSandboxProfiles.${purpose}`, `Unknown default sandbox profile ${profile}.`);
202
+ }
203
+ return result(diagnostics);
204
+ }
205
+ function validateCapacityProviderManifestV5(manifest) {
206
+ const compatible = { ...manifest, schemaVersion: 4, adapters: manifest.adapters.map((adapter) => ({
207
+ ...adapter,
208
+ capabilities: [...new Set(adapter.offers.flatMap(({ offer }) => offer.capabilities.map(({ id }) => id)))],
209
+ sandboxProfileIds: [...new Set(adapter.offers.map(({ sandboxProfileId }) => sandboxProfileId))],
210
+ defaultSandboxProfiles: void 0
211
+ })) };
212
+ const diagnostics = validateCapacityProviderManifestV4(compatible).diagnostics.filter((entry) => entry.code !== "provider_sandbox_default_unknown");
213
+ if (manifest.schemaVersion !== 5) add(diagnostics, "provider_manifest_schema_invalid", "schemaVersion", "Capacity provider manifest schemaVersion must be 5.");
214
+ if (!Number.isInteger(manifest.ontology?.generation) || manifest.ontology.generation < 1 || !/^sha256:[a-f0-9]{64}$/u.test(manifest.ontology?.digest ?? "")) add(diagnostics, "provider_ontology_binding_invalid", "ontology", "Manifest v5 requires an exact ontology generation and digest.");
215
+ const profiles = new Set(manifest.sandbox.profiles.map(({ id }) => id)), offerIds = /* @__PURE__ */ new Set();
216
+ for (const [profileIndex, profile] of manifest.sandbox.profiles.entries()) {
217
+ if (!profile.lineage || !/^sha256:[a-f0-9]{64}$/u.test(profile.lineage.baseImageDigest) || !/^sha256:[a-f0-9]{64}$/u.test(profile.lineage.provenanceDigest) || !profile.lineage.architectures.length || !profile.lineage.signature.value) add(diagnostics, "provider_sandbox_lineage_required", `sandbox.profiles[${profileIndex}].lineage`, "Manifest v5 sandbox images require signed exact sandbox-base lineage and architectures.");
218
+ }
219
+ for (const [adapterIndex, adapter] of manifest.adapters.entries()) {
220
+ if (!adapter.offers.length) add(diagnostics, "provider_adapter_offers_required", `adapters[${adapterIndex}].offers`, "Every v5 adapter must expose at least one standardized capability offer.");
221
+ for (const [offerIndex, binding] of adapter.offers.entries()) {
222
+ const path = `adapters[${adapterIndex}].offers[${offerIndex}]`;
223
+ if (offerIds.has(binding.offer.offerId)) add(diagnostics, "provider_offer_id_duplicate", `${path}.offer.offerId`, "Offer ids must be provider-global unique.");
224
+ offerIds.add(binding.offer.offerId);
225
+ if (!profiles.has(binding.sandboxProfileId)) add(diagnostics, "provider_offer_sandbox_unknown", `${path}.sandboxProfileId`, "Offer references an unknown provider-local sandbox profile.");
226
+ if (binding.offer.capabilities.some((reference) => !reference.id.startsWith("treeseed.") && !reference.id.startsWith("provider."))) add(diagnostics, "provider_offer_capability_namespace_invalid", `${path}.offer.capabilities`, "Offers require standardized TreeSeed or provider capability references.");
227
+ if (binding.offer.conformance.some((entry) => entry.status !== "passed")) add(diagnostics, "provider_offer_conformance_failed", `${path}.offer.conformance`, "Only passing capability conformance may be advertised.");
228
+ }
197
229
  }
198
230
  return result(diagnostics);
199
231
  }
@@ -211,6 +243,7 @@ export {
211
243
  result,
212
244
  validateCapacityProviderManifestV3,
213
245
  validateCapacityProviderManifestV4,
246
+ validateCapacityProviderManifestV5,
214
247
  validateCapacityProviderProofPayload,
215
248
  validateCapacityProviderPublicJwk,
216
249
  validateProviderSupplyOffer