@treeseed/sdk 0.12.60 → 0.12.61
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/guarantees/index.js +59 -56
- package/dist/hosting/contracts.d.ts +0 -19
- package/dist/hosting/graph.d.ts +1 -86
- package/dist/hosting/graph.js +96 -245
- package/dist/local-dev/managed-dev.js +30 -8
- package/dist/managed-dependencies.d.ts +3 -0
- package/dist/managed-dependencies.js +294 -20
- package/dist/operations/services/deploy.js +5 -5
- package/dist/operations/services/deployment-readiness.js +5 -4
- package/dist/operations/services/git-runner.d.ts +2 -0
- package/dist/operations/services/git-runner.js +23 -2
- package/dist/operations/services/hosted-service-checks.js +28 -0
- package/dist/operations/services/live-hosted-service-checks.js +51 -15
- package/dist/operations/services/local-cleanup.d.ts +1 -0
- package/dist/operations/services/local-cleanup.js +28 -9
- package/dist/operations/services/package-adapters.js +3 -3
- package/dist/operations/services/railway-api.d.ts +72 -28
- package/dist/operations/services/railway-api.js +321 -876
- package/dist/operations/services/railway-cli.d.ts +47 -0
- package/dist/operations/services/railway-cli.js +142 -0
- package/dist/operations/services/railway-deploy.d.ts +2 -2
- package/dist/operations/services/railway-deploy.js +36 -91
- package/dist/operations/services/railway-source-policy.d.ts +6 -0
- package/dist/operations/services/railway-source-policy.js +52 -9
- package/dist/operations/services/repository-save-orchestrator.d.ts +2 -0
- package/dist/operations/services/repository-save-orchestrator.js +45 -14
- package/dist/operations-types.d.ts +3 -1
- package/dist/platform/contracts.d.ts +1 -0
- package/dist/platform/deploy-config.js +2 -1
- package/dist/reconcile/builtin-adapters.js +519 -684
- package/dist/reconcile/desired-state.js +5 -3
- package/dist/reconcile/engine.js +34 -28
- package/dist/reconcile/live-acceptance.js +2 -11
- package/dist/reconcile/providers/railway-iac.d.ts +147 -0
- package/dist/reconcile/providers/railway-iac.js +289 -16
- package/dist/scenes/runner.js +11 -11
- package/dist/scripts/build-dist.js +22 -0
- package/dist/workflow/operations.d.ts +12 -0
- package/dist/workflow/operations.js +265 -90
- package/dist/workflow/runs.d.ts +4 -0
- package/dist/workflow/runs.js +4 -0
- package/dist/workflow-support.d.ts +1 -1
- package/dist/workflow-support.js +3 -1
- package/package.json +1 -2
package/dist/guarantees/index.js
CHANGED
|
@@ -19,6 +19,9 @@ function diagnostic(severity, code, message, path, sourcePath) {
|
|
|
19
19
|
function isRecord(value) {
|
|
20
20
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
21
21
|
}
|
|
22
|
+
function arrayOrEmpty(value) {
|
|
23
|
+
return value ?? [];
|
|
24
|
+
}
|
|
22
25
|
function stringValue(value) {
|
|
23
26
|
return typeof value === "string" ? value.trim() : "";
|
|
24
27
|
}
|
|
@@ -332,10 +335,10 @@ function validateTreeseedGuarantee(input) {
|
|
|
332
335
|
}
|
|
333
336
|
function allVerifierRefs(manifest) {
|
|
334
337
|
return [
|
|
335
|
-
...manifest.api?.verifierRefs
|
|
336
|
-
...manifest.content?.verifierRefs
|
|
337
|
-
...manifest.audit?.verifierRefs
|
|
338
|
-
...(manifest.negativeCases
|
|
338
|
+
...arrayOrEmpty(manifest.api?.verifierRefs),
|
|
339
|
+
...arrayOrEmpty(manifest.content?.verifierRefs),
|
|
340
|
+
...arrayOrEmpty(manifest.audit?.verifierRefs),
|
|
341
|
+
...arrayOrEmpty(manifest.negativeCases).flatMap((entry) => arrayOrEmpty(entry.verifierRefs))
|
|
339
342
|
];
|
|
340
343
|
}
|
|
341
344
|
function selectedByFilter(manifest, filter = {}) {
|
|
@@ -403,9 +406,9 @@ function dependencyIdsForGuarantee(input) {
|
|
|
403
406
|
reasons.add(reason);
|
|
404
407
|
deps.set(id, reasons);
|
|
405
408
|
};
|
|
406
|
-
for (const id of input.entry.manifest.dependencies.guarantees
|
|
407
|
-
for (const journeyIndex of input.entry.manifest.dependencies.journeys
|
|
408
|
-
for (const dep of input.entry.manifest.dependsOnGuarantees
|
|
409
|
+
for (const id of arrayOrEmpty(input.entry.manifest.dependencies.guarantees)) add(id, "explicit-guarantee");
|
|
410
|
+
for (const journeyIndex of arrayOrEmpty(input.entry.manifest.dependencies.journeys)) add(input.byJourneyIndex.get(journeyIndex)?.manifest.id, "journey-index");
|
|
411
|
+
for (const dep of arrayOrEmpty(input.entry.manifest.dependsOnGuarantees)) {
|
|
409
412
|
const [ownerPackage, ref] = dep.includes(":") ? dep.split(/:(.+)/u).filter(Boolean) : ["", dep];
|
|
410
413
|
const match = input.valid.find((candidate) => (!ownerPackage || candidate.manifest.ownerPackage === ownerPackage) && candidate.manifest.status === "active" && (candidate.manifest.id === ref || allVerifierRefs(candidate.manifest).includes(ref)));
|
|
411
414
|
add(match?.manifest.id, "depends-on-verifier");
|
|
@@ -455,14 +458,14 @@ function buildTreeseedGuaranteeDependencyGraph(input) {
|
|
|
455
458
|
const filtered = [...deps.keys()].filter((id) => includedIds.has(id)).sort((a, b) => sortGuaranteeEntries(byId.get(a), byId.get(b)));
|
|
456
459
|
depMap.set(entry.manifest.id, filtered);
|
|
457
460
|
const reasons = /* @__PURE__ */ new Set();
|
|
458
|
-
for (const depId of filtered) for (const reason of deps.get(depId)
|
|
459
|
-
for (const reason of reasonById.get(entry.manifest.id)
|
|
461
|
+
for (const depId of filtered) for (const reason of arrayOrEmpty(deps.get(depId))) reasons.add(reason);
|
|
462
|
+
for (const reason of arrayOrEmpty(reasonById.get(entry.manifest.id))) reasons.add(reason);
|
|
460
463
|
reasonMap.set(entry.manifest.id, reasons);
|
|
461
464
|
}
|
|
462
465
|
const producersByStateKey = /* @__PURE__ */ new Map();
|
|
463
466
|
for (const [id, keys] of stateProduces) {
|
|
464
467
|
for (const key of keys) {
|
|
465
|
-
producersByStateKey.set(key, [...producersByStateKey.get(key)
|
|
468
|
+
producersByStateKey.set(key, [...arrayOrEmpty(producersByStateKey.get(key)), id]);
|
|
466
469
|
}
|
|
467
470
|
}
|
|
468
471
|
for (const [key, producers] of producersByStateKey) {
|
|
@@ -480,10 +483,10 @@ function buildTreeseedGuaranteeDependencyGraph(input) {
|
|
|
480
483
|
}
|
|
481
484
|
for (const [id, keys] of stateConsumes) {
|
|
482
485
|
for (const key of keys) {
|
|
483
|
-
const producers = producersByStateKey.get(key)
|
|
486
|
+
const producers = arrayOrEmpty(producersByStateKey.get(key));
|
|
484
487
|
const producer = producers.length === 1 ? producers[0] : void 0;
|
|
485
488
|
if (producer && producer !== id && includedIds.has(producer)) {
|
|
486
|
-
const deps = depMap.get(id)
|
|
489
|
+
const deps = arrayOrEmpty(depMap.get(id));
|
|
487
490
|
if (!deps.includes(producer)) deps.push(producer);
|
|
488
491
|
depMap.set(id, deps.sort((a, b) => sortGuaranteeEntries(byId.get(a), byId.get(b))));
|
|
489
492
|
const reasons = reasonMap.get(id) ?? /* @__PURE__ */ new Set();
|
|
@@ -502,14 +505,14 @@ function buildTreeseedGuaranteeDependencyGraph(input) {
|
|
|
502
505
|
return;
|
|
503
506
|
}
|
|
504
507
|
visiting.add(id);
|
|
505
|
-
for (const dep of depMap.get(id)
|
|
508
|
+
for (const dep of arrayOrEmpty(depMap.get(id))) visitOrder(dep, [...chain, id]);
|
|
506
509
|
visiting.delete(id);
|
|
507
510
|
visited.add(id);
|
|
508
511
|
ordered.push(id);
|
|
509
512
|
};
|
|
510
513
|
for (const entry of included) visitOrder(entry.manifest.id, []);
|
|
511
514
|
const inverse = /* @__PURE__ */ new Map();
|
|
512
|
-
for (const [id, deps] of depMap) for (const dep of deps) inverse.set(dep, [...inverse.get(dep)
|
|
515
|
+
for (const [id, deps] of depMap) for (const dep of deps) inverse.set(dep, [...arrayOrEmpty(inverse.get(dep)), id]);
|
|
513
516
|
const depthCache = /* @__PURE__ */ new Map();
|
|
514
517
|
const depth = (id, chain = []) => {
|
|
515
518
|
if (depthCache.has(id)) return depthCache.get(id);
|
|
@@ -517,20 +520,20 @@ function buildTreeseedGuaranteeDependencyGraph(input) {
|
|
|
517
520
|
diagnostics.push(diagnostic("error", "guarantee.dependency_cycle", `Guarantee dependency cycle: ${[...chain, id].join(" -> ")}.`, "dependencies", byId.get(id)?.sourcePath));
|
|
518
521
|
return 0;
|
|
519
522
|
}
|
|
520
|
-
const value = Math.max(0, ...(depMap.get(id)
|
|
523
|
+
const value = Math.max(0, ...arrayOrEmpty(depMap.get(id)).map((dep) => depth(dep, [...chain, id]) + 1));
|
|
521
524
|
depthCache.set(id, value);
|
|
522
525
|
return value;
|
|
523
526
|
};
|
|
524
527
|
const meta = /* @__PURE__ */ new Map();
|
|
525
528
|
for (const [index, id] of ordered.entries()) {
|
|
526
529
|
meta.set(id, {
|
|
527
|
-
dependsOn: depMap.get(id)
|
|
528
|
-
dependencyOf: (inverse.get(id)
|
|
530
|
+
dependsOn: arrayOrEmpty(depMap.get(id)),
|
|
531
|
+
dependencyOf: arrayOrEmpty(inverse.get(id)).sort((a, b) => sortGuaranteeEntries(byId.get(a), byId.get(b))),
|
|
529
532
|
dependencyReason: [...reasonMap.get(id) ?? /* @__PURE__ */ new Set()],
|
|
530
533
|
dependencyDepth: depth(id),
|
|
531
534
|
executionOrder: index,
|
|
532
|
-
producesState: stateProduces.get(id)
|
|
533
|
-
consumesState: stateConsumes.get(id)
|
|
535
|
+
producesState: arrayOrEmpty(stateProduces.get(id)),
|
|
536
|
+
consumesState: arrayOrEmpty(stateConsumes.get(id))
|
|
534
537
|
});
|
|
535
538
|
}
|
|
536
539
|
return { entries: ordered.map((id) => byId.get(id)).filter(Boolean), selectedIds, meta, diagnostics };
|
|
@@ -541,7 +544,7 @@ function filterTreeseedGuarantees(input) {
|
|
|
541
544
|
function validateTreeseedGuaranteeRegistry(input) {
|
|
542
545
|
const diagnostics = [
|
|
543
546
|
...input.guarantees.flatMap((entry) => entry.diagnostics),
|
|
544
|
-
...(input.verifierRegistries
|
|
547
|
+
...arrayOrEmpty(input.verifierRegistries).flatMap((entry) => entry.diagnostics)
|
|
545
548
|
];
|
|
546
549
|
validateFilter(input.filter, diagnostics);
|
|
547
550
|
const valid = input.guarantees.filter((entry) => Boolean(entry.manifest));
|
|
@@ -558,16 +561,16 @@ function validateTreeseedGuaranteeRegistry(input) {
|
|
|
558
561
|
}
|
|
559
562
|
}
|
|
560
563
|
for (const entry of valid) {
|
|
561
|
-
for (const dep of entry.manifest.dependencies.guarantees
|
|
564
|
+
for (const dep of arrayOrEmpty(entry.manifest.dependencies.guarantees)) {
|
|
562
565
|
if (!ids.has(dep)) diagnostics.push(diagnostic("error", "guarantee.missing_dependency", `Missing guarantee dependency "${dep}".`, "dependencies.guarantees", entry.sourcePath));
|
|
563
566
|
}
|
|
564
|
-
for (const dep of entry.manifest.dependencies.journeys
|
|
567
|
+
for (const dep of arrayOrEmpty(entry.manifest.dependencies.journeys)) {
|
|
565
568
|
if (!journeyIndexes.has(dep)) diagnostics.push(diagnostic("error", "guarantee.missing_journey_dependency", `Missing journey dependency "${dep}".`, "dependencies.journeys", entry.sourcePath));
|
|
566
569
|
if (entry.manifest.journeyIndex && dep >= entry.manifest.journeyIndex) diagnostics.push(diagnostic("error", "guarantee.forward_journey_dependency", `Journey dependency ${dep} must be lower than ${entry.manifest.journeyIndex}.`, "dependencies.journeys", entry.sourcePath));
|
|
567
570
|
}
|
|
568
571
|
}
|
|
569
572
|
for (const entry of valid) {
|
|
570
|
-
for (const dep of entry.manifest.dependsOnGuarantees
|
|
573
|
+
for (const dep of arrayOrEmpty(entry.manifest.dependsOnGuarantees)) {
|
|
571
574
|
const [ownerPackage, ref] = dep.includes(":") ? dep.split(/:(.+)/u).filter(Boolean) : ["", dep];
|
|
572
575
|
const match = valid.find((candidate) => (!ownerPackage || candidate.manifest.ownerPackage === ownerPackage) && candidate.manifest.status === "active" && (candidate.manifest.id === ref || allVerifierRefs(candidate.manifest).includes(ref)));
|
|
573
576
|
if (!match) diagnostics.push(diagnostic("error", "guarantee.missing_depends_on_guarantee", `Missing active guarantee dependency "${dep}".`, "dependsOnGuarantees", entry.sourcePath));
|
|
@@ -582,13 +585,13 @@ function validateTreeseedGuaranteeRegistry(input) {
|
|
|
582
585
|
return;
|
|
583
586
|
}
|
|
584
587
|
visiting.add(id);
|
|
585
|
-
for (const dep of ids.get(id)?.manifest.dependencies.guarantees
|
|
588
|
+
for (const dep of arrayOrEmpty(ids.get(id)?.manifest.dependencies.guarantees)) visit(dep, [...chain, id]);
|
|
586
589
|
visiting.delete(id);
|
|
587
590
|
visited.add(id);
|
|
588
591
|
};
|
|
589
592
|
for (const id of ids.keys()) visit(id, []);
|
|
590
|
-
const verifierIds = new Set((input.verifierRegistries
|
|
591
|
-
const verifierKinds = new Map((input.verifierRegistries
|
|
593
|
+
const verifierIds = new Set(arrayOrEmpty(input.verifierRegistries).flatMap((entry) => Object.keys(entry.registry?.verifiers ?? {})));
|
|
594
|
+
const verifierKinds = new Map(arrayOrEmpty(input.verifierRegistries).flatMap(
|
|
592
595
|
(registry) => Object.entries(registry.registry?.verifiers ?? {}).map(([id, definition]) => [id, definition.kind])
|
|
593
596
|
));
|
|
594
597
|
for (const entry of valid) {
|
|
@@ -613,7 +616,7 @@ function validateTreeseedGuaranteeRegistry(input) {
|
|
|
613
616
|
ok: errors === 0,
|
|
614
617
|
workspaceRoot: resolve(input.workspaceRoot),
|
|
615
618
|
guarantees: input.guarantees,
|
|
616
|
-
verifierRegistries: input.verifierRegistries
|
|
619
|
+
verifierRegistries: arrayOrEmpty(input.verifierRegistries),
|
|
617
620
|
diagnostics,
|
|
618
621
|
counts: {
|
|
619
622
|
total: input.guarantees.length,
|
|
@@ -625,7 +628,7 @@ function validateTreeseedGuaranteeRegistry(input) {
|
|
|
625
628
|
};
|
|
626
629
|
}
|
|
627
630
|
function refs(contract) {
|
|
628
|
-
return contract?.verifierRefs
|
|
631
|
+
return arrayOrEmpty(contract?.verifierRefs);
|
|
629
632
|
}
|
|
630
633
|
function planTreeseedGuarantees(input) {
|
|
631
634
|
const registry = discoverTreeseedGuarantees({ workspaceRoot: input.workspaceRoot, filter: input.filter });
|
|
@@ -653,9 +656,9 @@ function planTreeseedGuarantees(input) {
|
|
|
653
656
|
auditVerifierRefs: refs(entry.manifest.audit),
|
|
654
657
|
evidenceRequired: entry.manifest.evidence.required,
|
|
655
658
|
dependencyDepth: meta?.dependencyDepth ?? 0,
|
|
656
|
-
dependencyOf: meta?.dependencyOf
|
|
657
|
-
dependsOn: meta?.dependsOn
|
|
658
|
-
dependencyReason: meta?.dependencyReason
|
|
659
|
+
dependencyOf: arrayOrEmpty(meta?.dependencyOf),
|
|
660
|
+
dependsOn: arrayOrEmpty(meta?.dependsOn),
|
|
661
|
+
dependencyReason: arrayOrEmpty(meta?.dependencyReason),
|
|
659
662
|
executionOrder: meta?.executionOrder ?? 0,
|
|
660
663
|
...meta?.producesState.length ? { producesState: meta.producesState } : {},
|
|
661
664
|
...meta?.consumesState.length ? { consumesState: meta.consumesState } : {}
|
|
@@ -894,19 +897,19 @@ function exportTreeseedGuaranteesCsv(input) {
|
|
|
894
897
|
entry.manifest.ownerPackage,
|
|
895
898
|
entry.manifest.surface ?? "",
|
|
896
899
|
entry.manifest.status,
|
|
897
|
-
[...entry.manifest.dependencies.guarantees
|
|
900
|
+
[...arrayOrEmpty(entry.manifest.dependencies.guarantees), ...arrayOrEmpty(entry.manifest.dependencies.journeys).map((id) => `journey:${id}`)],
|
|
898
901
|
entry.manifest.actors.allowed,
|
|
899
902
|
entry.manifest.actors.forbidden,
|
|
900
|
-
[...entry.manifest.devices.required, ...entry.manifest.devices.optional
|
|
901
|
-
[...entry.manifest.preconditions.fixtures
|
|
903
|
+
[...entry.manifest.devices.required, ...arrayOrEmpty(entry.manifest.devices.optional)],
|
|
904
|
+
[...arrayOrEmpty(entry.manifest.preconditions.fixtures), ...arrayOrEmpty(entry.manifest.preconditions.notes)],
|
|
902
905
|
entry.manifest.scene?.manifest ?? "",
|
|
903
|
-
entry.manifest.api?.verifierRefs
|
|
904
|
-
entry.manifest.content?.verifierRefs
|
|
905
|
-
entry.manifest.audit?.verifierRefs
|
|
906
|
-
(entry.manifest.negativeCases
|
|
906
|
+
arrayOrEmpty(entry.manifest.api?.verifierRefs),
|
|
907
|
+
arrayOrEmpty(entry.manifest.content?.verifierRefs),
|
|
908
|
+
arrayOrEmpty(entry.manifest.audit?.verifierRefs),
|
|
909
|
+
arrayOrEmpty(entry.manifest.negativeCases).map((negativeCase) => negativeCase.id),
|
|
907
910
|
entry.manifest.gates,
|
|
908
911
|
entry.manifest.evidence.required,
|
|
909
|
-
entry.manifest.notes
|
|
912
|
+
arrayOrEmpty(entry.manifest.notes),
|
|
910
913
|
entry.relativePath
|
|
911
914
|
]);
|
|
912
915
|
return [header, ...body].map((row) => row.map(csvEscape).join(",")).join("\n") + "\n";
|
|
@@ -1217,10 +1220,10 @@ async function defaultTreeseedGuaranteeVerifierExecutor(input) {
|
|
|
1217
1220
|
};
|
|
1218
1221
|
}
|
|
1219
1222
|
if (definition.kind === "manualEvidence") {
|
|
1220
|
-
return { status: "skipped", summary: `${input.ref} requires manual evidence.`, evidence: definition.evidence
|
|
1223
|
+
return { status: "skipped", summary: `${input.ref} requires manual evidence.`, evidence: arrayOrEmpty(definition.evidence) };
|
|
1221
1224
|
}
|
|
1222
1225
|
if (definition.kind === "scene") {
|
|
1223
|
-
return { status: "passed", summary: `${input.ref} is covered by the guarantee scene step.`, evidence: definition.evidence
|
|
1226
|
+
return { status: "passed", summary: `${input.ref} is covered by the guarantee scene step.`, evidence: arrayOrEmpty(definition.evidence) };
|
|
1224
1227
|
}
|
|
1225
1228
|
if (definition.kind === "apiAcceptanceCase") {
|
|
1226
1229
|
if (!definition.caseId) {
|
|
@@ -1261,7 +1264,7 @@ async function defaultTreeseedGuaranteeVerifierExecutor(input) {
|
|
|
1261
1264
|
outputRoot: input.outputRoot,
|
|
1262
1265
|
ref: input.ref,
|
|
1263
1266
|
command: "npm",
|
|
1264
|
-
args: ["-w", workspace, "run", definition.command, "--", ...definition.args
|
|
1267
|
+
args: ["-w", workspace, "run", definition.command, "--", ...arrayOrEmpty(definition.args)],
|
|
1265
1268
|
timeoutSeconds: definition.timeoutSeconds,
|
|
1266
1269
|
onProgress: input.onProgress
|
|
1267
1270
|
});
|
|
@@ -1275,7 +1278,7 @@ async function defaultTreeseedGuaranteeVerifierExecutor(input) {
|
|
|
1275
1278
|
outputRoot: input.outputRoot,
|
|
1276
1279
|
ref: input.ref,
|
|
1277
1280
|
command: "node",
|
|
1278
|
-
args: ["--import", "tsx", definition.command, ...definition.args
|
|
1281
|
+
args: ["--import", "tsx", definition.command, ...arrayOrEmpty(definition.args)],
|
|
1279
1282
|
cwd: definition.cwd,
|
|
1280
1283
|
timeoutSeconds: definition.timeoutSeconds,
|
|
1281
1284
|
onProgress: input.onProgress
|
|
@@ -1310,8 +1313,8 @@ function sceneDeviceRunsForGuarantee(devices) {
|
|
|
1310
1313
|
}
|
|
1311
1314
|
function sceneReportEvidencePaths(workspaceRoot, report) {
|
|
1312
1315
|
const primaryScreenshots = [
|
|
1313
|
-
...(report.steps
|
|
1314
|
-
...report.artifacts?.screenshotPaths
|
|
1316
|
+
...arrayOrEmpty(report.steps).map((step) => step.screenshotPath).filter(Boolean),
|
|
1317
|
+
...arrayOrEmpty(report.artifacts?.screenshotPaths)
|
|
1315
1318
|
].filter((path) => Boolean(path && !path.includes("/screenshots/viewport/")));
|
|
1316
1319
|
return sortedUnique([
|
|
1317
1320
|
...primaryScreenshots,
|
|
@@ -1347,7 +1350,7 @@ async function defaultTreeseedGuaranteeSceneExecutor(input) {
|
|
|
1347
1350
|
status: ok2 ? "passed" : "failed",
|
|
1348
1351
|
summary: ok2 ? "Scene device matrix passed." : contractDiagnostics.length > 0 ? "Scene is not a complete service journey." : "Scene device matrix failed.",
|
|
1349
1352
|
evidence: runReports.flatMap((entry) => sceneReportEvidencePaths(input.workspaceRoot, entry)),
|
|
1350
|
-
diagnostics: [...contractDiagnostics, ...runReports.flatMap((entry) => entry.diagnostics
|
|
1353
|
+
diagnostics: [...contractDiagnostics, ...runReports.flatMap((entry) => arrayOrEmpty(entry.diagnostics))]
|
|
1351
1354
|
};
|
|
1352
1355
|
}
|
|
1353
1356
|
const run = runs[0];
|
|
@@ -1368,7 +1371,7 @@ async function defaultTreeseedGuaranteeSceneExecutor(input) {
|
|
|
1368
1371
|
status: ok ? "passed" : "failed",
|
|
1369
1372
|
summary: ok ? "Scene passed." : contractDiagnostics.length > 0 ? "Scene is not a complete service journey." : "Scene failed.",
|
|
1370
1373
|
evidence: sceneReportEvidencePaths(input.workspaceRoot, report),
|
|
1371
|
-
diagnostics: [...contractDiagnostics, ...report.diagnostics
|
|
1374
|
+
diagnostics: [...contractDiagnostics, ...arrayOrEmpty(report.diagnostics)]
|
|
1372
1375
|
};
|
|
1373
1376
|
} catch (error) {
|
|
1374
1377
|
return {
|
|
@@ -1449,14 +1452,14 @@ async function runGuaranteeSteps(input) {
|
|
|
1449
1452
|
...step,
|
|
1450
1453
|
status: result.status,
|
|
1451
1454
|
summary: result.summary ?? step.summary,
|
|
1452
|
-
evidence: result.evidence ?? step.evidence
|
|
1453
|
-
diagnostics: result.diagnostics ?? step.diagnostics
|
|
1455
|
+
evidence: result.evidence ?? arrayOrEmpty(step.evidence),
|
|
1456
|
+
diagnostics: result.diagnostics ?? arrayOrEmpty(step.diagnostics),
|
|
1454
1457
|
startedAt: stepStartedAt,
|
|
1455
1458
|
completedAt
|
|
1456
1459
|
};
|
|
1457
1460
|
steps.push(nextStep);
|
|
1458
|
-
evidence.push(...nextStep.evidence
|
|
1459
|
-
diagnostics.push(...nextStep.diagnostics
|
|
1461
|
+
evidence.push(...arrayOrEmpty(nextStep.evidence));
|
|
1462
|
+
diagnostics.push(...arrayOrEmpty(nextStep.diagnostics));
|
|
1460
1463
|
input.onProgress?.(`[guarantees][step] ${input.guarantee.manifest.id}: ${nextStep.status} ${step.kind}${step.ref ? ` ${step.ref}` : ""}`);
|
|
1461
1464
|
};
|
|
1462
1465
|
const scene = input.guarantee.manifest.scene;
|
|
@@ -1475,10 +1478,10 @@ async function runGuaranteeSteps(input) {
|
|
|
1475
1478
|
}));
|
|
1476
1479
|
}
|
|
1477
1480
|
const verifierGroups = [
|
|
1478
|
-
{ kind: "api", refs: input.guarantee.manifest.api?.verifierRefs
|
|
1479
|
-
{ kind: "content", refs: input.guarantee.manifest.content?.verifierRefs
|
|
1480
|
-
{ kind: "audit", refs: input.guarantee.manifest.audit?.verifierRefs
|
|
1481
|
-
{ kind: "negative-case", refs: (input.guarantee.manifest.negativeCases
|
|
1481
|
+
{ kind: "api", refs: arrayOrEmpty(input.guarantee.manifest.api?.verifierRefs) },
|
|
1482
|
+
{ kind: "content", refs: arrayOrEmpty(input.guarantee.manifest.content?.verifierRefs) },
|
|
1483
|
+
{ kind: "audit", refs: arrayOrEmpty(input.guarantee.manifest.audit?.verifierRefs) },
|
|
1484
|
+
{ kind: "negative-case", refs: arrayOrEmpty(input.guarantee.manifest.negativeCases).flatMap((entry) => arrayOrEmpty(entry.verifierRefs)) }
|
|
1482
1485
|
];
|
|
1483
1486
|
for (const group of verifierGroups) {
|
|
1484
1487
|
for (const ref of group.refs) {
|
|
@@ -1553,7 +1556,7 @@ async function runTreeseedGuarantees(input) {
|
|
|
1553
1556
|
for (const [index, entry] of runEntries.entries()) {
|
|
1554
1557
|
input.onProgress?.(`[guarantees][run] ${index + 1}/${runEntries.length} ${entry.manifest.id} (${entry.manifest.ownerPackage}) ${entry.manifest.journey}`);
|
|
1555
1558
|
const planEntry = planEntryById.get(entry.manifest.id);
|
|
1556
|
-
const blockingDependencies = (planEntry?.dependsOn
|
|
1559
|
+
const blockingDependencies = arrayOrEmpty(planEntry?.dependsOn).map((id) => resultById.get(id)).filter((result2) => Boolean(result2 && result2.status !== "passed"));
|
|
1557
1560
|
if (blockingDependencies.length > 0) {
|
|
1558
1561
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1559
1562
|
const blockedBy = blockingDependencies.map((result2) => result2.id);
|
|
@@ -171,25 +171,6 @@ export interface TreeseedHostingPlan {
|
|
|
171
171
|
placements: TreeseedHostingPlacementSummary[];
|
|
172
172
|
warnings: string[];
|
|
173
173
|
}
|
|
174
|
-
export interface TreeseedHostingApplyResult {
|
|
175
|
-
environment: TreeseedHostingEnvironment;
|
|
176
|
-
planOnly: boolean;
|
|
177
|
-
selectedApps?: string[];
|
|
178
|
-
selectedSystems?: string[];
|
|
179
|
-
skippedSystems?: Array<{
|
|
180
|
-
system: string;
|
|
181
|
-
reason: string;
|
|
182
|
-
}>;
|
|
183
|
-
transport?: Record<string, Record<string, string>>;
|
|
184
|
-
results: Array<{
|
|
185
|
-
unit: TreeseedHostingUnit;
|
|
186
|
-
plan: TreeseedHostingUnitPlan;
|
|
187
|
-
result: TreeseedHostAdapterOperationResult;
|
|
188
|
-
verification: TreeseedHostingVerification;
|
|
189
|
-
}>;
|
|
190
|
-
placements: TreeseedHostingPlacementSummary[];
|
|
191
|
-
warnings: string[];
|
|
192
|
-
}
|
|
193
174
|
export interface TreeseedHostingPlacementSummary {
|
|
194
175
|
placement: TreeseedServicePlacement;
|
|
195
176
|
label: string;
|
package/dist/hosting/graph.d.ts
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import { type TreeseedCanonicalAction, type TreeseedCanonicalDrift, type TreeseedCanonicalGraphNode, type TreeseedCanonicalPostcondition } from '../reconcile/index.js';
|
|
2
2
|
import type { TreeseedRunnableBootstrapSystem } from '../reconcile/bootstrap-systems.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { TreeseedHostingEnvironment, TreeseedHostingGraph, TreeseedHostingGraphInput, TreeseedHostingPlan, TreeseedHostingPlacementSummary, TreeseedHostingUnit, TreeseedServicePlacement } from './contracts.js';
|
|
4
4
|
export declare function compileTreeseedHostingGraph(input: TreeseedHostingGraphInput): TreeseedHostingGraph;
|
|
5
5
|
export declare function planTreeseedHostingGraph(input: TreeseedHostingGraphInput & {
|
|
6
6
|
planOnly?: boolean;
|
|
7
7
|
}): Promise<TreeseedHostingPlan>;
|
|
8
|
-
/**
|
|
9
|
-
* @deprecated Use reconcileTreeseedTarget with hosting selectors instead.
|
|
10
|
-
*/
|
|
11
|
-
export declare function applyTreeseedHostingGraph(input: TreeseedHostingGraphInput & {
|
|
12
|
-
planOnly?: boolean;
|
|
13
|
-
}): Promise<TreeseedHostingApplyResult>;
|
|
14
8
|
export declare function serializeHostingUnit(unit: TreeseedHostingUnit): {
|
|
15
9
|
id: string;
|
|
16
10
|
label: string;
|
|
@@ -113,83 +107,4 @@ export declare function serializeHostingPlan(plan: TreeseedHostingPlan): {
|
|
|
113
107
|
environment: TreeseedHostingEnvironment;
|
|
114
108
|
planOnly: boolean;
|
|
115
109
|
};
|
|
116
|
-
export declare function serializeHostingApplyResult(result: TreeseedHostingApplyResult): {
|
|
117
|
-
selectedApps: string[];
|
|
118
|
-
selectedSystems: string[];
|
|
119
|
-
skippedSystems: {
|
|
120
|
-
system: string;
|
|
121
|
-
reason: string;
|
|
122
|
-
}[];
|
|
123
|
-
transport: Record<string, Record<string, string>> | undefined;
|
|
124
|
-
placements: TreeseedHostingPlacementSummary[];
|
|
125
|
-
results: {
|
|
126
|
-
unit: {
|
|
127
|
-
id: string;
|
|
128
|
-
label: string;
|
|
129
|
-
serviceType: string;
|
|
130
|
-
placement: TreeseedServicePlacement;
|
|
131
|
-
hostId: string;
|
|
132
|
-
environment: TreeseedHostingEnvironment;
|
|
133
|
-
projectGroupId: string | null;
|
|
134
|
-
requiredCapabilities: import("./contracts.js").TreeseedHostCapability[];
|
|
135
|
-
secretRefs: string[];
|
|
136
|
-
variableRefs: string[];
|
|
137
|
-
application: {
|
|
138
|
-
id: string;
|
|
139
|
-
relativeRoot: string;
|
|
140
|
-
roles: string[];
|
|
141
|
-
} | null;
|
|
142
|
-
config: unknown;
|
|
143
|
-
metadata: unknown;
|
|
144
|
-
};
|
|
145
|
-
desired: {
|
|
146
|
-
id: string;
|
|
147
|
-
label: string;
|
|
148
|
-
serviceType: string;
|
|
149
|
-
placement: TreeseedServicePlacement;
|
|
150
|
-
hostId: string;
|
|
151
|
-
environment: TreeseedHostingEnvironment;
|
|
152
|
-
projectGroupId: string | null;
|
|
153
|
-
requiredCapabilities: import("./contracts.js").TreeseedHostCapability[];
|
|
154
|
-
secretRefs: string[];
|
|
155
|
-
variableRefs: string[];
|
|
156
|
-
application: {
|
|
157
|
-
id: string;
|
|
158
|
-
relativeRoot: string;
|
|
159
|
-
roles: string[];
|
|
160
|
-
} | null;
|
|
161
|
-
config: unknown;
|
|
162
|
-
metadata: unknown;
|
|
163
|
-
};
|
|
164
|
-
observed: import("./contracts.js").TreeseedHostAdapterOperationResult;
|
|
165
|
-
diff: import("./contracts.js").TreeseedHostingUnitPlan;
|
|
166
|
-
actions: import("./contracts.js").TreeseedHostingAction[];
|
|
167
|
-
retainedResources: unknown[];
|
|
168
|
-
blockedDrift: unknown[];
|
|
169
|
-
providerLimitations: unknown[];
|
|
170
|
-
plan: import("./contracts.js").TreeseedHostingUnitPlan;
|
|
171
|
-
result: import("./contracts.js").TreeseedHostAdapterOperationResult;
|
|
172
|
-
verification: import("./contracts.js").TreeseedHostingVerification;
|
|
173
|
-
}[];
|
|
174
|
-
warnings: string[];
|
|
175
|
-
desiredGraph: TreeseedCanonicalGraphNode[];
|
|
176
|
-
observedGraph: TreeseedCanonicalGraphNode[];
|
|
177
|
-
stateGraph: TreeseedCanonicalGraphNode[];
|
|
178
|
-
diff: TreeseedCanonicalDrift[];
|
|
179
|
-
actions: TreeseedCanonicalAction[];
|
|
180
|
-
postconditions: TreeseedCanonicalPostcondition[];
|
|
181
|
-
selectedResources: string[];
|
|
182
|
-
skippedResources: Array<{
|
|
183
|
-
id: string;
|
|
184
|
-
reason: string;
|
|
185
|
-
}>;
|
|
186
|
-
blockedDrift: TreeseedCanonicalDrift[];
|
|
187
|
-
providerLimitations: TreeseedCanonicalDrift[];
|
|
188
|
-
retainedResources: TreeseedCanonicalGraphNode[];
|
|
189
|
-
destroyedResources: TreeseedCanonicalGraphNode[];
|
|
190
|
-
liveVerification: import("../reconcile/platform.js").TreeseedCanonicalLiveVerification;
|
|
191
|
-
ok: boolean;
|
|
192
|
-
environment: TreeseedHostingEnvironment;
|
|
193
|
-
planOnly: boolean;
|
|
194
|
-
};
|
|
195
110
|
export declare function hostingEnvironmentLabel(environment: TreeseedHostingEnvironment): string;
|