@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,23 +1,41 @@
|
|
|
1
|
-
import { canonicalJson, canonicalSha256, sha256Hex } from '../governance
|
|
2
|
-
import { currentActivationIdentity, canonicalPhaseGraph } from '../governance
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { canonicalJson, canonicalSha256, sha256Hex } from '../domain/governance/activation/canonical-json.js';
|
|
2
|
+
import { currentActivationIdentity, canonicalPhaseGraph } from '../domain/governance/activation/graph.js';
|
|
3
|
+
import { canonicalApprovalEnvelopeHash, evaluateApprovalForTransitionPlan, transitionPlanForPhase } from '../domain/governance/activation/approvals.js';
|
|
4
|
+
import { formatUpdateCommand } from '../application/update/command-guidance.js';
|
|
5
|
+
import { inspectCurrentActivationEvidence } from '../governance-activation/read-only.js';
|
|
6
6
|
import { governanceChangeMetadataFileName, validateGovernanceChangeMetadata } from '../governance-activation/source-of-truth.js';
|
|
7
|
+
import { phaseIds } from '../domain/governance/activation/types.js';
|
|
7
8
|
import { loadAssessmentCatalog } from './catalog.js';
|
|
8
|
-
import {
|
|
9
|
+
import { inspectAssessmentHistoricalActivation, inspectAssessmentProject, ordinaryGitAssessmentProject } from './project.js';
|
|
10
|
+
import { inspectAssessmentGit, repositoryName } from '../adapters/git/governance-assessment.js';
|
|
9
11
|
import { AssessmentFiles, AssessmentInputError, parseAssessmentJson } from './readers.js';
|
|
10
12
|
import { parseAssessmentWorkflow } from './yaml.js';
|
|
11
13
|
import { collectLiveAssessment } from './live.js';
|
|
12
|
-
import { classifyFinding, assembleAssessmentReport } from '
|
|
13
|
-
import { actionReferences, failOpenFlags, pinnedActions, protectedRefs, requiredCheckContexts, requiredContextBindings, securityPipeline, singleMaintainer, tagControls, workflowPermissions, observedRequiredContexts } from '
|
|
14
|
-
import { isRecord, jsonValue, notObserved, observed, sanitizeAssessmentText, source } from '
|
|
14
|
+
import { classifyFinding, assembleAssessmentReport } from '../domain/governance/assessment/report.js';
|
|
15
|
+
import { actionReferences, effectiveProtectedRefs, effectiveRequiredContextBindings, failOpenFlags, pinnedActions, protectedRefs, requiredCheckContexts, requiredContextBindings, runnerAlignment, securityPipeline, singleMaintainer, tagControls, workflowPermissions, observedRequiredContexts } from '../domain/governance/assessment/predicates.js';
|
|
16
|
+
import { isRecord, jsonValue, notObserved, observed, sanitizeAssessmentText, source } from '../domain/governance/assessment/sanitize.js';
|
|
15
17
|
const documentationPaths = [
|
|
16
18
|
['CONTRIBUTING.md'], ['docs', 'operations', 'github-governance.md'],
|
|
17
19
|
['docs', 'security', 'scanning.md'], ['docs', 'operations', 'alerting.md'],
|
|
18
20
|
['docs', 'operations', 'service-health.md'], ['docs', 'security', 'audit-evidence.md'],
|
|
19
21
|
['docs', 'ai-acceptable-use.md']
|
|
20
22
|
];
|
|
23
|
+
function activationAuthorityFingerprint(inspection) {
|
|
24
|
+
if (inspection.status === 'not-started') {
|
|
25
|
+
return canonicalSha256({ status: inspection.status });
|
|
26
|
+
}
|
|
27
|
+
const firstContext = inspection.contexts[phaseIds[0]];
|
|
28
|
+
const stable = JSON.parse(JSON.stringify({
|
|
29
|
+
status: inspection.status,
|
|
30
|
+
state: inspection.state,
|
|
31
|
+
snapshot: inspection.snapshot,
|
|
32
|
+
migration: inspection.migration,
|
|
33
|
+
records: inspection.records,
|
|
34
|
+
reviewedPlans: firstContext.reviewedPlans ?? [],
|
|
35
|
+
selections: inspection.selections
|
|
36
|
+
}));
|
|
37
|
+
return canonicalSha256(stable);
|
|
38
|
+
}
|
|
21
39
|
async function localFacts(files, project, capturedAt) {
|
|
22
40
|
const workflowParts = await files.list(['.github', 'workflows'], ['.yml', '.yaml']);
|
|
23
41
|
const workflows = [];
|
|
@@ -76,6 +94,15 @@ async function localFacts(files, project, capturedAt) {
|
|
|
76
94
|
throw new Error('Active governance metadata does not match the recorded change and identity.');
|
|
77
95
|
}
|
|
78
96
|
baseline = metadata.baselineSha === '0'.repeat(64) ? null : metadata.baselineSha;
|
|
97
|
+
if (baseline && project.inputSnapshot && baseline !== project.inputSnapshot.baselineSha) {
|
|
98
|
+
project.diagnostics.push({
|
|
99
|
+
code: 'current-input-mismatch',
|
|
100
|
+
severity: 'warning',
|
|
101
|
+
source: parts.join('/'),
|
|
102
|
+
message: 'The recorded governance baseline does not match the independently recomputed current input snapshot; evidence-backed scope is withheld.'
|
|
103
|
+
});
|
|
104
|
+
baseline = null;
|
|
105
|
+
}
|
|
79
106
|
}
|
|
80
107
|
catch (error) {
|
|
81
108
|
project.diagnostics.push({
|
|
@@ -97,58 +124,45 @@ async function localFacts(files, project, capturedAt) {
|
|
|
97
124
|
};
|
|
98
125
|
}
|
|
99
126
|
function boundPlan(project, phaseId, now) {
|
|
100
|
-
|
|
127
|
+
const currentContext = project.evidenceContexts?.[phaseId];
|
|
128
|
+
const selection = project.activationSelections?.[phaseId];
|
|
129
|
+
const selected = selection?.issues.length === 0 ? selection.selected : null;
|
|
130
|
+
const payload = selected?.payload;
|
|
131
|
+
if (!project.state || !currentContext || !selected ||
|
|
132
|
+
!isRecord(payload) || typeof payload.planDigest !== 'string' ||
|
|
133
|
+
typeof payload.savedPlanDigest !== 'string' ||
|
|
134
|
+
project.identity.availability !== 'known')
|
|
101
135
|
return null;
|
|
102
|
-
const candidates =
|
|
136
|
+
const candidates = (currentContext.reviewedPlans ?? []).filter((plan) => plan.phaseId === phaseId &&
|
|
137
|
+
plan.planDigest === payload.planDigest &&
|
|
138
|
+
canonicalSha256(plan) === payload.savedPlanDigest &&
|
|
139
|
+
plan.baselineDigest === currentContext.baselineSha &&
|
|
103
140
|
canonicalJson(plan.identity) === canonicalJson(currentActivationIdentity) &&
|
|
104
141
|
Date.parse(plan.createdAt) <= now.getTime() &&
|
|
105
142
|
Date.parse(plan.createdAt) <= Date.parse(project.state.phases[phaseId].updatedAt)).sort((a, b) => Date.parse(b.createdAt) - Date.parse(a.createdAt));
|
|
106
143
|
const plan = candidates[0];
|
|
107
144
|
if (!plan || plan.baselineDigest === '0'.repeat(64) || plan.inputDigest === '1'.repeat(64) ||
|
|
145
|
+
plan.baselineDigest !== currentContext.baselineSha ||
|
|
146
|
+
plan.inputDigest !== currentContext.inputDigest ||
|
|
147
|
+
plan.transitionDigest !== currentContext.transition.transitionDigest ||
|
|
108
148
|
candidates.some((candidate) => candidate.createdAt === plan.createdAt && candidate.planDigest !== plan.planDigest))
|
|
109
149
|
return null;
|
|
110
|
-
const phase = canonicalPhaseGraph.phases.find((entry) => entry.id === phaseId);
|
|
111
|
-
if (!phase)
|
|
112
|
-
return null;
|
|
113
|
-
const authority = transitionPlanForPhase(phase, project.state, {
|
|
114
|
-
phaseId, baselineSha: plan.baselineDigest, inputDigest: plan.inputDigest, transitionDigest: plan.transitionDigest
|
|
115
|
-
});
|
|
116
|
-
if (plan.planDigest !== planDigestFor({
|
|
117
|
-
phase, transitionDigest: plan.transitionDigest, operations: plan.operations, approvalPlanDigest: authority.planDigest
|
|
118
|
-
}))
|
|
119
|
-
return null;
|
|
120
150
|
return plan;
|
|
121
151
|
}
|
|
122
152
|
export function selectBoundAssessmentEvidence(project, phaseId, now) {
|
|
123
153
|
const plan = boundPlan(project, phaseId, now);
|
|
124
|
-
|
|
154
|
+
const selection = project.activationSelections?.[phaseId];
|
|
155
|
+
const selected = selection?.issues.length === 0 ? selection.selected : null;
|
|
156
|
+
if (!plan || !project.state || !selected ||
|
|
157
|
+
selected.header.result !== project.state.phases[phaseId].state)
|
|
125
158
|
return null;
|
|
126
|
-
|
|
127
|
-
return null;
|
|
128
|
-
const phase = canonicalPhaseGraph.phases.find((entry) => entry.id === phaseId);
|
|
129
|
-
const references = project.state.phases[phaseId].evidence;
|
|
130
|
-
const candidates = project.evidence.filter((record) => record.header.phaseId === phaseId &&
|
|
131
|
-
references.some((reference) => reference.phaseId === phaseId && reference.evidenceId === record.evidenceId &&
|
|
132
|
-
reference.headerDigest === canonicalSha256(record.header) && reference.result === record.header.result));
|
|
133
|
-
const selected = selectLatestPhaseEvidence(candidates, evidenceContextForPhase(phaseId, {
|
|
134
|
-
repositoryId: project.state.repository.id, identity: currentActivationIdentity,
|
|
135
|
-
phaseGraphHash: currentActivationIdentity.phaseGraphHash, now,
|
|
136
|
-
baselineSha: plan.baselineDigest, inputDigest: plan.inputDigest, transitionDigest: plan.transitionDigest,
|
|
137
|
-
liveReadbackProviders: phase ? requiredLiveReadbackProviders(phase) : []
|
|
138
|
-
})).selected;
|
|
139
|
-
if (!selected || selected.header.result !== project.state.phases[phaseId].state)
|
|
140
|
-
return null;
|
|
141
|
-
const record = candidates.find((entry) => entry.evidenceId === selected.evidenceId &&
|
|
142
|
-
canonicalSha256(entry.header) === selected.headerDigest);
|
|
143
|
-
return record ? { ...selected, record } : null;
|
|
159
|
+
return selected;
|
|
144
160
|
}
|
|
145
161
|
function applicability(control, project, now) {
|
|
146
162
|
if (control.applicability === 'always')
|
|
147
163
|
return 'applicable';
|
|
148
|
-
if (project.project.workload.kind === 'power-apps-code-app')
|
|
149
|
-
return 'inapplicable';
|
|
150
164
|
if (control.applicability === 'api')
|
|
151
|
-
return 'applicable';
|
|
165
|
+
return project.kind === 'liftoff' ? 'applicable' : 'unknown';
|
|
152
166
|
const discovery = selectBoundAssessmentEvidence(project, 'phase-0-complete', now);
|
|
153
167
|
if (!project.state || discovery?.header.result !== 'verified')
|
|
154
168
|
return 'unknown';
|
|
@@ -156,41 +170,81 @@ function applicability(control, project, now) {
|
|
|
156
170
|
? project.state.applicability.privateStagingDast
|
|
157
171
|
: project.state.applicability.statePath === 'bootstrap-local') ? 'applicable' : 'inapplicable';
|
|
158
172
|
}
|
|
173
|
+
function approvalBindsRepository(project, approval, repository, now) {
|
|
174
|
+
const currentBaseline = project.inputSnapshot?.baselineSha ??
|
|
175
|
+
project.bindingBaseline;
|
|
176
|
+
if (!project.state || !currentBaseline)
|
|
177
|
+
return false;
|
|
178
|
+
const plan = boundPlan(project, approval.phaseId, now);
|
|
179
|
+
const phase = canonicalPhaseGraph.phases.find((entry) => entry.id === approval.phaseId);
|
|
180
|
+
const authority = plan && phase ? transitionPlanForPhase(phase, project.state, {
|
|
181
|
+
phaseId: phase.id,
|
|
182
|
+
baselineSha: plan.baselineDigest,
|
|
183
|
+
inputDigest: plan.inputDigest,
|
|
184
|
+
transitionDigest: plan.transitionDigest
|
|
185
|
+
}) : null;
|
|
186
|
+
return approval.baselineSha === currentBaseline &&
|
|
187
|
+
project.identity.availability === 'known' &&
|
|
188
|
+
Date.parse(approval.approvedAt) <= now.getTime() &&
|
|
189
|
+
Date.parse(approval.expiresAt) > now.getTime() &&
|
|
190
|
+
project.state.phases[approval.phaseId].approvals.includes(approval.id) &&
|
|
191
|
+
Boolean(plan && authority && phase?.approvalGate.required) &&
|
|
192
|
+
authority?.planDigest === approval.planDigest &&
|
|
193
|
+
!evaluateApprovalForTransitionPlan(authority, [approval], { now }).approvalRequired &&
|
|
194
|
+
plan.approval.envelopeId === approval.id &&
|
|
195
|
+
plan.approval.envelopeHash === canonicalApprovalEnvelopeHash(approval) &&
|
|
196
|
+
approval.destinations.some((destination) => destination.type === 'repository' &&
|
|
197
|
+
(destination.repository ?? destination.identity).toLowerCase() === repository.toLowerCase());
|
|
198
|
+
}
|
|
159
199
|
export function resolveAssessmentLiveScope(project, git, now) {
|
|
160
|
-
|
|
161
|
-
let
|
|
162
|
-
if (git.repository &&
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
200
|
+
let repository = git.originState === 'verified' ? git.repository : null;
|
|
201
|
+
let remoteBindingVerified = false;
|
|
202
|
+
if (git.repository && project.state?.remoteBinding) {
|
|
203
|
+
const remote = project.state.remoteBinding;
|
|
204
|
+
const bound = repositoryName(remote.name, remote.id);
|
|
205
|
+
const matchingPush = git.pushUrls.length === 1 &&
|
|
206
|
+
git.pushUrls[0] === remote.pushUrl &&
|
|
207
|
+
project.inputSnapshot?.git.pushUrls.length === 1 &&
|
|
208
|
+
project.inputSnapshot.git.pushUrls[0] === remote.pushUrl;
|
|
209
|
+
if (!bound ||
|
|
210
|
+
`${git.repository.owner}/${git.repository.name}`.toLowerCase() !==
|
|
211
|
+
`${bound.owner}/${bound.name}`.toLowerCase() ||
|
|
212
|
+
!matchingPush) {
|
|
213
|
+
project.diagnostics.push({
|
|
214
|
+
code: 'repository-binding-conflict',
|
|
215
|
+
severity: 'warning',
|
|
216
|
+
source: 'Git/activation state',
|
|
217
|
+
message: 'Git fetch/push origin and the verified remote repository binding disagree; evidence-backed provider scope is withheld.'
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
repository = { ...git.repository, id: bound.id };
|
|
222
|
+
remoteBindingVerified = true;
|
|
166
223
|
}
|
|
167
|
-
else
|
|
168
|
-
repository = { ...git.repository, id: stateRepo.id };
|
|
169
224
|
}
|
|
170
225
|
const scope = {
|
|
171
|
-
repository,
|
|
172
|
-
|
|
226
|
+
repository,
|
|
227
|
+
refs: repository ? ['develop', 'main'] : [],
|
|
228
|
+
...(repository ? { refPrefixes: ['release/', 'hotfix/'] } : {}),
|
|
229
|
+
environments: project.project ? [...project.project.workload.environments] : [],
|
|
173
230
|
runner: null, azure: []
|
|
174
231
|
};
|
|
175
232
|
if (!repository || !project.state)
|
|
176
233
|
return scope;
|
|
234
|
+
if (!remoteBindingVerified) {
|
|
235
|
+
project.diagnostics.push({
|
|
236
|
+
code: 'remote-binding-unavailable',
|
|
237
|
+
severity: 'warning',
|
|
238
|
+
source: 'activation state',
|
|
239
|
+
message: 'No matching verified remote repository binding is available; evidence-backed runner and Azure reads are withheld.'
|
|
240
|
+
});
|
|
241
|
+
return scope;
|
|
242
|
+
}
|
|
177
243
|
const fullName = `${repository.owner}/${repository.name}`;
|
|
244
|
+
const azureBindings = new Map();
|
|
245
|
+
const conflictingAzureBindings = new Set();
|
|
178
246
|
for (const approval of project.approvals) {
|
|
179
|
-
|
|
180
|
-
const phase = canonicalPhaseGraph.phases.find((entry) => entry.id === approval.phaseId);
|
|
181
|
-
const authority = plan && phase ? transitionPlanForPhase(phase, project.state, {
|
|
182
|
-
phaseId: phase.id, baselineSha: plan.baselineDigest, inputDigest: plan.inputDigest, transitionDigest: plan.transitionDigest
|
|
183
|
-
}) : null;
|
|
184
|
-
if (!project.bindingBaseline || approval.baselineSha !== project.bindingBaseline ||
|
|
185
|
-
project.identity.availability !== 'known' ||
|
|
186
|
-
Date.parse(approval.approvedAt) > now.getTime() ||
|
|
187
|
-
Date.parse(approval.expiresAt) <= now.getTime() ||
|
|
188
|
-
!project.state.phases[approval.phaseId].approvals.includes(approval.id) ||
|
|
189
|
-
!plan || !authority || !phase?.approvalGate.required || authority.planDigest !== approval.planDigest ||
|
|
190
|
-
evaluateApprovalForTransitionPlan(authority, [approval], { now }).approvalRequired ||
|
|
191
|
-
plan.approval.envelopeId !== approval.id ||
|
|
192
|
-
plan.approval.envelopeHash !== canonicalApprovalEnvelopeHash(approval) ||
|
|
193
|
-
!approval.destinations.some((destination) => destination.type === 'repository' && (destination.repository ?? destination.identity).toLowerCase() === fullName.toLowerCase()))
|
|
247
|
+
if (!approvalBindsRepository(project, approval, fullName, now))
|
|
194
248
|
continue;
|
|
195
249
|
const environments = approval.destinations.filter((destination) => destination.type === 'environment' &&
|
|
196
250
|
['dev', 'staging', 'prod'].includes(destination.identity)).map((destination) => destination.identity);
|
|
@@ -199,22 +253,79 @@ export function resolveAssessmentLiveScope(project, git, now) {
|
|
|
199
253
|
const environment = environments[0];
|
|
200
254
|
if (environment !== 'dev' && environment !== 'staging' && environment !== 'prod')
|
|
201
255
|
continue;
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
256
|
+
const selected = selectBoundAssessmentEvidence(project, approval.phaseId, now);
|
|
257
|
+
const payload = selected?.payload;
|
|
258
|
+
const assessmentScope = isRecord(payload) && isRecord(payload.assessmentScope)
|
|
259
|
+
? payload.assessmentScope
|
|
260
|
+
: null;
|
|
261
|
+
if (!assessmentScope || !Array.isArray(assessmentScope.azure)) {
|
|
262
|
+
if (approval.resources.some((resource) => resource.identity.startsWith('/subscriptions/')) &&
|
|
263
|
+
!project.diagnostics.some((entry) => entry.code === 'unbound-resource-role' && entry.source === approval.phaseId)) {
|
|
264
|
+
project.diagnostics.push({
|
|
265
|
+
code: 'unbound-resource-role',
|
|
266
|
+
severity: 'warning',
|
|
267
|
+
source: approval.phaseId,
|
|
268
|
+
message: 'Approved ARM resources lacked a current body-committed evidence payload with explicit assessment environment and role; Azure reads were withheld.'
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
for (const value of assessmentScope.azure) {
|
|
274
|
+
if (!isRecord(value) ||
|
|
275
|
+
Object.keys(value).some((key) => ![
|
|
276
|
+
'subscriptionId', 'environment', 'resourceId', 'resourceType', 'role'
|
|
277
|
+
].includes(key)) ||
|
|
278
|
+
typeof value.subscriptionId !== 'string' ||
|
|
279
|
+
value.environment !== environment ||
|
|
280
|
+
typeof value.resourceId !== 'string' ||
|
|
281
|
+
typeof value.resourceType !== 'string' ||
|
|
282
|
+
!['state', 'application', 'runner-network'].includes(String(value.role))) {
|
|
205
283
|
continue;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
284
|
+
}
|
|
285
|
+
const subscriptionId = value.subscriptionId;
|
|
286
|
+
const resourceId = value.resourceId;
|
|
287
|
+
const resourceType = value.resourceType;
|
|
288
|
+
const match = resourceId.match(/^\/subscriptions\/([a-f0-9-]{36})\/resourceGroups\/[^/]+\/providers\/([A-Za-z0-9.]+)\/([A-Za-z0-9]+)\/[^/]+(?:\/[A-Za-z0-9]+\/[^/]+)*$/iu);
|
|
289
|
+
if (!match ||
|
|
290
|
+
match[1].toLowerCase() !== subscriptionId.toLowerCase() ||
|
|
291
|
+
!approval.resources.some((resource) => resource.identity.toLowerCase() === resourceId.toLowerCase()) ||
|
|
292
|
+
!approval.destinations.some((destination) => destination.type === 'subscription' &&
|
|
293
|
+
(destination.subscriptionId ?? destination.identity).toLowerCase() === subscriptionId.toLowerCase())) {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
const binding = {
|
|
297
|
+
subscriptionId,
|
|
298
|
+
environment: environment,
|
|
299
|
+
resourceId,
|
|
300
|
+
resourceType,
|
|
301
|
+
role: value.role
|
|
302
|
+
};
|
|
303
|
+
const key = binding.resourceId.toLowerCase();
|
|
304
|
+
const previous = azureBindings.get(key);
|
|
305
|
+
if (conflictingAzureBindings.has(key) ||
|
|
306
|
+
previous && (previous.environment !== binding.environment ||
|
|
307
|
+
previous.role !== binding.role ||
|
|
308
|
+
previous.resourceType.toLowerCase() !== binding.resourceType.toLowerCase())) {
|
|
309
|
+
azureBindings.delete(key);
|
|
310
|
+
conflictingAzureBindings.add(key);
|
|
311
|
+
project.diagnostics.push({
|
|
312
|
+
code: 'conflicting-resource-binding',
|
|
313
|
+
severity: 'warning',
|
|
314
|
+
source: binding.resourceId,
|
|
315
|
+
message: 'Conflicting body-committed ARM environment, role, or resource-type bindings were excluded before live scope deduplication.'
|
|
316
|
+
});
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
if (!previous)
|
|
320
|
+
azureBindings.set(key, binding);
|
|
213
321
|
}
|
|
214
322
|
}
|
|
215
323
|
const runnerRecord = selectBoundAssessmentEvidence(project, 'runner-ready', now);
|
|
216
|
-
const rawRunner = runnerRecord?.
|
|
217
|
-
|
|
324
|
+
const rawRunner = runnerRecord?.payload;
|
|
325
|
+
const runnerApproval = project.approvals.some((approval) => approval.phaseId === 'runner-ready' &&
|
|
326
|
+
approvalBindsRepository(project, approval, fullName, now));
|
|
327
|
+
if (runnerApproval && runnerRecord?.header.result === 'verified' &&
|
|
328
|
+
isRecord(rawRunner) && rawRunner.kind === 'runner-ready.v1' &&
|
|
218
329
|
rawRunner.organization === repository.owner && Number.isInteger(rawRunner.runnerId) && Number(rawRunner.runnerId) > 0 &&
|
|
219
330
|
(rawRunner.groupId === null || Number.isInteger(rawRunner.groupId)) &&
|
|
220
331
|
(rawRunner.networkConfigurationId === null || typeof rawRunner.networkConfigurationId === 'string')) {
|
|
@@ -224,7 +335,7 @@ export function resolveAssessmentLiveScope(project, git, now) {
|
|
|
224
335
|
networkConfigurationId: typeof rawRunner.networkConfigurationId === 'string' ? rawRunner.networkConfigurationId : null
|
|
225
336
|
};
|
|
226
337
|
}
|
|
227
|
-
scope.azure = [...
|
|
338
|
+
scope.azure = [...azureBindings.values()]
|
|
228
339
|
.sort((a, b) => a.resourceId.localeCompare(b.resourceId, 'en'));
|
|
229
340
|
return scope;
|
|
230
341
|
}
|
|
@@ -252,6 +363,34 @@ function livePredicate(live, key, evaluate) {
|
|
|
252
363
|
converted.facts = observation.value;
|
|
253
364
|
return converted;
|
|
254
365
|
}
|
|
366
|
+
function partialLivePredicate(live, key, evaluate) {
|
|
367
|
+
const observation = live.observations[key];
|
|
368
|
+
if (!observation) {
|
|
369
|
+
return {
|
|
370
|
+
observation: notObserved(`Live ${key} was not collected.`),
|
|
371
|
+
provenDifference: false
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
if (observation.availability === 'observed') {
|
|
375
|
+
return {
|
|
376
|
+
observation: livePredicate(live, key, evaluate),
|
|
377
|
+
provenDifference: false
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
if (observation.facts !== undefined) {
|
|
381
|
+
const evaluated = evaluate(observation.facts);
|
|
382
|
+
if (evaluated.value === false) {
|
|
383
|
+
return {
|
|
384
|
+
observation: {
|
|
385
|
+
...observation,
|
|
386
|
+
reason: `${observation.reason ?? 'Live collection was incomplete.'} Independently observed facts prove a difference: ${evaluated.reason}`
|
|
387
|
+
},
|
|
388
|
+
provenDifference: true
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return { observation, provenDifference: false };
|
|
393
|
+
}
|
|
255
394
|
function bool(value, reason) { return { value, reason }; }
|
|
256
395
|
function rows(value) {
|
|
257
396
|
return Array.isArray(value) && value.every(isRecord) ? value : null;
|
|
@@ -268,6 +407,18 @@ export function findAssessmentException(control, approvals, scope, baseline, res
|
|
|
268
407
|
(scope.environment === null || approval.destinations.some((entry) => entry.type === 'environment' && entry.identity === scope.environment)));
|
|
269
408
|
return found ? { id: found.id, expiresAt: found.expiresAt, envelopeDigest: canonicalApprovalEnvelopeHash(found) } : null;
|
|
270
409
|
}
|
|
410
|
+
export function rejectedAssessmentExceptionDiagnostic(control, approvals, exception) {
|
|
411
|
+
if (exception !== null ||
|
|
412
|
+
!approvals.some((approval) => approval.policyExceptions.includes(control.id))) {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
return {
|
|
416
|
+
code: 'rejected-exception',
|
|
417
|
+
severity: 'warning',
|
|
418
|
+
source: control.id,
|
|
419
|
+
message: 'A recorded exception was rejected because its current identity, baseline, scope, resource, approval time, or expiry did not match this finding.'
|
|
420
|
+
};
|
|
421
|
+
}
|
|
271
422
|
function evidenceObservation(project, git, capturedAt) {
|
|
272
423
|
if (!project.state)
|
|
273
424
|
return notObserved('No compatible activation state is available.');
|
|
@@ -288,14 +439,78 @@ function evidenceObservation(project, git, capturedAt) {
|
|
|
288
439
|
return notObserved('Baseline/setup progress, approvals, applicability and current readback are not all established.');
|
|
289
440
|
return observed(true, source('evidence', 'governance/evidence', capturedAt, project.evidence.map((record) => record.header.phaseId)));
|
|
290
441
|
}
|
|
442
|
+
function invalidateUnstableObservations(findings, kinds, reason) {
|
|
443
|
+
for (const finding of findings) {
|
|
444
|
+
if (finding.applicability === 'inapplicable')
|
|
445
|
+
continue;
|
|
446
|
+
let invalidated = false;
|
|
447
|
+
for (const layer of finding.requiredProof) {
|
|
448
|
+
const observation = finding.observations[layer];
|
|
449
|
+
if (observation?.source && kinds.has(observation.source.kind)) {
|
|
450
|
+
finding.observations[layer] = notObserved(reason);
|
|
451
|
+
invalidated = true;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
if (!invalidated)
|
|
455
|
+
continue;
|
|
456
|
+
finding.exception = null;
|
|
457
|
+
finding.missingProof = finding.requiredProof.filter((layer) => finding.observations[layer]?.availability === 'not-observed');
|
|
458
|
+
const remaining = finding.requiredProof
|
|
459
|
+
.map((layer) => finding.observations[layer])
|
|
460
|
+
.filter((observation) => observation !== undefined);
|
|
461
|
+
const absent = remaining.some((observation) => observation.availability === 'missing');
|
|
462
|
+
const differs = remaining.some((observation) => observation.availability === 'observed' &&
|
|
463
|
+
canonicalJson(observation.value) !== canonicalJson(finding.expected));
|
|
464
|
+
finding.classification = differs
|
|
465
|
+
? 'conflicting'
|
|
466
|
+
: absent
|
|
467
|
+
? 'missing'
|
|
468
|
+
: 'not-observed';
|
|
469
|
+
finding.reasons.push(reason);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
function invalidateChangedActivationAuthority(findings, controls) {
|
|
473
|
+
const controlsById = new Map(controls.map((control) => [
|
|
474
|
+
control.id,
|
|
475
|
+
control
|
|
476
|
+
]));
|
|
477
|
+
for (const finding of findings) {
|
|
478
|
+
const control = controlsById.get(finding.controlId);
|
|
479
|
+
const evidenceDerivedApplicability = control?.applicability === 'private-dast' ||
|
|
480
|
+
control?.applicability === 'state-path';
|
|
481
|
+
if (finding.applicability === 'inapplicable' &&
|
|
482
|
+
!evidenceDerivedApplicability ||
|
|
483
|
+
!(evidenceDerivedApplicability ||
|
|
484
|
+
finding.requiredProof.includes('evidence') ||
|
|
485
|
+
finding.controlId.startsWith('azure.') ||
|
|
486
|
+
finding.controlId.startsWith('runner.') ||
|
|
487
|
+
finding.controlId.startsWith('evidence.'))) {
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
if (evidenceDerivedApplicability) {
|
|
491
|
+
finding.applicability = 'unknown';
|
|
492
|
+
}
|
|
493
|
+
finding.classification = 'not-observed';
|
|
494
|
+
finding.exception = null;
|
|
495
|
+
finding.missingProof = [...finding.requiredProof];
|
|
496
|
+
finding.reasons.push('Current activation inputs, evidence references, evidence bodies, or reviewed plans changed during collection; evidence-backed scope and results were withheld.');
|
|
497
|
+
for (const layer of finding.requiredProof) {
|
|
498
|
+
finding.observations[layer] = notObserved('Activation authority changed during collection.');
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
291
502
|
async function managedFindings(control, project, files, scope, capturedAt) {
|
|
292
503
|
const findings = [];
|
|
293
504
|
if (project.renderedCore.length === 0) {
|
|
294
505
|
return [classifyFinding({
|
|
295
506
|
control, scope, applicability: 'applicable',
|
|
296
507
|
observations: {
|
|
297
|
-
recorded: notObserved(
|
|
298
|
-
|
|
508
|
+
recorded: notObserved(project.kind === 'git'
|
|
509
|
+
? 'Ordinary Git repositories have no recorded Liftoff ownership inventory.'
|
|
510
|
+
: 'Historical agent selection is not recorded.'),
|
|
511
|
+
declared: notObserved(project.kind === 'git'
|
|
512
|
+
? 'No Liftoff managed handoff is inferred for an ordinary Git repository.'
|
|
513
|
+
: 'The current handoff cannot be rendered without inferring agent configuration.')
|
|
299
514
|
}
|
|
300
515
|
})];
|
|
301
516
|
}
|
|
@@ -349,7 +564,22 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
|
|
|
349
564
|
const branch = repository?.availability === 'observed' && isRecord(repository.value) && typeof repository.value.defaultBranch === 'string'
|
|
350
565
|
? repository.value.defaultBranch : null;
|
|
351
566
|
observations.declared = declaredRules((value) => protectedRefs(value, project.state?.repository.defaultBranch ?? null));
|
|
352
|
-
|
|
567
|
+
const rules = live.observations['github.rulesets'];
|
|
568
|
+
const branches = live.observations['github.branches'];
|
|
569
|
+
const families = live.observations['github.ref-families'];
|
|
570
|
+
if (rules?.availability === 'observed' &&
|
|
571
|
+
branches?.availability === 'observed' &&
|
|
572
|
+
families?.availability === 'observed') {
|
|
573
|
+
observations.live = predicateObservation(effectiveProtectedRefs(rules.value, branches.value, families.value, branch), rules.source);
|
|
574
|
+
observations.live.facts = jsonValue({
|
|
575
|
+
rulesets: rules.value,
|
|
576
|
+
branches: branches.value,
|
|
577
|
+
refFamilies: families.value
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
observations.live = notObserved('Complete repository/inherited rulesets, classic/effective branch protection, and bounded release/hotfix enumeration are required.');
|
|
582
|
+
}
|
|
353
583
|
break;
|
|
354
584
|
}
|
|
355
585
|
case 'single-maintainer':
|
|
@@ -381,14 +611,27 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
|
|
|
381
611
|
: contexts.length ? predicateObservation(bool(true, `Declared contexts: ${contexts.map((entry) => entry.name).join(', ')}`), facts.ruleSource)
|
|
382
612
|
: absent('No required status check contexts were declared.', facts.ruleSource);
|
|
383
613
|
const rules = live.observations['github.rulesets'];
|
|
614
|
+
const branches = live.observations['github.branches'];
|
|
615
|
+
const families = live.observations['github.ref-families'];
|
|
384
616
|
const repository = live.observations['github.repository'];
|
|
385
617
|
const branch = repository?.availability === 'observed' && isRecord(repository.value) && typeof repository.value.defaultBranch === 'string'
|
|
386
618
|
? repository.value.defaultBranch : null;
|
|
387
|
-
const
|
|
388
|
-
|
|
619
|
+
const familyRefs = families?.availability === 'observed' && isRecord(families.value) &&
|
|
620
|
+
Array.isArray(families.value.refs)
|
|
621
|
+
? families.value.refs.filter((value) => typeof value === 'string')
|
|
622
|
+
: [];
|
|
623
|
+
const assessedRefs = [...new Set([...liveScope.refs, ...familyRefs])].sort();
|
|
624
|
+
const comparisonRefs = assessedRefs.length ? assessedRefs : ['develop', 'main'];
|
|
625
|
+
const declaredBindings = requiredContextBindings(facts.rulesets, comparisonRefs, branch);
|
|
626
|
+
const rulesetBindings = rules?.availability === 'observed'
|
|
627
|
+
? requiredContextBindings(rules.value, comparisonRefs, branch)
|
|
628
|
+
: null;
|
|
629
|
+
const enforcedBindings = rules?.availability === 'observed' && branches?.availability === 'observed'
|
|
630
|
+
? effectiveRequiredContextBindings(rules.value, branches.value, comparisonRefs, branch)
|
|
631
|
+
: rulesetBindings;
|
|
389
632
|
observations.declared.facts = jsonValue(declaredBindings);
|
|
390
|
-
const bindingsDiffer = Boolean(contexts?.length && declaredBindings &&
|
|
391
|
-
canonicalJson(declaredBindings) !== canonicalJson(
|
|
633
|
+
const bindingsDiffer = Boolean(contexts?.length && declaredBindings && rulesetBindings &&
|
|
634
|
+
canonicalJson(declaredBindings) !== canonicalJson(rulesetBindings));
|
|
392
635
|
if (bindingsDiffer) {
|
|
393
636
|
difference = 'conflicting';
|
|
394
637
|
const checks = live.observations['github.checks'];
|
|
@@ -398,8 +641,11 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
|
|
|
398
641
|
: notObserved(`${reason} Check-run proof remains unobserved: ${checks?.reason ?? 'not collected'}`, rules?.source ?? null);
|
|
399
642
|
}
|
|
400
643
|
else {
|
|
401
|
-
observations.live = rules?.availability === 'observed' &&
|
|
402
|
-
|
|
644
|
+
observations.live = rules?.availability === 'observed' &&
|
|
645
|
+
families?.availability === 'observed' &&
|
|
646
|
+
declaredBindings &&
|
|
647
|
+
enforcedBindings
|
|
648
|
+
? livePredicate(live, 'github.checks', (value) => observedRequiredContexts(rules.value, value, branch, branches?.value))
|
|
403
649
|
: notObserved('Live rule and exact commit-bound check observations are required.');
|
|
404
650
|
}
|
|
405
651
|
observations.live.facts = jsonValue({
|
|
@@ -457,19 +703,22 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
|
|
|
457
703
|
break;
|
|
458
704
|
case 'runner': {
|
|
459
705
|
observations.recorded = liveScope.runner ? observed(true, source('evidence', 'runner-ready repository binding', capturedAt, jsonValue(liveScope.runner))) : notObserved('No current, exact runner/group/network binding is available.');
|
|
460
|
-
observations.live = livePredicate(live, 'github.runner', (value) =>
|
|
461
|
-
&& value.groupId === liveScope.runner?.groupId && value.runnerId === liveScope.runner?.runnerId ? true : null, 'Exact repository/group/network assignment, labels and runner capacity must be observed.'));
|
|
706
|
+
observations.live = livePredicate(live, 'github.runner', (value) => runnerAlignment(value, scope.repository));
|
|
462
707
|
break;
|
|
463
708
|
}
|
|
464
|
-
case 'providers':
|
|
465
|
-
|
|
709
|
+
case 'providers': {
|
|
710
|
+
const evaluation = partialLivePredicate(live, 'azure.providers', (value) => {
|
|
466
711
|
const providers = rows(value);
|
|
467
712
|
return bool(!providers?.length ? null : providers.every((entry) => entry.registrationState === 'Registered'), 'Every explicitly required namespace must have terminal Registered readback.');
|
|
468
713
|
});
|
|
714
|
+
observations.live = evaluation.observation;
|
|
715
|
+
if (evaluation.provenDifference)
|
|
716
|
+
difference = 'conflicting';
|
|
469
717
|
expected = true;
|
|
470
718
|
break;
|
|
471
|
-
|
|
472
|
-
|
|
719
|
+
}
|
|
720
|
+
case 'storage': {
|
|
721
|
+
const evaluation = partialLivePredicate(live, 'azure.resources', (value) => {
|
|
473
722
|
const storage = rows(value)?.filter((entry) => String(entry.resourceType).toLowerCase() === 'microsoft.storage/storageaccounts');
|
|
474
723
|
if (!storage?.length)
|
|
475
724
|
return bool(null, 'No explicit environment/role-bound storage observation is available.');
|
|
@@ -481,11 +730,15 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
|
|
|
481
730
|
});
|
|
482
731
|
return bool(values.includes(false) ? false : values.includes(null) ? null : true, 'State storage requires ZRS; application storage uses Dev LRS and Staging/Production ZRS.');
|
|
483
732
|
});
|
|
733
|
+
observations.live = evaluation.observation;
|
|
734
|
+
if (evaluation.provenDifference)
|
|
735
|
+
difference = 'conflicting';
|
|
484
736
|
expected = true;
|
|
485
737
|
break;
|
|
486
|
-
|
|
738
|
+
}
|
|
739
|
+
case 'network': {
|
|
487
740
|
observations.recorded = liveScope.azure.some((entry) => entry.role === 'runner-network') ? observed(true, source('evidence', 'approved Staging network bindings', capturedAt, jsonValue(liveScope.azure))) : notObserved('No approved Staging network bindings were available.');
|
|
488
|
-
|
|
741
|
+
const evaluation = partialLivePredicate(live, 'azure.resources', (value) => {
|
|
489
742
|
const network = rows(value)?.filter((entry) => entry.role === 'runner-network');
|
|
490
743
|
if (!network?.length)
|
|
491
744
|
return bool(null, 'No bound runner-network readback is available.');
|
|
@@ -494,7 +747,11 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
|
|
|
494
747
|
return bool(false, 'A runner subnet still enables implicit default outbound access.');
|
|
495
748
|
return bool(null, 'Full subnet, route, DNS and exclusive NAT/Firewall proof is required; observed metadata alone is insufficient.');
|
|
496
749
|
});
|
|
750
|
+
observations.live = evaluation.observation;
|
|
751
|
+
if (evaluation.provenDifference)
|
|
752
|
+
difference = 'conflicting';
|
|
497
753
|
break;
|
|
754
|
+
}
|
|
498
755
|
case 'evidence':
|
|
499
756
|
observations.evidence = evidenceObservation(project, git, capturedAt);
|
|
500
757
|
break;
|
|
@@ -505,9 +762,15 @@ function evaluateControl(control, project, facts, live, git, liveScope, now) {
|
|
|
505
762
|
for (const layer of control.proofLayers)
|
|
506
763
|
observations[layer] = notObserved(`No supported evaluator exists for ${control.id}; the required proof is not inferred.`);
|
|
507
764
|
}
|
|
765
|
+
const exception = findAssessmentException(control, project.approvals, scope, facts.baseline, exceptionResource, now);
|
|
766
|
+
const exceptionDiagnostic = rejectedAssessmentExceptionDiagnostic(control, project.approvals, exception);
|
|
767
|
+
if (exceptionDiagnostic &&
|
|
768
|
+
!project.diagnostics.some((entry) => entry.code === 'rejected-exception' && entry.source === control.id)) {
|
|
769
|
+
project.diagnostics.push(exceptionDiagnostic);
|
|
770
|
+
}
|
|
508
771
|
return classifyFinding({
|
|
509
772
|
control, scope, expected, applicability: applicability(control, project, now), observations, difference,
|
|
510
|
-
exception
|
|
773
|
+
exception
|
|
511
774
|
});
|
|
512
775
|
}
|
|
513
776
|
export async function assessGovernance(projectRoot, options = {}) {
|
|
@@ -522,7 +785,88 @@ export async function assessGovernance(projectRoot, options = {}) {
|
|
|
522
785
|
try {
|
|
523
786
|
const loaded = loadAssessmentCatalog();
|
|
524
787
|
target = loaded.target;
|
|
525
|
-
|
|
788
|
+
let project;
|
|
789
|
+
let git;
|
|
790
|
+
let initialActivationInspection = null;
|
|
791
|
+
let initialActivationFingerprint = null;
|
|
792
|
+
try {
|
|
793
|
+
project = await inspectAssessmentProject(files);
|
|
794
|
+
git = await inspectAssessmentGit(projectRoot, options.runner);
|
|
795
|
+
}
|
|
796
|
+
catch (error) {
|
|
797
|
+
if (!(error instanceof AssessmentInputError) || error.code !== 'project-not-found') {
|
|
798
|
+
throw error;
|
|
799
|
+
}
|
|
800
|
+
git = await inspectAssessmentGit(projectRoot, options.runner);
|
|
801
|
+
if (!git.isRepository) {
|
|
802
|
+
throw new AssessmentInputError('project-not-found', 'No Liftoff manifest or valid Git worktree was found at the selected boundary.');
|
|
803
|
+
}
|
|
804
|
+
project = ordinaryGitAssessmentProject();
|
|
805
|
+
}
|
|
806
|
+
if (project.manifest && project.identity.availability === 'known') {
|
|
807
|
+
try {
|
|
808
|
+
const activation = await inspectCurrentActivationEvidence(projectRoot, project.manifest, {
|
|
809
|
+
...(options.runner ? { runner: options.runner } : {}),
|
|
810
|
+
now: captured
|
|
811
|
+
});
|
|
812
|
+
initialActivationInspection = activation;
|
|
813
|
+
initialActivationFingerprint = activationAuthorityFingerprint(activation);
|
|
814
|
+
if (activation.status === 'inspected') {
|
|
815
|
+
project.state = activation.state;
|
|
816
|
+
project.stateIdentity = jsonValue(activation.state.identity);
|
|
817
|
+
project.identity.stateSource = 'user';
|
|
818
|
+
project.inputSnapshot = activation.snapshot;
|
|
819
|
+
project.evidenceContexts = activation.contexts;
|
|
820
|
+
project.evidence = activation.records;
|
|
821
|
+
project.plans = activation.contexts[phaseIds[0]].reviewedPlans
|
|
822
|
+
? [...activation.contexts[phaseIds[0]].reviewedPlans]
|
|
823
|
+
: [];
|
|
824
|
+
project.activationSelections = activation.selections;
|
|
825
|
+
if (activation.migration) {
|
|
826
|
+
const complete = activation.migration.revalidation.status === 'complete';
|
|
827
|
+
project.diagnostics.push({
|
|
828
|
+
code: complete ? 'activation-migration-committed' : 'activation-revalidation-blocked',
|
|
829
|
+
severity: complete ? 'info' : 'warning',
|
|
830
|
+
source: 'governance/migration-state.json',
|
|
831
|
+
message: sanitizeAssessmentText(complete
|
|
832
|
+
? 'Local v2 migration and approved local revalidation are complete. Preserved v1 history is informational, not live enforcement proof.'
|
|
833
|
+
: `Local v2 migration committed; revalidation is ${activation.migration.revalidation.status}. ${activation.migration.revalidation.nextAction} Run ${formatUpdateCommand(projectRoot, 'check')} after repairing the named blocker.`)
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
for (const [phaseId, selection] of Object.entries(activation.selections)) {
|
|
837
|
+
if (selection.selected && selection.historicalIssues?.length) {
|
|
838
|
+
project.diagnostics.push({
|
|
839
|
+
code: 'historical-evidence-ignored',
|
|
840
|
+
severity: 'info',
|
|
841
|
+
source: phaseId,
|
|
842
|
+
message: sanitizeAssessmentText(selection.historicalIssues.map((issue) => issue.message).join('; '))
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
if (selection.issues.length === 0)
|
|
846
|
+
continue;
|
|
847
|
+
project.invalidEvidence = true;
|
|
848
|
+
project.diagnostics.push({
|
|
849
|
+
code: 'invalid-current-evidence',
|
|
850
|
+
severity: 'warning',
|
|
851
|
+
source: phaseId,
|
|
852
|
+
message: sanitizeAssessmentText(selection.issues.map((issue) => issue.message).join('; '))
|
|
853
|
+
});
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
catch (error) {
|
|
858
|
+
project.identity.availability = 'unsupported';
|
|
859
|
+
project.identity.stateSource = 'unsupported';
|
|
860
|
+
project.diagnostics.push({
|
|
861
|
+
code: 'activation-history-diagnostic-only',
|
|
862
|
+
severity: 'warning',
|
|
863
|
+
source: 'activation read-only inspection',
|
|
864
|
+
message: sanitizeAssessmentText(error instanceof Error
|
|
865
|
+
? error.message
|
|
866
|
+
: 'Activation history could not be interpreted as current executable proof.')
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
}
|
|
526
870
|
projectIdentity = project.identity;
|
|
527
871
|
const disabled = project.identity.profile === 'none';
|
|
528
872
|
if (disabled)
|
|
@@ -531,7 +875,6 @@ export async function assessGovernance(projectRoot, options = {}) {
|
|
|
531
875
|
snapshot: { capturedAt: captured.toISOString(), repository: null, localHead: null, worktreeDigest: files.digest(), inputsStable: await files.stable() },
|
|
532
876
|
findings: [], diagnostics: project.diagnostics, disabled: true
|
|
533
877
|
});
|
|
534
|
-
const git = await inspectAssessmentGit(projectRoot, options.runner);
|
|
535
878
|
project.diagnostics.push(...git.issues.map((message) => ({
|
|
536
879
|
code: 'git-not-observed', severity: 'warning', message, source: 'Git metadata'
|
|
537
880
|
})));
|
|
@@ -549,21 +892,54 @@ export async function assessGovernance(projectRoot, options = {}) {
|
|
|
549
892
|
findings.push(evaluateControl(control, project, facts, live, git, scope, captured));
|
|
550
893
|
}
|
|
551
894
|
const worktreeDigest = files.digest();
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
895
|
+
let activationStable = true;
|
|
896
|
+
if (project.manifest && initialActivationInspection && initialActivationFingerprint) {
|
|
897
|
+
try {
|
|
898
|
+
const finalActivation = await inspectCurrentActivationEvidence(projectRoot, project.manifest, {
|
|
899
|
+
...(options.runner ? { runner: options.runner } : {}),
|
|
900
|
+
now: captured
|
|
901
|
+
});
|
|
902
|
+
activationStable =
|
|
903
|
+
activationAuthorityFingerprint(finalActivation) ===
|
|
904
|
+
initialActivationFingerprint;
|
|
905
|
+
}
|
|
906
|
+
catch {
|
|
907
|
+
activationStable = false;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
let historicalActivationStable = true;
|
|
911
|
+
if (project.historicalActivation) {
|
|
912
|
+
const finalHistorical = await inspectAssessmentHistoricalActivation(projectRoot);
|
|
913
|
+
historicalActivationStable = finalHistorical.fingerprint === project.historicalActivation.fingerprint;
|
|
914
|
+
if (!historicalActivationStable) {
|
|
915
|
+
project.diagnostics = project.diagnostics.filter((entry) => entry !== project.historicalActivation?.diagnostic);
|
|
916
|
+
project.diagnostics.push({
|
|
917
|
+
code: 'activation-history-changed',
|
|
918
|
+
severity: 'warning',
|
|
919
|
+
source: 'activation read-only inspection',
|
|
920
|
+
message: sanitizeAssessmentText(`Historical activation inputs changed during collection; migration eligibility was withheld. Rerun assessment, then use ${formatUpdateCommand(projectRoot, 'check')} to review a stable source.`)
|
|
921
|
+
});
|
|
565
922
|
}
|
|
566
923
|
}
|
|
924
|
+
const finalGit = await inspectAssessmentGit(projectRoot, options.runner);
|
|
925
|
+
const filesStable = await files.stable();
|
|
926
|
+
const gitStable = canonicalJson(git) === canonicalJson(finalGit);
|
|
927
|
+
const inputsStable = filesStable && gitStable && activationStable && historicalActivationStable;
|
|
928
|
+
if (!filesStable) {
|
|
929
|
+
invalidateUnstableObservations(findings, new Set(['file', 'evidence']), 'Relevant local files changed during collection; rerun assessment for current local proof.');
|
|
930
|
+
}
|
|
931
|
+
if (!gitStable) {
|
|
932
|
+
invalidateUnstableObservations(findings, new Set(['git']), 'Relevant Git metadata changed during collection; rerun assessment for current Git proof.');
|
|
933
|
+
}
|
|
934
|
+
if (!activationStable) {
|
|
935
|
+
invalidateChangedActivationAuthority(findings, loaded.catalog.controls);
|
|
936
|
+
project.diagnostics.push({
|
|
937
|
+
code: 'activation-authority-changed',
|
|
938
|
+
severity: 'warning',
|
|
939
|
+
source: 'activation read-only inspection',
|
|
940
|
+
message: 'Current activation inputs, evidence, state references, or reviewed plans changed during collection; dependent proof was withheld.'
|
|
941
|
+
});
|
|
942
|
+
}
|
|
567
943
|
return assembleAssessmentReport({
|
|
568
944
|
projectRoot, mode: options.live ? 'live' : 'local', target, projectIdentity,
|
|
569
945
|
snapshot: { capturedAt: captured.toISOString(), repository, localHead: git.head, worktreeDigest, inputsStable },
|