Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 15 additions & 17 deletions plugins/azure-skills/skills/azure-validate/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,23 @@ metadata:

## Steps

| # | Action | Reference |
|---|--------|-----------|
| 1 | **Load Plan** — Read `.azure/deployment-plan.md` for recipe and configuration. If missing → run azure-prepare first | `.azure/deployment-plan.md` |
| 2 | **Add Validation Steps** — Copy recipe "Validation Steps" to `.azure/deployment-plan.md` as children of "All validation checks pass" | [recipes/README.md](references/recipes/README.md), `.azure/deployment-plan.md` |
| 3 | **Run Validation** — Execute recipe-specific validation commands | [recipes/README.md](references/recipes/README.md) |
| 4 | **Build Verification** — Build the project and fix any errors before proceeding | See recipe |
| 5 | **Static Role Verification** — Review Bicep/Terraform for correct RBAC role assignments in code | [role-verification.md](references/role-verification.md) |
| 6 | **Record Proof** — Populate **Section 7: Validation Proof** with commands run and results | `.azure/deployment-plan.md` |
| 7 | **Resolve Errors** — Fix failures before proceeding | See recipe's `errors.md` |
| 8 | **Update Status** — Only after ALL checks pass, set status to `Validated` | `.azure/deployment-plan.md` |
| 9 | **Deploy (only if the user asked to deploy)** — If the user explicitly requested deployment, invoke **azure-deploy**. Otherwise STOP and report validation results | — |
Run the workflow script and follow its instructions. It walks you through each validation step one at a time, recording progress in `.azure/validate-status.json`. Use [references/scripts/workflow.ps1](references/scripts/workflow.ps1) on Windows or [references/scripts/workflow.sh](references/scripts/workflow.sh) on macOS/Linux.

Start by calling the script **without** the completed-step argument:

```bash
pwsh references/scripts/workflow.ps1 -WorkspacePath <workspace-path>
# macOS/Linux: bash references/scripts/workflow.sh --workspace-path <workspace-path>
```

Each run prints the next action and the value to pass next. Perform the action, then re-run with that value (`-CompletedStep <value>` for pwsh, `--completed-step <value>` for bash). Repeat until it reports the azure-validate workflow is complete.

The steps reference recipe details in [references/recipes/README.md](references/recipes/README.md) and role checks in [references/role-verification.md](references/role-verification.md).

> **⛔ VALIDATION AUTHORITY**
>
> This skill is the officially verified way to set plan status to `Validated`. You MUST follow these steps to make sure every prerequisite is fulfilled before setting status to `Validated`:
> 1. Run actual validation commands (azd provision --preview, bicep build, terraform validate, etc.)
> 2. Populate **Section 7: Validation Proof** with the commands you ran and their results
> 3. Only then set status to `Validated`
>
> Do NOT set status to `Validated` without running checks and recording proof.
> This skill is the officially verified way to set plan status to `Validated`. You MUST follow the script's instructions to completion before setting status to `Validated`.
> Do NOT set status to `Validated` without doing so.

---

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<#
.SYNOPSIS
Walks the agent through the azure-validate workflow, one step at a time.
.PARAMETER WorkspacePath
Path to the workspace being validated (required).
.PARAMETER CompletedStep
The workflow step the agent just completed. Omit this on the first call to
start the workflow. The script records the value in
.azure/validate-status.json and returns the next action to take, along with
the value to pass as -CompletedStep on the next call.
#>
param(
[string]$WorkspacePath,
[string]$CompletedStep
)

enum ValidationStep {
None
LoadPlan
AddValidationSteps
RunValidation
BuildVerification
StaticRoleVerification
RecordProof
ResolveErrors
UpdateStatus
}

if (-not $WorkspacePath) {
Write-Error "WorkspacePath is required."
exit 2
}

if (-not (Test-Path -Path $WorkspacePath -PathType Container)) {
Write-Error "Error: WorkspacePath '$WorkspacePath' does not exist or is not a directory."
exit 2
}

# Resolve the step the agent just completed.
# Omitting -CompletedStep signals the start of the workflow (None).
$step = [ValidationStep]::None
if (-not [string]::IsNullOrEmpty($CompletedStep)) {
if (-not [enum]::TryParse([ValidationStep], $CompletedStep, $true, [ref]$step)) {
$validValues = ([enum]::GetNames([ValidationStep])) -join ", "
Write-Error "Error: '-CompletedStep $CompletedStep' is not a valid step. Valid values: $validValues"
exit 2
}
}

# Record progress in .azure/validate-status.json (creating it if needed).
$azureDir = Join-Path -Path $WorkspacePath -ChildPath ".azure"
if (-not (Test-Path -Path $azureDir)) {
New-Item -ItemType Directory -Path $azureDir | Out-Null
}
$validateStatusPath = Join-Path -Path $azureDir -ChildPath "validate-status.json"
$validateStatusJson = @{ completedStep = $step.ToString() } | ConvertTo-Json
[System.IO.File]::WriteAllText($validateStatusPath, $validateStatusJson + [Environment]::NewLine, (New-Object System.Text.UTF8Encoding($false)))

# Emit the next action based on the step just completed.

# Step 1: Load Plan
if ($step -eq [ValidationStep]::None) {
Write-Output 'Action: Read `.azure/deployment-plan.md` for recipe and configuration. If missing, run azure-prepare first, then come back to workflow.ps1.'
Write-Output "Next: re-run workflow.ps1 with -CompletedStep LoadPlan after completing the action."
Write-Output 'Reference: `.azure/deployment-plan.md'
exit 0
}

# Step 2: Add Validation Steps
if ($step -eq [ValidationStep]::LoadPlan) {
Write-Output 'Action: Copy the recipe''s `Validation Steps` into `.azure/deployment-plan.md` as children of `All validation checks pass`.'
Write-Output "Next: re-run workflow.ps1 with -CompletedStep AddValidationSteps after completing the action."
Write-Output 'Reference: references/recipes/README.md, `.azure/deployment-plan.md'
exit 0
}

# Step 3: Run Validation
if ($step -eq [ValidationStep]::AddValidationSteps) {
Write-Output "Action: Execute the recipe-specific validation commands."
Write-Output "Next: re-run workflow.ps1 with -CompletedStep RunValidation after completing the action."
Write-Output "Reference: references/recipes/README.md"
exit 0
}

# Step 4: Build Verification
if ($step -eq [ValidationStep]::RunValidation) {
Write-Output "Action: Build the project and fix any errors before proceeding."
Write-Output "Next: re-run workflow.ps1 with -CompletedStep BuildVerification after completing the action."
Write-Output "Reference: See the recipe for build details."
exit 0
}

# Step 5: Static Role Verification
if ($step -eq [ValidationStep]::BuildVerification) {
Write-Output "Action: Review the Bicep/Terraform for correct RBAC role assignments in code."
Write-Output "Next: re-run workflow.ps1 with -CompletedStep StaticRoleVerification after completing the action."
Write-Output "Reference: references/role-verification.md"
exit 0
}

# Step 6: Record Proof
if ($step -eq [ValidationStep]::StaticRoleVerification) {
Write-Output "Action: Populate **Section 7: Validation Proof** in the plan with the commands run and their results."
Write-Output "Next: re-run workflow.ps1 with -CompletedStep RecordProof after completing the action."
Write-Output 'Reference: `.azure/deployment-plan.md'
exit 0
}

# Step 7: Resolve Errors
if ($step -eq [ValidationStep]::RecordProof) {
Write-Output "Action: Fix any validation failures before proceeding."
Write-Output "Next: re-run workflow.ps1 with -CompletedStep ResolveErrors after completing the action."
Write-Output "Reference: See the recipe's errors.md."
exit 0
}

# Step 8: Update Status
if ($step -eq [ValidationStep]::ResolveErrors) {
Write-Output 'Action: Only after ALL checks pass, set the plan status to `Validated`.'
Write-Output "Next: re-run workflow.ps1 with -CompletedStep UpdateStatus after completing the action."
Write-Output 'Reference: `.azure/deployment-plan.md'
exit 0
}

# Step 9: Deploy (workflow complete)
if ($step -eq [ValidationStep]::UpdateStatus) {
Write-Output "Action: The azure-validate workflow is complete. If the user explicitly requested deployment, invoke azure-deploy. Otherwise STOP and report the validation results."
exit 0
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/usr/bin/env bash
# workflow.sh
# Walks the agent through the azure-validate workflow, one step at a time.
#
# Usage:
# ./workflow.sh --workspace-path <path> [--completed-step <step>]
#
# Options:
# --workspace-path <path> Path to the workspace being validated (required).
# --completed-step <step> The workflow step the agent just completed. Omit
# on the first call to start the workflow. The
# script records the value in
# .azure/validate-status.json and returns the next
# action to take, along with the value to pass as
# --completed-step on the next call.
#
# Exit codes:
# 0 - next action emitted (or workflow complete)
# 2 - usage / argument error (missing workspace path or invalid step)

set -uo pipefail

# Valid workflow steps, in order.
VALID_STEPS=(None LoadPlan AddValidationSteps RunValidation BuildVerification \
StaticRoleVerification RecordProof ResolveErrors UpdateStatus)

# Ensure an option that consumes a value actually has one ($@ = remaining args).
need_val() {
[ "$#" -ge 2 ] || { echo "ERROR: $1 requires a value." >&2; exit 2; }
}

WORKSPACE_PATH=""
COMPLETED_STEP=""

while [ $# -gt 0 ]; do
case "$1" in
--workspace-path) need_val "$@"; WORKSPACE_PATH="$2"; shift 2 ;;
--completed-step) need_val "$@"; COMPLETED_STEP="$2"; shift 2 ;;
-h|--help)
grep '^#' "$0" | grep -v '^#!' | sed 's/^# \{0,1\}//'
exit 0 ;;
*)
echo "Unknown argument: $1" >&2
exit 2 ;;
esac
done

if [ -z "$WORKSPACE_PATH" ]; then
echo "ERROR: --workspace-path is required." >&2
exit 2
fi

if [ ! -d "$WORKSPACE_PATH" ]; then
echo "Error: --workspace-path '$WORKSPACE_PATH' does not exist or is not a directory." >&2
exit 2
fi

# Resolve the step the agent just completed (case-insensitive).
# Omitting --completed-step signals the start of the workflow (None).
STEP="None"
if [ -n "$COMPLETED_STEP" ]; then
STEP=""
for valid in "${VALID_STEPS[@]}"; do
if [ "$(printf '%s' "$COMPLETED_STEP" | tr '[:upper:]' '[:lower:]')" = \
"$(printf '%s' "$valid" | tr '[:upper:]' '[:lower:]')" ]; then
STEP="$valid"
break
fi
done
if [ -z "$STEP" ]; then
printf 'Error: '\''--completed-step %s'\'' is not a valid step. Valid values: %s\n' \
"$COMPLETED_STEP" "$(printf '%s, ' "${VALID_STEPS[@]}" | sed 's/, $//')" >&2
exit 2
fi
fi

# Record progress in .azure/validate-status.json (creating it if needed).
AZURE_DIR="$WORKSPACE_PATH/.azure"
mkdir -p "$AZURE_DIR"
VALIDATE_STATUS_PATH="$AZURE_DIR/validate-status.json"
printf '{\n "completedStep": "%s"\n}\n' "$STEP" > "$VALIDATE_STATUS_PATH"

# Emit the next action based on the step just completed.
case "$STEP" in
None)
# Step 1: Load Plan
echo "Action: Read \`.azure/deployment-plan.md\` for recipe and configuration. If missing, run azure-prepare first, then come back to workflow.sh."
echo "Next: re-run workflow.sh with --completed-step LoadPlan after completing the action."
echo "Reference: \`.azure/deployment-plan.md"
;;
LoadPlan)
# Step 2: Add Validation Steps
echo "Action: Copy the recipe's \`Validation Steps\` into \`.azure/deployment-plan.md\` as children of \`All validation checks pass\`."
echo "Next: re-run workflow.sh with --completed-step AddValidationSteps after completing the action."
echo "Reference: references/recipes/README.md, \`.azure/deployment-plan.md"
;;
AddValidationSteps)
# Step 3: Run Validation
echo "Action: Execute the recipe-specific validation commands."
echo "Next: re-run workflow.sh with --completed-step RunValidation after completing the action."
echo "Reference: references/recipes/README.md"
;;
RunValidation)
# Step 4: Build Verification
echo "Action: Build the project and fix any errors before proceeding."
echo "Next: re-run workflow.sh with --completed-step BuildVerification after completing the action."
echo "Reference: See the recipe for build details."
;;
BuildVerification)
# Step 5: Static Role Verification
echo "Action: Review the Bicep/Terraform for correct RBAC role assignments in code."
echo "Next: re-run workflow.sh with --completed-step StaticRoleVerification after completing the action."
echo "Reference: references/role-verification.md"
;;
StaticRoleVerification)
# Step 6: Record Proof
echo "Action: Populate **Section 7: Validation Proof** in the plan with the commands run and their results."
echo "Next: re-run workflow.sh with --completed-step RecordProof after completing the action."
echo "Reference: \`.azure/deployment-plan.md"
;;
RecordProof)
# Step 7: Resolve Errors
echo "Action: Fix any validation failures before proceeding."
echo "Next: re-run workflow.sh with --completed-step ResolveErrors after completing the action."
echo "Reference: See the recipe's errors.md."
;;
ResolveErrors)
# Step 8: Update Status
echo "Action: Only after ALL checks pass, set the plan status to \`Validated\`."
echo "Next: re-run workflow.sh with --completed-step UpdateStatus after completing the action."
echo "Reference: \`.azure/deployment-plan.md"
;;
UpdateStatus)
# Step 9: Deploy (workflow complete)
echo "Action: The azure-validate workflow is complete. If the user explicitly requested deployment, invoke azure-deploy. Otherwise STOP and report the validation results."
;;
esac

exit 0
Loading