@treeseed/sdk 0.13.0-rc.70 → 0.13.0-rc.71

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.
@@ -1 +1 @@
1
- {"completedAt":"2026-09-01T21:09:39.160Z"}
1
+ {"completedAt":"2026-09-02T02:46:28.673Z"}
@@ -21917,7 +21917,7 @@ export declare function describeContentFrontmatterSchema(model: PortableContentM
21917
21917
  }>;
21918
21918
  /** A JSON-safe description derived directly from the canonical validation schema. */
21919
21919
  export declare function describeContentFrontmatterContract(model: PortableContentModel): {
21920
- model: "knowledge" | "agent" | "decision" | "objective" | "workday" | "proposal" | "question" | "group" | "discussion" | "page" | "person" | "note" | "book" | "discussion_message" | "discussion_event" | "group_edge" | "agent_context_query" | "agent_context_query_set" | "agent_instruction_template" | "discussion_topic" | "assignment_plan" | "assignment_status" | "assignment_summary" | "agent_evaluation" | "agent_test" | "template_product";
21920
+ model: "knowledge" | "decision" | "agent" | "objective" | "workday" | "proposal" | "question" | "group" | "discussion" | "page" | "person" | "note" | "book" | "discussion_message" | "discussion_event" | "group_edge" | "agent_context_query" | "agent_context_query_set" | "agent_instruction_template" | "discussion_topic" | "assignment_plan" | "assignment_status" | "assignment_summary" | "agent_evaluation" | "agent_test" | "template_product";
21921
21921
  fields: {
21922
21922
  [k: string]: Record<string, unknown>;
21923
21923
  };
@@ -0,0 +1,777 @@
1
+ import { z } from 'zod';
2
+ export declare const hostedProviderSchema: z.ZodEnum<["cloudflare", "railway"]>;
3
+ export declare const hostedResourceKindSchema: z.ZodEnum<["admin-application", "dns-record", "tls-policy", "api-proxy", "control-plane-api", "postgresql", "operations-runner", "treedx-service"]>;
4
+ export declare const hostedTopologyDeclarationSchema: z.ZodEffects<z.ZodObject<{
5
+ schemaVersion: z.ZodLiteral<"treeseed.hosted-topology/v1">;
6
+ id: z.ZodString;
7
+ environment: z.ZodEnum<["staging", "production"]>;
8
+ mutation: z.ZodLiteral<"approval-required">;
9
+ platform: z.ZodObject<{
10
+ repository: z.ZodLiteral<"treeseed-ai/platform">;
11
+ commit: z.ZodString;
12
+ }, "strict", z.ZodTypeAny, {
13
+ repository: "treeseed-ai/platform";
14
+ commit: string;
15
+ }, {
16
+ repository: "treeseed-ai/platform";
17
+ commit: string;
18
+ }>;
19
+ providerConnections: z.ZodRecord<z.ZodEnum<["cloudflare", "railway"]>, z.ZodObject<{
20
+ connectionRef: z.ZodString;
21
+ }, "strict", z.ZodTypeAny, {
22
+ connectionRef: string;
23
+ }, {
24
+ connectionRef: string;
25
+ }>>;
26
+ artifacts: z.ZodRecord<z.ZodString, z.ZodObject<{
27
+ digest: z.ZodString;
28
+ source: z.ZodString;
29
+ }, "strict", z.ZodTypeAny, {
30
+ digest: string;
31
+ source: string;
32
+ }, {
33
+ digest: string;
34
+ source: string;
35
+ }>>;
36
+ resources: z.ZodArray<z.ZodObject<{
37
+ id: z.ZodString;
38
+ provider: z.ZodEnum<["cloudflare", "railway"]>;
39
+ kind: z.ZodEnum<["admin-application", "dns-record", "tls-policy", "api-proxy", "control-plane-api", "postgresql", "operations-runner", "treedx-service"]>;
40
+ dependsOn: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
41
+ parameters: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
42
+ input: z.ZodString;
43
+ }, "strict", z.ZodTypeAny, {
44
+ input: string;
45
+ }, {
46
+ input: string;
47
+ }>, z.ZodObject<{
48
+ artifact: z.ZodString;
49
+ }, "strict", z.ZodTypeAny, {
50
+ artifact: string;
51
+ }, {
52
+ artifact: string;
53
+ }>, z.ZodObject<{
54
+ resourceOutput: z.ZodObject<{
55
+ resourceId: z.ZodString;
56
+ output: z.ZodString;
57
+ }, "strict", z.ZodTypeAny, {
58
+ resourceId: string;
59
+ output: string;
60
+ }, {
61
+ resourceId: string;
62
+ output: string;
63
+ }>;
64
+ }, "strict", z.ZodTypeAny, {
65
+ resourceOutput: {
66
+ resourceId: string;
67
+ output: string;
68
+ };
69
+ }, {
70
+ resourceOutput: {
71
+ resourceId: string;
72
+ output: string;
73
+ };
74
+ }>, z.ZodObject<{
75
+ literal: z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>;
76
+ }, "strict", z.ZodTypeAny, {
77
+ literal: string | number | boolean;
78
+ }, {
79
+ literal: string | number | boolean;
80
+ }>]>>>;
81
+ adoption: z.ZodObject<{
82
+ mode: z.ZodLiteral<"adopt-or-create">;
83
+ externalIdInput: z.ZodOptional<z.ZodString>;
84
+ replacement: z.ZodLiteral<"forbidden">;
85
+ }, "strict", z.ZodTypeAny, {
86
+ mode: "adopt-or-create";
87
+ replacement: "forbidden";
88
+ externalIdInput?: string | undefined;
89
+ }, {
90
+ mode: "adopt-or-create";
91
+ replacement: "forbidden";
92
+ externalIdInput?: string | undefined;
93
+ }>;
94
+ }, "strict", z.ZodTypeAny, {
95
+ id: string;
96
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
97
+ provider: "cloudflare" | "railway";
98
+ dependsOn: string[];
99
+ parameters: Record<string, {
100
+ input: string;
101
+ } | {
102
+ artifact: string;
103
+ } | {
104
+ resourceOutput: {
105
+ resourceId: string;
106
+ output: string;
107
+ };
108
+ } | {
109
+ literal: string | number | boolean;
110
+ }>;
111
+ adoption: {
112
+ mode: "adopt-or-create";
113
+ replacement: "forbidden";
114
+ externalIdInput?: string | undefined;
115
+ };
116
+ }, {
117
+ id: string;
118
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
119
+ provider: "cloudflare" | "railway";
120
+ adoption: {
121
+ mode: "adopt-or-create";
122
+ replacement: "forbidden";
123
+ externalIdInput?: string | undefined;
124
+ };
125
+ dependsOn?: string[] | undefined;
126
+ parameters?: Record<string, {
127
+ input: string;
128
+ } | {
129
+ artifact: string;
130
+ } | {
131
+ resourceOutput: {
132
+ resourceId: string;
133
+ output: string;
134
+ };
135
+ } | {
136
+ literal: string | number | boolean;
137
+ }> | undefined;
138
+ }>, "many">;
139
+ }, "strict", z.ZodTypeAny, {
140
+ schemaVersion: "treeseed.hosted-topology/v1";
141
+ resources: {
142
+ id: string;
143
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
144
+ provider: "cloudflare" | "railway";
145
+ dependsOn: string[];
146
+ parameters: Record<string, {
147
+ input: string;
148
+ } | {
149
+ artifact: string;
150
+ } | {
151
+ resourceOutput: {
152
+ resourceId: string;
153
+ output: string;
154
+ };
155
+ } | {
156
+ literal: string | number | boolean;
157
+ }>;
158
+ adoption: {
159
+ mode: "adopt-or-create";
160
+ replacement: "forbidden";
161
+ externalIdInput?: string | undefined;
162
+ };
163
+ }[];
164
+ id: string;
165
+ platform: {
166
+ repository: "treeseed-ai/platform";
167
+ commit: string;
168
+ };
169
+ mutation: "approval-required";
170
+ environment: "production" | "staging";
171
+ artifacts: Record<string, {
172
+ digest: string;
173
+ source: string;
174
+ }>;
175
+ providerConnections: Partial<Record<"cloudflare" | "railway", {
176
+ connectionRef: string;
177
+ }>>;
178
+ }, {
179
+ schemaVersion: "treeseed.hosted-topology/v1";
180
+ resources: {
181
+ id: string;
182
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
183
+ provider: "cloudflare" | "railway";
184
+ adoption: {
185
+ mode: "adopt-or-create";
186
+ replacement: "forbidden";
187
+ externalIdInput?: string | undefined;
188
+ };
189
+ dependsOn?: string[] | undefined;
190
+ parameters?: Record<string, {
191
+ input: string;
192
+ } | {
193
+ artifact: string;
194
+ } | {
195
+ resourceOutput: {
196
+ resourceId: string;
197
+ output: string;
198
+ };
199
+ } | {
200
+ literal: string | number | boolean;
201
+ }> | undefined;
202
+ }[];
203
+ id: string;
204
+ platform: {
205
+ repository: "treeseed-ai/platform";
206
+ commit: string;
207
+ };
208
+ mutation: "approval-required";
209
+ environment: "production" | "staging";
210
+ artifacts: Record<string, {
211
+ digest: string;
212
+ source: string;
213
+ }>;
214
+ providerConnections: Partial<Record<"cloudflare" | "railway", {
215
+ connectionRef: string;
216
+ }>>;
217
+ }>, {
218
+ schemaVersion: "treeseed.hosted-topology/v1";
219
+ resources: {
220
+ id: string;
221
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
222
+ provider: "cloudflare" | "railway";
223
+ dependsOn: string[];
224
+ parameters: Record<string, {
225
+ input: string;
226
+ } | {
227
+ artifact: string;
228
+ } | {
229
+ resourceOutput: {
230
+ resourceId: string;
231
+ output: string;
232
+ };
233
+ } | {
234
+ literal: string | number | boolean;
235
+ }>;
236
+ adoption: {
237
+ mode: "adopt-or-create";
238
+ replacement: "forbidden";
239
+ externalIdInput?: string | undefined;
240
+ };
241
+ }[];
242
+ id: string;
243
+ platform: {
244
+ repository: "treeseed-ai/platform";
245
+ commit: string;
246
+ };
247
+ mutation: "approval-required";
248
+ environment: "production" | "staging";
249
+ artifacts: Record<string, {
250
+ digest: string;
251
+ source: string;
252
+ }>;
253
+ providerConnections: Partial<Record<"cloudflare" | "railway", {
254
+ connectionRef: string;
255
+ }>>;
256
+ }, {
257
+ schemaVersion: "treeseed.hosted-topology/v1";
258
+ resources: {
259
+ id: string;
260
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
261
+ provider: "cloudflare" | "railway";
262
+ adoption: {
263
+ mode: "adopt-or-create";
264
+ replacement: "forbidden";
265
+ externalIdInput?: string | undefined;
266
+ };
267
+ dependsOn?: string[] | undefined;
268
+ parameters?: Record<string, {
269
+ input: string;
270
+ } | {
271
+ artifact: string;
272
+ } | {
273
+ resourceOutput: {
274
+ resourceId: string;
275
+ output: string;
276
+ };
277
+ } | {
278
+ literal: string | number | boolean;
279
+ }> | undefined;
280
+ }[];
281
+ id: string;
282
+ platform: {
283
+ repository: "treeseed-ai/platform";
284
+ commit: string;
285
+ };
286
+ mutation: "approval-required";
287
+ environment: "production" | "staging";
288
+ artifacts: Record<string, {
289
+ digest: string;
290
+ source: string;
291
+ }>;
292
+ providerConnections: Partial<Record<"cloudflare" | "railway", {
293
+ connectionRef: string;
294
+ }>>;
295
+ }>;
296
+ export declare const hostedResourceObservationSchema: z.ZodObject<{
297
+ resourceId: z.ZodString;
298
+ provider: z.ZodEnum<["cloudflare", "railway"]>;
299
+ kind: z.ZodEnum<["admin-application", "dns-record", "tls-policy", "api-proxy", "control-plane-api", "postgresql", "operations-runner", "treedx-service"]>;
300
+ providerResourceId: z.ZodNullable<z.ZodString>;
301
+ state: z.ZodEnum<["missing", "healthy", "degraded"]>;
302
+ managedBy: z.ZodNullable<z.ZodEnum<["treeseed", "external"]>>;
303
+ observedDigest: z.ZodNullable<z.ZodString>;
304
+ observedAt: z.ZodString;
305
+ }, "strict", z.ZodTypeAny, {
306
+ state: "missing" | "degraded" | "healthy";
307
+ resourceId: string;
308
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
309
+ provider: "cloudflare" | "railway";
310
+ providerResourceId: string | null;
311
+ managedBy: "external" | "treeseed" | null;
312
+ observedDigest: string | null;
313
+ observedAt: string;
314
+ }, {
315
+ state: "missing" | "degraded" | "healthy";
316
+ resourceId: string;
317
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
318
+ provider: "cloudflare" | "railway";
319
+ providerResourceId: string | null;
320
+ managedBy: "external" | "treeseed" | null;
321
+ observedDigest: string | null;
322
+ observedAt: string;
323
+ }>;
324
+ export declare const hostedTopologyPlanSchema: z.ZodObject<{
325
+ schemaVersion: z.ZodLiteral<"treeseed.hosted-topology-plan/v1">;
326
+ planId: z.ZodString;
327
+ planDigest: z.ZodString;
328
+ declarationDigest: z.ZodString;
329
+ topologyId: z.ZodString;
330
+ environment: z.ZodEnum<["staging", "production"]>;
331
+ platformCommit: z.ZodString;
332
+ actions: z.ZodArray<z.ZodObject<{
333
+ resourceId: z.ZodString;
334
+ provider: z.ZodEnum<["cloudflare", "railway"]>;
335
+ kind: z.ZodEnum<["admin-application", "dns-record", "tls-policy", "api-proxy", "control-plane-api", "postgresql", "operations-runner", "treedx-service"]>;
336
+ action: z.ZodEnum<["create", "adopt", "update", "noop"]>;
337
+ desiredDigest: z.ZodString;
338
+ previousDigest: z.ZodNullable<z.ZodString>;
339
+ providerResourceId: z.ZodNullable<z.ZodString>;
340
+ }, "strict", z.ZodTypeAny, {
341
+ action: "noop" | "create" | "adopt" | "update";
342
+ resourceId: string;
343
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
344
+ provider: "cloudflare" | "railway";
345
+ providerResourceId: string | null;
346
+ desiredDigest: string;
347
+ previousDigest: string | null;
348
+ }, {
349
+ action: "noop" | "create" | "adopt" | "update";
350
+ resourceId: string;
351
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
352
+ provider: "cloudflare" | "railway";
353
+ providerResourceId: string | null;
354
+ desiredDigest: string;
355
+ previousDigest: string | null;
356
+ }>, "many">;
357
+ blockers: z.ZodArray<z.ZodObject<{
358
+ code: z.ZodEnum<["connection-unavailable", "dependency-cycle", "observation-unhealthy", "adoption-drift"]>;
359
+ resourceId: z.ZodOptional<z.ZodString>;
360
+ message: z.ZodString;
361
+ }, "strict", z.ZodTypeAny, {
362
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
363
+ message: string;
364
+ resourceId?: string | undefined;
365
+ }, {
366
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
367
+ message: string;
368
+ resourceId?: string | undefined;
369
+ }>, "many">;
370
+ approvalRequired: z.ZodBoolean;
371
+ executable: z.ZodLiteral<false>;
372
+ }, "strict", z.ZodTypeAny, {
373
+ schemaVersion: "treeseed.hosted-topology-plan/v1";
374
+ blockers: {
375
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
376
+ message: string;
377
+ resourceId?: string | undefined;
378
+ }[];
379
+ planDigest: string;
380
+ actions: {
381
+ action: "noop" | "create" | "adopt" | "update";
382
+ resourceId: string;
383
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
384
+ provider: "cloudflare" | "railway";
385
+ providerResourceId: string | null;
386
+ desiredDigest: string;
387
+ previousDigest: string | null;
388
+ }[];
389
+ environment: "production" | "staging";
390
+ executable: false;
391
+ planId: string;
392
+ declarationDigest: string;
393
+ topologyId: string;
394
+ platformCommit: string;
395
+ approvalRequired: boolean;
396
+ }, {
397
+ schemaVersion: "treeseed.hosted-topology-plan/v1";
398
+ blockers: {
399
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
400
+ message: string;
401
+ resourceId?: string | undefined;
402
+ }[];
403
+ planDigest: string;
404
+ actions: {
405
+ action: "noop" | "create" | "adopt" | "update";
406
+ resourceId: string;
407
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
408
+ provider: "cloudflare" | "railway";
409
+ providerResourceId: string | null;
410
+ desiredDigest: string;
411
+ previousDigest: string | null;
412
+ }[];
413
+ environment: "production" | "staging";
414
+ executable: false;
415
+ planId: string;
416
+ declarationDigest: string;
417
+ topologyId: string;
418
+ platformCommit: string;
419
+ approvalRequired: boolean;
420
+ }>;
421
+ export declare const hostedTopologyApprovalSchema: z.ZodObject<{
422
+ schemaVersion: z.ZodLiteral<"treeseed.hosted-topology-approval/v1">;
423
+ planDigest: z.ZodString;
424
+ environment: z.ZodEnum<["staging", "production"]>;
425
+ decision: z.ZodLiteral<"approved">;
426
+ approvedBy: z.ZodString;
427
+ approvedAt: z.ZodString;
428
+ }, "strict", z.ZodTypeAny, {
429
+ schemaVersion: "treeseed.hosted-topology-approval/v1";
430
+ planDigest: string;
431
+ environment: "production" | "staging";
432
+ decision: "approved";
433
+ approvedBy: string;
434
+ approvedAt: string;
435
+ }, {
436
+ schemaVersion: "treeseed.hosted-topology-approval/v1";
437
+ planDigest: string;
438
+ environment: "production" | "staging";
439
+ decision: "approved";
440
+ approvedBy: string;
441
+ approvedAt: string;
442
+ }>;
443
+ export declare const authorizedHostedTopologyPlanSchema: z.ZodObject<Omit<{
444
+ schemaVersion: z.ZodLiteral<"treeseed.hosted-topology-plan/v1">;
445
+ planId: z.ZodString;
446
+ planDigest: z.ZodString;
447
+ declarationDigest: z.ZodString;
448
+ topologyId: z.ZodString;
449
+ environment: z.ZodEnum<["staging", "production"]>;
450
+ platformCommit: z.ZodString;
451
+ actions: z.ZodArray<z.ZodObject<{
452
+ resourceId: z.ZodString;
453
+ provider: z.ZodEnum<["cloudflare", "railway"]>;
454
+ kind: z.ZodEnum<["admin-application", "dns-record", "tls-policy", "api-proxy", "control-plane-api", "postgresql", "operations-runner", "treedx-service"]>;
455
+ action: z.ZodEnum<["create", "adopt", "update", "noop"]>;
456
+ desiredDigest: z.ZodString;
457
+ previousDigest: z.ZodNullable<z.ZodString>;
458
+ providerResourceId: z.ZodNullable<z.ZodString>;
459
+ }, "strict", z.ZodTypeAny, {
460
+ action: "noop" | "create" | "adopt" | "update";
461
+ resourceId: string;
462
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
463
+ provider: "cloudflare" | "railway";
464
+ providerResourceId: string | null;
465
+ desiredDigest: string;
466
+ previousDigest: string | null;
467
+ }, {
468
+ action: "noop" | "create" | "adopt" | "update";
469
+ resourceId: string;
470
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
471
+ provider: "cloudflare" | "railway";
472
+ providerResourceId: string | null;
473
+ desiredDigest: string;
474
+ previousDigest: string | null;
475
+ }>, "many">;
476
+ blockers: z.ZodArray<z.ZodObject<{
477
+ code: z.ZodEnum<["connection-unavailable", "dependency-cycle", "observation-unhealthy", "adoption-drift"]>;
478
+ resourceId: z.ZodOptional<z.ZodString>;
479
+ message: z.ZodString;
480
+ }, "strict", z.ZodTypeAny, {
481
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
482
+ message: string;
483
+ resourceId?: string | undefined;
484
+ }, {
485
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
486
+ message: string;
487
+ resourceId?: string | undefined;
488
+ }>, "many">;
489
+ approvalRequired: z.ZodBoolean;
490
+ } & {
491
+ executable: z.ZodLiteral<true>;
492
+ approval: z.ZodNullable<z.ZodObject<{
493
+ schemaVersion: z.ZodLiteral<"treeseed.hosted-topology-approval/v1">;
494
+ planDigest: z.ZodString;
495
+ environment: z.ZodEnum<["staging", "production"]>;
496
+ decision: z.ZodLiteral<"approved">;
497
+ approvedBy: z.ZodString;
498
+ approvedAt: z.ZodString;
499
+ }, "strict", z.ZodTypeAny, {
500
+ schemaVersion: "treeseed.hosted-topology-approval/v1";
501
+ planDigest: string;
502
+ environment: "production" | "staging";
503
+ decision: "approved";
504
+ approvedBy: string;
505
+ approvedAt: string;
506
+ }, {
507
+ schemaVersion: "treeseed.hosted-topology-approval/v1";
508
+ planDigest: string;
509
+ environment: "production" | "staging";
510
+ decision: "approved";
511
+ approvedBy: string;
512
+ approvedAt: string;
513
+ }>>;
514
+ }, "approvalRequired">, "strict", z.ZodTypeAny, {
515
+ schemaVersion: "treeseed.hosted-topology-plan/v1";
516
+ blockers: {
517
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
518
+ message: string;
519
+ resourceId?: string | undefined;
520
+ }[];
521
+ planDigest: string;
522
+ actions: {
523
+ action: "noop" | "create" | "adopt" | "update";
524
+ resourceId: string;
525
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
526
+ provider: "cloudflare" | "railway";
527
+ providerResourceId: string | null;
528
+ desiredDigest: string;
529
+ previousDigest: string | null;
530
+ }[];
531
+ environment: "production" | "staging";
532
+ executable: true;
533
+ planId: string;
534
+ declarationDigest: string;
535
+ topologyId: string;
536
+ platformCommit: string;
537
+ approval: {
538
+ schemaVersion: "treeseed.hosted-topology-approval/v1";
539
+ planDigest: string;
540
+ environment: "production" | "staging";
541
+ decision: "approved";
542
+ approvedBy: string;
543
+ approvedAt: string;
544
+ } | null;
545
+ }, {
546
+ schemaVersion: "treeseed.hosted-topology-plan/v1";
547
+ blockers: {
548
+ code: "connection-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
549
+ message: string;
550
+ resourceId?: string | undefined;
551
+ }[];
552
+ planDigest: string;
553
+ actions: {
554
+ action: "noop" | "create" | "adopt" | "update";
555
+ resourceId: string;
556
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
557
+ provider: "cloudflare" | "railway";
558
+ providerResourceId: string | null;
559
+ desiredDigest: string;
560
+ previousDigest: string | null;
561
+ }[];
562
+ environment: "production" | "staging";
563
+ executable: true;
564
+ planId: string;
565
+ declarationDigest: string;
566
+ topologyId: string;
567
+ platformCommit: string;
568
+ approval: {
569
+ schemaVersion: "treeseed.hosted-topology-approval/v1";
570
+ planDigest: string;
571
+ environment: "production" | "staging";
572
+ decision: "approved";
573
+ approvedBy: string;
574
+ approvedAt: string;
575
+ } | null;
576
+ }>;
577
+ export declare const hostedTopologyReceiptSchema: z.ZodObject<{
578
+ schemaVersion: z.ZodLiteral<"treeseed.hosted-topology-receipt/v1">;
579
+ receiptId: z.ZodString;
580
+ planDigest: z.ZodString;
581
+ declarationDigest: z.ZodString;
582
+ topologyId: z.ZodString;
583
+ environment: z.ZodEnum<["staging", "production"]>;
584
+ platformCommit: z.ZodString;
585
+ resources: z.ZodArray<z.ZodObject<{
586
+ resourceId: z.ZodString;
587
+ provider: z.ZodEnum<["cloudflare", "railway"]>;
588
+ kind: z.ZodEnum<["admin-application", "dns-record", "tls-policy", "api-proxy", "control-plane-api", "postgresql", "operations-runner", "treedx-service"]>;
589
+ providerResourceId: z.ZodNullable<z.ZodString>;
590
+ state: z.ZodEnum<["missing", "healthy", "degraded"]>;
591
+ managedBy: z.ZodNullable<z.ZodEnum<["treeseed", "external"]>>;
592
+ observedDigest: z.ZodNullable<z.ZodString>;
593
+ observedAt: z.ZodString;
594
+ }, "strict", z.ZodTypeAny, {
595
+ state: "missing" | "degraded" | "healthy";
596
+ resourceId: string;
597
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
598
+ provider: "cloudflare" | "railway";
599
+ providerResourceId: string | null;
600
+ managedBy: "external" | "treeseed" | null;
601
+ observedDigest: string | null;
602
+ observedAt: string;
603
+ }, {
604
+ state: "missing" | "degraded" | "healthy";
605
+ resourceId: string;
606
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
607
+ provider: "cloudflare" | "railway";
608
+ providerResourceId: string | null;
609
+ managedBy: "external" | "treeseed" | null;
610
+ observedDigest: string | null;
611
+ observedAt: string;
612
+ }>, "many">;
613
+ previousResources: z.ZodArray<z.ZodObject<{
614
+ resourceId: z.ZodString;
615
+ provider: z.ZodEnum<["cloudflare", "railway"]>;
616
+ kind: z.ZodEnum<["admin-application", "dns-record", "tls-policy", "api-proxy", "control-plane-api", "postgresql", "operations-runner", "treedx-service"]>;
617
+ providerResourceId: z.ZodNullable<z.ZodString>;
618
+ state: z.ZodEnum<["missing", "healthy", "degraded"]>;
619
+ managedBy: z.ZodNullable<z.ZodEnum<["treeseed", "external"]>>;
620
+ observedDigest: z.ZodNullable<z.ZodString>;
621
+ observedAt: z.ZodString;
622
+ }, "strict", z.ZodTypeAny, {
623
+ state: "missing" | "degraded" | "healthy";
624
+ resourceId: string;
625
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
626
+ provider: "cloudflare" | "railway";
627
+ providerResourceId: string | null;
628
+ managedBy: "external" | "treeseed" | null;
629
+ observedDigest: string | null;
630
+ observedAt: string;
631
+ }, {
632
+ state: "missing" | "degraded" | "healthy";
633
+ resourceId: string;
634
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
635
+ provider: "cloudflare" | "railway";
636
+ providerResourceId: string | null;
637
+ managedBy: "external" | "treeseed" | null;
638
+ observedDigest: string | null;
639
+ observedAt: string;
640
+ }>, "many">;
641
+ state: z.ZodLiteral<"known-good">;
642
+ completedAt: z.ZodString;
643
+ }, "strict", z.ZodTypeAny, {
644
+ schemaVersion: "treeseed.hosted-topology-receipt/v1";
645
+ resources: {
646
+ state: "missing" | "degraded" | "healthy";
647
+ resourceId: string;
648
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
649
+ provider: "cloudflare" | "railway";
650
+ providerResourceId: string | null;
651
+ managedBy: "external" | "treeseed" | null;
652
+ observedDigest: string | null;
653
+ observedAt: string;
654
+ }[];
655
+ planDigest: string;
656
+ state: "known-good";
657
+ environment: "production" | "staging";
658
+ completedAt: string;
659
+ receiptId: string;
660
+ declarationDigest: string;
661
+ topologyId: string;
662
+ platformCommit: string;
663
+ previousResources: {
664
+ state: "missing" | "degraded" | "healthy";
665
+ resourceId: string;
666
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
667
+ provider: "cloudflare" | "railway";
668
+ providerResourceId: string | null;
669
+ managedBy: "external" | "treeseed" | null;
670
+ observedDigest: string | null;
671
+ observedAt: string;
672
+ }[];
673
+ }, {
674
+ schemaVersion: "treeseed.hosted-topology-receipt/v1";
675
+ resources: {
676
+ state: "missing" | "degraded" | "healthy";
677
+ resourceId: string;
678
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
679
+ provider: "cloudflare" | "railway";
680
+ providerResourceId: string | null;
681
+ managedBy: "external" | "treeseed" | null;
682
+ observedDigest: string | null;
683
+ observedAt: string;
684
+ }[];
685
+ planDigest: string;
686
+ state: "known-good";
687
+ environment: "production" | "staging";
688
+ completedAt: string;
689
+ receiptId: string;
690
+ declarationDigest: string;
691
+ topologyId: string;
692
+ platformCommit: string;
693
+ previousResources: {
694
+ state: "missing" | "degraded" | "healthy";
695
+ resourceId: string;
696
+ kind: "admin-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
697
+ provider: "cloudflare" | "railway";
698
+ providerResourceId: string | null;
699
+ managedBy: "external" | "treeseed" | null;
700
+ observedDigest: string | null;
701
+ observedAt: string;
702
+ }[];
703
+ }>;
704
+ export declare const hostedTopologyRollbackSchema: z.ZodObject<{
705
+ schemaVersion: z.ZodLiteral<"treeseed.hosted-topology-rollback/v1">;
706
+ rollbackId: z.ZodString;
707
+ sourceReceiptId: z.ZodString;
708
+ operations: z.ZodArray<z.ZodObject<{
709
+ resourceId: z.ZodString;
710
+ action: z.ZodEnum<["restore", "delete-created", "noop"]>;
711
+ providerResourceId: z.ZodString;
712
+ targetDigest: z.ZodNullable<z.ZodString>;
713
+ }, "strict", z.ZodTypeAny, {
714
+ action: "noop" | "restore" | "delete-created";
715
+ resourceId: string;
716
+ providerResourceId: string;
717
+ targetDigest: string | null;
718
+ }, {
719
+ action: "noop" | "restore" | "delete-created";
720
+ resourceId: string;
721
+ providerResourceId: string;
722
+ targetDigest: string | null;
723
+ }>, "many">;
724
+ rollbackDigest: z.ZodString;
725
+ }, "strict", z.ZodTypeAny, {
726
+ schemaVersion: "treeseed.hosted-topology-rollback/v1";
727
+ operations: {
728
+ action: "noop" | "restore" | "delete-created";
729
+ resourceId: string;
730
+ providerResourceId: string;
731
+ targetDigest: string | null;
732
+ }[];
733
+ rollbackId: string;
734
+ sourceReceiptId: string;
735
+ rollbackDigest: string;
736
+ }, {
737
+ schemaVersion: "treeseed.hosted-topology-rollback/v1";
738
+ operations: {
739
+ action: "noop" | "restore" | "delete-created";
740
+ resourceId: string;
741
+ providerResourceId: string;
742
+ targetDigest: string | null;
743
+ }[];
744
+ rollbackId: string;
745
+ sourceReceiptId: string;
746
+ rollbackDigest: string;
747
+ }>;
748
+ export type HostedTopologyDeclaration = z.infer<typeof hostedTopologyDeclarationSchema>;
749
+ export type HostedResourceObservation = z.infer<typeof hostedResourceObservationSchema>;
750
+ export type HostedTopologyPlan = z.infer<typeof hostedTopologyPlanSchema>;
751
+ export type HostedTopologyApproval = z.infer<typeof hostedTopologyApprovalSchema>;
752
+ export type AuthorizedHostedTopologyPlan = z.infer<typeof authorizedHostedTopologyPlanSchema>;
753
+ export type HostedTopologyReceipt = z.infer<typeof hostedTopologyReceiptSchema>;
754
+ export declare function planHostedTopology(input: {
755
+ declaration: HostedTopologyDeclaration;
756
+ observations: HostedResourceObservation[];
757
+ availableConnections: string[];
758
+ }): HostedTopologyPlan;
759
+ export declare function authorizeHostedTopologyPlan(planInput: HostedTopologyPlan, approvalInput?: HostedTopologyApproval): AuthorizedHostedTopologyPlan;
760
+ export declare function verifyHostedTopologyReadback(input: {
761
+ plan: AuthorizedHostedTopologyPlan;
762
+ previousResources: HostedResourceObservation[];
763
+ resources: HostedResourceObservation[];
764
+ completedAt: string;
765
+ }): HostedTopologyReceipt;
766
+ export declare function planHostedTopologyRollback(receiptInput: HostedTopologyReceipt): {
767
+ schemaVersion: "treeseed.hosted-topology-rollback/v1";
768
+ operations: {
769
+ action: "noop" | "restore" | "delete-created";
770
+ resourceId: string;
771
+ providerResourceId: string;
772
+ targetDigest: string | null;
773
+ }[];
774
+ rollbackId: string;
775
+ sourceReceiptId: string;
776
+ rollbackDigest: string;
777
+ };
@@ -0,0 +1,230 @@
1
+ import { z } from "zod";
2
+ import { deploymentDigest } from "./canonical.js";
3
+ const identifier = z.string().regex(/^[a-z][a-z0-9.-]{1,63}$/u);
4
+ const digest = z.string().regex(/^sha256:[a-f0-9]{64}$/u);
5
+ const gitCommit = z.string().regex(/^[a-f0-9]{40}$/u);
6
+ const timestamp = z.string().datetime();
7
+ const hostedProviderSchema = z.enum(["cloudflare", "railway"]);
8
+ const hostedResourceKindSchema = z.enum([
9
+ "admin-application",
10
+ "dns-record",
11
+ "tls-policy",
12
+ "api-proxy",
13
+ "control-plane-api",
14
+ "postgresql",
15
+ "operations-runner",
16
+ "treedx-service"
17
+ ]);
18
+ const parameterSchema = z.union([
19
+ z.object({ input: identifier }).strict(),
20
+ z.object({ artifact: identifier }).strict(),
21
+ z.object({ resourceOutput: z.object({ resourceId: identifier, output: identifier }).strict() }).strict(),
22
+ z.object({ literal: z.union([z.string().max(4096), z.number().finite(), z.boolean()]) }).strict()
23
+ ]);
24
+ const resourceProviderKinds = {
25
+ cloudflare: /* @__PURE__ */ new Set(["admin-application", "dns-record", "tls-policy", "api-proxy"]),
26
+ railway: /* @__PURE__ */ new Set(["control-plane-api", "postgresql", "operations-runner", "treedx-service"])
27
+ };
28
+ const sensitiveKey = /(?:credential|password|private.?key|registration.?code|secret|token)/iu;
29
+ const personalPath = /(?:^|[\s'"`:=])(?:\/home\/[^/\s]+|\/Users\/[^/\s]+|[A-Za-z]:\\Users\\[^\\\s]+)/u;
30
+ const hostedTopologyDeclarationSchema = z.object({
31
+ schemaVersion: z.literal("treeseed.hosted-topology/v1"),
32
+ id: identifier,
33
+ environment: z.enum(["staging", "production"]),
34
+ mutation: z.literal("approval-required"),
35
+ platform: z.object({ repository: z.literal("treeseed-ai/platform"), commit: gitCommit }).strict(),
36
+ providerConnections: z.record(hostedProviderSchema, z.object({ connectionRef: identifier }).strict()),
37
+ artifacts: z.record(identifier, z.object({ digest, source: z.string().url() }).strict()),
38
+ resources: z.array(z.object({
39
+ id: identifier,
40
+ provider: hostedProviderSchema,
41
+ kind: hostedResourceKindSchema,
42
+ dependsOn: z.array(identifier).default([]),
43
+ parameters: z.record(identifier, parameterSchema).default({}),
44
+ adoption: z.object({ mode: z.literal("adopt-or-create"), externalIdInput: identifier.optional(), replacement: z.literal("forbidden") }).strict()
45
+ }).strict()).min(1)
46
+ }).strict().superRefine((declaration, context) => {
47
+ const ids = declaration.resources.map(({ id }) => id);
48
+ if (new Set(ids).size !== ids.length) context.addIssue({ code: z.ZodIssueCode.custom, path: ["resources"], message: "Hosted topology resource identities must be unique." });
49
+ for (const [index, resource] of declaration.resources.entries()) {
50
+ if (!resourceProviderKinds[resource.provider].has(resource.kind)) context.addIssue({ code: z.ZodIssueCode.custom, path: ["resources", index, "kind"], message: `${resource.kind} is not owned by ${resource.provider}.` });
51
+ for (const dependency of resource.dependsOn) if (!ids.includes(dependency)) context.addIssue({ code: z.ZodIssueCode.custom, path: ["resources", index, "dependsOn"], message: `Unknown hosted resource dependency ${dependency}.` });
52
+ for (const key of Object.keys(resource.parameters)) if (sensitiveKey.test(key)) context.addIssue({ code: z.ZodIssueCode.custom, path: ["resources", index, "parameters", key], message: "Hosted topology parameters cannot carry credential-like values." });
53
+ for (const [key, parameter] of Object.entries(resource.parameters)) if ("literal" in parameter && typeof parameter.literal === "string" && personalPath.test(parameter.literal)) context.addIssue({ code: z.ZodIssueCode.custom, path: ["resources", index, "parameters", key], message: "Hosted topology parameters cannot contain personal filesystem paths." });
54
+ }
55
+ });
56
+ const hostedResourceObservationSchema = z.object({
57
+ resourceId: identifier,
58
+ provider: hostedProviderSchema,
59
+ kind: hostedResourceKindSchema,
60
+ providerResourceId: z.string().min(1).max(512).nullable(),
61
+ state: z.enum(["missing", "healthy", "degraded"]),
62
+ managedBy: z.enum(["treeseed", "external"]).nullable(),
63
+ observedDigest: digest.nullable(),
64
+ observedAt: timestamp
65
+ }).strict();
66
+ const hostedTopologyPlanSchema = z.object({
67
+ schemaVersion: z.literal("treeseed.hosted-topology-plan/v1"),
68
+ planId: z.string().regex(/^topology-plan-[a-f0-9]{16}$/u),
69
+ planDigest: digest,
70
+ declarationDigest: digest,
71
+ topologyId: identifier,
72
+ environment: z.enum(["staging", "production"]),
73
+ platformCommit: gitCommit,
74
+ actions: z.array(z.object({
75
+ resourceId: identifier,
76
+ provider: hostedProviderSchema,
77
+ kind: hostedResourceKindSchema,
78
+ action: z.enum(["create", "adopt", "update", "noop"]),
79
+ desiredDigest: digest,
80
+ previousDigest: digest.nullable(),
81
+ providerResourceId: z.string().min(1).max(512).nullable()
82
+ }).strict()),
83
+ blockers: z.array(z.object({ code: z.enum(["connection-unavailable", "dependency-cycle", "observation-unhealthy", "adoption-drift"]), resourceId: identifier.optional(), message: z.string().min(1) }).strict()),
84
+ approvalRequired: z.boolean(),
85
+ executable: z.literal(false)
86
+ }).strict();
87
+ const hostedTopologyApprovalSchema = z.object({
88
+ schemaVersion: z.literal("treeseed.hosted-topology-approval/v1"),
89
+ planDigest: digest,
90
+ environment: z.enum(["staging", "production"]),
91
+ decision: z.literal("approved"),
92
+ approvedBy: z.string().min(1).max(256),
93
+ approvedAt: timestamp
94
+ }).strict();
95
+ const authorizedHostedTopologyPlanSchema = hostedTopologyPlanSchema.extend({
96
+ executable: z.literal(true),
97
+ approval: hostedTopologyApprovalSchema.nullable()
98
+ }).omit({ approvalRequired: true });
99
+ const hostedTopologyReceiptSchema = z.object({
100
+ schemaVersion: z.literal("treeseed.hosted-topology-receipt/v1"),
101
+ receiptId: z.string().regex(/^topology-receipt-[a-f0-9]{16}$/u),
102
+ planDigest: digest,
103
+ declarationDigest: digest,
104
+ topologyId: identifier,
105
+ environment: z.enum(["staging", "production"]),
106
+ platformCommit: gitCommit,
107
+ resources: z.array(hostedResourceObservationSchema),
108
+ previousResources: z.array(hostedResourceObservationSchema),
109
+ state: z.literal("known-good"),
110
+ completedAt: timestamp
111
+ }).strict();
112
+ const hostedTopologyRollbackSchema = z.object({
113
+ schemaVersion: z.literal("treeseed.hosted-topology-rollback/v1"),
114
+ rollbackId: z.string().regex(/^topology-rollback-[a-f0-9]{16}$/u),
115
+ sourceReceiptId: z.string().regex(/^topology-receipt-[a-f0-9]{16}$/u),
116
+ operations: z.array(z.object({
117
+ resourceId: identifier,
118
+ action: z.enum(["restore", "delete-created", "noop"]),
119
+ providerResourceId: z.string().min(1).max(512),
120
+ targetDigest: digest.nullable()
121
+ }).strict()),
122
+ rollbackDigest: digest
123
+ }).strict();
124
+ function observationMap(items, declaration) {
125
+ const resources = new Map(declaration.resources.map((resource) => [resource.id, resource]));
126
+ const observations = /* @__PURE__ */ new Map();
127
+ for (const input of items) {
128
+ const item = hostedResourceObservationSchema.parse(input), resource = resources.get(item.resourceId);
129
+ if (observations.has(item.resourceId)) throw new Error(`Duplicate hosted resource observation ${item.resourceId}.`);
130
+ if (!resource) throw new Error(`Unknown hosted resource observation ${item.resourceId}.`);
131
+ if (item.provider !== resource.provider || item.kind !== resource.kind) throw new Error(`Hosted resource observation identity mismatch for ${item.resourceId}.`);
132
+ observations.set(item.resourceId, item);
133
+ }
134
+ return observations;
135
+ }
136
+ function cycleMembers(declaration) {
137
+ const dependencies = new Map(declaration.resources.map(({ id, dependsOn }) => [id, dependsOn]));
138
+ const visiting = /* @__PURE__ */ new Set(), visited = /* @__PURE__ */ new Set(), cycles = /* @__PURE__ */ new Set();
139
+ const visit = (id) => {
140
+ if (visiting.has(id)) {
141
+ cycles.add(id);
142
+ return;
143
+ }
144
+ if (visited.has(id)) return;
145
+ visiting.add(id);
146
+ for (const dependency of dependencies.get(id) ?? []) {
147
+ visit(dependency);
148
+ if (cycles.has(dependency)) cycles.add(id);
149
+ }
150
+ visiting.delete(id);
151
+ visited.add(id);
152
+ };
153
+ for (const id of dependencies.keys()) visit(id);
154
+ return [...cycles].sort();
155
+ }
156
+ function planHostedTopology(input) {
157
+ const declaration = hostedTopologyDeclarationSchema.parse(input.declaration);
158
+ const normalizedDeclaration = {
159
+ ...declaration,
160
+ resources: [...declaration.resources].map((resource) => ({ ...resource, dependsOn: [...resource.dependsOn].sort() })).sort((left, right) => left.id.localeCompare(right.id))
161
+ };
162
+ const observations = observationMap(input.observations, normalizedDeclaration);
163
+ const blockers = [];
164
+ for (const [provider, binding] of Object.entries(normalizedDeclaration.providerConnections)) if (!input.availableConnections.includes(binding.connectionRef)) blockers.push({ code: "connection-unavailable", message: `${provider} connection ${binding.connectionRef} is unavailable.` });
165
+ for (const resourceId of cycleMembers(normalizedDeclaration)) blockers.push({ code: "dependency-cycle", resourceId, message: `Hosted resource ${resourceId} participates in a dependency cycle.` });
166
+ const actions = normalizedDeclaration.resources.map((resource) => {
167
+ const desiredDigest = deploymentDigest(resource);
168
+ const observation = observations.get(resource.id);
169
+ let action = "create";
170
+ if (observation?.state === "degraded") blockers.push({ code: "observation-unhealthy", resourceId: resource.id, message: `Hosted resource ${resource.id} is degraded and cannot be reconciled automatically.` });
171
+ if (observation?.state === "healthy") {
172
+ if (observation.observedDigest === desiredDigest) action = observation.managedBy === "external" ? "adopt" : "noop";
173
+ else if (observation.managedBy === "external") blockers.push({ code: "adoption-drift", resourceId: resource.id, message: `External resource ${resource.id} differs from the declaration and cannot be replaced.` });
174
+ else action = "update";
175
+ }
176
+ return { resourceId: resource.id, provider: resource.provider, kind: resource.kind, action, desiredDigest, previousDigest: observation?.observedDigest ?? null, providerResourceId: observation?.providerResourceId ?? null };
177
+ });
178
+ const declarationDigest = deploymentDigest(normalizedDeclaration);
179
+ const core = { declarationDigest, topologyId: declaration.id, environment: declaration.environment, platformCommit: declaration.platform.commit, actions, blockers };
180
+ const planDigest = deploymentDigest(core);
181
+ return hostedTopologyPlanSchema.parse({ schemaVersion: "treeseed.hosted-topology-plan/v1", planId: `topology-plan-${planDigest.slice(7, 23)}`, planDigest, ...core, approvalRequired: actions.some(({ action }) => action !== "noop"), executable: false });
182
+ }
183
+ function authorizeHostedTopologyPlan(planInput, approvalInput) {
184
+ const plan = hostedTopologyPlanSchema.parse(planInput);
185
+ if (plan.blockers.length) throw new Error("Hosted topology plan has unresolved blockers.");
186
+ const approval = approvalInput ? hostedTopologyApprovalSchema.parse(approvalInput) : null;
187
+ if (plan.approvalRequired && !approval) throw new Error("Hosted topology mutation requires environment approval.");
188
+ if (approval && (approval.planDigest !== plan.planDigest || approval.environment !== plan.environment)) throw new Error("Hosted topology approval does not bind the exact plan and environment.");
189
+ const { approvalRequired: _approvalRequired, ...approvedPlan } = plan;
190
+ return authorizedHostedTopologyPlanSchema.parse({ ...approvedPlan, executable: true, approval });
191
+ }
192
+ function verifyHostedTopologyReadback(input) {
193
+ const plan = authorizedHostedTopologyPlanSchema.parse(input.plan);
194
+ const expectedIds = new Set(plan.actions.map(({ resourceId }) => resourceId));
195
+ const resources = input.resources.map((item) => hostedResourceObservationSchema.parse(item)).sort((left, right) => left.resourceId.localeCompare(right.resourceId));
196
+ if (resources.length !== expectedIds.size || new Set(resources.map(({ resourceId }) => resourceId)).size !== resources.length || resources.some(({ resourceId }) => !expectedIds.has(resourceId))) throw new Error("Authoritative read-back must contain each planned hosted resource exactly once.");
197
+ const observed = new Map(resources.map((item) => [item.resourceId, item]));
198
+ for (const action of plan.actions) {
199
+ const item = observed.get(action.resourceId);
200
+ if (!item || item.provider !== action.provider || item.kind !== action.kind || item.state !== "healthy" || !item.providerResourceId || item.observedDigest !== action.desiredDigest) throw new Error(`Authoritative read-back failed for hosted resource ${action.resourceId}.`);
201
+ }
202
+ const completedAt = timestamp.parse(input.completedAt);
203
+ const receiptDigest = deploymentDigest({ planDigest: plan.planDigest, resources, completedAt });
204
+ return hostedTopologyReceiptSchema.parse({ schemaVersion: "treeseed.hosted-topology-receipt/v1", receiptId: `topology-receipt-${receiptDigest.slice(7, 23)}`, planDigest: plan.planDigest, declarationDigest: plan.declarationDigest, topologyId: plan.topologyId, environment: plan.environment, platformCommit: plan.platformCommit, resources, previousResources: input.previousResources.map((item) => hostedResourceObservationSchema.parse(item)).sort((left, right) => left.resourceId.localeCompare(right.resourceId)), state: "known-good", completedAt });
205
+ }
206
+ function planHostedTopologyRollback(receiptInput) {
207
+ const receipt = hostedTopologyReceiptSchema.parse(receiptInput);
208
+ const previous = new Map(receipt.previousResources.map((item) => [item.resourceId, item]));
209
+ const operations = receipt.resources.map((resource) => {
210
+ const prior = previous.get(resource.resourceId);
211
+ return { resourceId: resource.resourceId, action: !prior || prior.state === "missing" ? "delete-created" : prior.observedDigest === resource.observedDigest ? "noop" : "restore", providerResourceId: resource.providerResourceId, targetDigest: prior?.observedDigest ?? null };
212
+ }).sort((left, right) => left.resourceId.localeCompare(right.resourceId));
213
+ const rollbackDigest = deploymentDigest({ sourceReceiptId: receipt.receiptId, operations });
214
+ return hostedTopologyRollbackSchema.parse({ schemaVersion: "treeseed.hosted-topology-rollback/v1", rollbackId: `topology-rollback-${rollbackDigest.slice(7, 23)}`, sourceReceiptId: receipt.receiptId, operations, rollbackDigest });
215
+ }
216
+ export {
217
+ authorizeHostedTopologyPlan,
218
+ authorizedHostedTopologyPlanSchema,
219
+ hostedProviderSchema,
220
+ hostedResourceKindSchema,
221
+ hostedResourceObservationSchema,
222
+ hostedTopologyApprovalSchema,
223
+ hostedTopologyDeclarationSchema,
224
+ hostedTopologyPlanSchema,
225
+ hostedTopologyReceiptSchema,
226
+ hostedTopologyRollbackSchema,
227
+ planHostedTopology,
228
+ planHostedTopologyRollback,
229
+ verifyHostedTopologyReadback
230
+ };
@@ -3,3 +3,4 @@ export * from './canonical.js';
3
3
  export * from './catalog.js';
4
4
  export * from './topology.js';
5
5
  export * from './ai-mode.js';
6
+ export * from './hosted-topology.js';
@@ -3,3 +3,4 @@ export * from "./canonical.js";
3
3
  export * from "./catalog.js";
4
4
  export * from "./topology.js";
5
5
  export * from "./ai-mode.js";
6
+ export * from "./hosted-topology.js";
@@ -410,8 +410,8 @@ export declare function providerCommunicationLifecycleOperations(): {
410
410
  assignmentId: string;
411
411
  }, {}, {
412
412
  providerId: string;
413
- runnerId: string;
414
413
  observedAt: string;
414
+ runnerId: string;
415
415
  }, {
416
416
  assignmentId: string;
417
417
  acknowledgedAt: string;
@@ -1716,12 +1716,12 @@ export declare const providerCommunicationNotificationAcknowledgeRequestSchema:
1716
1716
  observedAt: z.ZodString;
1717
1717
  }, "strict", z.ZodTypeAny, {
1718
1718
  providerId: string;
1719
- runnerId: string;
1720
1719
  observedAt: string;
1720
+ runnerId: string;
1721
1721
  }, {
1722
1722
  providerId: string;
1723
- runnerId: string;
1724
1723
  observedAt: string;
1724
+ runnerId: string;
1725
1725
  }>;
1726
1726
  export declare const providerCommunicationTraceEventRequestSchema: z.ZodObject<{
1727
1727
  leaseToken: z.ZodString;
@@ -1909,8 +1909,8 @@ export declare const CONTROL_PLANE_OPERATIONS: {
1909
1909
  assignmentId: string;
1910
1910
  }, {}, {
1911
1911
  providerId: string;
1912
- runnerId: string;
1913
1912
  observedAt: string;
1913
+ runnerId: string;
1914
1914
  }, {
1915
1915
  assignmentId: string;
1916
1916
  acknowledgedAt: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.13.0-rc.70",
3
+ "version": "0.13.0-rc.71",
4
4
  "description": "Portable TreeSeed contracts, standards, and typed remote control-plane clients.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {