@msn-control/liftoff 0.10.4 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEVELOPER.md +238 -77
- package/README.md +38 -33
- package/assets/supported-stack.json +3 -136
- package/dist/adapters/azure/governance-assessment.d.ts +2 -0
- package/dist/adapters/azure/governance-assessment.js +21 -0
- package/dist/adapters/azure/governance-assessment.js.map +1 -0
- package/dist/adapters/filesystem/atomic-write.d.ts +2 -0
- package/dist/adapters/filesystem/atomic-write.js +74 -0
- package/dist/adapters/filesystem/atomic-write.js.map +1 -0
- package/dist/adapters/filesystem/errors.d.ts +2 -0
- package/dist/adapters/filesystem/errors.js +8 -0
- package/dist/adapters/filesystem/errors.js.map +1 -0
- package/dist/adapters/filesystem/manifest-file.d.ts +1 -0
- package/dist/adapters/filesystem/manifest-file.js +21 -0
- package/dist/adapters/filesystem/manifest-file.js.map +1 -0
- package/dist/adapters/filesystem/project-config.d.ts +4 -0
- package/dist/adapters/filesystem/project-config.js +157 -0
- package/dist/adapters/filesystem/project-config.js.map +1 -0
- package/dist/adapters/filesystem/project-discovery.d.ts +2 -0
- package/dist/adapters/filesystem/project-discovery.js +30 -0
- package/dist/adapters/filesystem/project-discovery.js.map +1 -0
- package/dist/adapters/filesystem/project-files.d.ts +6 -0
- package/dist/adapters/filesystem/project-files.js +68 -0
- package/dist/adapters/filesystem/project-files.js.map +1 -0
- package/dist/adapters/filesystem/project-lock.d.ts +8 -0
- package/dist/adapters/filesystem/project-lock.js +164 -0
- package/dist/adapters/filesystem/project-lock.js.map +1 -0
- package/dist/adapters/filesystem/project-paths.d.ts +2 -0
- package/dist/adapters/filesystem/project-paths.js +60 -0
- package/dist/adapters/filesystem/project-paths.js.map +1 -0
- package/dist/adapters/filesystem/project-transaction.d.ts +24 -0
- package/dist/adapters/filesystem/project-transaction.js +177 -0
- package/dist/adapters/filesystem/project-transaction.js.map +1 -0
- package/dist/adapters/filesystem/reviewed-update-transaction.d.ts +53 -0
- package/dist/adapters/filesystem/reviewed-update-transaction.js +864 -0
- package/dist/adapters/filesystem/reviewed-update-transaction.js.map +1 -0
- package/dist/adapters/filesystem/update-previews.d.ts +50 -0
- package/dist/adapters/filesystem/update-previews.js +613 -0
- package/dist/adapters/filesystem/update-previews.js.map +1 -0
- package/dist/adapters/git/governance-assessment.d.ts +22 -0
- package/dist/adapters/git/governance-assessment.js +161 -0
- package/dist/adapters/git/governance-assessment.js.map +1 -0
- package/dist/adapters/github/governance-assessment.d.ts +2 -0
- package/dist/adapters/github/governance-assessment.js +18 -0
- package/dist/adapters/github/governance-assessment.js.map +1 -0
- package/dist/adapters/packaged-assets/package-root.d.ts +3 -0
- package/dist/adapters/packaged-assets/package-root.js +21 -0
- package/dist/adapters/packaged-assets/package-root.js.map +1 -0
- package/dist/adapters/packaged-assets/supported-stack.d.ts +4 -0
- package/dist/adapters/packaged-assets/supported-stack.js +18 -0
- package/dist/adapters/packaged-assets/supported-stack.js.map +1 -0
- package/dist/adapters/packaged-assets/template-assets.d.ts +23 -0
- package/dist/adapters/packaged-assets/template-assets.js +36 -0
- package/dist/adapters/packaged-assets/template-assets.js.map +1 -0
- package/dist/adapters/process/shell-command.d.ts +6 -0
- package/dist/adapters/process/shell-command.js +27 -0
- package/dist/adapters/process/shell-command.js.map +1 -0
- package/dist/application/context.d.ts +25 -0
- package/dist/application/context.js +2 -0
- package/dist/application/context.js.map +1 -0
- package/dist/application/diagnose/doctor.d.ts +21 -0
- package/dist/application/diagnose/doctor.js +580 -0
- package/dist/application/diagnose/doctor.js.map +1 -0
- package/dist/application/diagnose/generated-project.d.ts +1 -0
- package/dist/application/diagnose/generated-project.js +105 -0
- package/dist/application/diagnose/generated-project.js.map +1 -0
- package/dist/application/diagnose/validate.d.ts +6 -0
- package/dist/application/diagnose/validate.js +27 -0
- package/dist/application/diagnose/validate.js.map +1 -0
- package/dist/application/initialize/fixture.d.ts +2 -0
- package/dist/application/initialize/fixture.js +39 -0
- package/dist/application/initialize/fixture.js.map +1 -0
- package/dist/application/initialize/inputs.d.ts +3 -0
- package/dist/application/initialize/inputs.js +35 -0
- package/dist/application/initialize/inputs.js.map +1 -0
- package/dist/application/initialize/use-case.d.ts +23 -0
- package/dist/application/initialize/use-case.js +360 -0
- package/dist/application/initialize/use-case.js.map +1 -0
- package/dist/application/migrate/use-case.d.ts +7 -0
- package/dist/application/migrate/use-case.js +378 -0
- package/dist/application/migrate/use-case.js.map +1 -0
- package/dist/application/project/catalog.d.ts +46 -0
- package/dist/application/project/catalog.js +12 -0
- package/dist/application/project/catalog.js.map +1 -0
- package/dist/application/project/manifest.d.ts +2 -0
- package/dist/application/project/manifest.js +29 -0
- package/dist/application/project/manifest.js.map +1 -0
- package/dist/application/project/planning.d.ts +6 -0
- package/dist/application/project/planning.js +12 -0
- package/dist/application/project/planning.js.map +1 -0
- package/dist/application/update/approval.d.ts +39 -0
- package/dist/application/update/approval.js +54 -0
- package/dist/application/update/approval.js.map +1 -0
- package/dist/application/update/command-guidance.d.ts +2 -0
- package/dist/application/update/command-guidance.js +14 -0
- package/dist/application/update/command-guidance.js.map +1 -0
- package/dist/application/update/inspection.d.ts +37 -0
- package/dist/application/update/inspection.js +235 -0
- package/dist/application/update/inspection.js.map +1 -0
- package/dist/application/update/migration-runtime.d.ts +14 -0
- package/dist/application/update/migration-runtime.js +178 -0
- package/dist/application/update/migration-runtime.js.map +1 -0
- package/dist/application/update/output.d.ts +134 -0
- package/dist/application/update/output.js +182 -0
- package/dist/application/update/output.js.map +1 -0
- package/dist/application/update/planning.d.ts +40 -0
- package/dist/application/update/planning.js +293 -0
- package/dist/application/update/planning.js.map +1 -0
- package/dist/application/update/preview.d.ts +49 -0
- package/dist/application/update/preview.js +220 -0
- package/dist/application/update/preview.js.map +1 -0
- package/dist/application/update/protected-source.d.ts +25 -0
- package/dist/application/update/protected-source.js +81 -0
- package/dist/application/update/protected-source.js.map +1 -0
- package/dist/application/update/reporting.d.ts +42 -0
- package/dist/application/update/reporting.js +326 -0
- package/dist/application/update/reporting.js.map +1 -0
- package/dist/application/update/revalidation-plan.d.ts +22 -0
- package/dist/application/update/revalidation-plan.js +108 -0
- package/dist/application/update/revalidation-plan.js.map +1 -0
- package/dist/application/update/revalidation.d.ts +70 -0
- package/dist/application/update/revalidation.js +337 -0
- package/dist/application/update/revalidation.js.map +1 -0
- package/dist/application/update/review-plan.d.ts +25 -0
- package/dist/application/update/review-plan.js +89 -0
- package/dist/application/update/review-plan.js.map +1 -0
- package/dist/application/update/transaction-approval.d.ts +29 -0
- package/dist/application/update/transaction-approval.js +82 -0
- package/dist/application/update/transaction-approval.js.map +1 -0
- package/dist/application/update/use-case.d.ts +9 -0
- package/dist/application/update/use-case.js +271 -0
- package/dist/application/update/use-case.js.map +1 -0
- package/dist/application/update/write-plan.d.ts +15 -0
- package/dist/application/update/write-plan.js +115 -0
- package/dist/application/update/write-plan.js.map +1 -0
- package/dist/application/upgrade/use-case.d.ts +6 -0
- package/dist/application/upgrade/use-case.js +82 -0
- package/dist/application/upgrade/use-case.js.map +1 -0
- package/dist/args.d.ts +5 -65
- package/dist/args.js +4 -472
- package/dist/args.js.map +1 -1
- package/dist/artifact-lifecycle.d.ts +1 -21
- package/dist/artifact-lifecycle.js +1 -75
- package/dist/artifact-lifecycle.js.map +1 -1
- package/dist/catalogs.d.ts +1 -50
- package/dist/catalogs.js +1 -472
- package/dist/catalogs.js.map +1 -1
- package/dist/cli/args/contracts.d.ts +51 -0
- package/dist/cli/args/contracts.js +2 -0
- package/dist/cli/args/contracts.js.map +1 -0
- package/dist/cli/args/definitions.d.ts +6 -0
- package/dist/cli/args/definitions.js +188 -0
- package/dist/cli/args/definitions.js.map +1 -0
- package/dist/cli/args/help.d.ts +5 -0
- package/dist/cli/args/help.js +142 -0
- package/dist/cli/args/help.js.map +1 -0
- package/dist/cli/args/parser.d.ts +5 -0
- package/dist/cli/args/parser.js +160 -0
- package/dist/cli/args/parser.js.map +1 -0
- package/dist/cli/args/readers.d.ts +4 -0
- package/dist/cli/args/readers.js +19 -0
- package/dist/cli/args/readers.js.map +1 -0
- package/dist/cli/commands/diagnose.d.ts +4 -0
- package/dist/cli/commands/diagnose.js +12 -0
- package/dist/cli/commands/diagnose.js.map +1 -0
- package/dist/cli/commands/dispatch.d.ts +3 -0
- package/dist/cli/commands/dispatch.js +94 -0
- package/dist/cli/commands/dispatch.js.map +1 -0
- package/dist/cli/commands/help.d.ts +3 -0
- package/dist/cli/commands/help.js +32 -0
- package/dist/cli/commands/help.js.map +1 -0
- package/dist/cli/commands/helpers.d.ts +8 -0
- package/dist/cli/commands/helpers.js +97 -0
- package/dist/cli/commands/helpers.js.map +1 -0
- package/dist/cli/commands/initialize.d.ts +3 -0
- package/dist/cli/commands/initialize.js +7 -0
- package/dist/cli/commands/initialize.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +3 -0
- package/dist/cli/commands/migrate.js +8 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +3 -0
- package/dist/cli/commands/plan.js +34 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/reference.d.ts +5 -0
- package/dist/cli/commands/reference.js +43 -0
- package/dist/cli/commands/reference.js.map +1 -0
- package/dist/cli/commands/update.d.ts +3 -0
- package/dist/cli/commands/update.js +10 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/upgrade.d.ts +3 -0
- package/dist/cli/commands/upgrade.js +7 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/context.d.ts +1 -0
- package/dist/cli/context.js +2 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/project-options.d.ts +3 -0
- package/dist/cli/project-options.js +41 -0
- package/dist/cli/project-options.js.map +1 -0
- package/dist/cli.d.ts +3 -3
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts +4 -35
- package/dist/commands.js +3 -2969
- package/dist/commands.js.map +1 -1
- package/dist/container-validation.d.ts +1 -1
- package/dist/domain/governance/activation/approvals.d.ts +351 -0
- package/dist/domain/governance/activation/approvals.js +528 -0
- package/dist/domain/governance/activation/approvals.js.map +1 -0
- package/dist/domain/governance/activation/canonical-json.d.ts +4 -0
- package/dist/domain/governance/activation/canonical-json.js +39 -0
- package/dist/domain/governance/activation/canonical-json.js.map +1 -0
- package/dist/domain/governance/activation/capabilities.d.ts +7 -0
- package/dist/domain/governance/activation/capabilities.js +33 -0
- package/dist/domain/governance/activation/capabilities.js.map +1 -0
- package/dist/domain/governance/activation/evidence.d.ts +63 -0
- package/dist/domain/governance/activation/evidence.js +444 -0
- package/dist/domain/governance/activation/evidence.js.map +1 -0
- package/dist/domain/governance/activation/graph.d.ts +397 -0
- package/dist/domain/governance/activation/graph.js +441 -0
- package/dist/domain/governance/activation/graph.js.map +1 -0
- package/dist/domain/governance/activation/inputs.d.ts +25 -0
- package/dist/domain/governance/activation/inputs.js +63 -0
- package/dist/domain/governance/activation/inputs.js.map +1 -0
- package/dist/domain/governance/activation/operations.d.ts +19 -0
- package/dist/domain/governance/activation/operations.js +181 -0
- package/dist/domain/governance/activation/operations.js.map +1 -0
- package/dist/domain/governance/activation/readiness.d.ts +27 -0
- package/dist/domain/governance/activation/readiness.js +269 -0
- package/dist/domain/governance/activation/readiness.js.map +1 -0
- package/dist/domain/governance/activation/types.d.ts +399 -0
- package/dist/domain/governance/activation/types.js +109 -0
- package/dist/domain/governance/activation/types.js.map +1 -0
- package/dist/domain/governance/activation/validators.d.ts +22 -0
- package/dist/domain/governance/activation/validators.js +1347 -0
- package/dist/domain/governance/activation/validators.js.map +1 -0
- package/dist/domain/governance/assessment/catalog.d.ts +14 -0
- package/dist/domain/governance/assessment/catalog.js +105 -0
- package/dist/domain/governance/assessment/catalog.js.map +1 -0
- package/dist/domain/governance/assessment/errors.d.ts +10 -0
- package/dist/domain/governance/assessment/errors.js +22 -0
- package/dist/domain/governance/assessment/errors.js.map +1 -0
- package/dist/domain/governance/assessment/index.d.ts +8 -0
- package/dist/domain/governance/assessment/index.js +9 -0
- package/dist/domain/governance/assessment/index.js.map +1 -0
- package/dist/domain/governance/assessment/live-normalize.d.ts +19 -0
- package/dist/domain/governance/assessment/live-normalize.js +403 -0
- package/dist/domain/governance/assessment/live-normalize.js.map +1 -0
- package/dist/domain/governance/assessment/predicates.d.ts +36 -0
- package/dist/domain/governance/assessment/predicates.js +545 -0
- package/dist/domain/governance/assessment/predicates.js.map +1 -0
- package/dist/domain/governance/assessment/report.d.ts +23 -0
- package/dist/domain/governance/assessment/report.js +266 -0
- package/dist/domain/governance/assessment/report.js.map +1 -0
- package/dist/domain/governance/assessment/sanitize.d.ts +8 -0
- package/dist/domain/governance/assessment/sanitize.js +60 -0
- package/dist/domain/governance/assessment/sanitize.js.map +1 -0
- package/dist/domain/governance/assessment/types.d.ts +174 -0
- package/dist/domain/governance/assessment/types.js +13 -0
- package/dist/domain/governance/assessment/types.js.map +1 -0
- package/dist/domain/governance/assessment/yaml.d.ts +6 -0
- package/dist/domain/governance/assessment/yaml.js +30 -0
- package/dist/domain/governance/assessment/yaml.js.map +1 -0
- package/dist/domain/governance/policy/identity.d.ts +64 -0
- package/dist/domain/governance/policy/identity.js +112 -0
- package/dist/domain/governance/policy/identity.js.map +1 -0
- package/dist/domain/migration/dependencies.d.ts +7 -0
- package/dist/domain/migration/dependencies.js +221 -0
- package/dist/domain/migration/dependencies.js.map +1 -0
- package/dist/domain/migration/inventory.d.ts +3 -0
- package/dist/domain/migration/inventory.js +15 -0
- package/dist/domain/migration/inventory.js.map +1 -0
- package/dist/domain/project/artifact-lifecycle.d.ts +69 -0
- package/dist/domain/project/artifact-lifecycle.js +137 -0
- package/dist/domain/project/artifact-lifecycle.js.map +1 -0
- package/dist/domain/project/catalog.d.ts +48 -0
- package/dist/domain/project/catalog.js +507 -0
- package/dist/domain/project/catalog.js.map +1 -0
- package/dist/domain/project/contracts.d.ts +247 -0
- package/dist/domain/project/contracts.js +2 -0
- package/dist/domain/project/contracts.js.map +1 -0
- package/dist/domain/project/errors.d.ts +3 -0
- package/dist/domain/project/errors.js +7 -0
- package/dist/domain/project/errors.js.map +1 -0
- package/dist/domain/project/infrastructure-layout.d.ts +26 -0
- package/dist/domain/project/infrastructure-layout.js +125 -0
- package/dist/domain/project/infrastructure-layout.js.map +1 -0
- package/dist/domain/project/inputs.d.ts +21 -0
- package/dist/domain/project/inputs.js +41 -0
- package/dist/domain/project/inputs.js.map +1 -0
- package/dist/domain/project/manifest/artifacts.d.ts +8 -0
- package/dist/domain/project/manifest/artifacts.js +150 -0
- package/dist/domain/project/manifest/artifacts.js.map +1 -0
- package/dist/domain/project/manifest/context.d.ts +13 -0
- package/dist/domain/project/manifest/context.js +2 -0
- package/dist/domain/project/manifest/context.js.map +1 -0
- package/dist/domain/project/manifest/fields.d.ts +6 -0
- package/dist/domain/project/manifest/fields.js +36 -0
- package/dist/domain/project/manifest/fields.js.map +1 -0
- package/dist/domain/project/manifest/governance.d.ts +8 -0
- package/dist/domain/project/manifest/governance.js +161 -0
- package/dist/domain/project/manifest/governance.js.map +1 -0
- package/dist/domain/project/manifest/project-identity.d.ts +6 -0
- package/dist/domain/project/manifest/project-identity.js +273 -0
- package/dist/domain/project/manifest/project-identity.js.map +1 -0
- package/dist/domain/project/manifest/reader.d.ts +9 -0
- package/dist/domain/project/manifest/reader.js +141 -0
- package/dist/domain/project/manifest/reader.js.map +1 -0
- package/dist/domain/project/paths.d.ts +2 -0
- package/dist/domain/project/paths.js +29 -0
- package/dist/domain/project/paths.js.map +1 -0
- package/dist/domain/project/planning.d.ts +19 -0
- package/dist/domain/project/planning.js +329 -0
- package/dist/domain/project/planning.js.map +1 -0
- package/dist/domain/project/retired-workload.d.ts +4 -0
- package/dist/domain/project/retired-workload.js +18 -0
- package/dist/domain/project/retired-workload.js.map +1 -0
- package/dist/domain/project/reviewed-update-artifacts.d.ts +2 -0
- package/dist/domain/project/reviewed-update-artifacts.js +3 -0
- package/dist/domain/project/reviewed-update-artifacts.js.map +1 -0
- package/dist/domain/project/supported-stack.d.ts +113 -0
- package/dist/domain/project/supported-stack.js +426 -0
- package/dist/domain/project/supported-stack.js.map +1 -0
- package/dist/domain/workstation/constraints.d.ts +6 -0
- package/dist/domain/workstation/constraints.js +8 -0
- package/dist/domain/workstation/constraints.js.map +1 -0
- package/dist/file-system.d.ts +10 -44
- package/dist/file-system.js +9 -1245
- package/dist/file-system.js.map +1 -1
- package/dist/framework-adapters.d.ts +1 -1
- package/dist/framework-validation.d.ts +1 -1
- package/dist/framework-validation.js +1 -1
- package/dist/framework-validation.js.map +1 -1
- package/dist/genai-templates.d.ts +2 -9
- package/dist/genai-templates.js +4 -5
- package/dist/genai-templates.js.map +1 -1
- package/dist/generators/common/artifacts.d.ts +6 -0
- package/dist/generators/common/artifacts.js +30 -0
- package/dist/generators/common/artifacts.js.map +1 -0
- package/dist/generators/common/base.d.ts +17 -0
- package/dist/generators/common/base.js +425 -0
- package/dist/generators/common/base.js.map +1 -0
- package/dist/generators/common/dotenv-validation.d.ts +2 -0
- package/dist/generators/common/dotenv-validation.js +80 -0
- package/dist/generators/common/dotenv-validation.js.map +1 -0
- package/dist/generators/common/environments.d.ts +3 -0
- package/dist/generators/common/environments.js +15 -0
- package/dist/generators/common/environments.js.map +1 -0
- package/dist/generators/common/frontend.d.ts +15 -0
- package/dist/generators/common/frontend.js +166 -0
- package/dist/generators/common/frontend.js.map +1 -0
- package/dist/generators/common/python-settings.d.ts +2 -0
- package/dist/generators/common/python-settings.js +70 -0
- package/dist/generators/common/python-settings.js.map +1 -0
- package/dist/generators/common/spec-workflow.d.ts +28 -0
- package/dist/generators/common/spec-workflow.js +567 -0
- package/dist/generators/common/spec-workflow.js.map +1 -0
- package/dist/generators/common/values.d.ts +13 -0
- package/dist/generators/common/values.js +16 -0
- package/dist/generators/common/values.js.map +1 -0
- package/dist/generators/containers/compose.d.ts +7 -0
- package/dist/generators/containers/compose.js +196 -0
- package/dist/generators/containers/compose.js.map +1 -0
- package/dist/generators/containers/context.d.ts +1 -0
- package/dist/generators/containers/context.js +43 -0
- package/dist/generators/containers/context.js.map +1 -0
- package/dist/generators/containers/images.d.ts +7 -0
- package/dist/generators/containers/images.js +119 -0
- package/dist/generators/containers/images.js.map +1 -0
- package/dist/generators/context.d.ts +42 -0
- package/dist/generators/context.js +38 -0
- package/dist/generators/context.js.map +1 -0
- package/dist/generators/genai/backend.d.ts +20 -0
- package/dist/generators/genai/backend.js +667 -0
- package/dist/generators/genai/backend.js.map +1 -0
- package/dist/generators/genai/configuration.d.ts +3 -0
- package/dist/generators/genai/configuration.js +43 -0
- package/dist/generators/genai/configuration.js.map +1 -0
- package/dist/generators/genai/database.d.ts +7 -0
- package/dist/generators/genai/database.js +71 -0
- package/dist/generators/genai/database.js.map +1 -0
- package/dist/generators/genai/functions.d.ts +15 -0
- package/dist/generators/genai/functions.js +156 -0
- package/dist/generators/genai/functions.js.map +1 -0
- package/dist/generators/genai/index.d.ts +8 -0
- package/dist/generators/genai/index.js +11 -0
- package/dist/generators/genai/index.js.map +1 -0
- package/dist/generators/genai/patterns.d.ts +9 -0
- package/dist/generators/genai/patterns.js +309 -0
- package/dist/generators/genai/patterns.js.map +1 -0
- package/dist/generators/infrastructure/azure.d.ts +18 -0
- package/dist/generators/infrastructure/azure.js +655 -0
- package/dist/generators/infrastructure/azure.js.map +1 -0
- package/dist/generators/infrastructure/names.d.ts +23 -0
- package/dist/generators/infrastructure/names.js +51 -0
- package/dist/generators/infrastructure/names.js.map +1 -0
- package/dist/generators/standard/configuration.d.ts +3 -0
- package/dist/generators/standard/configuration.js +26 -0
- package/dist/generators/standard/configuration.js.map +1 -0
- package/dist/generators/standard/go.d.ts +17 -0
- package/dist/generators/standard/go.js +338 -0
- package/dist/generators/standard/go.js.map +1 -0
- package/dist/generators/standard/index.d.ts +12 -0
- package/dist/generators/standard/index.js +12 -0
- package/dist/generators/standard/index.js.map +1 -0
- package/dist/generators/standard/node.d.ts +20 -0
- package/dist/generators/standard/node.js +314 -0
- package/dist/generators/standard/node.js.map +1 -0
- package/dist/generators/standard/python.d.ts +18 -0
- package/dist/generators/standard/python.js +191 -0
- package/dist/generators/standard/python.js.map +1 -0
- package/dist/go-template-assets.js +3 -3
- package/dist/go-template-assets.js.map +1 -1
- package/dist/governance-activation/activation-state.d.ts +1 -1
- package/dist/governance-activation/activation-state.js +49 -9
- package/dist/governance-activation/activation-state.js.map +1 -1
- package/dist/governance-activation/approvals.d.ts +1 -188
- package/dist/governance-activation/approvals.js +1 -507
- package/dist/governance-activation/approvals.js.map +1 -1
- package/dist/governance-activation/canonical-json.d.ts +1 -3
- package/dist/governance-activation/canonical-json.js +1 -35
- package/dist/governance-activation/canonical-json.js.map +1 -1
- package/dist/governance-activation/commands.d.ts +6 -1
- package/dist/governance-activation/commands.js +135 -107
- package/dist/governance-activation/commands.js.map +1 -1
- package/dist/governance-activation/compatibility.d.ts +30 -5
- package/dist/governance-activation/compatibility.js +74 -8
- package/dist/governance-activation/compatibility.js.map +1 -1
- package/dist/governance-activation/credentials.d.ts +3 -3
- package/dist/governance-activation/credentials.js +5 -5
- package/dist/governance-activation/credentials.js.map +1 -1
- package/dist/governance-activation/doctor.d.ts +1 -1
- package/dist/governance-activation/doctor.js +59 -100
- package/dist/governance-activation/doctor.js.map +1 -1
- package/dist/governance-activation/evidence.d.ts +1 -49
- package/dist/governance-activation/evidence.js +1 -245
- package/dist/governance-activation/evidence.js.map +1 -1
- package/dist/governance-activation/git-ignore.d.ts +9 -0
- package/dist/governance-activation/git-ignore.js +76 -0
- package/dist/governance-activation/git-ignore.js.map +1 -0
- package/dist/governance-activation/graph.d.ts +1 -397
- package/dist/governance-activation/graph.js +1 -440
- package/dist/governance-activation/graph.js.map +1 -1
- package/dist/governance-activation/historical-state.d.ts +81 -0
- package/dist/governance-activation/historical-state.js +817 -0
- package/dist/governance-activation/historical-state.js.map +1 -0
- package/dist/governance-activation/history-contracts.d.ts +109 -0
- package/dist/governance-activation/history-contracts.js +303 -0
- package/dist/governance-activation/history-contracts.js.map +1 -0
- package/dist/governance-activation/identity.d.ts +1 -35
- package/dist/governance-activation/identity.js +1 -88
- package/dist/governance-activation/identity.js.map +1 -1
- package/dist/governance-activation/index.d.ts +3 -0
- package/dist/governance-activation/index.js +3 -0
- package/dist/governance-activation/index.js.map +1 -1
- package/dist/governance-activation/inputs.d.ts +10 -0
- package/dist/governance-activation/inputs.js +158 -0
- package/dist/governance-activation/inputs.js.map +1 -0
- package/dist/governance-activation/migration-history.d.ts +97 -0
- package/dist/governance-activation/migration-history.js +388 -0
- package/dist/governance-activation/migration-history.js.map +1 -0
- package/dist/governance-activation/migration.d.ts +4 -3
- package/dist/governance-activation/migration.js +14 -6
- package/dist/governance-activation/migration.js.map +1 -1
- package/dist/governance-activation/phase-bootstrap-state.d.ts +3 -0
- package/dist/governance-activation/phase-bootstrap-state.js +128 -0
- package/dist/governance-activation/phase-bootstrap-state.js.map +1 -0
- package/dist/governance-activation/phase-discovery.d.ts +2 -0
- package/dist/governance-activation/phase-discovery.js +88 -0
- package/dist/governance-activation/phase-discovery.js.map +1 -0
- package/dist/governance-activation/phase-governance.d.ts +4 -0
- package/dist/governance-activation/phase-governance.js +141 -0
- package/dist/governance-activation/phase-governance.js.map +1 -0
- package/dist/governance-activation/phase-publication.d.ts +8 -0
- package/dist/governance-activation/phase-publication.js +318 -0
- package/dist/governance-activation/phase-publication.js.map +1 -0
- package/dist/governance-activation/proof-records.d.ts +3 -0
- package/dist/governance-activation/proof-records.js +78 -0
- package/dist/governance-activation/proof-records.js.map +1 -0
- package/dist/governance-activation/read-only.d.ts +30 -0
- package/dist/governance-activation/read-only.js +33 -0
- package/dist/governance-activation/read-only.js.map +1 -0
- package/dist/governance-activation/readiness.d.ts +1 -25
- package/dist/governance-activation/readiness.js +1 -222
- package/dist/governance-activation/readiness.js.map +1 -1
- package/dist/governance-activation/reconciliation.d.ts +1 -1
- package/dist/governance-activation/reconciliation.js +3 -3
- package/dist/governance-activation/reconciliation.js.map +1 -1
- package/dist/governance-activation/release-integrity.d.ts +1 -1
- package/dist/governance-activation/release-integrity.js +2 -2
- package/dist/governance-activation/release-integrity.js.map +1 -1
- package/dist/governance-activation/seed-lifecycle.d.ts +36 -6
- package/dist/governance-activation/seed-lifecycle.js +444 -77
- package/dist/governance-activation/seed-lifecycle.js.map +1 -1
- package/dist/governance-activation/source-of-truth.d.ts +5 -3
- package/dist/governance-activation/source-of-truth.js +32 -52
- package/dist/governance-activation/source-of-truth.js.map +1 -1
- package/dist/governance-activation/spec-kit-seed.d.ts +9 -0
- package/dist/governance-activation/spec-kit-seed.js +43 -0
- package/dist/governance-activation/spec-kit-seed.js.map +1 -0
- package/dist/governance-activation/task-projection.d.ts +1 -1
- package/dist/governance-activation/transition-planning.d.ts +17 -0
- package/dist/governance-activation/transition-planning.js +259 -0
- package/dist/governance-activation/transition-planning.js.map +1 -0
- package/dist/governance-activation/transition-ports.d.ts +150 -0
- package/dist/governance-activation/transition-ports.js +2 -0
- package/dist/governance-activation/transition-ports.js.map +1 -0
- package/dist/governance-activation/transition-process.d.ts +7 -0
- package/dist/governance-activation/transition-process.js +21 -0
- package/dist/governance-activation/transition-process.js.map +1 -0
- package/dist/governance-activation/transition-records.d.ts +56 -0
- package/dist/governance-activation/transition-records.js +208 -0
- package/dist/governance-activation/transition-records.js.map +1 -0
- package/dist/governance-activation/transitions.d.ts +14 -167
- package/dist/governance-activation/transitions.js +173 -2061
- package/dist/governance-activation/transitions.js.map +1 -1
- package/dist/governance-activation/types.d.ts +1 -390
- package/dist/governance-activation/types.js +1 -107
- package/dist/governance-activation/types.js.map +1 -1
- package/dist/governance-activation/validators.d.ts +1 -17
- package/dist/governance-activation/validators.js +1 -1304
- package/dist/governance-activation/validators.js.map +1 -1
- package/dist/governance-assessment/catalog.d.ts +1 -2
- package/dist/governance-assessment/catalog.js +18 -85
- package/dist/governance-assessment/catalog.js.map +1 -1
- package/dist/governance-assessment/command.d.ts +1 -1
- package/dist/governance-assessment/command.js +8 -12
- package/dist/governance-assessment/command.js.map +1 -1
- package/dist/governance-assessment/engine.d.ts +6 -11
- package/dist/governance-assessment/engine.js +490 -114
- package/dist/governance-assessment/engine.js.map +1 -1
- package/dist/governance-assessment/live-normalize.d.ts +1 -19
- package/dist/governance-assessment/live-normalize.js +1 -402
- package/dist/governance-assessment/live-normalize.js.map +1 -1
- package/dist/governance-assessment/live-transport.d.ts +2 -6
- package/dist/governance-assessment/live-transport.js +10 -22
- package/dist/governance-assessment/live-transport.js.map +1 -1
- package/dist/governance-assessment/live.js +55 -5
- package/dist/governance-assessment/live.js.map +1 -1
- package/dist/governance-assessment/predicates.d.ts +1 -27
- package/dist/governance-assessment/predicates.js +1 -329
- package/dist/governance-assessment/predicates.js.map +1 -1
- package/dist/governance-assessment/project.d.ts +20 -17
- package/dist/governance-assessment/project.js +101 -151
- package/dist/governance-assessment/project.js.map +1 -1
- package/dist/governance-assessment/readers.d.ts +1 -5
- package/dist/governance-assessment/readers.js +5 -13
- package/dist/governance-assessment/readers.js.map +1 -1
- package/dist/governance-assessment/report.d.ts +1 -23
- package/dist/governance-assessment/report.js +1 -265
- package/dist/governance-assessment/report.js.map +1 -1
- package/dist/governance-assessment/sanitize.d.ts +1 -8
- package/dist/governance-assessment/sanitize.js +1 -56
- package/dist/governance-assessment/sanitize.js.map +1 -1
- package/dist/governance-assessment/types.d.ts +1 -173
- package/dist/governance-assessment/types.js +1 -12
- package/dist/governance-assessment/types.js.map +1 -1
- package/dist/governance-assessment/yaml.d.ts +1 -6
- package/dist/governance-assessment/yaml.js +1 -29
- package/dist/governance-assessment/yaml.js.map +1 -1
- package/dist/init-filesystem.d.ts +1 -1
- package/dist/init-filesystem.js +126 -174
- package/dist/init-filesystem.js.map +1 -1
- package/dist/interactive.d.ts +2 -2
- package/dist/interactive.js +42 -41
- package/dist/interactive.js.map +1 -1
- package/dist/migrate-plan.d.ts +1 -1
- package/dist/migrate-plan.js +14 -8
- package/dist/migrate-plan.js.map +1 -1
- package/dist/npm-template-assets.js +5 -4
- package/dist/npm-template-assets.js.map +1 -1
- package/dist/openspec-profile.d.ts +1 -1
- package/dist/opentofu-template-assets.js +3 -3
- package/dist/opentofu-template-assets.js.map +1 -1
- package/dist/package-identity.d.ts +3 -0
- package/dist/package-identity.js +13 -2
- package/dist/package-identity.js.map +1 -1
- package/dist/planner.d.ts +1 -19
- package/dist/planner.js +1 -565
- package/dist/planner.js.map +1 -1
- package/dist/process-runner.d.ts +1 -1
- package/dist/project-dependencies.d.ts +5 -3
- package/dist/project-dependencies.js +74 -63
- package/dist/project-dependencies.js.map +1 -1
- package/dist/published-verifier.js +61 -30
- package/dist/published-verifier.js.map +1 -1
- package/dist/python-template-assets.js +6 -9
- package/dist/python-template-assets.js.map +1 -1
- package/dist/reconcile.d.ts +1 -1
- package/dist/reconcile.js +2 -2
- package/dist/reconcile.js.map +1 -1
- package/dist/repository-governance.d.ts +5 -2
- package/dist/repository-governance.js +140 -113
- package/dist/repository-governance.js.map +1 -1
- package/dist/runtime.js +1 -1
- package/dist/runtime.js.map +1 -1
- package/dist/scan.d.ts +6 -2
- package/dist/scan.js +78 -30
- package/dist/scan.js.map +1 -1
- package/dist/self-upgrade.d.ts +1 -1
- package/dist/self-upgrade.js +20 -7
- package/dist/self-upgrade.js.map +1 -1
- package/dist/stable-release.js +7 -1
- package/dist/stable-release.js.map +1 -1
- package/dist/standard-templates.d.ts +2 -2
- package/dist/standard-templates.js +6 -841
- package/dist/standard-templates.js.map +1 -1
- package/dist/supported-stack.d.ts +3 -115
- package/dist/supported-stack.js +4 -438
- package/dist/supported-stack.js.map +1 -1
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/templates.d.ts +10 -20
- package/dist/templates.js +52 -3261
- package/dist/templates.js.map +1 -1
- package/dist/types.d.ts +1 -263
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/version.js +2 -6
- package/dist/version.js.map +1 -1
- package/dist/workstation-catalog.d.ts +5 -2
- package/dist/workstation-catalog.js +33 -2
- package/dist/workstation-catalog.js.map +1 -1
- package/dist/workstation.d.ts +4 -3
- package/dist/workstation.js +86 -32
- package/dist/workstation.js.map +1 -1
- package/docs/assets/liftoff-terminal.svg +3 -3
- package/docs/azure-deployment.md +107 -10
- package/docs/cli-reference.md +144 -35
- package/docs/configuration-and-manifests.md +152 -35
- package/docs/existing-repositories.md +48 -12
- package/docs/getting-started.md +44 -31
- package/docs/prerequisites.md +34 -35
- package/docs/project-structure.md +39 -46
- package/docs/repository-governance.md +96 -26
- package/docs/safety-and-consent.md +90 -28
- package/docs/spec-workflows-and-agents.md +31 -28
- package/docs/supported-stack.md +11 -9
- package/docs/troubleshooting.md +114 -54
- package/docs/workloads.md +52 -67
- package/package.json +4 -7
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/UPSTREAM_LICENSE.txt +0 -21
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/catalog.json +0 -520
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/packaged/gitignore +0 -27
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/README.md +0 -25
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/components.json +0 -22
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/eslint.config.js +0 -23
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/index.html +0 -13
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/package-lock.json +0 -6156
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/package.json +0 -60
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/public/power-apps.svg +0 -55
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/App.tsx +0 -17
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/assets/react.svg +0 -1
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/mode-toggle.tsx +0 -37
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/badge.tsx +0 -46
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/button.tsx +0 -60
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/calendar.tsx +0 -211
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/card.tsx +0 -92
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/chart.tsx +0 -355
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/checkbox.tsx +0 -32
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/command.tsx +0 -184
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/dialog.tsx +0 -141
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/dropdown-menu.tsx +0 -257
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/input.tsx +0 -21
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/label.tsx +0 -22
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/popover.tsx +0 -46
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/progress.tsx +0 -29
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/select.tsx +0 -185
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/separator.tsx +0 -26
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/skeleton.tsx +0 -13
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/table.tsx +0 -114
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/tabs.tsx +0 -66
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/textarea.tsx +0 -18
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/components/ui/tooltip.tsx +0 -61
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/hooks/use-theme.ts +0 -11
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/index.css +0 -131
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/lib/utils.ts +0 -6
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/main.tsx +0 -10
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/_layout.tsx +0 -31
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/home.tsx +0 -59
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/pages/not-found.tsx +0 -14
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/query-provider.tsx +0 -26
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/sonner-provider.tsx +0 -23
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/providers/theme-provider.tsx +0 -64
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/src/router.tsx +0 -24
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.app.json +0 -34
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.json +0 -13
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/tsconfig.node.json +0 -26
- package/assets/power-apps-code-app/3438c352483e40982f6c5c0fc36fd71f8e7adbbb/starter/vite.config.ts +0 -19
- package/assets/power-apps-code-app/README.md +0 -27
- package/dist/code-apps-plugin.d.ts +0 -13
- package/dist/code-apps-plugin.js +0 -69
- package/dist/code-apps-plugin.js.map +0 -1
- package/dist/power-apps-assets.d.ts +0 -30
- package/dist/power-apps-assets.js +0 -131
- package/dist/power-apps-assets.js.map +0 -1
- package/dist/power-apps-templates.d.ts +0 -3
- package/dist/power-apps-templates.js +0 -177
- package/dist/power-apps-templates.js.map +0 -1
- package/dist/power-apps-validation.d.ts +0 -1
- package/dist/power-apps-validation.js +0 -79
- package/dist/power-apps-validation.js.map +0 -1
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import { readdir, readFile } from 'node:fs/promises';
|
|
1
|
+
import { lstat, readdir, readFile } from 'node:fs/promises';
|
|
2
2
|
import { stripVTControlCharacters } from 'node:util';
|
|
3
|
-
import { loadManifest
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { loadManifest } from '../application/project/manifest.js';
|
|
4
|
+
import { readProjectFile, writeProjectFile } from '../adapters/filesystem/project-files.js';
|
|
5
|
+
import { resolveProjectPath } from '../adapters/filesystem/project-paths.js';
|
|
6
|
+
import { captureProjectFileSnapshot } from '../adapters/filesystem/project-transaction.js';
|
|
7
|
+
import { withProjectMutationLock } from '../adapters/filesystem/project-lock.js';
|
|
8
|
+
import { completedSpecKitTasks, inspectSpecKitBootstrap, specKitBootstrapId, specKitBootstrapPath } from './spec-kit-seed.js';
|
|
9
|
+
import { canonicalSha256 } from '../domain/governance/activation/canonical-json.js';
|
|
10
|
+
import { getPattern } from '../application/project/catalog.js';
|
|
11
|
+
import { toSafeProjectName } from '../domain/project/planning.js';
|
|
12
|
+
import { assessInfrastructureLayout } from '../domain/project/infrastructure-layout.js';
|
|
6
13
|
import { formatCommand } from '../process-runner.js';
|
|
7
14
|
import { detectCredentialLeaks } from './credentials.js';
|
|
8
15
|
const seedChangePathParts = (changeName) => ['openspec', 'changes', changeName];
|
|
@@ -17,12 +24,11 @@ function errorMessage(error) {
|
|
|
17
24
|
return error instanceof Error ? error.message : String(error);
|
|
18
25
|
}
|
|
19
26
|
export function generatedSeedChangeName(manifest) {
|
|
27
|
+
if (manifest.project.specWorkflow === 'spec-kit')
|
|
28
|
+
return specKitBootstrapId;
|
|
20
29
|
return `bootstrap-${toSafeProjectName(manifest.project.name)}`;
|
|
21
30
|
}
|
|
22
31
|
export function generatedSeedCapabilityId(workload) {
|
|
23
|
-
if (workload.kind === 'power-apps-code-app') {
|
|
24
|
-
return 'power-apps-code-app-baseline';
|
|
25
|
-
}
|
|
26
32
|
if (workload.kind === 'standard') {
|
|
27
33
|
return `${workload.apiStack}-application-baseline`;
|
|
28
34
|
}
|
|
@@ -31,7 +37,16 @@ export function generatedSeedCapabilityId(workload) {
|
|
|
31
37
|
function isWorkerWorkload(workload) {
|
|
32
38
|
return workload.kind === 'genai' && getPattern(workload.pattern)?.worker === true;
|
|
33
39
|
}
|
|
34
|
-
export function
|
|
40
|
+
export function seedInfrastructureBaselineBlocker(manifest) {
|
|
41
|
+
const layout = assessInfrastructureLayout(manifest);
|
|
42
|
+
return layout.kind === 'independent' ? undefined :
|
|
43
|
+
`Infrastructure layout migration-required (${layout.kind}): ${layout.reason} ` +
|
|
44
|
+
'No baseline infrastructure recipe is available; existing roots and state are not moved or initialized.';
|
|
45
|
+
}
|
|
46
|
+
export function selectSeedBaselineChecks(manifest, changeName = generatedSeedChangeName(manifest), seedState = 'active', options = {}) {
|
|
47
|
+
const layoutBlocker = seedInfrastructureBaselineBlocker(manifest);
|
|
48
|
+
if (layoutBlocker)
|
|
49
|
+
throw new Error(layoutBlocker);
|
|
35
50
|
const workload = manifest.project.workload;
|
|
36
51
|
const checks = [
|
|
37
52
|
{
|
|
@@ -45,18 +60,7 @@ export function selectSeedBaselineChecks(manifest, changeName = generatedSeedCha
|
|
|
45
60
|
}
|
|
46
61
|
}
|
|
47
62
|
];
|
|
48
|
-
if (workload.kind === '
|
|
49
|
-
checks.push({
|
|
50
|
-
id: 'backend-tests',
|
|
51
|
-
taskId: '2.2',
|
|
52
|
-
label: 'Record backend tests as inapplicable',
|
|
53
|
-
applicability: {
|
|
54
|
-
applicable: false,
|
|
55
|
-
reason: 'no Liftoff backend is generated for Power Apps code apps'
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
else if (workload.kind === 'genai' || workload.apiStack === 'python-fastapi') {
|
|
63
|
+
if (workload.kind === 'genai' || workload.apiStack === 'python-fastapi') {
|
|
60
64
|
checks.push({
|
|
61
65
|
id: 'backend-tests',
|
|
62
66
|
taskId: '2.2',
|
|
@@ -115,19 +119,7 @@ export function selectSeedBaselineChecks(manifest, changeName = generatedSeedCha
|
|
|
115
119
|
}
|
|
116
120
|
});
|
|
117
121
|
}
|
|
118
|
-
if (workload.
|
|
119
|
-
checks.push({
|
|
120
|
-
id: 'frontend-build',
|
|
121
|
-
taskId: '2.4',
|
|
122
|
-
label: 'Run frontend build',
|
|
123
|
-
applicability: {
|
|
124
|
-
applicable: true,
|
|
125
|
-
command: { executable: 'npm', args: ['run', 'build'] },
|
|
126
|
-
cwdPathParts: []
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
else if (workload.frontend) {
|
|
122
|
+
if (workload.frontend) {
|
|
131
123
|
checks.push({
|
|
132
124
|
id: 'frontend-build',
|
|
133
125
|
taskId: '2.4',
|
|
@@ -150,27 +142,7 @@ export function selectSeedBaselineChecks(manifest, changeName = generatedSeedCha
|
|
|
150
142
|
}
|
|
151
143
|
});
|
|
152
144
|
}
|
|
153
|
-
|
|
154
|
-
for (const [id, taskId, label] of [
|
|
155
|
-
['docker-compose-config', '2.5', 'Record Docker Compose validation as inapplicable'],
|
|
156
|
-
['tofu-fmt', '2.6', 'Record OpenTofu formatting as inapplicable'],
|
|
157
|
-
['tofu-init', '2.7', 'Record OpenTofu initialization as inapplicable'],
|
|
158
|
-
['tofu-validate', '2.8', 'Record OpenTofu validation as inapplicable']
|
|
159
|
-
]) {
|
|
160
|
-
checks.push({
|
|
161
|
-
id,
|
|
162
|
-
taskId,
|
|
163
|
-
label,
|
|
164
|
-
applicability: {
|
|
165
|
-
applicable: false,
|
|
166
|
-
reason: id === 'docker-compose-config'
|
|
167
|
-
? 'no generated Docker Compose boundary is present'
|
|
168
|
-
: 'no generated OpenTofu boundary is present'
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
145
|
+
{
|
|
174
146
|
checks.push({
|
|
175
147
|
id: 'docker-compose-config',
|
|
176
148
|
taskId: '2.5',
|
|
@@ -213,7 +185,10 @@ export function selectSeedBaselineChecks(manifest, changeName = generatedSeedCha
|
|
|
213
185
|
id: 'openspec-strict',
|
|
214
186
|
taskId: '2.9',
|
|
215
187
|
label: 'Run strict OpenSpec validation',
|
|
216
|
-
applicability: {
|
|
188
|
+
applicability: manifest.project.specWorkflow === 'spec-kit' ? {
|
|
189
|
+
applicable: false,
|
|
190
|
+
reason: 'Spec Kit validates its real bootstrap bundle and official markers locally; OpenSpec is inapplicable.'
|
|
191
|
+
} : {
|
|
217
192
|
applicable: true,
|
|
218
193
|
command: {
|
|
219
194
|
executable: 'openspec',
|
|
@@ -224,7 +199,183 @@ export function selectSeedBaselineChecks(manifest, changeName = generatedSeedCha
|
|
|
224
199
|
cwdPathParts: []
|
|
225
200
|
}
|
|
226
201
|
});
|
|
227
|
-
|
|
202
|
+
const environmentChecks = manifest.project.workload.environments.flatMap((environment, index) => {
|
|
203
|
+
const cwdPathParts = ['infrastructure', 'opentofu', 'azure', 'environments', environment];
|
|
204
|
+
return [
|
|
205
|
+
{ id: 'tofu-init', taskId: `2.7.${index + 1}`, label: `Initialize ${environment} OpenTofu without a backend`, applicability: {
|
|
206
|
+
applicable: true, command: { executable: 'tofu', args: ['init', '-backend=false'] }, cwdPathParts
|
|
207
|
+
} },
|
|
208
|
+
{ id: 'tofu-validate', taskId: `2.8.${index + 1}`, label: `Validate ${environment} OpenTofu without plan or apply`, applicability: {
|
|
209
|
+
applicable: true, command: { executable: 'tofu', args: ['validate'] }, cwdPathParts
|
|
210
|
+
} }
|
|
211
|
+
];
|
|
212
|
+
});
|
|
213
|
+
const firstInit = checks.findIndex((check) => check.id === 'tofu-init');
|
|
214
|
+
const selected = [...checks.slice(0, firstInit), ...environmentChecks, ...checks.slice(firstInit + 2)];
|
|
215
|
+
if (!options.localRevalidation)
|
|
216
|
+
return selected;
|
|
217
|
+
return selected.filter((check) => check.id !== 'tofu-init').map((check) => {
|
|
218
|
+
if (!check.applicability.applicable)
|
|
219
|
+
return check;
|
|
220
|
+
const applicability = check.applicability;
|
|
221
|
+
const command = applicability.command;
|
|
222
|
+
if (command.executable === 'uv')
|
|
223
|
+
return {
|
|
224
|
+
...check,
|
|
225
|
+
applicability: {
|
|
226
|
+
...applicability,
|
|
227
|
+
command: { executable: 'uv', args: ['run', '--no-sync', '--offline', ...command.args.slice(1)] },
|
|
228
|
+
env: { UV_PYTHON_DOWNLOADS: 'never' }
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
if (command.executable === 'go')
|
|
232
|
+
return {
|
|
233
|
+
...check,
|
|
234
|
+
applicability: {
|
|
235
|
+
...applicability,
|
|
236
|
+
command: { executable: 'go', args: ['test', '-mod=readonly', './...'] },
|
|
237
|
+
env: { GOPROXY: 'off', GOSUMDB: 'off', GOTOOLCHAIN: 'local', GONOPROXY: 'none', GOVCS: '*:off', GOFLAGS: '', GOWORK: 'off' }
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
if (command.executable === 'npm')
|
|
241
|
+
return {
|
|
242
|
+
...check,
|
|
243
|
+
applicability: {
|
|
244
|
+
...applicability,
|
|
245
|
+
command: { executable: 'npm', args: ['--offline', '--ignore-scripts', '--no-audit', '--no-fund', ...command.args] },
|
|
246
|
+
env: { npm_config_offline: 'true', npm_config_ignore_scripts: 'true', npm_config_update_notifier: 'false' }
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
if (command.executable === 'tofu')
|
|
250
|
+
return {
|
|
251
|
+
...check,
|
|
252
|
+
label: check.id === 'tofu-validate'
|
|
253
|
+
? `Observe already initialized OpenTofu at ${applicability.cwdPathParts.join('/')} with validate (no init)`
|
|
254
|
+
: check.label,
|
|
255
|
+
applicability: {
|
|
256
|
+
...applicability,
|
|
257
|
+
env: { TF_CLI_ARGS: '', TF_CLI_ARGS_validate: '', TF_CLI_ARGS_fmt: '', TF_DATA_DIR: '.terraform', TF_INPUT: '0', CHECKPOINT_DISABLE: '1' }
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
return check;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
export async function previewLocalSeedPhase(projectRoot, manifest, phaseId) {
|
|
264
|
+
const discovery = await discoverGeneratedSeed(projectRoot, manifest);
|
|
265
|
+
const blockers = discovery.state === 'blocked' ? [...discovery.issues] : [];
|
|
266
|
+
const changeName = generatedSeedChangeName(manifest);
|
|
267
|
+
const commands = [];
|
|
268
|
+
const observations = [];
|
|
269
|
+
let checks = [];
|
|
270
|
+
if (discovery.state === 'archived') {
|
|
271
|
+
const integrity = await inspectArchivedSeedIntegrity(projectRoot, manifest);
|
|
272
|
+
if (integrity.status !== 'valid')
|
|
273
|
+
blockers.push(...(integrity.status === 'invalid'
|
|
274
|
+
? integrity.issues : ['The archived seed is no longer independently observable.']));
|
|
275
|
+
const archiveRoot = ['openspec', 'changes', 'archive'];
|
|
276
|
+
const archives = (await readdir(await resolveProjectPath(projectRoot, archiveRoot), { withFileTypes: true }))
|
|
277
|
+
.filter((entry) => entry.isDirectory() && (entry.name === changeName || entry.name.endsWith(`-${changeName}`)));
|
|
278
|
+
if (archives.length !== 1)
|
|
279
|
+
blockers.push('The exact archived seed location changed during inspection.');
|
|
280
|
+
else {
|
|
281
|
+
const archived = [...archiveRoot, archives[0].name];
|
|
282
|
+
const capability = generatedSeedCapabilityId(manifest.project.workload);
|
|
283
|
+
const artifacts = [
|
|
284
|
+
['.openspec.yaml'], ['proposal.md'], ['design.md'], ['tasks.md'], ['specs', capability, 'spec.md']
|
|
285
|
+
].map((parts) => [...archived, ...parts]);
|
|
286
|
+
observations.push(...artifacts, ['openspec', 'specs', capability, 'spec.md']);
|
|
287
|
+
for (const parts of artifacts) {
|
|
288
|
+
if (!(await readRequiredProjectText(projectRoot, parts)).trim())
|
|
289
|
+
blockers.push(`Archived seed artifact ${parts.join('/')} is empty.`);
|
|
290
|
+
}
|
|
291
|
+
const declared = extractDeclaredCapabilities(await readRequiredProjectText(projectRoot, [...archived, 'proposal.md']));
|
|
292
|
+
if (declared.length !== 1 || declared[0] !== capability)
|
|
293
|
+
blockers.push(`Archived seed proposal must declare exactly the generated capability ${capability}.`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else if (discovery.state === 'active') {
|
|
297
|
+
observations.push(discovery.changePathParts);
|
|
298
|
+
}
|
|
299
|
+
if (phaseId === 'seed-verified') {
|
|
300
|
+
const infrastructureBlocker = seedInfrastructureBaselineBlocker(manifest);
|
|
301
|
+
if (infrastructureBlocker)
|
|
302
|
+
blockers.push(infrastructureBlocker);
|
|
303
|
+
else
|
|
304
|
+
checks = selectSeedBaselineChecks(manifest, changeName, discovery.state === 'archived' ? 'archived' : 'active', { localRevalidation: true });
|
|
305
|
+
for (const check of checks) {
|
|
306
|
+
if (!check.applicability.applicable)
|
|
307
|
+
continue;
|
|
308
|
+
const { command, cwdPathParts, env } = check.applicability;
|
|
309
|
+
commands.push({ command, cwdPathParts, env: env ?? {} });
|
|
310
|
+
}
|
|
311
|
+
for (const environment of manifest.project.workload.environments) {
|
|
312
|
+
const root = ['infrastructure', 'opentofu', 'azure', 'environments', environment];
|
|
313
|
+
if (await readProjectFile(projectRoot, [...root, 'main.tf']) === undefined) {
|
|
314
|
+
blockers.push(`Missing selected OpenTofu environment root ${[...root, 'main.tf'].join('/')}.`);
|
|
315
|
+
}
|
|
316
|
+
await requireInstalledDirectory([...root, '.terraform'], 'OpenTofu initialization');
|
|
317
|
+
}
|
|
318
|
+
if (manifest.project.workload.kind === 'genai' || manifest.project.workload.apiStack === 'python-fastapi') {
|
|
319
|
+
await requireInstalledDirectory(['backend', '.venv'], 'Python environment');
|
|
320
|
+
}
|
|
321
|
+
else if (manifest.project.workload.apiStack === 'node-fastify') {
|
|
322
|
+
await requireInstalledDirectory(['backend', 'node_modules'], 'Backend dependencies');
|
|
323
|
+
}
|
|
324
|
+
if (manifest.project.workload.frontend)
|
|
325
|
+
await requireInstalledDirectory(['frontend', 'node_modules'], 'Frontend dependencies');
|
|
326
|
+
}
|
|
327
|
+
else if (manifest.project.specWorkflow === 'openspec') {
|
|
328
|
+
if (phaseId === 'seed-archived' && discovery.state !== 'archived') {
|
|
329
|
+
blockers.push('The seed is not already archived. Review liftoff governance plan and complete its separate setup/archive transition; update revalidation never archives or edits seed files.');
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
commands.push({
|
|
333
|
+
command: { executable: 'openspec', args: discovery.state === 'archived'
|
|
334
|
+
? ['validate', '--all', '--strict'] : ['validate', changeName, '--strict'] },
|
|
335
|
+
cwdPathParts: [], env: {}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (manifest.project.specWorkflow === 'spec-kit' && phaseId !== 'seed-valid') {
|
|
340
|
+
const bundle = await inspectSpecKitBootstrap(projectRoot, manifest);
|
|
341
|
+
if (bundle.tasks !== undefined && completedSpecKitTasks(bundle.tasks) !== bundle.tasks) {
|
|
342
|
+
blockers.push('Spec Kit bootstrap tasks are not already the completed matching projection. Review the separate governance setup transition; update revalidation does not write tasks.');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
const actionId = phaseId === 'seed-valid' ? 'openspec.seed.validate'
|
|
346
|
+
: phaseId === 'seed-verified' ? 'openspec.seed.baseline-verify' : 'openspec.seed.archive';
|
|
347
|
+
const operation = {
|
|
348
|
+
adapter: 'selected-spec-workflow', actionId, mutationClass: 'read-worktree', phaseId,
|
|
349
|
+
inputs: {
|
|
350
|
+
changeName, localRevalidation: true, workflow: manifest.project.specWorkflow,
|
|
351
|
+
seedState: discovery.state, observations, commands,
|
|
352
|
+
...(phaseId === 'seed-verified' ? {
|
|
353
|
+
checks: checks.map((check) => ({
|
|
354
|
+
id: check.id, taskId: check.taskId, label: check.label,
|
|
355
|
+
applicable: check.applicability.applicable,
|
|
356
|
+
...(check.applicability.applicable ? {
|
|
357
|
+
command: check.applicability.command, cwdPathParts: check.applicability.cwdPathParts,
|
|
358
|
+
env: check.applicability.env ?? {}
|
|
359
|
+
} : { reason: check.applicability.reason })
|
|
360
|
+
}))
|
|
361
|
+
} : {})
|
|
362
|
+
},
|
|
363
|
+
destination: { type: 'local', identity: projectRoot },
|
|
364
|
+
remote: false, destructive: false
|
|
365
|
+
};
|
|
366
|
+
return { phaseId, operation, commands, blockers };
|
|
367
|
+
async function requireInstalledDirectory(parts, label) {
|
|
368
|
+
const target = await resolveProjectPath(projectRoot, parts);
|
|
369
|
+
try {
|
|
370
|
+
if (!(await lstat(target)).isDirectory())
|
|
371
|
+
throw new Error(`${parts.join('/')} must be an existing regular directory.`);
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
if (errorCode(error) !== 'ENOENT')
|
|
375
|
+
throw error;
|
|
376
|
+
blockers.push(`${label} is unavailable at ${parts.join('/')}. Install or initialize it separately, then run liftoff update --check; revalidation never installs dependencies or runs tofu init.`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
228
379
|
}
|
|
229
380
|
function extractDeclaredCapabilities(proposal) {
|
|
230
381
|
const capabilities = [];
|
|
@@ -331,21 +482,44 @@ export async function inspectArchivedSeedIntegrity(projectRoot, suppliedManifest
|
|
|
331
482
|
]
|
|
332
483
|
};
|
|
333
484
|
}
|
|
334
|
-
return { status: 'valid', changeName, capabilityId, issues: [] };
|
|
485
|
+
return { status: 'valid', changeName, capabilityId, contentDigest: canonicalSha256(spec.replace(/\r\n/g, '\n')), issues: [] };
|
|
335
486
|
}
|
|
336
|
-
export async function discoverGeneratedSeed(projectRoot) {
|
|
337
|
-
const manifest = await loadManifest(projectRoot);
|
|
487
|
+
export async function discoverGeneratedSeed(projectRoot, suppliedManifest) {
|
|
488
|
+
const manifest = suppliedManifest ?? await loadManifest(projectRoot);
|
|
338
489
|
const changeName = generatedSeedChangeName(manifest);
|
|
339
490
|
if (manifest.project.specWorkflow !== 'openspec') {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
changeName,
|
|
343
|
-
|
|
491
|
+
const bundle = await inspectSpecKitBootstrap(projectRoot, manifest);
|
|
492
|
+
return bundle.issues.length ? { state: 'blocked', changeName, issues: bundle.issues } : {
|
|
493
|
+
state: 'active', changeName, changePathParts: specKitBootstrapPath,
|
|
494
|
+
capabilityId: generatedSeedCapabilityId(manifest.project.workload)
|
|
344
495
|
};
|
|
345
496
|
}
|
|
346
497
|
const active = await activeBootstrapChanges(projectRoot);
|
|
347
498
|
if (active.length === 0) {
|
|
348
499
|
if (await archivedBootstrapChangeExists(projectRoot, changeName)) {
|
|
500
|
+
const archiveRoot = await resolveProjectPath(projectRoot, ['openspec', 'changes', 'archive']);
|
|
501
|
+
const archives = (await readdir(archiveRoot, { withFileTypes: true }))
|
|
502
|
+
.filter((entry) => entry.isDirectory() && (entry.name === changeName || entry.name.endsWith(`-${changeName}`)));
|
|
503
|
+
const issues = [];
|
|
504
|
+
if (archives.length !== 1) {
|
|
505
|
+
issues.push(`Expected exactly one archived generated seed ${changeName}; found ${archives.length}.`);
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
const archived = ['openspec', 'changes', 'archive', archives[0].name];
|
|
509
|
+
for (const parts of [
|
|
510
|
+
['.openspec.yaml'], ['proposal.md'], ['design.md'], ['tasks.md'],
|
|
511
|
+
['specs', generatedSeedCapabilityId(manifest.project.workload), 'spec.md']
|
|
512
|
+
]) {
|
|
513
|
+
try {
|
|
514
|
+
await readRequiredProjectText(projectRoot, [...archived, ...parts]);
|
|
515
|
+
}
|
|
516
|
+
catch (error) {
|
|
517
|
+
issues.push(errorMessage(error));
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
if (issues.length)
|
|
522
|
+
return { state: 'blocked', changeName, issues };
|
|
349
523
|
return {
|
|
350
524
|
state: 'archived',
|
|
351
525
|
changeName,
|
|
@@ -365,6 +539,9 @@ export async function discoverGeneratedSeed(projectRoot) {
|
|
|
365
539
|
issues: [`Expected exactly active generated seed ${changeName}; found ${active.join(', ')}.`]
|
|
366
540
|
};
|
|
367
541
|
}
|
|
542
|
+
if (await archivedBootstrapChangeExists(projectRoot, changeName)) {
|
|
543
|
+
return { state: 'blocked', changeName, issues: [`Generated seed ${changeName} has both active and archived copies; resolve ownership explicitly without deleting or inventing history.`] };
|
|
544
|
+
}
|
|
368
545
|
const changePathParts = seedChangePathParts(changeName);
|
|
369
546
|
const issues = [];
|
|
370
547
|
let proposal = '';
|
|
@@ -411,11 +588,28 @@ function checkFailureDetail(result) {
|
|
|
411
588
|
if (result.timedOut) {
|
|
412
589
|
return 'command timed out';
|
|
413
590
|
}
|
|
591
|
+
if (result.aborted)
|
|
592
|
+
return 'command was interrupted or cancelled';
|
|
593
|
+
if (result.outputLimitExceeded)
|
|
594
|
+
return 'command output exceeded the supported limit';
|
|
595
|
+
if (result.signal)
|
|
596
|
+
return `command terminated by ${result.signal}`;
|
|
414
597
|
if (result.errorCode || result.errorMessage) {
|
|
415
598
|
return [result.errorCode, result.errorMessage].filter(Boolean).join(': ');
|
|
416
599
|
}
|
|
417
600
|
return `exit status ${result.status ?? 'unknown'}`;
|
|
418
601
|
}
|
|
602
|
+
function commandSucceeded(result) {
|
|
603
|
+
return result.status === 0 && !result.signal && !result.timedOut && !result.errorCode &&
|
|
604
|
+
!result.errorMessage && !result.aborted && !result.outputLimitExceeded;
|
|
605
|
+
}
|
|
606
|
+
function localValidationObservation(result) {
|
|
607
|
+
return {
|
|
608
|
+
command: result.command,
|
|
609
|
+
exitStatus: result.status,
|
|
610
|
+
outputDigest: canonicalSha256({ stdout: result.stdout, stderr: result.stderr })
|
|
611
|
+
};
|
|
612
|
+
}
|
|
419
613
|
function sanitizeOpenSpecDiagnostic(output) {
|
|
420
614
|
const plain = stripVTControlCharacters(output)
|
|
421
615
|
.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f]/gu, '')
|
|
@@ -438,7 +632,7 @@ async function validateAllOpenSpecAfterArchive(projectRoot, runner, changeName)
|
|
|
438
632
|
args: ['validate', '--all', '--strict']
|
|
439
633
|
};
|
|
440
634
|
const result = await runner.run(command, { cwd: projectRoot });
|
|
441
|
-
if (result
|
|
635
|
+
if (!commandSucceeded(result)) {
|
|
442
636
|
return {
|
|
443
637
|
status: 'blocked',
|
|
444
638
|
issues: [
|
|
@@ -463,8 +657,10 @@ async function runSeedBaselineCheck(projectRoot, runner, check) {
|
|
|
463
657
|
const cwd = check.applicability.cwdPathParts.length === 0
|
|
464
658
|
? projectRoot
|
|
465
659
|
: await resolveProjectPath(projectRoot, [...check.applicability.cwdPathParts]);
|
|
466
|
-
const result = await runner.run(check.applicability.command, {
|
|
467
|
-
|
|
660
|
+
const result = await runner.run(check.applicability.command, {
|
|
661
|
+
cwd, ...(check.applicability.env ? { env: check.applicability.env } : {})
|
|
662
|
+
});
|
|
663
|
+
if (commandSucceeded(result)) {
|
|
468
664
|
return {
|
|
469
665
|
id: check.id,
|
|
470
666
|
taskId: check.taskId,
|
|
@@ -472,6 +668,7 @@ async function runSeedBaselineCheck(projectRoot, runner, check) {
|
|
|
472
668
|
status: 'passed',
|
|
473
669
|
command: check.applicability.command,
|
|
474
670
|
cwdPathParts: check.applicability.cwdPathParts,
|
|
671
|
+
...(check.applicability.env ? { env: check.applicability.env } : {}),
|
|
475
672
|
result
|
|
476
673
|
};
|
|
477
674
|
}
|
|
@@ -482,6 +679,7 @@ async function runSeedBaselineCheck(projectRoot, runner, check) {
|
|
|
482
679
|
status: 'failed',
|
|
483
680
|
command: check.applicability.command,
|
|
484
681
|
cwdPathParts: check.applicability.cwdPathParts,
|
|
682
|
+
...(check.applicability.env ? { env: check.applicability.env } : {}),
|
|
485
683
|
result,
|
|
486
684
|
detail: checkFailureDetail(result)
|
|
487
685
|
};
|
|
@@ -532,6 +730,12 @@ export function markAllSeedTasksForArchive(markdown) {
|
|
|
532
730
|
'2.6',
|
|
533
731
|
'2.7',
|
|
534
732
|
'2.8',
|
|
733
|
+
'2.7.1',
|
|
734
|
+
'2.7.2',
|
|
735
|
+
'2.7.3',
|
|
736
|
+
'2.8.1',
|
|
737
|
+
'2.8.2',
|
|
738
|
+
'2.8.3',
|
|
535
739
|
'2.9',
|
|
536
740
|
'3.1'
|
|
537
741
|
];
|
|
@@ -552,9 +756,22 @@ export function markAllSeedTasksForArchive(markdown) {
|
|
|
552
756
|
}
|
|
553
757
|
return lines.join('\n');
|
|
554
758
|
}
|
|
555
|
-
export async function validateGeneratedSeedForPhase(projectRoot, runner) {
|
|
759
|
+
export async function validateGeneratedSeedForPhase(projectRoot, runner, options = {}) {
|
|
556
760
|
const discovery = await discoverGeneratedSeed(projectRoot);
|
|
557
761
|
if (discovery.state === 'archived') {
|
|
762
|
+
if (options.localRevalidation) {
|
|
763
|
+
const integrity = await inspectArchivedSeedIntegrity(projectRoot);
|
|
764
|
+
if (integrity.status !== 'valid')
|
|
765
|
+
return {
|
|
766
|
+
status: 'blocked', changeName: discovery.changeName,
|
|
767
|
+
issues: integrity.status === 'invalid' ? integrity.issues : ['The archived seed is no longer independently observable.']
|
|
768
|
+
};
|
|
769
|
+
const validation = await validateAllOpenSpecAfterArchive(projectRoot, runner, discovery.changeName);
|
|
770
|
+
if (validation.status === 'blocked')
|
|
771
|
+
return { status: 'blocked', changeName: discovery.changeName, issues: validation.issues };
|
|
772
|
+
return { status: 'passed', changeName: discovery.changeName, command: validation.command,
|
|
773
|
+
detail: 'Existing archived seed artifacts are present and synchronized main specifications are strict-valid; no archive was replayed.' };
|
|
774
|
+
}
|
|
558
775
|
return {
|
|
559
776
|
status: 'passed',
|
|
560
777
|
changeName: discovery.changeName,
|
|
@@ -568,9 +785,13 @@ export async function validateGeneratedSeedForPhase(projectRoot, runner) {
|
|
|
568
785
|
issues: discovery.issues
|
|
569
786
|
};
|
|
570
787
|
}
|
|
788
|
+
const manifest = await loadManifest(projectRoot);
|
|
789
|
+
if (manifest.project.specWorkflow === 'spec-kit') {
|
|
790
|
+
return { status: 'passed', changeName: discovery.changeName, detail: 'Real Spec Kit bootstrap bundle and independent official initialization markers are valid.' };
|
|
791
|
+
}
|
|
571
792
|
const command = { executable: 'openspec', args: ['validate', discovery.changeName, '--strict'] };
|
|
572
793
|
const result = await runner.run(command, { cwd: projectRoot });
|
|
573
|
-
if (result
|
|
794
|
+
if (!commandSucceeded(result)) {
|
|
574
795
|
return {
|
|
575
796
|
status: 'blocked',
|
|
576
797
|
changeName: discovery.changeName,
|
|
@@ -587,7 +808,7 @@ export async function validateGeneratedSeedForPhase(projectRoot, runner) {
|
|
|
587
808
|
detail: 'Generated seed artifacts are present and strict-valid.'
|
|
588
809
|
};
|
|
589
810
|
}
|
|
590
|
-
export async function verifyGeneratedSeedBaselineForPhase(projectRoot, runner) {
|
|
811
|
+
export async function verifyGeneratedSeedBaselineForPhase(projectRoot, runner, options = {}) {
|
|
591
812
|
const manifest = await loadManifest(projectRoot);
|
|
592
813
|
const discovery = await discoverGeneratedSeed(projectRoot);
|
|
593
814
|
if (discovery.state === 'blocked') {
|
|
@@ -611,7 +832,21 @@ export async function verifyGeneratedSeedBaselineForPhase(projectRoot, runner) {
|
|
|
611
832
|
};
|
|
612
833
|
}
|
|
613
834
|
}
|
|
614
|
-
const
|
|
835
|
+
const layoutBlocker = seedInfrastructureBaselineBlocker(manifest);
|
|
836
|
+
if (layoutBlocker)
|
|
837
|
+
return { status: 'blocked', changeName: discovery.changeName, checks: [], issues: [layoutBlocker] };
|
|
838
|
+
if (options.localRevalidation) {
|
|
839
|
+
const preview = await previewLocalSeedPhase(projectRoot, manifest, 'seed-verified');
|
|
840
|
+
if (preview.blockers.length)
|
|
841
|
+
return { status: 'blocked', changeName: discovery.changeName, checks: [], issues: preview.blockers };
|
|
842
|
+
}
|
|
843
|
+
const checks = selectSeedBaselineChecks(manifest, discovery.changeName, discovery.state, options);
|
|
844
|
+
for (const environment of manifest.project.workload.environments) {
|
|
845
|
+
const parts = ['infrastructure', 'opentofu', 'azure', 'environments', environment, 'main.tf'];
|
|
846
|
+
if (await readProjectFile(projectRoot, parts) === undefined) {
|
|
847
|
+
return { status: 'blocked', changeName: discovery.changeName, checks: [], issues: [`Missing selected OpenTofu environment root ${parts.join('/')}.`] };
|
|
848
|
+
}
|
|
849
|
+
}
|
|
615
850
|
const outcomes = await runSeedBaselineChecks(projectRoot, runner, checks);
|
|
616
851
|
const failures = outcomes.filter((outcome) => outcome.status === 'failed');
|
|
617
852
|
if (failures.length > 0) {
|
|
@@ -622,17 +857,46 @@ export async function verifyGeneratedSeedBaselineForPhase(projectRoot, runner) {
|
|
|
622
857
|
checks: outcomes
|
|
623
858
|
};
|
|
624
859
|
}
|
|
860
|
+
if (manifest.project.specWorkflow === 'spec-kit') {
|
|
861
|
+
const bundle = await inspectSpecKitBootstrap(projectRoot, manifest);
|
|
862
|
+
if (bundle.issues.length || bundle.tasks === undefined)
|
|
863
|
+
return { status: 'blocked', changeName: discovery.changeName, checks: outcomes, issues: bundle.issues };
|
|
864
|
+
const snapshot = await captureProjectFileSnapshot(projectRoot, [...specKitBootstrapPath, 'tasks.md']);
|
|
865
|
+
if (snapshot.content?.toString('utf8') !== bundle.tasks)
|
|
866
|
+
return {
|
|
867
|
+
status: 'blocked', changeName: discovery.changeName, checks: outcomes, issues: ['Spec Kit tasks changed during baseline finalization; concurrent bytes were preserved.']
|
|
868
|
+
};
|
|
869
|
+
return {
|
|
870
|
+
status: 'passed', changeName: discovery.changeName, checks: outcomes,
|
|
871
|
+
fileMutations: [{ type: 'write', pathParts: [...specKitBootstrapPath, 'tasks.md'], content: completedSpecKitTasks(bundle.tasks) }],
|
|
872
|
+
filePreconditions: [snapshot]
|
|
873
|
+
};
|
|
874
|
+
}
|
|
625
875
|
return { status: 'passed', changeName: discovery.changeName, checks: outcomes };
|
|
626
876
|
}
|
|
627
|
-
export async function archiveGeneratedSeedForPhase(projectRoot, runner) {
|
|
877
|
+
export async function archiveGeneratedSeedForPhase(projectRoot, runner, options = {}) {
|
|
878
|
+
return withProjectMutationLock(projectRoot, (lease) => archiveGeneratedSeedForPhaseLocked(projectRoot, runner, lease, options));
|
|
879
|
+
}
|
|
880
|
+
async function archiveGeneratedSeedForPhaseLocked(projectRoot, runner, lease, options) {
|
|
881
|
+
const manifest = await loadManifest(projectRoot);
|
|
882
|
+
if (manifest.project.specWorkflow === 'spec-kit') {
|
|
883
|
+
const bundle = await inspectSpecKitBootstrap(projectRoot, manifest);
|
|
884
|
+
if (bundle.issues.length || !bundle.tasks || /^\s*- \[ \] B00[1-6] /m.test(bundle.tasks)) {
|
|
885
|
+
return { status: 'blocked', changeName: specKitBootstrapId, issues: [
|
|
886
|
+
...bundle.issues, 'The explicit Spec Kit local baseline task projection must be finalized by successful baseline execution.'
|
|
887
|
+
] };
|
|
888
|
+
}
|
|
889
|
+
return { status: 'already-archived', changeName: specKitBootstrapId,
|
|
890
|
+
detail: 'Spec Kit local bootstrap handoff is finalized; no OpenSpec archive or Git branch was created.' };
|
|
891
|
+
}
|
|
628
892
|
const discovery = await discoverGeneratedSeed(projectRoot);
|
|
629
893
|
if (discovery.state === 'archived') {
|
|
630
894
|
const integrity = await inspectArchivedSeedIntegrity(projectRoot);
|
|
631
|
-
if (integrity.status === 'invalid') {
|
|
895
|
+
if (integrity.status === 'invalid' || options.localRevalidation && integrity.status !== 'valid') {
|
|
632
896
|
return {
|
|
633
897
|
status: 'blocked',
|
|
634
898
|
changeName: discovery.changeName,
|
|
635
|
-
issues: integrity.issues,
|
|
899
|
+
issues: integrity.status === 'invalid' ? integrity.issues : ['The archived seed is no longer independently observable.'],
|
|
636
900
|
retryableAfterRepair: true
|
|
637
901
|
};
|
|
638
902
|
}
|
|
@@ -648,6 +912,8 @@ export async function archiveGeneratedSeedForPhase(projectRoot, runner) {
|
|
|
648
912
|
return {
|
|
649
913
|
status: 'already-archived',
|
|
650
914
|
changeName: discovery.changeName,
|
|
915
|
+
...(integrity.status === 'valid' ? { synchronizedSpecDigest: integrity.contentDigest } : {}),
|
|
916
|
+
...(options.localRevalidation ? { validation: validation.command } : {}),
|
|
651
917
|
detail: `${discovery.detail} The synchronized main specs remain strict-valid.`
|
|
652
918
|
};
|
|
653
919
|
}
|
|
@@ -658,29 +924,43 @@ export async function archiveGeneratedSeedForPhase(projectRoot, runner) {
|
|
|
658
924
|
issues: discovery.issues
|
|
659
925
|
};
|
|
660
926
|
}
|
|
927
|
+
if (options.localRevalidation)
|
|
928
|
+
return {
|
|
929
|
+
status: 'blocked', changeName: discovery.changeName,
|
|
930
|
+
issues: ['The seed is not already archived. Review the separate governance setup/archive transition; update revalidation never archives or edits seed files.']
|
|
931
|
+
};
|
|
661
932
|
const taskPathParts = [...discovery.changePathParts, 'tasks.md'];
|
|
662
933
|
const originalTasks = await readRequiredProjectText(projectRoot, taskPathParts);
|
|
663
934
|
const completedTasks = markAllSeedTasksForArchive(originalTasks);
|
|
664
935
|
await writeProjectFile(projectRoot, taskPathParts, completedTasks);
|
|
665
936
|
const archiveCommand = { executable: 'openspec', args: ['archive', discovery.changeName, '--yes', '--json'] };
|
|
937
|
+
await lease.assertHeld();
|
|
666
938
|
const archive = await runner.run(archiveCommand, { cwd: projectRoot });
|
|
667
939
|
if (archive.status !== 0 || archive.timedOut || archive.errorCode) {
|
|
668
|
-
await
|
|
940
|
+
const remaining = await readProjectFile(projectRoot, taskPathParts);
|
|
941
|
+
const archiveCompleted = remaining === undefined && await archivedBootstrapChangeExists(projectRoot, discovery.changeName);
|
|
942
|
+
const restored = remaining?.toString('utf8') === completedTasks;
|
|
943
|
+
if (restored)
|
|
944
|
+
await writeProjectFile(projectRoot, taskPathParts, originalTasks);
|
|
669
945
|
return {
|
|
670
946
|
status: 'blocked',
|
|
671
947
|
changeName: discovery.changeName,
|
|
948
|
+
retryableAfterRepair: true,
|
|
949
|
+
archiveCompleted,
|
|
672
950
|
issues: [
|
|
673
951
|
`OpenSpec archive failed: ${formatCommand(archiveCommand)} (${checkFailureDetail(archive)}). ` +
|
|
674
|
-
'
|
|
952
|
+
(archiveCompleted ? 'The seed was already moved to the archive; explicit retry revalidates it without recreating an active seed.' :
|
|
953
|
+
restored ? 'Seed tasks were restored and the seed remains active.' :
|
|
954
|
+
'Concurrent or uncertain seed task changes were preserved; no original task bytes were written over them.')
|
|
675
955
|
]
|
|
676
956
|
};
|
|
677
957
|
}
|
|
678
958
|
const integrity = await inspectArchivedSeedIntegrity(projectRoot);
|
|
679
|
-
if (integrity.status
|
|
959
|
+
if (integrity.status !== 'valid') {
|
|
680
960
|
return {
|
|
681
961
|
status: 'blocked',
|
|
682
962
|
changeName: discovery.changeName,
|
|
683
|
-
issues: integrity.issues,
|
|
963
|
+
issues: integrity.status === 'invalid' ? integrity.issues : ['Archive success was not independently observed; the seed handoff remains incomplete.'],
|
|
684
964
|
retryableAfterRepair: true,
|
|
685
965
|
archiveCompleted: true
|
|
686
966
|
};
|
|
@@ -698,13 +978,100 @@ export async function archiveGeneratedSeedForPhase(projectRoot, runner) {
|
|
|
698
978
|
return {
|
|
699
979
|
status: 'archived',
|
|
700
980
|
changeName: discovery.changeName,
|
|
981
|
+
synchronizedSpecDigest: integrity.contentDigest,
|
|
701
982
|
capabilityId: discovery.capabilityId,
|
|
702
983
|
archive,
|
|
703
984
|
archiveSyncBehavior: 'OpenSpec archive updates main specs as part of archive; the lifecycle engine intentionally never passes --skip-specs.',
|
|
704
985
|
detail: 'Generated seed was archived and the synchronized main specs passed strict validation.'
|
|
705
986
|
};
|
|
706
987
|
}
|
|
988
|
+
export async function executeSeedOperations(input, options = {}) {
|
|
989
|
+
if (!input.phase.id.startsWith('seed-'))
|
|
990
|
+
return null;
|
|
991
|
+
if (input.phase.id === 'seed-valid') {
|
|
992
|
+
const result = await validateGeneratedSeedForPhase(input.inspection.projectRoot, input.runner, options);
|
|
993
|
+
if (result.status === 'blocked') {
|
|
994
|
+
return { status: 'blocked', blocker: result.issues[0] ?? 'Seed validation failed.', completedOperations: [] };
|
|
995
|
+
}
|
|
996
|
+
return {
|
|
997
|
+
status: 'completed',
|
|
998
|
+
resultState: 'verified',
|
|
999
|
+
evidencePayload: {
|
|
1000
|
+
kind: 'seed-valid.v1', changeName: result.changeName, detail: result.detail,
|
|
1001
|
+
...(options.localRevalidation && result.command ? { validation: localValidationObservation(result.command) } : {})
|
|
1002
|
+
},
|
|
1003
|
+
completedOperations: input.plan.operations.filter((op) => op.actionId === 'openspec.seed.validate')
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
if (input.phase.id === 'seed-verified') {
|
|
1007
|
+
const result = await verifyGeneratedSeedBaselineForPhase(input.inspection.projectRoot, input.runner, options);
|
|
1008
|
+
if (result.status === 'blocked') {
|
|
1009
|
+
return { status: 'blocked', blocker: result.issues[0] ?? 'Seed baseline verification failed.', completedOperations: [] };
|
|
1010
|
+
}
|
|
1011
|
+
if (options.localRevalidation) {
|
|
1012
|
+
for (const mutation of result.fileMutations ?? []) {
|
|
1013
|
+
const current = await readProjectFile(input.inspection.projectRoot, mutation.pathParts);
|
|
1014
|
+
if (mutation.type !== 'write' || current?.toString('utf8') !== mutation.content)
|
|
1015
|
+
return {
|
|
1016
|
+
status: 'blocked',
|
|
1017
|
+
blocker: 'The baseline requires a differing Spec Kit task projection. Review the separate setup transition; revalidation preserved the existing tasks.',
|
|
1018
|
+
completedOperations: []
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
return {
|
|
1023
|
+
status: 'completed',
|
|
1024
|
+
resultState: 'verified',
|
|
1025
|
+
evidencePayload: {
|
|
1026
|
+
kind: 'seed-verified.v1',
|
|
1027
|
+
checks: result.checks.map((check) => ({
|
|
1028
|
+
id: check.id, taskId: check.taskId, status: check.status,
|
|
1029
|
+
...(options.localRevalidation && check.status === 'passed' ? {
|
|
1030
|
+
label: check.label, cwdPathParts: check.cwdPathParts, env: check.env ?? {},
|
|
1031
|
+
...localValidationObservation(check.result)
|
|
1032
|
+
} : {})
|
|
1033
|
+
}))
|
|
1034
|
+
},
|
|
1035
|
+
completedOperations: input.plan.operations.filter((op) => op.actionId === 'openspec.seed.baseline-verify' || op.actionId === 'seed.tasks.project'),
|
|
1036
|
+
fileMutations: options.localRevalidation ? undefined : result.fileMutations,
|
|
1037
|
+
filePreconditions: result.filePreconditions
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
const result = await archiveGeneratedSeedForPhase(input.inspection.projectRoot, input.runner, options);
|
|
1041
|
+
if (result.status === 'blocked') {
|
|
1042
|
+
return {
|
|
1043
|
+
status: 'blocked',
|
|
1044
|
+
blocker: result.issues[0] ?? 'Seed archive failed.',
|
|
1045
|
+
completedOperations: result.archiveCompleted ? input.plan.operations.filter((op) => op.actionId === 'openspec.seed.archive') : [],
|
|
1046
|
+
retryableWithoutStateMutation: result.retryableAfterRepair
|
|
1047
|
+
};
|
|
1048
|
+
}
|
|
1049
|
+
return {
|
|
1050
|
+
status: 'completed',
|
|
1051
|
+
resultState: 'verified',
|
|
1052
|
+
evidencePayload: {
|
|
1053
|
+
kind: 'seed-archived.v1',
|
|
1054
|
+
...(result.synchronizedSpecDigest ? { synchronizedSpecDigest: result.synchronizedSpecDigest } : {}),
|
|
1055
|
+
archiveSyncBehavior: result.archiveSyncBehavior ?? null,
|
|
1056
|
+
...(options.localRevalidation ? {
|
|
1057
|
+
observation: result.detail,
|
|
1058
|
+
...(result.validation ? { validation: localValidationObservation(result.validation) } : {})
|
|
1059
|
+
} : {})
|
|
1060
|
+
},
|
|
1061
|
+
completedOperations: input.plan.operations.filter((op) => op.actionId === 'openspec.seed.archive')
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
707
1064
|
export async function completeGeneratedSeedLifecycle(projectRoot, runner) {
|
|
1065
|
+
return withProjectMutationLock(projectRoot, () => completeGeneratedSeedLifecycleLocked(projectRoot, runner));
|
|
1066
|
+
}
|
|
1067
|
+
async function completeGeneratedSeedLifecycleLocked(projectRoot, runner) {
|
|
1068
|
+
const manifest = await loadManifest(projectRoot);
|
|
1069
|
+
if (manifest.project.specWorkflow === 'spec-kit') {
|
|
1070
|
+
return {
|
|
1071
|
+
status: 'blocked', changeName: specKitBootstrapId, checks: [],
|
|
1072
|
+
issues: ['Spec Kit local completion requires the explicitly planned governance apply-next --execute phases so task projection and the body-bound baseline receipt are persisted together. No standalone archive is supported.']
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
708
1075
|
const discovery = await discoverGeneratedSeed(projectRoot);
|
|
709
1076
|
if (discovery.state === 'archived') {
|
|
710
1077
|
const archive = await archiveGeneratedSeedForPhase(projectRoot, runner);
|