@msn-control/liftoff 0.11.2 → 0.12.0
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 +26 -24
- package/README.md +18 -18
- package/assets/governance/single-maintainer-gitflow/activation-v2-graph.json +1583 -0
- package/dist/adapters/credentials/github-enrollment.d.ts +51 -0
- package/dist/adapters/credentials/github-enrollment.js +226 -0
- package/dist/adapters/credentials/github-enrollment.js.map +1 -0
- package/dist/adapters/credentials/protected-input.d.ts +7 -0
- package/dist/adapters/credentials/protected-input.js +68 -0
- package/dist/adapters/credentials/protected-input.js.map +1 -0
- package/dist/adapters/filesystem/executables.d.ts +2 -0
- package/dist/adapters/filesystem/executables.js +70 -0
- package/dist/adapters/filesystem/executables.js.map +1 -0
- package/dist/adapters/filesystem/update-previews.d.ts +9 -0
- package/dist/adapters/filesystem/update-previews.js +45 -2
- package/dist/adapters/filesystem/update-previews.js.map +1 -1
- package/dist/adapters/filesystem/workstation-attempts.d.ts +13 -0
- package/dist/adapters/filesystem/workstation-attempts.js +78 -0
- package/dist/adapters/filesystem/workstation-attempts.js.map +1 -0
- package/dist/adapters/github/activation-rest.d.ts +40 -0
- package/dist/adapters/github/activation-rest.js +272 -0
- package/dist/adapters/github/activation-rest.js.map +1 -0
- package/dist/adapters/process/shell-command.d.ts +1 -0
- package/dist/adapters/process/shell-command.js +5 -2
- package/dist/adapters/process/shell-command.js.map +1 -1
- package/dist/adapters/state/azure-blob.d.ts +43 -0
- package/dist/adapters/state/azure-blob.js +335 -0
- package/dist/adapters/state/azure-blob.js.map +1 -0
- package/dist/adapters/state/darwin-capabilities.d.ts +33 -0
- package/dist/adapters/state/darwin-capabilities.js +146 -0
- package/dist/adapters/state/darwin-capabilities.js.map +1 -0
- package/dist/adapters/state/darwin-native-host.d.ts +32 -0
- package/dist/adapters/state/darwin-native-host.js +294 -0
- package/dist/adapters/state/darwin-native-host.js.map +1 -0
- package/dist/adapters/state/darwin-profile.d.ts +6 -0
- package/dist/adapters/state/darwin-profile.js +56 -0
- package/dist/adapters/state/darwin-profile.js.map +1 -0
- package/dist/adapters/state/darwin-system-program.d.ts +1 -0
- package/dist/adapters/state/darwin-system-program.js +94 -0
- package/dist/adapters/state/darwin-system-program.js.map +1 -0
- package/dist/adapters/state/local-qualification.d.ts +16 -0
- package/dist/adapters/state/local-qualification.js +299 -0
- package/dist/adapters/state/local-qualification.js.map +1 -0
- package/dist/adapters/state/local.d.ts +25 -0
- package/dist/adapters/state/local.js +145 -0
- package/dist/adapters/state/local.js.map +1 -0
- package/dist/adapters/state/native-command.d.ts +21 -0
- package/dist/adapters/state/native-command.js +82 -0
- package/dist/adapters/state/native-command.js.map +1 -0
- package/dist/adapters/state/native-files.d.ts +2 -0
- package/dist/adapters/state/native-files.js +47 -0
- package/dist/adapters/state/native-files.js.map +1 -0
- package/dist/adapters/state/native-system.d.ts +38 -0
- package/dist/adapters/state/native-system.js +86 -0
- package/dist/adapters/state/native-system.js.map +1 -0
- package/dist/adapters/state/opentofu.d.ts +35 -0
- package/dist/adapters/state/opentofu.js +350 -0
- package/dist/adapters/state/opentofu.js.map +1 -0
- package/dist/adapters/state/owned-process.d.ts +43 -0
- package/dist/adapters/state/owned-process.js +252 -0
- package/dist/adapters/state/owned-process.js.map +1 -0
- package/dist/adapters/state/posix-lock-program.d.ts +1 -0
- package/dist/adapters/state/posix-lock-program.js +185 -0
- package/dist/adapters/state/posix-lock-program.js.map +1 -0
- package/dist/adapters/state/posix-native-lock.d.ts +15 -0
- package/dist/adapters/state/posix-native-lock.js +145 -0
- package/dist/adapters/state/posix-native-lock.js.map +1 -0
- package/dist/adapters/state/protected-workspace.d.ts +57 -0
- package/dist/adapters/state/protected-workspace.js +412 -0
- package/dist/adapters/state/protected-workspace.js.map +1 -0
- package/dist/application/context.d.ts +3 -0
- package/dist/application/diagnose/doctor.d.ts +5 -0
- package/dist/application/diagnose/doctor.js +21 -5
- package/dist/application/diagnose/doctor.js.map +1 -1
- package/dist/application/diagnose/generated-project.js +2 -7
- package/dist/application/diagnose/generated-project.js.map +1 -1
- package/dist/application/initialize/fixture.js +8 -1
- package/dist/application/initialize/fixture.js.map +1 -1
- package/dist/application/initialize/use-case.js +70 -36
- package/dist/application/initialize/use-case.js.map +1 -1
- package/dist/application/project/manifest.js +5 -4
- package/dist/application/project/manifest.js.map +1 -1
- package/dist/application/state-migration/execution.d.ts +32 -0
- package/dist/application/state-migration/execution.js +440 -0
- package/dist/application/state-migration/execution.js.map +1 -0
- package/dist/application/state-migration/index.d.ts +22 -0
- package/dist/application/state-migration/index.js +17 -0
- package/dist/application/state-migration/index.js.map +1 -0
- package/dist/application/state-migration/lifecycle.d.ts +3 -0
- package/dist/application/state-migration/lifecycle.js +149 -0
- package/dist/application/state-migration/lifecycle.js.map +1 -0
- package/dist/application/state-migration/planning.d.ts +7 -0
- package/dist/application/state-migration/planning.js +150 -0
- package/dist/application/state-migration/planning.js.map +1 -0
- package/dist/application/state-migration/recovery.d.ts +5 -0
- package/dist/application/state-migration/recovery.js +145 -0
- package/dist/application/state-migration/recovery.js.map +1 -0
- package/dist/application/state-migration/runtime.d.ts +32 -0
- package/dist/application/state-migration/runtime.js +188 -0
- package/dist/application/state-migration/runtime.js.map +1 -0
- package/dist/application/state-migration/service.d.ts +2 -0
- package/dist/application/state-migration/service.js +20 -0
- package/dist/application/state-migration/service.js.map +1 -0
- package/dist/application/update/command-guidance.d.ts +19 -2
- package/dist/application/update/command-guidance.js +20 -6
- package/dist/application/update/command-guidance.js.map +1 -1
- package/dist/application/update/guidance-context.d.ts +2 -0
- package/dist/application/update/guidance-context.js +35 -0
- package/dist/application/update/guidance-context.js.map +1 -0
- package/dist/application/update/inspection.d.ts +21 -4
- package/dist/application/update/inspection.js +88 -29
- package/dist/application/update/inspection.js.map +1 -1
- package/dist/application/update/migration-runtime.js +25 -13
- package/dist/application/update/migration-runtime.js.map +1 -1
- package/dist/application/update/output.d.ts +4 -1
- package/dist/application/update/output.js +14 -4
- package/dist/application/update/output.js.map +1 -1
- package/dist/application/update/preview.d.ts +10 -1
- package/dist/application/update/preview.js +26 -4
- package/dist/application/update/preview.js.map +1 -1
- package/dist/application/update/revalidation-plan.d.ts +1 -0
- package/dist/application/update/revalidation-plan.js +27 -15
- package/dist/application/update/revalidation-plan.js.map +1 -1
- package/dist/application/update/revalidation.d.ts +4 -1
- package/dist/application/update/revalidation.js +64 -23
- package/dist/application/update/revalidation.js.map +1 -1
- package/dist/application/update/use-case.js +50 -29
- package/dist/application/update/use-case.js.map +1 -1
- package/dist/cli/args/definitions.js +11 -3
- package/dist/cli/args/definitions.js.map +1 -1
- package/dist/cli/args/parser.js +29 -3
- package/dist/cli/args/parser.js.map +1 -1
- package/dist/domain/governance/activation/approvals.d.ts +264 -7
- package/dist/domain/governance/activation/approvals.js +166 -23
- package/dist/domain/governance/activation/approvals.js.map +1 -1
- package/dist/domain/governance/activation/capabilities.js +5 -2
- package/dist/domain/governance/activation/capabilities.js.map +1 -1
- package/dist/domain/governance/activation/evidence.d.ts +2 -1
- package/dist/domain/governance/activation/evidence.js +64 -11
- package/dist/domain/governance/activation/evidence.js.map +1 -1
- package/dist/domain/governance/activation/graph.d.ts +11 -384
- package/dist/domain/governance/activation/graph.js +424 -379
- package/dist/domain/governance/activation/graph.js.map +1 -1
- package/dist/domain/governance/activation/inputs.d.ts +3 -1
- package/dist/domain/governance/activation/inputs.js +47 -6
- package/dist/domain/governance/activation/inputs.js.map +1 -1
- package/dist/domain/governance/activation/operations.d.ts +4 -1
- package/dist/domain/governance/activation/operations.js +110 -22
- package/dist/domain/governance/activation/operations.js.map +1 -1
- package/dist/domain/governance/activation/readiness.d.ts +10 -0
- package/dist/domain/governance/activation/readiness.js +77 -38
- package/dist/domain/governance/activation/readiness.js.map +1 -1
- package/dist/domain/governance/activation/types.d.ts +151 -9
- package/dist/domain/governance/activation/types.js +23 -1
- package/dist/domain/governance/activation/types.js.map +1 -1
- package/dist/domain/governance/activation/validators.d.ts +4 -1
- package/dist/domain/governance/activation/validators.js +419 -26
- package/dist/domain/governance/activation/validators.js.map +1 -1
- package/dist/domain/governance/policy/identity.d.ts +55 -13
- package/dist/domain/governance/policy/identity.js +28 -8
- package/dist/domain/governance/policy/identity.js.map +1 -1
- package/dist/domain/project/artifact-lifecycle.d.ts +2 -1
- package/dist/domain/project/artifact-lifecycle.js +7 -1
- package/dist/domain/project/artifact-lifecycle.js.map +1 -1
- package/dist/domain/project/catalog.d.ts +50 -1
- package/dist/domain/project/catalog.js +104 -4
- package/dist/domain/project/catalog.js.map +1 -1
- package/dist/domain/project/contracts.d.ts +9 -1
- package/dist/domain/project/infrastructure-layout.d.ts +1 -1
- package/dist/domain/project/infrastructure-layout.js +3 -1
- package/dist/domain/project/infrastructure-layout.js.map +1 -1
- package/dist/domain/project/manifest/governance.d.ts +1 -1
- package/dist/domain/project/manifest/governance.js +9 -10
- package/dist/domain/project/manifest/governance.js.map +1 -1
- package/dist/domain/project/planning.js +4 -5
- package/dist/domain/project/planning.js.map +1 -1
- package/dist/domain/repair/stateful-bounded.d.ts +1 -0
- package/dist/domain/repair/stateful-bounded.js +37 -0
- package/dist/domain/repair/stateful-bounded.js.map +1 -0
- package/dist/domain/repair/stateful-invariants.d.ts +28 -0
- package/dist/domain/repair/stateful-invariants.js +278 -0
- package/dist/domain/repair/stateful-invariants.js.map +1 -0
- package/dist/domain/repair/stateful.d.ts +690 -0
- package/dist/domain/repair/stateful.js +26 -0
- package/dist/domain/repair/stateful.js.map +1 -0
- package/dist/domain/workstation/constraints.d.ts +1 -0
- package/dist/domain/workstation/constraints.js.map +1 -1
- package/dist/domain/workstation/contracts.d.ts +42 -0
- package/dist/domain/workstation/contracts.js +2 -0
- package/dist/domain/workstation/contracts.js.map +1 -0
- package/dist/domain/workstation/executables.d.ts +19 -0
- package/dist/domain/workstation/executables.js +68 -0
- package/dist/domain/workstation/executables.js.map +1 -0
- package/dist/domain/workstation/versions.d.ts +8 -0
- package/dist/domain/workstation/versions.js +145 -0
- package/dist/domain/workstation/versions.js.map +1 -0
- package/dist/framework-adapters.d.ts +2 -0
- package/dist/framework-adapters.js +148 -22
- package/dist/framework-adapters.js.map +1 -1
- package/dist/framework-validation.d.ts +6 -0
- package/dist/framework-validation.js +89 -24
- package/dist/framework-validation.js.map +1 -1
- package/dist/generators/common/base.js +57 -17
- package/dist/generators/common/base.js.map +1 -1
- package/dist/governance-activation/activation-state.js +39 -7
- package/dist/governance-activation/activation-state.js.map +1 -1
- package/dist/governance-activation/authority-records.d.ts +4 -0
- package/dist/governance-activation/authority-records.js +24 -0
- package/dist/governance-activation/authority-records.js.map +1 -0
- package/dist/governance-activation/commands.d.ts +9 -1
- package/dist/governance-activation/commands.js +392 -97
- package/dist/governance-activation/commands.js.map +1 -1
- package/dist/governance-activation/compatibility.d.ts +11 -8
- package/dist/governance-activation/compatibility.js +37 -23
- package/dist/governance-activation/compatibility.js.map +1 -1
- package/dist/governance-activation/doctor.js +40 -16
- package/dist/governance-activation/doctor.js.map +1 -1
- package/dist/governance-activation/github-config.d.ts +17 -0
- package/dist/governance-activation/github-config.js +88 -0
- package/dist/governance-activation/github-config.js.map +1 -0
- package/dist/governance-activation/github-discovery.d.ts +18 -0
- package/dist/governance-activation/github-discovery.js +229 -0
- package/dist/governance-activation/github-discovery.js.map +1 -0
- package/dist/governance-activation/github-ports.d.ts +12 -0
- package/dist/governance-activation/github-ports.js +4 -0
- package/dist/governance-activation/github-ports.js.map +1 -0
- package/dist/governance-activation/github-publication.d.ts +3 -0
- package/dist/governance-activation/github-publication.js +190 -0
- package/dist/governance-activation/github-publication.js.map +1 -0
- package/dist/governance-activation/historical-common.d.ts +98 -0
- package/dist/governance-activation/historical-common.js +269 -0
- package/dist/governance-activation/historical-common.js.map +1 -0
- package/dist/governance-activation/historical-credential-policy.d.ts +3 -0
- package/dist/governance-activation/historical-credential-policy.js +91 -0
- package/dist/governance-activation/historical-credential-policy.js.map +1 -0
- package/dist/governance-activation/historical-inputs.d.ts +6 -0
- package/dist/governance-activation/historical-inputs.js +57 -0
- package/dist/governance-activation/historical-inputs.js.map +1 -0
- package/dist/governance-activation/historical-safety.d.ts +9 -0
- package/dist/governance-activation/historical-safety.js +102 -0
- package/dist/governance-activation/historical-safety.js.map +1 -0
- package/dist/governance-activation/historical-source-metadata.d.ts +31 -0
- package/dist/governance-activation/historical-source-metadata.js +55 -0
- package/dist/governance-activation/historical-source-metadata.js.map +1 -0
- package/dist/governance-activation/historical-state.d.ts +12 -50
- package/dist/governance-activation/historical-state.js +195 -308
- package/dist/governance-activation/historical-state.js.map +1 -1
- package/dist/governance-activation/historical-v1-auxiliary.d.ts +1 -0
- package/dist/governance-activation/historical-v1-auxiliary.js +43 -0
- package/dist/governance-activation/historical-v1-auxiliary.js.map +1 -0
- package/dist/governance-activation/historical-v1-phase-contracts.d.ts +31 -0
- package/dist/governance-activation/historical-v1-phase-contracts.js +46 -0
- package/dist/governance-activation/historical-v1-phase-contracts.js.map +1 -0
- package/dist/governance-activation/historical-v2.d.ts +53 -0
- package/dist/governance-activation/historical-v2.js +313 -0
- package/dist/governance-activation/historical-v2.js.map +1 -0
- package/dist/governance-activation/history-contracts.d.ts +21 -12
- package/dist/governance-activation/history-contracts.js +99 -27
- package/dist/governance-activation/history-contracts.js.map +1 -1
- package/dist/governance-activation/inputs.d.ts +8 -2
- package/dist/governance-activation/inputs.js +41 -6
- package/dist/governance-activation/inputs.js.map +1 -1
- package/dist/governance-activation/migration-history.d.ts +43 -5
- package/dist/governance-activation/migration-history.js +231 -50
- package/dist/governance-activation/migration-history.js.map +1 -1
- package/dist/governance-activation/migration.d.ts +7 -4
- package/dist/governance-activation/migration.js +53 -252
- package/dist/governance-activation/migration.js.map +1 -1
- package/dist/governance-activation/phase-azure.d.ts +3 -0
- package/dist/governance-activation/phase-azure.js +205 -0
- package/dist/governance-activation/phase-azure.js.map +1 -0
- package/dist/governance-activation/phase-bootstrap-state.js +3 -0
- package/dist/governance-activation/phase-bootstrap-state.js.map +1 -1
- package/dist/governance-activation/phase-github.d.ts +3 -0
- package/dist/governance-activation/phase-github.js +192 -0
- package/dist/governance-activation/phase-github.js.map +1 -0
- package/dist/governance-activation/phase-governance.js +8 -2
- package/dist/governance-activation/phase-governance.js.map +1 -1
- package/dist/governance-activation/public-plans.d.ts +36 -0
- package/dist/governance-activation/public-plans.js +100 -0
- package/dist/governance-activation/public-plans.js.map +1 -0
- package/dist/governance-activation/read-only.d.ts +3 -1
- package/dist/governance-activation/read-only.js +7 -3
- package/dist/governance-activation/read-only.js.map +1 -1
- package/dist/governance-activation/reconciliation.js +10 -0
- package/dist/governance-activation/reconciliation.js.map +1 -1
- package/dist/governance-activation/seed-lifecycle.js +14 -25
- package/dist/governance-activation/seed-lifecycle.js.map +1 -1
- package/dist/governance-activation/source-of-truth.d.ts +21 -5
- package/dist/governance-activation/source-of-truth.js +102 -13
- package/dist/governance-activation/source-of-truth.js.map +1 -1
- package/dist/governance-activation/task-projection.d.ts +4 -1
- package/dist/governance-activation/task-projection.js +32 -3
- package/dist/governance-activation/task-projection.js.map +1 -1
- package/dist/governance-activation/task-writes.d.ts +42 -0
- package/dist/governance-activation/task-writes.js +250 -0
- package/dist/governance-activation/task-writes.js.map +1 -0
- package/dist/governance-activation/transition-files.d.ts +12 -0
- package/dist/governance-activation/transition-files.js +109 -0
- package/dist/governance-activation/transition-files.js.map +1 -0
- package/dist/governance-activation/transition-planning.d.ts +3 -1
- package/dist/governance-activation/transition-planning.js +158 -20
- package/dist/governance-activation/transition-planning.js.map +1 -1
- package/dist/governance-activation/transition-ports.d.ts +31 -3
- package/dist/governance-activation/transition-records.d.ts +11 -1
- package/dist/governance-activation/transition-records.js +52 -6
- package/dist/governance-activation/transition-records.js.map +1 -1
- package/dist/governance-activation/transitions.d.ts +5 -0
- package/dist/governance-activation/transitions.js +271 -37
- package/dist/governance-activation/transitions.js.map +1 -1
- package/dist/governance-assessment/engine.js +22 -15
- package/dist/governance-assessment/engine.js.map +1 -1
- package/dist/governance-assessment/project.d.ts +2 -0
- package/dist/governance-assessment/project.js +2 -1
- package/dist/governance-assessment/project.js.map +1 -1
- package/dist/interactive.d.ts +0 -1
- package/dist/interactive.js +3 -22
- package/dist/interactive.js.map +1 -1
- package/dist/openspec-profile.d.ts +2 -1
- package/dist/openspec-profile.js +11 -41
- package/dist/openspec-profile.js.map +1 -1
- package/dist/repository-governance.d.ts +10 -5
- package/dist/repository-governance.js +178 -92
- package/dist/repository-governance.js.map +1 -1
- package/dist/telemetry/contract.d.ts +1 -1
- package/dist/telemetry/contract.js +3 -0
- package/dist/telemetry/contract.js.map +1 -1
- package/dist/workstation-catalog.d.ts +13 -1
- package/dist/workstation-catalog.js +122 -0
- package/dist/workstation-catalog.js.map +1 -1
- package/dist/workstation.d.ts +69 -14
- package/dist/workstation.js +600 -215
- package/dist/workstation.js.map +1 -1
- package/docs/cli-reference.md +94 -23
- package/docs/configuration-and-manifests.md +11 -10
- package/docs/prerequisites.md +93 -18
- package/docs/repository-governance.md +68 -40
- package/docs/spec-workflows-and-agents.md +132 -13
- package/docs/troubleshooting.md +28 -0
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { canonicalJson, canonicalSha256, sha256Hex } from './canonical-json.js';
|
|
2
2
|
import { activationContractVersion, approvalEnvelopeSchemaVersion, buildActivationCompatibilityMap, createActivationIdentity, evidenceHeaderSchemaVersion, governanceActivationPolicyVersion, liftoffActivationPackageVersion, phaseGraphSchemaVersion } from '../policy/identity.js';
|
|
3
|
+
import { activationPhaseIds, lifecyclePhaseIds, localSetupPhaseIds } from './types.js';
|
|
3
4
|
const terminalVerified = ['verified', 'failed'];
|
|
4
5
|
const terminalApproved = ['approved', 'failed'];
|
|
5
6
|
const terminalConditional = ['verified', 'failed', 'inapplicable'];
|
|
@@ -12,7 +13,7 @@ function mutations(local, remote = ['none']) {
|
|
|
12
13
|
!normalizedLocal.includes('write-activation-state')) {
|
|
13
14
|
normalizedLocal.push('write-activation-state');
|
|
14
15
|
}
|
|
15
|
-
return { local: normalizedLocal, remote };
|
|
16
|
+
return { local: normalizedLocal.filter((mutation) => mutation !== 'none'), remote };
|
|
16
17
|
}
|
|
17
18
|
function evidence(schema, required = true, liveReadbackProviders = []) {
|
|
18
19
|
return { schema, required, headerSchemaVersion: evidenceHeaderSchemaVersion, liveReadbackProviders };
|
|
@@ -23,394 +24,438 @@ function approval(kind, required) {
|
|
|
23
24
|
function rollback(kind, target, description) {
|
|
24
25
|
return { kind, target, description };
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
const nonGovernanceTaskPhases = new Set([
|
|
28
|
+
'seed-valid',
|
|
29
|
+
'seed-verified',
|
|
30
|
+
'seed-archived',
|
|
31
|
+
'committed',
|
|
32
|
+
'pushed',
|
|
33
|
+
'phase-0-complete'
|
|
34
|
+
]);
|
|
35
|
+
const rawPhases = [
|
|
36
|
+
{
|
|
37
|
+
id: 'seed-valid',
|
|
38
|
+
label: 'Generated bootstrap seed is strict-valid',
|
|
39
|
+
dependencies: [],
|
|
40
|
+
applicability: { kind: 'always' },
|
|
41
|
+
allowedMutations: mutations(['read-worktree', 'write-evidence']),
|
|
42
|
+
evidence: evidence('seed-valid.v1'),
|
|
43
|
+
approvalGate: approval('none', false),
|
|
44
|
+
invalidationInputs: ['project-files', 'policy', 'activation-identity'],
|
|
45
|
+
rollback: rollback('none', null, 'No mutation is authorized by seed validation.'),
|
|
46
|
+
terminalStates: terminalVerified
|
|
33
47
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
exclusiveWith: []
|
|
129
|
-
},
|
|
130
|
-
allowedMutations: mutations(['write-evidence'], ['github-secret-write', 'github-read']),
|
|
131
|
-
evidence: evidence('credential-ready.v1', true, ['github']),
|
|
132
|
-
approvalGate: approval('credential-enrollment', true),
|
|
133
|
-
invalidationInputs: ['credentials', 'approval-envelope', 'activation-identity'],
|
|
134
|
-
rollback: rollback('none', null, 'Leaked or expired credentials block use and require rotation.'),
|
|
135
|
-
terminalStates: terminalConditional
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
id: 'provider-ready',
|
|
139
|
-
label: 'Azure provider namespaces are terminal ready',
|
|
140
|
-
dependencies: [
|
|
141
|
-
dep(['activation-approved'], 'Provider readiness belongs to approved infrastructure scope.'),
|
|
142
|
-
dep(['credential-ready'], 'Runner preflight credential readiness or inapplicability precedes provider work.')
|
|
143
|
-
],
|
|
144
|
-
applicability: {
|
|
145
|
-
kind: 'conditional',
|
|
146
|
-
discriminator: 'private-staging-dast',
|
|
147
|
-
when: 'privateStagingDast=true',
|
|
148
|
-
inapplicableWhen: 'privateStagingDast=false',
|
|
149
|
-
exclusiveWith: []
|
|
150
|
-
},
|
|
151
|
-
allowedMutations: mutations(['write-evidence'], ['azure-read', 'azure-provider-register']),
|
|
152
|
-
evidence: evidence('provider-ready.v1', true, ['azure']),
|
|
153
|
-
approvalGate: approval('infrastructure-cost', true),
|
|
154
|
-
invalidationInputs: ['provider-inventory', 'approval-envelope', 'policy'],
|
|
155
|
-
rollback: rollback('retain', null, 'Provider registrations are retained subscription capabilities.'),
|
|
156
|
-
terminalStates: ['verified', 'failed', 'inapplicable', 'retained']
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
id: 'state-path-selected',
|
|
160
|
-
label: 'Private state path is selected',
|
|
161
|
-
dependencies: [dep(['provider-ready'], 'Provider readiness precedes private state path selection.')],
|
|
162
|
-
applicability: {
|
|
163
|
-
kind: 'conditional',
|
|
164
|
-
discriminator: 'private-staging-dast',
|
|
165
|
-
when: 'privateStagingDast=true',
|
|
166
|
-
inapplicableWhen: 'privateStagingDast=false',
|
|
167
|
-
exclusiveWith: []
|
|
168
|
-
},
|
|
169
|
-
allowedMutations: mutations(['write-activation-state', 'write-evidence'], ['azure-read']),
|
|
170
|
-
evidence: evidence('state-path-selected.v1', true, ['azure']),
|
|
171
|
-
approvalGate: approval('infrastructure-cost', true),
|
|
172
|
-
invalidationInputs: ['remote-state', 'provider-inventory', 'approval-envelope'],
|
|
173
|
-
rollback: rollback('none', null, 'A changed path selection invalidates mutually exclusive descendants.'),
|
|
174
|
-
terminalStates: terminalConditional
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
id: 'existing-private-path',
|
|
178
|
-
label: 'Existing private backend management path is verified',
|
|
179
|
-
dependencies: [dep(['state-path-selected'], 'State path selection chooses this branch.')],
|
|
180
|
-
applicability: {
|
|
181
|
-
kind: 'conditional',
|
|
182
|
-
discriminator: 'state-path',
|
|
183
|
-
when: 'statePath=existing-private',
|
|
184
|
-
inapplicableWhen: 'statePath!=existing-private',
|
|
185
|
-
exclusiveWith: ['bootstrap-local']
|
|
186
|
-
},
|
|
187
|
-
allowedMutations: mutations(['write-evidence'], ['azure-read']),
|
|
188
|
-
evidence: evidence('existing-private-path.v1', true, ['azure']),
|
|
189
|
-
approvalGate: approval('none', false),
|
|
190
|
-
invalidationInputs: ['remote-state', 'live-readback'],
|
|
191
|
-
rollback: rollback('none', null, 'Existing path verification is read-only.'),
|
|
192
|
-
terminalStates: terminalConditional
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
id: 'bootstrap-local',
|
|
196
|
-
label: 'Bounded local bootstrap creates access-establishing resources',
|
|
197
|
-
dependencies: [
|
|
198
|
-
dep(['provider-ready'], 'Provider readiness precedes local bootstrap.'),
|
|
199
|
-
dep(['state-path-selected'], 'State path selection precedes local bootstrap.')
|
|
200
|
-
],
|
|
201
|
-
applicability: {
|
|
202
|
-
kind: 'conditional',
|
|
203
|
-
discriminator: 'state-path',
|
|
204
|
-
when: 'statePath=bootstrap-local',
|
|
205
|
-
inapplicableWhen: 'statePath!=bootstrap-local',
|
|
206
|
-
exclusiveWith: ['existing-private-path']
|
|
207
|
-
},
|
|
208
|
-
allowedMutations: mutations(['write-local-state', 'write-evidence'], ['azure-network-provision', 'github-write']),
|
|
209
|
-
evidence: evidence('bootstrap-local.v1', true, ['github', 'azure']),
|
|
210
|
-
approvalGate: approval('infrastructure-cost', true),
|
|
211
|
-
invalidationInputs: ['approval-envelope', 'provider-inventory', 'remote-state'],
|
|
212
|
-
rollback: rollback('reverse-to', 'provider-ready', 'Remove only repository-owned bootstrap resources in dependency order.'),
|
|
213
|
-
terminalStates: terminalConditional
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
id: 'runner-ready',
|
|
217
|
-
label: 'Restricted larger runner is assigned and ready',
|
|
218
|
-
dependencies: [dep(['bootstrap-local'], 'Local bootstrap must establish runner networking before runner proof.')],
|
|
219
|
-
applicability: {
|
|
220
|
-
kind: 'conditional',
|
|
221
|
-
discriminator: 'state-path',
|
|
222
|
-
when: 'statePath=bootstrap-local',
|
|
223
|
-
inapplicableWhen: 'statePath!=bootstrap-local',
|
|
224
|
-
exclusiveWith: []
|
|
225
|
-
},
|
|
226
|
-
allowedMutations: mutations(['write-evidence'], ['github-read', 'github-write']),
|
|
227
|
-
evidence: evidence('runner-ready.v1', true, ['github']),
|
|
228
|
-
approvalGate: approval('infrastructure-cost', true),
|
|
229
|
-
invalidationInputs: ['runner-inventory', 'approval-envelope'],
|
|
230
|
-
rollback: rollback('reverse-to', 'bootstrap-local', 'Remove repository runner assignment before network resources.'),
|
|
231
|
-
terminalStates: terminalConditional
|
|
232
|
-
},
|
|
233
|
-
{
|
|
234
|
-
id: 'private-backend-proof',
|
|
235
|
-
label: 'Private backend is reachable from runner',
|
|
236
|
-
dependencies: [dep(['runner-ready'], 'Runner readiness precedes private backend proof.')],
|
|
237
|
-
applicability: {
|
|
238
|
-
kind: 'conditional',
|
|
239
|
-
discriminator: 'state-path',
|
|
240
|
-
when: 'statePath=bootstrap-local',
|
|
241
|
-
inapplicableWhen: 'statePath!=bootstrap-local',
|
|
242
|
-
exclusiveWith: []
|
|
243
|
-
},
|
|
244
|
-
allowedMutations: mutations(['write-evidence'], ['github-read', 'azure-read']),
|
|
245
|
-
evidence: evidence('private-backend-proof.v1', true, ['github', 'azure']),
|
|
246
|
-
approvalGate: approval('none', false),
|
|
247
|
-
invalidationInputs: ['runner-inventory', 'remote-state', 'live-readback'],
|
|
248
|
-
rollback: rollback('reverse-to', 'runner-ready', 'Failed proof keeps remote import blocked.'),
|
|
249
|
-
terminalStates: terminalConditional
|
|
250
|
-
},
|
|
251
|
-
{
|
|
252
|
-
id: 'remote-import-verified',
|
|
253
|
-
label: 'Declarative remote import and no-change plan are verified',
|
|
254
|
-
dependencies: [dep(['private-backend-proof'], 'Private backend proof precedes remote import.')],
|
|
255
|
-
applicability: {
|
|
256
|
-
kind: 'conditional',
|
|
257
|
-
discriminator: 'state-path',
|
|
258
|
-
when: 'statePath=bootstrap-local',
|
|
259
|
-
inapplicableWhen: 'statePath!=bootstrap-local',
|
|
260
|
-
exclusiveWith: []
|
|
261
|
-
},
|
|
262
|
-
allowedMutations: mutations(['write-evidence'], ['azure-state-import']),
|
|
263
|
-
evidence: evidence('remote-import-verified.v1', true, ['azure']),
|
|
264
|
-
approvalGate: approval('infrastructure-cost', true),
|
|
265
|
-
invalidationInputs: ['remote-state', 'approval-envelope'],
|
|
266
|
-
rollback: rollback('reverse-to', 'private-backend-proof', 'Failed import leaves local state retained for remediation.'),
|
|
267
|
-
terminalStates: terminalConditional
|
|
268
|
-
},
|
|
269
|
-
{
|
|
270
|
-
id: 'remote-ready',
|
|
271
|
-
label: 'Remote state is ready and local bootstrap state is frozen',
|
|
272
|
-
dependencies: [dep(['existing-private-path', 'remote-import-verified'], 'Remote readiness follows either existing private path or verified remote import.')],
|
|
273
|
-
applicability: {
|
|
274
|
-
kind: 'conditional',
|
|
275
|
-
discriminator: 'private-staging-dast',
|
|
276
|
-
when: 'privateStagingDast=true',
|
|
277
|
-
inapplicableWhen: 'privateStagingDast=false',
|
|
278
|
-
exclusiveWith: []
|
|
279
|
-
},
|
|
280
|
-
allowedMutations: mutations(['write-evidence'], ['azure-read']),
|
|
281
|
-
evidence: evidence('remote-ready.v1'),
|
|
282
|
-
approvalGate: approval('none', false),
|
|
283
|
-
invalidationInputs: ['remote-state', 'live-readback'],
|
|
284
|
-
rollback: rollback('retain', null, 'Retain local bootstrap state read-only for exactly 30 days when used.'),
|
|
285
|
-
terminalStates: ['verified', 'failed', 'inapplicable', 'retained']
|
|
286
|
-
},
|
|
287
|
-
{
|
|
288
|
-
id: 'application-foundation',
|
|
289
|
-
label: 'Application infrastructure foundation is reconciled',
|
|
290
|
-
dependencies: [dep(['remote-ready'], 'Application resources wait for remote state readiness or inapplicability.')],
|
|
291
|
-
applicability: { kind: 'always' },
|
|
292
|
-
allowedMutations: mutations(['write-evidence', 'write-openspec-governance'], ['azure-resource-provision']),
|
|
293
|
-
evidence: evidence('application-foundation.v1', true, ['azure']),
|
|
294
|
-
approvalGate: approval('infrastructure-cost', true),
|
|
295
|
-
invalidationInputs: ['project-files', 'remote-state', 'approval-envelope'],
|
|
296
|
-
rollback: rollback('reverse-to', 'remote-ready', 'Application resources are removed without unregistering providers.'),
|
|
297
|
-
terminalStates: terminalVerified
|
|
48
|
+
{
|
|
49
|
+
id: 'seed-verified',
|
|
50
|
+
label: 'Generated bootstrap baseline checks are verified',
|
|
51
|
+
dependencies: [dep(['seed-valid'], 'Seed strict validation must pass first.')],
|
|
52
|
+
applicability: { kind: 'always' },
|
|
53
|
+
allowedMutations: mutations(['read-worktree', 'write-seed-tasks', 'write-evidence']),
|
|
54
|
+
evidence: evidence('seed-verified.v1'),
|
|
55
|
+
approvalGate: approval('none', false),
|
|
56
|
+
invalidationInputs: ['project-files', 'activation-identity'],
|
|
57
|
+
rollback: rollback('none', null, 'A failed baseline leaves the seed active.'),
|
|
58
|
+
terminalStates: terminalVerified
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: 'seed-archived',
|
|
62
|
+
label: 'Generated bootstrap seed is synced and archived',
|
|
63
|
+
dependencies: [dep(['seed-verified'], 'Only a verified seed may be archived.')],
|
|
64
|
+
applicability: { kind: 'always' },
|
|
65
|
+
allowedMutations: mutations(['read-worktree', 'write-openspec-seed', 'write-evidence']),
|
|
66
|
+
evidence: evidence('seed-archived.v1'),
|
|
67
|
+
approvalGate: approval('none', false),
|
|
68
|
+
invalidationInputs: ['project-files', 'activation-identity'],
|
|
69
|
+
rollback: rollback('none', null, 'Archive failures keep the seed active.'),
|
|
70
|
+
terminalStates: terminalVerified
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 'committed',
|
|
74
|
+
label: 'Initial repository baseline is committed',
|
|
75
|
+
dependencies: [dep(['seed-archived'], 'Generated seed must be complete before commit guidance.')],
|
|
76
|
+
applicability: { kind: 'always' },
|
|
77
|
+
allowedMutations: mutations(['read-worktree', 'git-commit', 'write-evidence']),
|
|
78
|
+
evidence: evidence('committed.v1'),
|
|
79
|
+
approvalGate: approval('repository-publish', true),
|
|
80
|
+
invalidationInputs: ['baseline-sha', 'project-files', 'approval-envelope'],
|
|
81
|
+
rollback: rollback('none', null, 'Never rewrite a committed user history automatically.'),
|
|
82
|
+
terminalStates: terminalVerified
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'pushed',
|
|
86
|
+
label: 'Initial repository baseline is pushed',
|
|
87
|
+
dependencies: [dep(['committed'], 'Commit evidence precedes initial push.')],
|
|
88
|
+
applicability: { kind: 'always' },
|
|
89
|
+
allowedMutations: mutations(['read-worktree', 'git-remote-bind', 'write-evidence'], ['git-push', 'github-read', 'github-repository-create', 'github-write']),
|
|
90
|
+
evidence: evidence('pushed.v1', true, ['github']),
|
|
91
|
+
approvalGate: approval('repository-publish', true),
|
|
92
|
+
invalidationInputs: ['baseline-sha', 'approval-envelope'],
|
|
93
|
+
rollback: rollback('none', null, 'Never force-push, delete, or rewrite refs.'),
|
|
94
|
+
terminalStates: terminalVerified
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
id: 'phase-0-complete',
|
|
98
|
+
label: 'Read-only Phase 0 discovery is complete',
|
|
99
|
+
dependencies: [dep(['pushed'], 'Remote repository identity must be resolvable.')],
|
|
100
|
+
applicability: { kind: 'always' },
|
|
101
|
+
allowedMutations: mutations(['write-evidence'], ['github-read', 'azure-read']),
|
|
102
|
+
evidence: evidence('phase-0-complete.v1', true, ['github']),
|
|
103
|
+
approvalGate: approval('none', false),
|
|
104
|
+
invalidationInputs: ['baseline-sha', 'policy', 'live-readback'],
|
|
105
|
+
rollback: rollback('none', null, 'Discovery is read-only and can be refreshed.'),
|
|
106
|
+
terminalStates: terminalVerified
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 'activation-approved',
|
|
110
|
+
label: 'Governance activation plan is approved',
|
|
111
|
+
dependencies: [dep(['phase-0-complete'], 'Approval reviews Phase 0 evidence.')],
|
|
112
|
+
applicability: { kind: 'always' },
|
|
113
|
+
allowedMutations: mutations(['write-openspec-governance', 'write-activation-state', 'write-evidence']),
|
|
114
|
+
evidence: evidence('activation-approved.v1', false),
|
|
115
|
+
approvalGate: approval('activation-plan', true),
|
|
116
|
+
invalidationInputs: ['baseline-sha', 'approval-envelope', 'policy'],
|
|
117
|
+
rollback: rollback('none', null, 'Approval expiry returns descendants to blocked.'),
|
|
118
|
+
terminalStates: terminalApproved
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: 'bootstrap-workflow-source-ready',
|
|
122
|
+
label: 'Scoped bootstrap verification workflows are published',
|
|
123
|
+
dependencies: [dep(['activation-approved'], 'Bootstrap workflow publication requires the reviewed activation scope.')],
|
|
124
|
+
applicability: { kind: 'always' },
|
|
125
|
+
allowedMutations: mutations(['read-worktree', 'write-workflows', 'git-commit', 'write-evidence'], ['git-push', 'github-read', 'github-write']),
|
|
126
|
+
evidence: evidence('bootstrap-workflow-source-ready.v1', true, ['github']),
|
|
127
|
+
approvalGate: approval('repository-publish', true),
|
|
128
|
+
invalidationInputs: ['workflow-source', 'approval-envelope', 'baseline-sha'],
|
|
129
|
+
rollback: rollback('none', null, 'Preserve published history; repair only the approved workflow scope.'),
|
|
130
|
+
terminalStates: terminalVerified
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
id: 'credential-ready',
|
|
134
|
+
label: 'Runner preflight credential policy is ready when required',
|
|
135
|
+
dependencies: [dep(['bootstrap-workflow-source-ready'], 'Credential use is verified through the published approved bootstrap workflow.')],
|
|
136
|
+
applicability: {
|
|
137
|
+
kind: 'conditional',
|
|
138
|
+
discriminator: 'credential-required',
|
|
139
|
+
when: 'credentialRequired=true',
|
|
140
|
+
inapplicableWhen: 'credentialRequired=false',
|
|
141
|
+
exclusiveWith: []
|
|
298
142
|
},
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
143
|
+
allowedMutations: mutations(['write-credential-policy', 'write-evidence'], ['github-secret-write', 'github-read', 'github-workflow-dispatch']),
|
|
144
|
+
evidence: evidence('credential-ready.v1', true, ['github']),
|
|
145
|
+
approvalGate: approval('credential-enrollment', true),
|
|
146
|
+
invalidationInputs: ['credentials', 'approval-envelope', 'activation-identity'],
|
|
147
|
+
rollback: rollback('none', null, 'Leaked or expired credentials block use and require rotation.'),
|
|
148
|
+
terminalStates: terminalConditional
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: 'provider-ready',
|
|
152
|
+
label: 'Azure provider namespaces are terminal ready',
|
|
153
|
+
dependencies: [
|
|
154
|
+
dep(['activation-approved'], 'Provider readiness belongs to approved infrastructure scope.'),
|
|
155
|
+
dep(['credential-ready'], 'Runner preflight credential readiness or inapplicability precedes provider work.')
|
|
156
|
+
],
|
|
157
|
+
applicability: { kind: 'always' },
|
|
158
|
+
allowedMutations: mutations(['write-evidence'], ['azure-read', 'azure-provider-register']),
|
|
159
|
+
evidence: evidence('provider-ready.v1', true, ['azure']),
|
|
160
|
+
approvalGate: approval('infrastructure-cost', true),
|
|
161
|
+
invalidationInputs: ['provider-inventory', 'approval-envelope', 'policy'],
|
|
162
|
+
rollback: rollback('retain', null, 'Provider registrations are retained subscription capabilities.'),
|
|
163
|
+
terminalStates: ['verified', 'failed', 'inapplicable', 'retained']
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: 'state-path-selected',
|
|
167
|
+
label: 'Private state path is selected',
|
|
168
|
+
dependencies: [dep(['provider-ready'], 'Provider readiness precedes private state path selection.')],
|
|
169
|
+
applicability: {
|
|
170
|
+
kind: 'conditional',
|
|
171
|
+
discriminator: 'cloud-state-required',
|
|
172
|
+
when: 'cloudStateRequired=true',
|
|
173
|
+
inapplicableWhen: 'cloudStateRequired=false',
|
|
174
|
+
exclusiveWith: []
|
|
310
175
|
},
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
176
|
+
allowedMutations: mutations(['write-activation-state', 'write-evidence'], ['azure-read']),
|
|
177
|
+
evidence: evidence('state-path-selected.v1', true, ['azure']),
|
|
178
|
+
approvalGate: approval('infrastructure-cost', true),
|
|
179
|
+
invalidationInputs: ['remote-state', 'provider-inventory', 'approval-envelope'],
|
|
180
|
+
rollback: rollback('none', null, 'A changed path selection invalidates mutually exclusive descendants.'),
|
|
181
|
+
terminalStates: terminalConditional
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: 'existing-private-path',
|
|
185
|
+
label: 'Existing private backend management path is verified',
|
|
186
|
+
dependencies: [dep(['state-path-selected'], 'State path selection chooses this branch.')],
|
|
187
|
+
applicability: {
|
|
188
|
+
kind: 'conditional',
|
|
189
|
+
discriminator: 'state-path',
|
|
190
|
+
when: 'statePath=existing-private',
|
|
191
|
+
inapplicableWhen: 'statePath!=existing-private',
|
|
192
|
+
exclusiveWith: ['bootstrap-local']
|
|
322
193
|
},
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
194
|
+
allowedMutations: mutations(['write-evidence'], ['azure-read', 'github-read', 'backend-state-read']),
|
|
195
|
+
evidence: evidence('existing-private-path.v1', true, ['azure']),
|
|
196
|
+
approvalGate: approval('none', false),
|
|
197
|
+
invalidationInputs: ['remote-state', 'live-readback'],
|
|
198
|
+
rollback: rollback('none', null, 'Existing path verification is read-only.'),
|
|
199
|
+
terminalStates: terminalConditional
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
id: 'bootstrap-local',
|
|
203
|
+
label: 'Bounded local bootstrap creates access-establishing resources',
|
|
204
|
+
dependencies: [
|
|
205
|
+
dep(['provider-ready'], 'Provider readiness precedes local bootstrap.'),
|
|
206
|
+
dep(['state-path-selected'], 'State path selection precedes local bootstrap.')
|
|
207
|
+
],
|
|
208
|
+
applicability: {
|
|
209
|
+
kind: 'conditional',
|
|
210
|
+
discriminator: 'state-path',
|
|
211
|
+
when: 'statePath=bootstrap-local',
|
|
212
|
+
inapplicableWhen: 'statePath!=bootstrap-local',
|
|
213
|
+
exclusiveWith: ['existing-private-path']
|
|
334
214
|
},
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
215
|
+
allowedMutations: mutations(['read-worktree', 'write-local-state', 'write-evidence'], ['azure-network-provision', 'azure-read']),
|
|
216
|
+
evidence: evidence('bootstrap-local.v1', true, ['azure']),
|
|
217
|
+
approvalGate: approval('infrastructure-cost', true),
|
|
218
|
+
invalidationInputs: ['approval-envelope', 'provider-inventory', 'remote-state'],
|
|
219
|
+
rollback: rollback('reverse-to', 'provider-ready', 'Remove only repository-owned bootstrap resources in dependency order.'),
|
|
220
|
+
terminalStates: terminalConditional
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
id: 'runner-ready',
|
|
224
|
+
label: 'Restricted larger runner is assigned and ready',
|
|
225
|
+
dependencies: [dep(['bootstrap-local'], 'Local bootstrap must establish runner networking before runner proof.')],
|
|
226
|
+
applicability: {
|
|
227
|
+
kind: 'conditional',
|
|
228
|
+
discriminator: 'state-path',
|
|
229
|
+
when: 'statePath=bootstrap-local',
|
|
230
|
+
inapplicableWhen: 'statePath!=bootstrap-local',
|
|
231
|
+
exclusiveWith: []
|
|
346
232
|
},
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
233
|
+
allowedMutations: mutations(['write-evidence'], ['github-read', 'github-write', 'github-workflow-dispatch']),
|
|
234
|
+
evidence: evidence('runner-ready.v1', true, ['github']),
|
|
235
|
+
approvalGate: approval('infrastructure-cost', true),
|
|
236
|
+
invalidationInputs: ['runner-inventory', 'approval-envelope'],
|
|
237
|
+
rollback: rollback('reverse-to', 'bootstrap-local', 'Remove repository runner assignment before network resources.'),
|
|
238
|
+
terminalStates: terminalConditional
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: 'private-backend-proof',
|
|
242
|
+
label: 'Private backend is reachable from runner',
|
|
243
|
+
dependencies: [dep(['runner-ready'], 'Runner readiness precedes private backend proof.')],
|
|
244
|
+
applicability: {
|
|
245
|
+
kind: 'conditional',
|
|
246
|
+
discriminator: 'state-path',
|
|
247
|
+
when: 'statePath=bootstrap-local',
|
|
248
|
+
inapplicableWhen: 'statePath!=bootstrap-local',
|
|
249
|
+
exclusiveWith: []
|
|
358
250
|
},
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
251
|
+
allowedMutations: mutations(['write-evidence'], ['github-read', 'github-workflow-dispatch', 'azure-read', 'backend-state-read']),
|
|
252
|
+
evidence: evidence('private-backend-proof.v1', true, ['github', 'azure']),
|
|
253
|
+
approvalGate: approval('activation-plan', true),
|
|
254
|
+
invalidationInputs: ['runner-inventory', 'remote-state', 'live-readback'],
|
|
255
|
+
rollback: rollback('reverse-to', 'runner-ready', 'Failed proof keeps remote import blocked.'),
|
|
256
|
+
terminalStates: terminalConditional
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
id: 'remote-import-verified',
|
|
260
|
+
label: 'Declarative remote import and no-change plan are verified',
|
|
261
|
+
dependencies: [dep(['private-backend-proof'], 'Private backend proof precedes remote import.')],
|
|
262
|
+
applicability: {
|
|
263
|
+
kind: 'conditional',
|
|
264
|
+
discriminator: 'state-path',
|
|
265
|
+
when: 'statePath=bootstrap-local',
|
|
266
|
+
inapplicableWhen: 'statePath!=bootstrap-local',
|
|
267
|
+
exclusiveWith: []
|
|
370
268
|
},
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
269
|
+
allowedMutations: mutations(['write-evidence'], ['azure-state-import', 'azure-read', 'backend-state-read', 'backend-state-write']),
|
|
270
|
+
evidence: evidence('remote-import-verified.v1', true, ['azure']),
|
|
271
|
+
approvalGate: approval('infrastructure-cost', true),
|
|
272
|
+
invalidationInputs: ['remote-state', 'approval-envelope'],
|
|
273
|
+
rollback: rollback('reverse-to', 'private-backend-proof', 'Failed import leaves local state retained for remediation.'),
|
|
274
|
+
terminalStates: terminalConditional
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
id: 'remote-ready',
|
|
278
|
+
label: 'Remote state is ready and local bootstrap state is frozen',
|
|
279
|
+
dependencies: [dep(['existing-private-path', 'remote-import-verified'], 'Remote readiness follows either existing private path or verified remote import.')],
|
|
280
|
+
applicability: {
|
|
281
|
+
kind: 'conditional',
|
|
282
|
+
discriminator: 'cloud-state-required',
|
|
283
|
+
when: 'cloudStateRequired=true',
|
|
284
|
+
inapplicableWhen: 'cloudStateRequired=false',
|
|
285
|
+
exclusiveWith: []
|
|
382
286
|
},
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
287
|
+
allowedMutations: mutations(['write-evidence'], ['azure-read', 'backend-state-read']),
|
|
288
|
+
evidence: evidence('remote-ready.v1'),
|
|
289
|
+
approvalGate: approval('none', false),
|
|
290
|
+
invalidationInputs: ['remote-state', 'live-readback'],
|
|
291
|
+
rollback: rollback('retain', null, 'Retain local bootstrap state read-only for exactly 30 days when used.'),
|
|
292
|
+
terminalStates: ['verified', 'failed', 'inapplicable', 'retained']
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
id: 'application-prerequisites-ready',
|
|
296
|
+
label: 'Application registry and workload identity prerequisites are ready',
|
|
297
|
+
dependencies: [dep(['remote-ready'], 'Registry and identity prerequisites require verified backend readiness.')],
|
|
298
|
+
applicability: { kind: 'always' },
|
|
299
|
+
allowedMutations: mutations(['read-worktree', 'write-evidence', 'write-openspec-governance'], ['azure-resource-provision', 'azure-read', 'backend-state-read', 'backend-state-write']),
|
|
300
|
+
evidence: evidence('application-prerequisites-ready.v1', true, ['azure']),
|
|
301
|
+
approvalGate: approval('infrastructure-cost', true),
|
|
302
|
+
invalidationInputs: ['project-files', 'remote-state', 'approval-envelope'],
|
|
303
|
+
rollback: rollback('reverse-to', 'remote-ready', 'Compensate only owned prerequisites within the approved recovery scope.'),
|
|
304
|
+
terminalStates: terminalVerified
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
id: 'workflow-source-ready',
|
|
308
|
+
label: 'Workflow source and ruleset payloads are ready',
|
|
309
|
+
dependencies: [dep(['application-prerequisites-ready'], 'Workflow source binds the verified registry and workload identities.')],
|
|
310
|
+
applicability: { kind: 'always' },
|
|
311
|
+
allowedMutations: mutations(['read-worktree', 'write-workflows', 'write-ruleset-source', 'write-evidence']),
|
|
312
|
+
evidence: evidence('workflow-source-ready.v1'),
|
|
313
|
+
approvalGate: approval('none', false),
|
|
314
|
+
invalidationInputs: ['project-files', 'policy'],
|
|
315
|
+
rollback: rollback('reverse-to', 'application-prerequisites-ready', 'Repair only approved workflow/ruleset changes without rewriting Git history.'),
|
|
316
|
+
terminalStates: terminalVerified
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
id: 'application-artifact-ready',
|
|
320
|
+
label: 'Immutable application artifacts are built and published from approved source',
|
|
321
|
+
dependencies: [dep(['workflow-source-ready'], 'The reviewed build workflow must be published before artifact production.')],
|
|
322
|
+
applicability: { kind: 'always' },
|
|
323
|
+
allowedMutations: mutations(['read-worktree', 'write-evidence'], ['github-read', 'github-workflow-dispatch', 'registry-publish', 'azure-read']),
|
|
324
|
+
evidence: evidence('application-artifact-ready.v1', true, ['github', 'azure']),
|
|
325
|
+
approvalGate: approval('infrastructure-cost', true),
|
|
326
|
+
invalidationInputs: ['project-files', 'workflow-source', 'approval-envelope'],
|
|
327
|
+
rollback: rollback('retain', null, 'Keep immutable published artifacts; never replace an existing digest.'),
|
|
328
|
+
terminalStates: terminalVerified
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
id: 'application-foundation',
|
|
332
|
+
label: 'Application infrastructure is deployed with the verified immutable artifact',
|
|
333
|
+
dependencies: [dep(['application-artifact-ready'], 'Deployment requires real source-bound immutable application artifacts.')],
|
|
334
|
+
applicability: { kind: 'always' },
|
|
335
|
+
allowedMutations: mutations(['read-worktree', 'write-evidence', 'write-openspec-governance'], ['azure-resource-provision', 'azure-read', 'backend-state-read', 'backend-state-write']),
|
|
336
|
+
evidence: evidence('application-foundation.v1', true, ['azure']),
|
|
337
|
+
approvalGate: approval('infrastructure-cost', true),
|
|
338
|
+
invalidationInputs: ['project-files', 'remote-state', 'approval-envelope'],
|
|
339
|
+
rollback: rollback('reverse-to', 'application-artifact-ready', 'Recover only approved owned resources; never unregister shared providers.'),
|
|
340
|
+
terminalStates: terminalVerified
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
id: 'dev-proof',
|
|
344
|
+
label: 'Development proof is green',
|
|
345
|
+
dependencies: [dep(['application-foundation'], 'The real application deployment precedes development proof.')],
|
|
346
|
+
applicability: { kind: 'always' },
|
|
347
|
+
allowedMutations: mutations(['write-evidence'], ['github-read', 'github-workflow-dispatch']),
|
|
348
|
+
evidence: evidence('dev-proof.v1', true, ['github']),
|
|
349
|
+
approvalGate: approval('activation-plan', true),
|
|
350
|
+
invalidationInputs: ['workflow-source', 'project-files'],
|
|
351
|
+
rollback: rollback('none', null, 'A failed check blocks descendants until fixed.'),
|
|
352
|
+
terminalStates: terminalVerified
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
id: 'staging-qualified',
|
|
356
|
+
label: 'Staging release qualification is complete',
|
|
357
|
+
dependencies: [dep(['dev-proof'], 'Development proof precedes staging qualification.')],
|
|
358
|
+
applicability: { kind: 'always' },
|
|
359
|
+
allowedMutations: mutations(['write-evidence'], ['github-read', 'github-workflow-dispatch', 'azure-read', 'azure-resource-provision', 'backend-state-write']),
|
|
360
|
+
evidence: evidence('staging-qualified.v1', true, ['github', 'azure']),
|
|
361
|
+
approvalGate: approval('infrastructure-cost', true),
|
|
362
|
+
invalidationInputs: ['workflow-source', 'security-evidence', 'live-readback'],
|
|
363
|
+
rollback: rollback('none', null, 'Qualification failures keep production blocked.'),
|
|
364
|
+
terminalStates: terminalVerified
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
id: 'production-rehearsed',
|
|
368
|
+
label: 'Production promotion and rollback are rehearsed',
|
|
369
|
+
dependencies: [dep(['staging-qualified'], 'Only a staging-qualified candidate may be rehearsed.')],
|
|
370
|
+
applicability: { kind: 'always' },
|
|
371
|
+
allowedMutations: mutations(['write-evidence'], ['github-read', 'github-workflow-dispatch', 'azure-read', 'azure-resource-provision', 'backend-state-write']),
|
|
372
|
+
evidence: evidence('production-rehearsed.v1', true, ['github', 'azure']),
|
|
373
|
+
approvalGate: approval('infrastructure-cost', true),
|
|
374
|
+
invalidationInputs: ['live-readback', 'workflow-source'],
|
|
375
|
+
rollback: rollback('none', null, 'Rollback remains ungated and documented.'),
|
|
376
|
+
terminalStates: terminalVerified
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
id: 'green-red-proof',
|
|
380
|
+
label: 'Required checks are proven green and deliberately red',
|
|
381
|
+
dependencies: [dep(['production-rehearsed'], 'Promotion rehearsal precedes final context proof.')],
|
|
382
|
+
applicability: { kind: 'always' },
|
|
383
|
+
allowedMutations: mutations(['write-evidence'], ['github-read', 'github-workflow-dispatch']),
|
|
384
|
+
evidence: evidence('green-red-proof.v1', true, ['github']),
|
|
385
|
+
approvalGate: approval('activation-plan', true),
|
|
386
|
+
invalidationInputs: ['security-evidence', 'workflow-source'],
|
|
387
|
+
rollback: rollback('none', null, 'Missing red proof prevents enforcement.'),
|
|
388
|
+
terminalStates: terminalVerified
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
id: 'enforcement-approved',
|
|
392
|
+
label: 'Final ruleset enforcement is approved',
|
|
393
|
+
dependencies: [dep(['green-red-proof'], 'Only exact green/red evidence may request enforcement.')],
|
|
394
|
+
applicability: { kind: 'always' },
|
|
395
|
+
allowedMutations: mutations(['write-activation-state', 'write-evidence']),
|
|
396
|
+
evidence: evidence('enforcement-approved.v1', false),
|
|
397
|
+
approvalGate: approval('enforcement', true),
|
|
398
|
+
invalidationInputs: ['approval-envelope', 'ruleset-readback'],
|
|
399
|
+
rollback: rollback('none', null, 'Approval expiry blocks ruleset application.'),
|
|
400
|
+
terminalStates: terminalApproved
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
id: 'rulesets-applied',
|
|
404
|
+
label: 'Repository rulesets are applied idempotently last',
|
|
405
|
+
dependencies: [dep(['enforcement-approved'], 'Final enforcement approval precedes ruleset mutation.')],
|
|
406
|
+
applicability: { kind: 'always' },
|
|
407
|
+
allowedMutations: mutations(['write-evidence'], ['github-ruleset-write', 'github-read']),
|
|
408
|
+
evidence: evidence('rulesets-applied.v1', true, ['github']),
|
|
409
|
+
approvalGate: approval('enforcement', true),
|
|
410
|
+
invalidationInputs: ['approval-envelope', 'ruleset-readback'],
|
|
411
|
+
rollback: rollback('reverse-to', 'green-red-proof', 'Rulesets can be disabled or repaired without approval-gating rollback.'),
|
|
412
|
+
terminalStates: terminalVerified
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
id: 'live-readback',
|
|
416
|
+
label: 'Live enforcement readback matches source',
|
|
417
|
+
dependencies: [dep(['rulesets-applied'], 'Live readback follows ruleset application.')],
|
|
418
|
+
applicability: { kind: 'always' },
|
|
419
|
+
allowedMutations: mutations(['write-evidence'], ['github-read']),
|
|
420
|
+
evidence: evidence('live-readback.v1', true, ['github']),
|
|
421
|
+
approvalGate: approval('none', false),
|
|
422
|
+
invalidationInputs: ['ruleset-readback', 'live-readback'],
|
|
423
|
+
rollback: rollback('reverse-to', 'rulesets-applied', 'Mismatched live readback blocks completion.'),
|
|
424
|
+
terminalStates: terminalVerified
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
id: 'bootstrap-state-disposed',
|
|
428
|
+
label: 'Retained local bootstrap state is disposed after day 30',
|
|
429
|
+
dependencies: [dep(['live-readback'], 'Disposal is scheduled only after live enforcement readback.')],
|
|
430
|
+
applicability: {
|
|
431
|
+
kind: 'conditional',
|
|
432
|
+
discriminator: 'state-path',
|
|
433
|
+
when: 'statePath=bootstrap-local',
|
|
434
|
+
inapplicableWhen: 'statePath!=bootstrap-local',
|
|
435
|
+
exclusiveWith: []
|
|
394
436
|
},
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
437
|
+
allowedMutations: mutations(['delete-local-state', 'write-evidence']),
|
|
438
|
+
evidence: evidence('bootstrap-state-disposed.v1'),
|
|
439
|
+
approvalGate: approval('destructive-disposal', true),
|
|
440
|
+
invalidationInputs: ['remote-state', 'approval-envelope'],
|
|
441
|
+
rollback: rollback('dispose', null, 'Deletion destroys only the local encryption key and records no payload.'),
|
|
442
|
+
terminalStates: ['disposed', 'failed', 'inapplicable']
|
|
443
|
+
}
|
|
444
|
+
];
|
|
445
|
+
export const canonicalPhaseGraph = {
|
|
446
|
+
schemaVersion: phaseGraphSchemaVersion,
|
|
447
|
+
versions: {
|
|
448
|
+
liftoffVersion: liftoffActivationPackageVersion,
|
|
449
|
+
policyVersion: governanceActivationPolicyVersion,
|
|
450
|
+
activationContractVersion,
|
|
451
|
+
phaseGraphSchemaVersion
|
|
452
|
+
},
|
|
453
|
+
completionGroups: {
|
|
454
|
+
local: localSetupPhaseIds,
|
|
455
|
+
activation: activationPhaseIds,
|
|
456
|
+
lifecycle: lifecyclePhaseIds
|
|
457
|
+
},
|
|
458
|
+
phases: rawPhases
|
|
414
459
|
};
|
|
415
460
|
function phaseBehavior(node) {
|
|
416
461
|
return {
|