@apexops/cli 0.10.0-next.5 → 0.11.0-next.1
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/assets/capability-packs/registry.v1.json +1 -62
- package/assets/client-projection-metadata/copilot-cli-agent-tools.json +12 -0
- package/assets/client-projections/github-copilot-cli/.github/copilot/settings.json +13 -0
- package/assets/client-projections/github-copilot-cli/.github/instructions/apex-prompt-authoring.instructions.md +1 -1
- package/assets/client-projections/github-copilot-cli/.github/workflows/governance-policy-baseline.yml +101 -0
- package/assets/client-projections/github-copilot-cli/tools/schemas/governance-baseline.schema.json +118 -0
- package/assets/client-projections/github-copilot-cli/tools/scripts/collect-governance-baseline.ps1 +817 -0
- package/assets/config/capability-packs.v1.json +1 -32
- package/assets/config/governance-reference.v1.json +26379 -0
- package/assets/config/recipe-packs.v1.json +1 -26
- package/assets/config/runtime-bundle.v1.json +7 -7
- package/assets/config/toolchain.v1.json +35 -33
- package/assets/config/workflow.v1.json +103 -72
- package/assets/customizations/.github/agents/apex-codegen.agent.md +8 -22
- package/assets/customizations/.github/agents/apex-validator.agent.md +14 -20
- package/assets/customizations/.github/agents/apex.agent.md +108 -75
- package/assets/customizations/.github/copilot/settings.json +13 -0
- package/assets/customizations/.github/instructions/apex-prompt-authoring.instructions.md +1 -1
- package/assets/customizations/.github/skills/apex-architecture/SKILL.md +62 -18
- package/assets/customizations/.github/skills/apex-artifacts/SKILL.md +28 -6
- package/assets/customizations/.github/skills/apex-azure-adr/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-cloud-migrate/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-compliance/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-compute/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-cost-optimization/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-defaults/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-defaults/references/governance-effects.md +5 -3
- package/assets/customizations/.github/skills/apex-azure-deploy/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-diagnostics/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-governance/SKILL.md +19 -3
- package/assets/customizations/.github/skills/apex-azure-governance/references/evidence-interpretation.md +38 -3
- package/assets/customizations/.github/skills/apex-azure-kusto/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-prepare/SKILL.md +5 -3
- package/assets/customizations/.github/skills/apex-azure-quotas/SKILL.md +6 -2
- package/assets/customizations/.github/skills/apex-azure-quotas/references/capacity-decision-rules.md +4 -3
- package/assets/customizations/.github/skills/apex-azure-quotas/references/operational-checklist.md +3 -2
- package/assets/customizations/.github/skills/apex-azure-rbac/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-resources/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-storage/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-azure-validate/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-bicep-patterns/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-codegen/SKILL.md +6 -2
- package/assets/customizations/.github/skills/apex-entra-app-registration/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-mermaid/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-microsoft-docs/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-next/SKILL.md +99 -0
- package/assets/customizations/.github/skills/apex-operations/SKILL.md +46 -16
- package/assets/customizations/.github/skills/apex-planning/SKILL.md +48 -19
- package/assets/customizations/.github/skills/apex-requirements/SKILL.md +61 -26
- package/assets/customizations/.github/skills/apex-terraform-import/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-terraform-patterns/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-terraform-test/SKILL.md +3 -0
- package/assets/customizations/.github/skills/apex-unslop/LICENSE.txt +21 -0
- package/assets/customizations/.github/skills/apex-unslop/SKILL.md +94 -0
- package/assets/customizations/.github/skills/apex-workflow/SKILL.md +15 -5
- package/assets/customizations/.github/workflows/governance-policy-baseline.yml +101 -0
- package/assets/customizations/README.md +8 -9
- package/assets/customizations/manifest.json +167 -209
- package/assets/customizations/tools/schemas/governance-baseline.schema.json +118 -0
- package/assets/customizations/tools/scripts/collect-governance-baseline.ps1 +817 -0
- package/assets/manifest.json +423 -4241
- package/assets/schemas/governance-baseline.schema.json +118 -0
- package/dist/assets.d.ts +18 -2
- package/dist/assets.js +115 -35
- package/dist/bootstrap-wizard.d.ts +37 -0
- package/dist/bootstrap-wizard.js +259 -0
- package/dist/cli.d.ts +17 -2
- package/dist/cli.js +180 -63
- package/dist/dependency-revision.js +8 -0
- package/dist/errors.d.ts +6 -1
- package/dist/errors.js +55 -0
- package/dist/host-profile.d.ts +47 -0
- package/dist/host-profile.js +269 -0
- package/dist/mcp-output-schemas.d.ts +43 -0
- package/dist/mcp-output-schemas.js +279 -0
- package/dist/mcp-tool-effects.d.ts +101 -0
- package/dist/mcp-tool-effects.js +66 -0
- package/dist/mcp.d.ts +50 -3
- package/dist/mcp.js +800 -87
- package/dist/runtime-binding.d.ts +37 -0
- package/dist/runtime-binding.js +131 -0
- package/dist/service.d.ts +643 -38
- package/dist/service.js +4937 -662
- package/dist/state-transfer.js +21 -1
- package/dist/target-scope.d.ts +4 -0
- package/dist/target-scope.js +9 -0
- package/dist/version.d.ts +3 -1
- package/dist/version.js +19 -1
- package/dist/workflow-validators.d.ts +20 -3
- package/dist/workflow-validators.js +408 -67
- package/dist/workspace-root.d.ts +7 -0
- package/dist/workspace-root.js +67 -0
- package/package.json +11 -12
- package/assets/capability-packs/azure-governance-discovery/source/scripts/discover.py +0 -1189
- package/assets/capability-packs/azure-governance-discovery/source/scripts/render_governance.py +0 -676
- package/assets/client-projections/github-copilot-cli/.github/agents/apex-architect.agent.md +0 -91
- package/assets/client-projections/github-copilot-cli/.github/agents/apex-operator.agent.md +0 -75
- package/assets/client-projections/github-copilot-cli/.github/agents/apex-planner.agent.md +0 -88
- package/assets/client-projections/github-copilot-cli/.github/agents/apex-requirements.agent.md +0 -99
- package/assets/client-projections/github-copilot-cli/.github/agents/apex.agent.md +0 -88
- package/assets/client-projections/github-copilot-cli/.github/mcp.json +0 -65
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-architecture/SKILL.md +0 -36
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-artifacts/SKILL.md +0 -65
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-artifacts/references/presentation-conventions.md +0 -52
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-artifacts/references/reference-only-outlines.md +0 -78
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-artifacts/templates/architecture-assessment.md +0 -35
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-artifacts/templates/cost-estimate.md +0 -47
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-artifacts/templates/deployment-summary.md +0 -35
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-artifacts/templates/governance-constraints.md +0 -35
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-artifacts/templates/implementation-plan.md +0 -43
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-artifacts/templates/operations-runbook.md +0 -35
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-artifacts/templates/requirements.md +0 -42
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-artifacts/templates/resource-inventory.md +0 -29
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-adr/SKILL.md +0 -52
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-adr/references/decision-examples.md +0 -38
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-adr/references/decision-guardrails.md +0 -36
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-adr/references/decision-quality.md +0 -21
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-adr/references/decision-record-fields.md +0 -57
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-cloud-migrate/SKILL.md +0 -55
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-cloud-migrate/references/lambda-to-functions-assessment.md +0 -29
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-cloud-migrate/references/migration-readiness.md +0 -27
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-cloud-migrate/references/staged-validation-handoff.md +0 -26
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-cloud-migrate/references/workload-mapping.md +0 -27
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-compliance/SKILL.md +0 -58
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-compliance/references/compliance-finding-criteria.md +0 -63
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-compliance/references/operational-checklist.md +0 -24
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-compute/SKILL.md +0 -36
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-compute/references/compute-selection.md +0 -26
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-compute/references/pricing-evidence.md +0 -11
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-compute/references/recommendation-and-scale-rules.md +0 -44
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-cost-optimization/SKILL.md +0 -61
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-cost-optimization/references/cost-assessment-criteria.md +0 -61
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-cost-optimization/references/operational-checklist.md +0 -24
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-defaults/SKILL.md +0 -59
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-defaults/references/avm-binding-guidance.md +0 -29
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-defaults/references/baseline-fallbacks.md +0 -53
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-defaults/references/cost-monitoring.md +0 -47
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-defaults/references/decision-boundaries.md +0 -19
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-defaults/references/governance-effects.md +0 -28
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-defaults/references/naming.md +0 -47
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-defaults/references/network-planning.md +0 -47
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-defaults/references/security-baseline.md +0 -40
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-defaults/references/service-selection.md +0 -51
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-defaults/references/tag-precedence.md +0 -31
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-deploy/SKILL.md +0 -50
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-deploy/references/operational-checklist.md +0 -26
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-deploy/references/preview-recovery-verification.md +0 -48
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-diagnostics/SKILL.md +0 -60
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-diagnostics/references/diagnostic-interpretation.md +0 -42
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-diagnostics/references/operational-checklist.md +0 -24
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-governance/SKILL.md +0 -52
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-governance/references/evidence-interpretation.md +0 -58
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-governance/references/operational-checklist.md +0 -25
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-kusto/SKILL.md +0 -58
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-kusto/references/kql-evidence-interpretation.md +0 -41
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-kusto/references/operational-checklist.md +0 -25
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-prepare/SKILL.md +0 -52
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-prepare/references/functions-recipe-pack.md +0 -27
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-prepare/references/preparation-lineage.md +0 -36
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-quotas/SKILL.md +0 -53
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-quotas/references/capacity-decision-rules.md +0 -48
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-quotas/references/operational-checklist.md +0 -23
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-rbac/SKILL.md +0 -45
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-rbac/references/assignment-intent.md +0 -39
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-rbac/references/least-privilege-selection.md +0 -50
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-resources/SKILL.md +0 -54
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-resources/references/inventory-query-patterns.md +0 -49
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-resources/references/operational-checklist.md +0 -24
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-storage/SKILL.md +0 -35
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-storage/references/security-and-governance.md +0 -12
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-storage/references/service-auth-and-sdk-boundary.md +0 -33
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-storage/references/storage-selection.md +0 -12
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-validate/SKILL.md +0 -49
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-validate/references/operational-checklist.md +0 -24
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-azure-validate/references/preflight-evidence.md +0 -43
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-bicep-patterns/SKILL.md +0 -41
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-bicep-patterns/references/avm-and-codegen-acceptance.md +0 -11
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-bicep-patterns/references/codegen-acceptance-checklist.md +0 -46
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-bicep-patterns/references/compiler-and-provider-gotchas.md +0 -74
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-bicep-patterns/references/module-interfaces-and-parameters.md +0 -56
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-bicep-patterns/references/network-and-observability.md +0 -52
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-codegen/SKILL.md +0 -32
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-entra-app-registration/SKILL.md +0 -53
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-entra-app-registration/references/capability-receipts.md +0 -21
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-entra-app-registration/references/design-and-diagnostics.md +0 -36
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-entra-app-registration/references/oauth-registration-model.md +0 -26
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-entra-app-registration/references/permissions-and-credentials.md +0 -27
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-mermaid/SKILL.md +0 -44
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-mermaid/references/styling.md +0 -33
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-mermaid/references/syntax.md +0 -99
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-microsoft-docs/SKILL.md +0 -53
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-microsoft-docs/references/research-method.md +0 -91
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-operations/SKILL.md +0 -34
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-planning/SKILL.md +0 -36
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-requirements/SKILL.md +0 -46
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-import/SKILL.md +0 -47
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-import/references/adoption-attestation.md +0 -10
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-import/references/import-assessment.md +0 -14
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-import/references/import-mapping.md +0 -27
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-import/references/mapping-and-adoption-attestation.md +0 -12
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-patterns/SKILL.md +0 -49
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-patterns/references/module-composition-and-refactor.md +0 -20
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-patterns/references/module-composition-and-state-boundaries.md +0 -11
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-patterns/references/module-locks-and-codegen-acceptance.md +0 -14
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-patterns/references/network-and-observability.md +0 -12
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-patterns/references/plan-and-change-assessment.md +0 -24
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-test/SKILL.md +0 -45
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-test/references/evidence-acceptance.md +0 -10
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-test/references/plan-mode-and-mock-design.md +0 -12
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-test/references/plan-mode-test-design.md +0 -23
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-terraform-test/references/test-design.md +0 -13
- package/assets/client-projections/github-copilot-cli/.github/skills/apex-workflow/SKILL.md +0 -37
- package/assets/client-projections/github-copilot-vscode/.github/agents/apex-architect.agent.md +0 -100
- package/assets/client-projections/github-copilot-vscode/.github/agents/apex-codegen.agent.md +0 -62
- package/assets/client-projections/github-copilot-vscode/.github/agents/apex-operator.agent.md +0 -79
- package/assets/client-projections/github-copilot-vscode/.github/agents/apex-planner.agent.md +0 -98
- package/assets/client-projections/github-copilot-vscode/.github/agents/apex-requirements.agent.md +0 -108
- package/assets/client-projections/github-copilot-vscode/.github/agents/apex-reviewer.agent.md +0 -63
- package/assets/client-projections/github-copilot-vscode/.github/agents/apex-validator.agent.md +0 -61
- package/assets/client-projections/github-copilot-vscode/.github/agents/apex.agent.md +0 -107
- package/assets/client-projections/github-copilot-vscode/.github/copilot-instructions.md +0 -13
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-agent-authoring.instructions.md +0 -14
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-artifact-contracts.instructions.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-automation.instructions.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-azure-yaml.instructions.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-bicep.instructions.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-code-quality.instructions.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-context.instructions.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-documentation.instructions.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-governance.instructions.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-instruction-authoring.instructions.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-javascript.instructions.md +0 -11
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-json.instructions.md +0 -11
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-markdown.instructions.md +0 -13
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-powershell.instructions.md +0 -11
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-prompt-authoring.instructions.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-python.instructions.md +0 -11
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-safe-file-edits.instructions.md +0 -11
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-safe-shell.instructions.md +0 -11
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-shell.instructions.md +0 -11
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-skill-authoring.instructions.md +0 -13
- package/assets/client-projections/github-copilot-vscode/.github/instructions/apex-terraform.instructions.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-architecture/SKILL.md +0 -36
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-artifacts/SKILL.md +0 -65
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-artifacts/references/presentation-conventions.md +0 -52
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-artifacts/references/reference-only-outlines.md +0 -78
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-artifacts/templates/architecture-assessment.md +0 -35
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-artifacts/templates/cost-estimate.md +0 -47
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-artifacts/templates/deployment-summary.md +0 -35
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-artifacts/templates/governance-constraints.md +0 -35
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-artifacts/templates/implementation-plan.md +0 -43
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-artifacts/templates/operations-runbook.md +0 -35
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-artifacts/templates/requirements.md +0 -42
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-artifacts/templates/resource-inventory.md +0 -29
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-adr/SKILL.md +0 -52
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-adr/references/decision-examples.md +0 -38
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-adr/references/decision-guardrails.md +0 -36
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-adr/references/decision-quality.md +0 -21
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-adr/references/decision-record-fields.md +0 -57
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-cloud-migrate/SKILL.md +0 -55
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-cloud-migrate/references/lambda-to-functions-assessment.md +0 -29
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-cloud-migrate/references/migration-readiness.md +0 -27
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-cloud-migrate/references/staged-validation-handoff.md +0 -26
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-cloud-migrate/references/workload-mapping.md +0 -27
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-compliance/SKILL.md +0 -58
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-compliance/references/compliance-finding-criteria.md +0 -63
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-compliance/references/operational-checklist.md +0 -24
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-compute/SKILL.md +0 -36
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-compute/references/compute-selection.md +0 -26
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-compute/references/pricing-evidence.md +0 -11
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-compute/references/recommendation-and-scale-rules.md +0 -44
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-cost-optimization/SKILL.md +0 -61
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-cost-optimization/references/cost-assessment-criteria.md +0 -61
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-cost-optimization/references/operational-checklist.md +0 -24
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-defaults/SKILL.md +0 -59
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-defaults/references/avm-binding-guidance.md +0 -29
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-defaults/references/baseline-fallbacks.md +0 -53
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-defaults/references/cost-monitoring.md +0 -47
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-defaults/references/decision-boundaries.md +0 -19
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-defaults/references/governance-effects.md +0 -28
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-defaults/references/naming.md +0 -47
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-defaults/references/network-planning.md +0 -47
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-defaults/references/security-baseline.md +0 -40
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-defaults/references/service-selection.md +0 -51
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-defaults/references/tag-precedence.md +0 -31
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-deploy/SKILL.md +0 -50
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-deploy/references/operational-checklist.md +0 -26
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-deploy/references/preview-recovery-verification.md +0 -48
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-diagnostics/SKILL.md +0 -60
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-diagnostics/references/diagnostic-interpretation.md +0 -42
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-diagnostics/references/operational-checklist.md +0 -24
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-governance/SKILL.md +0 -52
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-governance/references/evidence-interpretation.md +0 -58
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-governance/references/operational-checklist.md +0 -25
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-kusto/SKILL.md +0 -58
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-kusto/references/kql-evidence-interpretation.md +0 -41
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-kusto/references/operational-checklist.md +0 -25
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-prepare/SKILL.md +0 -52
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-prepare/references/functions-recipe-pack.md +0 -27
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-prepare/references/preparation-lineage.md +0 -36
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-quotas/SKILL.md +0 -53
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-quotas/references/capacity-decision-rules.md +0 -48
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-quotas/references/operational-checklist.md +0 -23
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-rbac/SKILL.md +0 -45
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-rbac/references/assignment-intent.md +0 -39
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-rbac/references/least-privilege-selection.md +0 -50
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-resources/SKILL.md +0 -54
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-resources/references/inventory-query-patterns.md +0 -49
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-resources/references/operational-checklist.md +0 -24
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-storage/SKILL.md +0 -35
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-storage/references/security-and-governance.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-storage/references/service-auth-and-sdk-boundary.md +0 -33
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-storage/references/storage-selection.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-validate/SKILL.md +0 -49
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-validate/references/operational-checklist.md +0 -24
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-azure-validate/references/preflight-evidence.md +0 -43
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-bicep-patterns/SKILL.md +0 -41
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-bicep-patterns/references/avm-and-codegen-acceptance.md +0 -11
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-bicep-patterns/references/codegen-acceptance-checklist.md +0 -46
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-bicep-patterns/references/compiler-and-provider-gotchas.md +0 -74
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-bicep-patterns/references/module-interfaces-and-parameters.md +0 -56
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-bicep-patterns/references/network-and-observability.md +0 -52
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-codegen/SKILL.md +0 -32
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-entra-app-registration/SKILL.md +0 -53
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-entra-app-registration/references/capability-receipts.md +0 -21
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-entra-app-registration/references/design-and-diagnostics.md +0 -36
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-entra-app-registration/references/oauth-registration-model.md +0 -26
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-entra-app-registration/references/permissions-and-credentials.md +0 -27
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-mermaid/SKILL.md +0 -44
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-mermaid/references/styling.md +0 -33
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-mermaid/references/syntax.md +0 -99
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-microsoft-docs/SKILL.md +0 -53
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-microsoft-docs/references/research-method.md +0 -91
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-operations/SKILL.md +0 -34
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-planning/SKILL.md +0 -36
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-requirements/SKILL.md +0 -46
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-import/SKILL.md +0 -47
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-import/references/adoption-attestation.md +0 -10
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-import/references/import-assessment.md +0 -14
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-import/references/import-mapping.md +0 -27
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-import/references/mapping-and-adoption-attestation.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-patterns/SKILL.md +0 -49
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-patterns/references/module-composition-and-refactor.md +0 -20
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-patterns/references/module-composition-and-state-boundaries.md +0 -11
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-patterns/references/module-locks-and-codegen-acceptance.md +0 -14
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-patterns/references/network-and-observability.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-patterns/references/plan-and-change-assessment.md +0 -24
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-test/SKILL.md +0 -45
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-test/references/evidence-acceptance.md +0 -10
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-test/references/plan-mode-and-mock-design.md +0 -12
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-test/references/plan-mode-test-design.md +0 -23
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-terraform-test/references/test-design.md +0 -13
- package/assets/client-projections/github-copilot-vscode/.github/skills/apex-workflow/SKILL.md +0 -37
- package/assets/client-projections/github-copilot-vscode/.vscode/mcp.json +0 -29
- package/assets/customizations/.github/agents/apex-architect.agent.md +0 -93
- package/assets/customizations/.github/agents/apex-operator.agent.md +0 -72
- package/assets/customizations/.github/agents/apex-planner.agent.md +0 -91
- package/assets/customizations/.github/agents/apex-requirements.agent.md +0 -101
- package/assets/customizations/.github/agents/apex-reviewer.agent.md +0 -60
- package/assets/customizations/.github/mcp.json +0 -65
- package/assets/customizations/.github/skills/apex-azure-prepare/references/functions-recipe-pack.md +0 -27
- package/assets/customizations/.vscode/mcp.json +0 -29
- package/dist/azure-mcp-environment.d.ts +0 -2
- package/dist/azure-mcp-environment.js +0 -7
- package/dist/azure-mcp.d.ts +0 -2
- package/dist/azure-mcp.js +0 -21
|
@@ -1,6 +1,195 @@
|
|
|
1
|
-
import { ArchitectureV1Schema, GovernanceConstraintsV1Schema, IacBindingV1Schema, ImplementationIntentV1Schema, PolicyPropertyMapV1Schema, RequirementsV1Schema, WorkloadDecisionManifestV1Schema, SECRET_FIELD_PATTERN, SECRET_VALUE_PATTERN, hasValidCostArithmetic, } from "@apexops/contracts";
|
|
1
|
+
import { ArchitectureV1Schema, GovernanceConstraintsV1Schema, IacBindingV1Schema, ImplementationIntentV1Schema, PolicyPropertyMapV1Schema, RequirementsV1Schema, WorkloadDecisionManifestV1Schema, SECRET_FIELD_PATTERN, SECRET_VALUE_PATTERN, hasValidCostArithmetic, isGovernanceObservationCurrent, } from "@apexops/contracts";
|
|
2
2
|
import { WORKFLOW_VALIDATOR_OWNERSHIP, sha256Json, } from "@apexops/kernel";
|
|
3
3
|
import { evaluateQualityScorecard } from "@apexops/renderers";
|
|
4
|
+
import { Value } from "@sinclair/typebox/value";
|
|
5
|
+
const bicepResourceGroupScopePattern = /^\/subscriptions\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/resourceGroups\/[A-Za-z0-9_()-][A-Za-z0-9_.()-]*$(?![\s\S])/i;
|
|
6
|
+
const bicepPhysicalResourcesSchema = IacBindingV1Schema.properties.resourceBindings.patternProperties["^(.*)$"].properties.physicalResources;
|
|
7
|
+
function exactBicepPhysicalResourceType(resourceId, targetScope) {
|
|
8
|
+
if (!resourceId.toLowerCase().startsWith(`${targetScope}/providers/`.toLowerCase()))
|
|
9
|
+
return undefined;
|
|
10
|
+
const segments = resourceId.slice(targetScope.length + 1).split("/");
|
|
11
|
+
if (segments.some((segment) => !/^[A-Za-z0-9_()-][A-Za-z0-9_.()-]*$/.test(segment)))
|
|
12
|
+
return undefined;
|
|
13
|
+
let offset = 0;
|
|
14
|
+
let resourceType;
|
|
15
|
+
while (offset < segments.length) {
|
|
16
|
+
if (segments[offset].toLowerCase() !== "providers" ||
|
|
17
|
+
!/^Microsoft\.[A-Za-z0-9.]+$/i.test(segments[offset + 1] ?? ""))
|
|
18
|
+
return undefined;
|
|
19
|
+
const namespace = segments[offset + 1];
|
|
20
|
+
offset += 2;
|
|
21
|
+
const types = [];
|
|
22
|
+
while (offset < segments.length && segments[offset].toLowerCase() !== "providers") {
|
|
23
|
+
if (!/^[A-Za-z][A-Za-z0-9]*$/.test(segments[offset]) || segments[offset + 1] === undefined)
|
|
24
|
+
return undefined;
|
|
25
|
+
types.push(segments[offset]);
|
|
26
|
+
offset += 2;
|
|
27
|
+
}
|
|
28
|
+
if (types.length === 0)
|
|
29
|
+
return undefined;
|
|
30
|
+
resourceType = `${namespace}/${types.join("/")}`;
|
|
31
|
+
}
|
|
32
|
+
return resourceType;
|
|
33
|
+
}
|
|
34
|
+
function bicepPhysicalResourceIssues(binding, intentType, targetScope, path, physicalIds) {
|
|
35
|
+
const physicalResources = binding.physicalResources;
|
|
36
|
+
if (!binding.implementation.startsWith("avm:") ||
|
|
37
|
+
physicalResources === undefined ||
|
|
38
|
+
!Value.Check(bicepPhysicalResourcesSchema, physicalResources)) {
|
|
39
|
+
return [
|
|
40
|
+
{ path, message: "Bicep module ownership is unresolved; AVM requires a bounded exact physical resource map" },
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
if (!bicepResourceGroupScopePattern.test(targetScope)) {
|
|
44
|
+
return [{ path, message: "AVM ownership requires an exact resource-group scope" }];
|
|
45
|
+
}
|
|
46
|
+
const issues = [];
|
|
47
|
+
const primary = physicalResources.filter(({ role }) => role === "primary");
|
|
48
|
+
if (primary.length !== 1 ||
|
|
49
|
+
primary[0].ownership !== "managed" ||
|
|
50
|
+
primary[0].type.toLowerCase() !== intentType.toLowerCase()) {
|
|
51
|
+
issues.push({ path, message: "AVM ownership requires exactly one managed primary of the intent type" });
|
|
52
|
+
}
|
|
53
|
+
for (const { resourceId, type } of physicalResources) {
|
|
54
|
+
if (exactBicepPhysicalResourceType(resourceId, targetScope)?.toLowerCase() !== type.toLowerCase()) {
|
|
55
|
+
issues.push({ path, message: "AVM ownership requires exact target RG resource IDs with matching ARM types" });
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const normalizedId = resourceId.toLowerCase();
|
|
59
|
+
if (physicalIds.has(normalizedId)) {
|
|
60
|
+
issues.push({ path, message: "Bicep bindings resolve to duplicate resource IDs" });
|
|
61
|
+
}
|
|
62
|
+
physicalIds.add(normalizedId);
|
|
63
|
+
}
|
|
64
|
+
return issues;
|
|
65
|
+
}
|
|
66
|
+
export function resolveNativeBicepResourceOwnership(context) {
|
|
67
|
+
const { intent, binding, manifest, targetScope } = context;
|
|
68
|
+
const issues = [];
|
|
69
|
+
const resourceIdsByLogicalId = Object.create(null);
|
|
70
|
+
const expectedResourceIds = [];
|
|
71
|
+
const protectedResourceIds = [];
|
|
72
|
+
if (!bicepResourceGroupScopePattern.test(targetScope)) {
|
|
73
|
+
issues.push({ path: "/targetScope", message: "Native Bicep ownership requires an exact resource-group scope" });
|
|
74
|
+
}
|
|
75
|
+
const intentIds = intent.resources.map(({ id }) => id).sort();
|
|
76
|
+
if (binding.track !== "bicep" ||
|
|
77
|
+
manifest.track !== "bicep" ||
|
|
78
|
+
binding.projectId !== intent.projectId ||
|
|
79
|
+
manifest.projectId !== intent.projectId ||
|
|
80
|
+
binding.runId !== intent.runId ||
|
|
81
|
+
manifest.runId !== intent.runId ||
|
|
82
|
+
binding.intentHash !== sha256Json(intent) ||
|
|
83
|
+
new Set(intentIds).size !== intentIds.length ||
|
|
84
|
+
JSON.stringify(Object.keys(binding.resourceBindings).sort()) !== JSON.stringify(intentIds) ||
|
|
85
|
+
JSON.stringify(manifest.resources.map(({ logicalId }) => logicalId).sort()) !== JSON.stringify(intentIds)) {
|
|
86
|
+
issues.push({
|
|
87
|
+
path: "/binding",
|
|
88
|
+
message: "Bicep ownership requires matching accepted intent, binding, and manifest coverage",
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
if (issues.length > 0) {
|
|
92
|
+
return { expectedResourceIds: [], resourceIdsByLogicalId, protectedResourceIds, issues };
|
|
93
|
+
}
|
|
94
|
+
const manifestResources = new Map(manifest.resources.map((resource) => [resource.logicalId, resource]));
|
|
95
|
+
const physicalIds = new Set();
|
|
96
|
+
const orderedResources = [
|
|
97
|
+
...intent.resources.filter(({ id }) => binding.resourceBindings[id].scopeLogicalId === undefined),
|
|
98
|
+
...intent.resources.filter(({ id }) => binding.resourceBindings[id].scopeLogicalId !== undefined),
|
|
99
|
+
];
|
|
100
|
+
for (const resource of orderedResources) {
|
|
101
|
+
const resourceBinding = binding.resourceBindings[resource.id];
|
|
102
|
+
const entry = manifestResources.get(resource.id);
|
|
103
|
+
const path = `/binding/resourceBindings/${resource.id}`;
|
|
104
|
+
if (entry.type !== resource.type || entry.implementationAddress !== resourceBinding.implementation) {
|
|
105
|
+
issues.push({ path, message: "Manifest resource does not match the accepted binding and type" });
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const scopeId = resourceBinding.scopeLogicalId;
|
|
109
|
+
if (scopeId !== undefined &&
|
|
110
|
+
(resource.type.toLowerCase() !== "microsoft.insights/diagnosticsettings" ||
|
|
111
|
+
!resourceBinding.implementation.startsWith("native:Microsoft.Insights/diagnosticSettings@") ||
|
|
112
|
+
!resource.dependsOn.includes(scopeId) ||
|
|
113
|
+
scopeId === resource.id ||
|
|
114
|
+
binding.resourceBindings[scopeId]?.scopeLogicalId !== undefined ||
|
|
115
|
+
!binding.resourceBindings[scopeId]?.implementation.startsWith("native:") ||
|
|
116
|
+
manifestResources.get(scopeId)?.ownership !== "managed" ||
|
|
117
|
+
entry.ownership !== "managed" ||
|
|
118
|
+
!Object.hasOwn(resourceIdsByLogicalId, scopeId) ||
|
|
119
|
+
Object.hasOwn(resourceBinding.parameters, "scope") ||
|
|
120
|
+
Object.hasOwn(resourceBinding.parameters, "parent"))) {
|
|
121
|
+
issues.push({ path, message: "Diagnostic scope requires an exactly resolved managed native dependency" });
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (resourceBinding.implementation.startsWith("avm:") || entry.implementationKind === "module") {
|
|
125
|
+
if (entry.ownership !== "managed" || entry.implementationKind !== "module") {
|
|
126
|
+
issues.push({
|
|
127
|
+
path,
|
|
128
|
+
message: "Bicep module ownership is unresolved; only managed AVM logical modules are supported",
|
|
129
|
+
});
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const mapIssues = bicepPhysicalResourceIssues(resourceBinding, resource.type, targetScope, path, physicalIds);
|
|
133
|
+
issues.push(...mapIssues);
|
|
134
|
+
if (mapIssues.length > 0)
|
|
135
|
+
continue;
|
|
136
|
+
for (const { resourceId, ownership, role } of resourceBinding.physicalResources) {
|
|
137
|
+
if (ownership === "existing")
|
|
138
|
+
protectedResourceIds.push(resourceId);
|
|
139
|
+
else {
|
|
140
|
+
expectedResourceIds.push(resourceId);
|
|
141
|
+
if (role === "primary")
|
|
142
|
+
resourceIdsByLogicalId[resource.id] = resourceId;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (resourceBinding.physicalResources !== undefined) {
|
|
148
|
+
issues.push({ path, message: "Physical resource maps are not supported on native Bicep declarations" });
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const descriptor = /^native:(Microsoft\.[A-Za-z0-9.]+(?:\/[A-Za-z][A-Za-z0-9]*)+)@([0-9]{4}-[0-9]{2}-[0-9]{2}(?:-preview)?)$/.exec(resourceBinding.implementation);
|
|
152
|
+
const { name, parentId } = resourceBinding.parameters;
|
|
153
|
+
const typeSegments = descriptor?.[1]?.split("/") ?? [];
|
|
154
|
+
const nameSegments = typeof name === "string" ? name.split("/") : [];
|
|
155
|
+
if (descriptor === null ||
|
|
156
|
+
descriptor[1].toLowerCase() !== resource.type.toLowerCase() ||
|
|
157
|
+
resourceBinding.version !== descriptor[2] ||
|
|
158
|
+
typeof name !== "string" ||
|
|
159
|
+
nameSegments.length !== typeSegments.length - 1 ||
|
|
160
|
+
nameSegments.some((segment) => !/^[A-Za-z0-9][A-Za-z0-9_.-]*$(?![\s\S])/.test(segment)) ||
|
|
161
|
+
typeof parentId !== "string" ||
|
|
162
|
+
(parentId !== "/" && parentId.toLowerCase() !== targetScope.toLowerCase()) ||
|
|
163
|
+
(entry.ownership === "managed" && entry.implementationKind !== "resource")) {
|
|
164
|
+
issues.push({
|
|
165
|
+
path,
|
|
166
|
+
message: "Native Bicep ownership requires a matching type, exact literal name segments, and target RG parent",
|
|
167
|
+
});
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const resourceId = `${scopeId === undefined ? targetScope : resourceIdsByLogicalId[scopeId]}/providers/${typeSegments[0]}/${typeSegments
|
|
171
|
+
.slice(1)
|
|
172
|
+
.map((segment, index) => `${segment}/${nameSegments[index]}`)
|
|
173
|
+
.join("/")}`;
|
|
174
|
+
const normalizedId = resourceId.toLowerCase();
|
|
175
|
+
if (physicalIds.has(normalizedId)) {
|
|
176
|
+
issues.push({ path, message: "Bicep bindings resolve to duplicate resource IDs" });
|
|
177
|
+
}
|
|
178
|
+
physicalIds.add(normalizedId);
|
|
179
|
+
if (entry.ownership === "existing")
|
|
180
|
+
protectedResourceIds.push(resourceId);
|
|
181
|
+
else {
|
|
182
|
+
expectedResourceIds.push(resourceId);
|
|
183
|
+
resourceIdsByLogicalId[resource.id] = resourceId;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
expectedResourceIds: issues.length === 0 ? expectedResourceIds : [],
|
|
188
|
+
resourceIdsByLogicalId: issues.length === 0 ? resourceIdsByLogicalId : {},
|
|
189
|
+
protectedResourceIds,
|
|
190
|
+
issues,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
4
193
|
const VALIDATION_EVIDENCE_IDS = new Set([
|
|
5
194
|
"bicep:build",
|
|
6
195
|
"bicep:format",
|
|
@@ -12,6 +201,13 @@ const VALIDATION_EVIDENCE_IDS = new Set([
|
|
|
12
201
|
"terraform:init-backend-false",
|
|
13
202
|
"terraform:validate",
|
|
14
203
|
]);
|
|
204
|
+
const WELL_ARCHITECTED_PILLARS = [
|
|
205
|
+
"security",
|
|
206
|
+
"reliability",
|
|
207
|
+
"performance-efficiency",
|
|
208
|
+
"cost-optimization",
|
|
209
|
+
"operational-excellence",
|
|
210
|
+
];
|
|
15
211
|
function issue(path, message) {
|
|
16
212
|
return [{ path, message }];
|
|
17
213
|
}
|
|
@@ -47,6 +243,10 @@ function requirementsTraceability(value) {
|
|
|
47
243
|
if (requirements === undefined)
|
|
48
244
|
return issue("/artifacts/requirements", "Accepted requirements are required");
|
|
49
245
|
const knownIds = new Set(requirements.requirements.map(({ id }) => id));
|
|
246
|
+
const records = architecture.decisionRecords ?? [];
|
|
247
|
+
if (new Set(records.map(({ id }) => id)).size !== records.length ||
|
|
248
|
+
records.some(({ requirementIds }) => requirementIds.some((id) => !knownIds.has(id))))
|
|
249
|
+
return issue("/outputs/architecture/decisionRecords", "Decision records require unique IDs and accepted requirement references");
|
|
50
250
|
const referencedIds = architecture.components.flatMap(({ requirementIds }) => requirementIds);
|
|
51
251
|
const unknown = [...new Set(referencedIds.filter((id) => !knownIds.has(id)))].sort();
|
|
52
252
|
if (unknown.length > 0) {
|
|
@@ -61,6 +261,42 @@ function requirementsTraceability(value) {
|
|
|
61
261
|
? []
|
|
62
262
|
: issue("/outputs/architecture/components", `Uncovered confirmed must requirements: ${missing.join(", ")}`);
|
|
63
263
|
}
|
|
264
|
+
function wellArchitectedAssessmentComplete(value) {
|
|
265
|
+
const context = taskContext(value);
|
|
266
|
+
const architecture = context.outputs.architecture;
|
|
267
|
+
const requirements = context.artifacts.requirements;
|
|
268
|
+
const assessment = architecture.wellArchitectedAssessment;
|
|
269
|
+
if (requirements === undefined)
|
|
270
|
+
return issue("/artifacts/requirements", "Accepted requirements are required");
|
|
271
|
+
if (assessment === undefined) {
|
|
272
|
+
return issue("/outputs/architecture/wellArchitectedAssessment", "Well-Architected assessment is required");
|
|
273
|
+
}
|
|
274
|
+
const expectedPillars = [...WELL_ARCHITECTED_PILLARS].sort();
|
|
275
|
+
const actualPillars = assessment.pillars.map(({ pillar }) => pillar).sort();
|
|
276
|
+
if (new Set(actualPillars).size !== expectedPillars.length ||
|
|
277
|
+
JSON.stringify(actualPillars) !== JSON.stringify(expectedPillars)) {
|
|
278
|
+
return issue("/outputs/architecture/wellArchitectedAssessment/pillars", "Assessment must cover exactly the five Azure Well-Architected pillars");
|
|
279
|
+
}
|
|
280
|
+
const knownRequirementIds = new Set(requirements.requirements.map(({ id }) => id));
|
|
281
|
+
const acceptedEvidence = new Set([...context.inputRefs, ...Object.values(context.artifactHashes)]);
|
|
282
|
+
for (const pillar of assessment.pillars) {
|
|
283
|
+
if (pillar.requirementIds.length === 0 && pillar.evidenceRefs.length === 0) {
|
|
284
|
+
return issue("/outputs/architecture/wellArchitectedAssessment/pillars", `${pillar.pillar} must reference at least one accepted requirement or evidence item`);
|
|
285
|
+
}
|
|
286
|
+
const unknownRequirements = pillar.requirementIds.filter((id) => !knownRequirementIds.has(id));
|
|
287
|
+
if (unknownRequirements.length > 0) {
|
|
288
|
+
return issue("/outputs/architecture/wellArchitectedAssessment/pillars/requirementIds", `${pillar.pillar} references unknown requirements: ${unknownRequirements.join(", ")}`);
|
|
289
|
+
}
|
|
290
|
+
const unknownEvidence = pillar.evidenceRefs.filter((hash) => !acceptedEvidence.has(hash));
|
|
291
|
+
if (unknownEvidence.length > 0) {
|
|
292
|
+
return issue("/outputs/architecture/wellArchitectedAssessment/pillars/evidenceRefs", `${pillar.pillar} references evidence not accepted for this task`);
|
|
293
|
+
}
|
|
294
|
+
if ((pillar.status === "concern" || pillar.status === "blocker") && pillar.recommendations.length === 0) {
|
|
295
|
+
return issue("/outputs/architecture/wellArchitectedAssessment/pillars/recommendations", `${pillar.pillar} ${pillar.status} requires a recommendation`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return [];
|
|
299
|
+
}
|
|
64
300
|
function costArithmetic(value) {
|
|
65
301
|
const estimate = taskContext(value).outputs["cost-estimate"];
|
|
66
302
|
return hasValidCostArithmetic(estimate) ? [] : issue("/outputs/cost-estimate", "Cost arithmetic does not reconcile");
|
|
@@ -101,13 +337,20 @@ function workloadDecisionCoverage(value) {
|
|
|
101
337
|
for (const decision of manifest.skuDecisions) {
|
|
102
338
|
const component = components.get(decision.logicalId);
|
|
103
339
|
const costMatches = estimate.lineItems.filter((line) => line.service === decision.service && line.sku === decision.sku && line.quantity === decision.quantity);
|
|
340
|
+
const unavailableMatches = (estimate.unpricedItems ?? []).filter((line) => line.service === decision.service && line.sku === decision.sku && line.quantity === decision.quantity);
|
|
104
341
|
if (component === undefined ||
|
|
105
342
|
component.service !== decision.service ||
|
|
106
343
|
!decision.requirementIds.every((id) => component.requirementIds.includes(id)) ||
|
|
107
|
-
costMatches.length !== 1) {
|
|
344
|
+
costMatches.length + unavailableMatches.length !== 1) {
|
|
108
345
|
return issue("/outputs/workload-decision-manifest/skuDecisions", `SKU decision ${decision.id} is not architecture and cost traceable`);
|
|
109
346
|
}
|
|
110
347
|
}
|
|
348
|
+
const unpricedItems = estimate.unpricedItems ?? [];
|
|
349
|
+
if ((unpricedItems.length > 0 && estimate.pricingStatus !== "partial") ||
|
|
350
|
+
(unpricedItems.length === 0 && estimate.pricingStatus === "partial") ||
|
|
351
|
+
estimate.lineItems.length + unpricedItems.length === 0) {
|
|
352
|
+
return issue("/outputs/cost-estimate", "Partial pricing requires explicit unpriced items; complete pricing requires priced line items");
|
|
353
|
+
}
|
|
111
354
|
for (const decision of manifest.sloDecisions) {
|
|
112
355
|
const component = components.get(decision.logicalId);
|
|
113
356
|
if (component === undefined || !decision.requirementIds.every((id) => component.requirementIds.includes(id))) {
|
|
@@ -116,53 +359,6 @@ function workloadDecisionCoverage(value) {
|
|
|
116
359
|
}
|
|
117
360
|
return [];
|
|
118
361
|
}
|
|
119
|
-
function availabilityCurrent(value) {
|
|
120
|
-
const context = taskContext(value);
|
|
121
|
-
const evidence = context.availabilityEvidence;
|
|
122
|
-
if (evidence === undefined)
|
|
123
|
-
return issue("/availabilityEvidence", "Current architecture availability evidence is required");
|
|
124
|
-
const architecture = context.outputs.architecture;
|
|
125
|
-
const issues = [];
|
|
126
|
-
if (evidence.projectId !== architecture.projectId ||
|
|
127
|
-
evidence.runId !== architecture.runId ||
|
|
128
|
-
evidence.targetScope !== context.targetScope) {
|
|
129
|
-
issues.push({
|
|
130
|
-
path: "/availabilityEvidence",
|
|
131
|
-
message: "Availability evidence does not match the architecture run",
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
const missingSourceRefs = Object.values(evidence.checks)
|
|
135
|
-
.map(({ evidenceRef }) => evidenceRef)
|
|
136
|
-
.filter((reference) => !context.inputRefs.includes(reference))
|
|
137
|
-
.sort();
|
|
138
|
-
if (missingSourceRefs.length > 0) {
|
|
139
|
-
issues.push({
|
|
140
|
-
path: "/availabilityEvidence/checks",
|
|
141
|
-
message: `Availability source evidence was not pinned to the task: ${missingSourceRefs.join(", ")}`,
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
const now = Date.parse(context.now);
|
|
145
|
-
if (Date.parse(evidence.collectedAt) > now) {
|
|
146
|
-
issues.push({
|
|
147
|
-
path: "/availabilityEvidence/collectedAt",
|
|
148
|
-
message: "Architecture availability evidence has a future collection timestamp",
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
if (Date.parse(evidence.expiresAt) <= now) {
|
|
152
|
-
issues.push({ path: "/availabilityEvidence/expiresAt", message: "Architecture availability evidence is expired" });
|
|
153
|
-
}
|
|
154
|
-
const unavailable = Object.entries(evidence.checks)
|
|
155
|
-
.filter(([, check]) => check.status !== "current")
|
|
156
|
-
.map(([name]) => name)
|
|
157
|
-
.sort();
|
|
158
|
-
if (unavailable.length > 0) {
|
|
159
|
-
issues.push({
|
|
160
|
-
path: "/availabilityEvidence/checks",
|
|
161
|
-
message: `Architecture availability checks are not current: ${unavailable.join(", ")}`,
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
return issues;
|
|
165
|
-
}
|
|
166
362
|
function governanceCompleteness(value) {
|
|
167
363
|
const governance = taskContext(value).outputs["governance-constraints"];
|
|
168
364
|
const discoveredItems = Object.values(governance.summary).reduce((total, count) => total + count, 0);
|
|
@@ -173,6 +369,11 @@ function governanceCompleteness(value) {
|
|
|
173
369
|
function governanceFreshness(value) {
|
|
174
370
|
const context = taskContext(value);
|
|
175
371
|
const governance = context.outputs["governance-constraints"];
|
|
372
|
+
if (governance.constraintsRef.uri === `apex-object:${governance.constraintsRef.digest}`) {
|
|
373
|
+
return isGovernanceObservationCurrent(governance.discoveredAt, context.now)
|
|
374
|
+
? []
|
|
375
|
+
: issue("/outputs/governance-constraints/discoveredAt", "Governance snapshot requires refresh at 30 days");
|
|
376
|
+
}
|
|
176
377
|
const now = Date.parse(context.now);
|
|
177
378
|
if (Date.parse(governance.discoveredAt) > now) {
|
|
178
379
|
return issue("/outputs/governance-constraints/discoveredAt", "Governance discovery is from the future");
|
|
@@ -191,11 +392,17 @@ function policyEffectCoverage(value) {
|
|
|
191
392
|
const counts = new Map();
|
|
192
393
|
for (const mapping of policyMap.mappings)
|
|
193
394
|
counts.set(mapping.effect, (counts.get(mapping.effect) ?? 0) + 1);
|
|
194
|
-
const
|
|
195
|
-
[
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
395
|
+
const requiredCounts = context.importedPolicyEffects === undefined
|
|
396
|
+
? [
|
|
397
|
+
["deny", governance.summary.denyCount],
|
|
398
|
+
["modify", governance.summary.modifyCount],
|
|
399
|
+
["audit", governance.summary.auditCount],
|
|
400
|
+
]
|
|
401
|
+
: ["deny", "modify", "deployIfNotExists"].map((effect) => [
|
|
402
|
+
effect,
|
|
403
|
+
context.importedPolicyEffects.filter((value) => value === effect).length,
|
|
404
|
+
]);
|
|
405
|
+
const missing = requiredCounts.flatMap(([effect, required]) => (counts.get(effect) ?? 0) < required ? [effect] : []);
|
|
199
406
|
return missing.length === 0
|
|
200
407
|
? []
|
|
201
408
|
: issue("/outputs/policy-property-map/mappings", `Missing policy effect coverage: ${missing.join(", ")}`);
|
|
@@ -205,9 +412,27 @@ function planSourceCoverage(value) {
|
|
|
205
412
|
const intent = context.outputs["implementation-intent"];
|
|
206
413
|
const requiredSources = ["requirements", "architecture", "governance-constraints", "policy-property-map"].filter((kind) => context.artifactHashes[kind] !== undefined);
|
|
207
414
|
const invalid = requiredSources.filter((kind) => intent.sourceHashes[kind] !== context.artifactHashes[kind]);
|
|
208
|
-
|
|
415
|
+
const issues = invalid.length === 0
|
|
209
416
|
? []
|
|
210
417
|
: issue("/outputs/implementation-intent/sourceHashes", `Missing or stale source hashes: ${invalid.join(", ")}`);
|
|
418
|
+
const policy = context.artifacts["policy-property-map"];
|
|
419
|
+
if (context.artifactHashes["policy-property-map"] !== undefined && policy === undefined) {
|
|
420
|
+
issues.push({ path: "/artifacts/policy-property-map", message: "Accepted policy mappings are required" });
|
|
421
|
+
}
|
|
422
|
+
const resources = new Set(intent.resources.map(({ id }) => id));
|
|
423
|
+
for (const mapping of policy?.mappings ?? []) {
|
|
424
|
+
if (mapping.disposition !== "not-applicable" && !resources.has(mapping.logicalResourceId))
|
|
425
|
+
issues.push({
|
|
426
|
+
path: "/outputs/implementation-intent/resources",
|
|
427
|
+
message: "Policy mapping references a resource absent from the plan",
|
|
428
|
+
});
|
|
429
|
+
if (mapping.disposition === "blocked")
|
|
430
|
+
issues.push({
|
|
431
|
+
path: "/artifacts/policy-property-map/mappings",
|
|
432
|
+
message: "Blocked policy controls must be resolved before plan acceptance",
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
return issues;
|
|
211
436
|
}
|
|
212
437
|
function bindingTrackMatch(value) {
|
|
213
438
|
const context = taskContext(value);
|
|
@@ -215,12 +440,46 @@ function bindingTrackMatch(value) {
|
|
|
215
440
|
const binding = context.outputs["iac-binding"];
|
|
216
441
|
const resourceIds = new Set(intent.resources.map(({ id }) => id));
|
|
217
442
|
const bindingIds = Object.keys(binding.resourceBindings);
|
|
218
|
-
|
|
443
|
+
const issues = binding.track === context.track &&
|
|
219
444
|
binding.intentHash === sha256Json(intent) &&
|
|
220
445
|
bindingIds.length === resourceIds.size &&
|
|
221
446
|
bindingIds.every((id) => resourceIds.has(id))
|
|
222
447
|
? []
|
|
223
448
|
: issue("/outputs/iac-binding", "IaC binding track, intent, or resource coverage is invalid");
|
|
449
|
+
if (Object.values(binding.resourceBindings).some(({ physicalResources, scopeLogicalId }) => physicalResources !== undefined || scopeLogicalId !== undefined)) {
|
|
450
|
+
if (binding.track !== "bicep") {
|
|
451
|
+
issues.push({
|
|
452
|
+
path: "/outputs/iac-binding",
|
|
453
|
+
message: "Exact physical resource maps and diagnostic scope references are supported only for Bicep bindings",
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
else if (issues.length === 0) {
|
|
457
|
+
issues.push(...resolveNativeBicepResourceOwnership({
|
|
458
|
+
intent,
|
|
459
|
+
binding,
|
|
460
|
+
targetScope: context.targetScope,
|
|
461
|
+
manifest: {
|
|
462
|
+
schemaVersion: "1.0.0",
|
|
463
|
+
projectId: intent.projectId,
|
|
464
|
+
runId: intent.runId,
|
|
465
|
+
track: "bicep",
|
|
466
|
+
resources: intent.resources.map((resource) => ({
|
|
467
|
+
logicalId: resource.id,
|
|
468
|
+
type: resource.type,
|
|
469
|
+
implementationAddress: binding.resourceBindings[resource.id].implementation,
|
|
470
|
+
implementationKind: binding.resourceBindings[resource.id].implementation.startsWith("avm:")
|
|
471
|
+
? "module"
|
|
472
|
+
: "resource",
|
|
473
|
+
ownership: "managed",
|
|
474
|
+
dependsOn: resource.dependsOn,
|
|
475
|
+
generatedDependencies: [],
|
|
476
|
+
sourcePath: "main.bicep",
|
|
477
|
+
})),
|
|
478
|
+
},
|
|
479
|
+
}).issues);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
return issues;
|
|
224
483
|
}
|
|
225
484
|
function dependencyAcyclic(value) {
|
|
226
485
|
const intent = taskContext(value).outputs["implementation-intent"];
|
|
@@ -267,17 +526,27 @@ function bindingCoverage(expectedTrack, value) {
|
|
|
267
526
|
const expectedIds = intent.resources.map(({ id }) => id).sort();
|
|
268
527
|
const bindingIds = Object.keys(binding.resourceBindings).sort();
|
|
269
528
|
const manifestIds = manifest.resources.map(({ logicalId }) => logicalId).sort();
|
|
529
|
+
const intentById = new Map(intent.resources.map((resource) => [resource.id, resource]));
|
|
270
530
|
return binding.track === expectedTrack &&
|
|
271
531
|
manifest.track === expectedTrack &&
|
|
272
532
|
JSON.stringify(bindingIds) === JSON.stringify(expectedIds) &&
|
|
273
|
-
JSON.stringify(manifestIds) === JSON.stringify(expectedIds)
|
|
533
|
+
JSON.stringify(manifestIds) === JSON.stringify(expectedIds) &&
|
|
534
|
+
manifest.resources.every((resource) => {
|
|
535
|
+
const approved = intentById.get(resource.logicalId);
|
|
536
|
+
const implementation = binding.resourceBindings[resource.logicalId];
|
|
537
|
+
return (approved !== undefined &&
|
|
538
|
+
implementation !== undefined &&
|
|
539
|
+
resource.type === approved.type &&
|
|
540
|
+
resource.implementationAddress === implementation.implementation &&
|
|
541
|
+
JSON.stringify([...resource.dependsOn].sort()) === JSON.stringify([...approved.dependsOn].sort()));
|
|
542
|
+
})
|
|
274
543
|
? []
|
|
275
544
|
: issue("/outputs/logical-resource-manifest", `${expectedTrack} binding coverage is incomplete`);
|
|
276
545
|
}
|
|
277
546
|
function comprehensiveReview(expectedNode, value) {
|
|
278
547
|
const context = taskContext(value);
|
|
279
548
|
const review = context.outputs["review-findings"];
|
|
280
|
-
const subjectKind = expectedNode
|
|
549
|
+
const subjectKind = expectedNode;
|
|
281
550
|
const artifactKind = subjectKind === "plan" ? "implementation-intent" : subjectKind;
|
|
282
551
|
const expectedHash = context.artifactHashes[artifactKind];
|
|
283
552
|
const findingIds = review.findings.map(({ id }) => id);
|
|
@@ -288,6 +557,41 @@ function comprehensiveReview(expectedNode, value) {
|
|
|
288
557
|
? []
|
|
289
558
|
: issue("/outputs/review-findings", `Review does not bind the accepted ${subjectKind} artifact`);
|
|
290
559
|
}
|
|
560
|
+
function wellArchitectedCriteriaComplete(value) {
|
|
561
|
+
const context = taskContext(value);
|
|
562
|
+
const review = context.outputs["review-findings"];
|
|
563
|
+
const architecture = context.artifacts.architecture;
|
|
564
|
+
if (architecture?.wellArchitectedAssessment === undefined) {
|
|
565
|
+
return issue("/artifacts/architecture/wellArchitectedAssessment", "Accepted Well-Architected assessment is required");
|
|
566
|
+
}
|
|
567
|
+
const criteria = review.criteria;
|
|
568
|
+
if (criteria === undefined) {
|
|
569
|
+
return issue("/outputs/review-findings/criteria", "Well-Architected review criteria are required");
|
|
570
|
+
}
|
|
571
|
+
const expectedPillars = [...WELL_ARCHITECTED_PILLARS].sort();
|
|
572
|
+
const actualPillars = criteria.map(({ criterionId }) => criterionId).sort();
|
|
573
|
+
if (new Set(actualPillars).size !== expectedPillars.length ||
|
|
574
|
+
JSON.stringify(actualPillars) !== JSON.stringify(expectedPillars)) {
|
|
575
|
+
return issue("/outputs/review-findings/criteria", "Review must cover exactly the five Azure Well-Architected pillars");
|
|
576
|
+
}
|
|
577
|
+
const findingIds = new Set(review.findings.map(({ id }) => id));
|
|
578
|
+
const statusByPillar = new Map(architecture.wellArchitectedAssessment.pillars.map(({ pillar, status }) => [pillar, status]));
|
|
579
|
+
for (const criterion of criteria) {
|
|
580
|
+
if (criterion.findingIds.some((id) => !findingIds.has(id))) {
|
|
581
|
+
return issue("/outputs/review-findings/criteria/findingIds", `${criterion.criterionId} references an unknown finding`);
|
|
582
|
+
}
|
|
583
|
+
if (criterion.outcome === "finding" && criterion.findingIds.length === 0) {
|
|
584
|
+
return issue("/outputs/review-findings/criteria/findingIds", `${criterion.criterionId} requires a linked finding`);
|
|
585
|
+
}
|
|
586
|
+
if (criterion.outcome === "pass" && criterion.findingIds.length > 0) {
|
|
587
|
+
return issue("/outputs/review-findings/criteria/findingIds", `${criterion.criterionId} pass cannot link findings`);
|
|
588
|
+
}
|
|
589
|
+
if (criterion.outcome === "not-applicable" && statusByPillar.get(criterion.criterionId) !== "not-applicable") {
|
|
590
|
+
return issue("/outputs/review-findings/criteria/outcome", `${criterion.criterionId} can be not applicable only when the accepted assessment is not applicable`);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return [];
|
|
594
|
+
}
|
|
291
595
|
function requiredValidationEvidence(id, value) {
|
|
292
596
|
const evidence = value;
|
|
293
597
|
const matches = evidence.entries.filter(({ kind }) => kind === id);
|
|
@@ -306,8 +610,8 @@ function gateReady(expectedGate, value) {
|
|
|
306
610
|
3: ["implementation-intent", "iac-binding", "environment-inputs"],
|
|
307
611
|
};
|
|
308
612
|
const requiredReviews = {
|
|
309
|
-
1:
|
|
310
|
-
2: ["architecture-review"
|
|
613
|
+
1: ["requirements-review"],
|
|
614
|
+
2: ["architecture-review"],
|
|
311
615
|
3: ["plan-review"],
|
|
312
616
|
};
|
|
313
617
|
const issues = [];
|
|
@@ -434,8 +738,9 @@ function previewCoverage(value) {
|
|
|
434
738
|
const context = previewContext(value);
|
|
435
739
|
const changes = context.preview.changes;
|
|
436
740
|
const resourceIds = changes.map(({ resourceId }) => resourceId);
|
|
437
|
-
const issues = [];
|
|
438
|
-
|
|
741
|
+
const issues = [...(context.ownershipIssues ?? [])];
|
|
742
|
+
const uniqueIds = context.provider === "bicep" ? resourceIds.map((id) => id.toLowerCase()) : resourceIds;
|
|
743
|
+
if (new Set(uniqueIds).size !== resourceIds.length) {
|
|
439
744
|
issues.push({ path: "/changes", message: "Preview contains duplicate resource changes" });
|
|
440
745
|
}
|
|
441
746
|
if (changes.some(({ action }) => action === "unknown")) {
|
|
@@ -448,6 +753,32 @@ function previewCoverage(value) {
|
|
|
448
753
|
issues.push({ path: "/changes", message: "Fake preview does not cover every requested resource" });
|
|
449
754
|
}
|
|
450
755
|
}
|
|
756
|
+
if (context.provider === "terraform") {
|
|
757
|
+
const managedAddresses = new Set(context.expectedResourceIds);
|
|
758
|
+
if (changes.some(({ resourceId, action, material }) => (action !== "no-op" || material) && !managedAddresses.has(resourceId))) {
|
|
759
|
+
issues.push({
|
|
760
|
+
path: "/changes",
|
|
761
|
+
message: "Terraform preview would modify a resource outside accepted managed ownership",
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
if (context.provider === "bicep") {
|
|
766
|
+
const protectedIds = (context.protectedResourceIds ?? []).map((id) => id.toLowerCase());
|
|
767
|
+
if (changes.some(({ resourceId, action }) => (action === "delete" || action === "replace") &&
|
|
768
|
+
protectedIds.some((id) => id === resourceId.toLowerCase() || id.startsWith(`${resourceId.toLowerCase()}/`)))) {
|
|
769
|
+
issues.push({
|
|
770
|
+
path: "/changes",
|
|
771
|
+
message: "Bicep destructive operation would remove a protected existing resource or its ancestor",
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
const managedIds = new Set(context.expectedResourceIds.map((id) => id.toLowerCase()));
|
|
775
|
+
if (changes.some(({ resourceId, action, material }) => (action !== "no-op" || material) && !managedIds.has(resourceId.toLowerCase()))) {
|
|
776
|
+
issues.push({
|
|
777
|
+
path: "/changes",
|
|
778
|
+
message: "Bicep preview would modify a resource outside accepted managed ownership",
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
}
|
|
451
782
|
return issues;
|
|
452
783
|
}
|
|
453
784
|
function previewFreshness(value) {
|
|
@@ -473,6 +804,7 @@ function terraformSavedPlanBinding(value) {
|
|
|
473
804
|
lockfileHash: attestation.lockfileHash,
|
|
474
805
|
recipient: attestation.recipient,
|
|
475
806
|
artifactRef: attestation.artifactRef,
|
|
807
|
+
...(context.policyValidationBinding === undefined ? {} : { policyValidation: context.policyValidationBinding }),
|
|
476
808
|
});
|
|
477
809
|
const valid = attestation.projectId === preview.projectId &&
|
|
478
810
|
attestation.runId === preview.runId &&
|
|
@@ -587,7 +919,7 @@ function inventorySecretFree(value) {
|
|
|
587
919
|
function inventorySourceCoverage(value) {
|
|
588
920
|
const context = inventoryContext(value);
|
|
589
921
|
const inventory = context.inventory;
|
|
590
|
-
const resourceIds = inventory.resources.map(({ resourceId }) => resourceId);
|
|
922
|
+
const resourceIds = inventory.resources.map(({ resourceId }) => /^\/subscriptions\//i.test(resourceId) ? resourceId.toLowerCase() : resourceId);
|
|
591
923
|
const logicalIds = inventory.resources.map(({ logicalId }) => logicalId);
|
|
592
924
|
const issues = [];
|
|
593
925
|
if (new Set(resourceIds).size !== resourceIds.length || new Set(logicalIds).size !== logicalIds.length) {
|
|
@@ -596,7 +928,9 @@ function inventorySourceCoverage(value) {
|
|
|
596
928
|
const expected = context.preview.changes
|
|
597
929
|
.filter(({ material, action }) => material && action !== "delete" && action !== "no-op")
|
|
598
930
|
.map(({ resourceId }) => resourceId);
|
|
599
|
-
const missing = expected.filter((expectedId) => !inventory.resources.some(({ logicalId, resourceId }) =>
|
|
931
|
+
const missing = expected.filter((expectedId) => !inventory.resources.some(({ logicalId, resourceId }) => /^\/subscriptions\//i.test(expectedId)
|
|
932
|
+
? resourceId.toLowerCase() === expectedId.toLowerCase()
|
|
933
|
+
: logicalId === expectedId || resourceId === expectedId || resourceId.endsWith(`:${expectedId}`)));
|
|
600
934
|
if (missing.length > 0) {
|
|
601
935
|
issues.push({
|
|
602
936
|
path: "/inventory/resources",
|
|
@@ -637,7 +971,13 @@ function diagnosisReadOnly(value) {
|
|
|
637
971
|
message: "Diagnosis is not a read-only observation of current inventory",
|
|
638
972
|
});
|
|
639
973
|
}
|
|
640
|
-
const
|
|
974
|
+
const checks = diagnosis.operationalHandoff?.healthChecks ?? [];
|
|
975
|
+
if (checks.some(({ resourceId }) => !inventory.resources.some((resource) => resource.resourceId === resourceId)))
|
|
976
|
+
issues.push({
|
|
977
|
+
path: "/outputs/diagnosis/operationalHandoff/healthChecks",
|
|
978
|
+
message: "Health checks must reference recorded inventory resources",
|
|
979
|
+
});
|
|
980
|
+
const unpinned = [...diagnosis.causes, ...checks]
|
|
641
981
|
.flatMap(({ evidenceRefs }) => evidenceRefs)
|
|
642
982
|
.filter((reference) => !context.inputRefs.includes(reference))
|
|
643
983
|
.sort();
|
|
@@ -762,9 +1102,10 @@ export function registerWorkflowValidators(registry) {
|
|
|
762
1102
|
registry.register("schema:iac-binding-v1", IacBindingV1Schema);
|
|
763
1103
|
registry.registerHandler("business:requirements-completeness", requirementsCompleteness);
|
|
764
1104
|
registry.registerHandler("business:requirements-traceability", requirementsTraceability);
|
|
1105
|
+
registry.registerHandler("business:well-architected-assessment-complete", wellArchitectedAssessmentComplete);
|
|
765
1106
|
registry.registerHandler("business:workload-decision-manifest-coverage", workloadDecisionCoverage);
|
|
766
1107
|
registry.registerHandler("business:cost-arithmetic", costArithmetic);
|
|
767
|
-
registry.registerHandler("business:availability-current",
|
|
1108
|
+
registry.registerHandler("business:availability-current", () => [], "freshness");
|
|
768
1109
|
registry.registerHandler("business:governance-completeness", governanceCompleteness);
|
|
769
1110
|
registry.registerHandler("business:governance-freshness", governanceFreshness, "freshness");
|
|
770
1111
|
registry.registerHandler("business:policy-effect-coverage", policyEffectCoverage);
|
|
@@ -775,7 +1116,7 @@ export function registerWorkflowValidators(registry) {
|
|
|
775
1116
|
registry.registerHandler("business:terraform-binding-coverage", (value) => bindingCoverage("terraform", value));
|
|
776
1117
|
registry.registerHandler("review:requirements-comprehensive", (value) => comprehensiveReview("requirements", value));
|
|
777
1118
|
registry.registerHandler("review:architecture-comprehensive", (value) => comprehensiveReview("architecture", value));
|
|
778
|
-
registry.registerHandler("review:
|
|
1119
|
+
registry.registerHandler("review:well-architected-criteria-complete", wellArchitectedCriteriaComplete);
|
|
779
1120
|
registry.registerHandler("review:plan-comprehensive", (value) => comprehensiveReview("plan", value));
|
|
780
1121
|
for (const id of VALIDATION_EVIDENCE_IDS) {
|
|
781
1122
|
registry.registerHandler(id, (value) => requiredValidationEvidence(id, value));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ResolvedMcpWorkspace {
|
|
2
|
+
workspace: string;
|
|
3
|
+
root: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function mcpWorkspaceRoot(start: string): Promise<string>;
|
|
6
|
+
export declare function resolveMcpWorkspace(start: string): Promise<ResolvedMcpWorkspace>;
|
|
7
|
+
//# sourceMappingURL=workspace-root.d.ts.map
|