Subagent Template โ Validation & Manifest (Steps 10โ12)
Validate IaC syntax, write scaffold-manifest.json, and generate deploy checklist. Follow the workflow below.
Critical Rules
- โ Do NOT invoke ANY skills โ no
{"skill": "azure-validate"},{"skill": "azure-deploy"},{"skill": "azure-prepare"}, or any other skill call. Use the procedures in THIS file only. - โ Do NOT create or modify Azure resources โ validation is syntax-only (
bicep build/terraform validate), neveraz deployment sub create. - โ Do NOT run
what-iforterraform planโ deploy runs the mandatory what-if with real secret params. Scaffold validates syntax only.
Input (provided by caller)
| Field | Required |
|---|---|
IaC file paths (all generated .bicep or .tf files) |
YES |
| Self-review findings from Steps 6โ9 | YES |
prepare-plan.json โ services, naming, region, subscriptionId |
YES |
prereq-output.json.warnings[] โ prereq warnings with fixPhase |
YES |
prereq-output.json.healthEndpoint โ detected health path (or null) |
YES |
| Conformance result JSON (from main-thread Step 10a-conf) | YES |
Output
| Artifact | Location |
|---|---|
scaffold-manifest.json |
Session folder |
deploy-result.json skeleton |
Session folder |
| Validation result status | Return to caller: Validated or Failed |
| Deploy checklist | .copilot-azure/sessions/{id}/deploy-checklist.md |
Workflow
Step 1 โ Read validation + manifest rules
Read validation-and-manifest.md and scaffold-schemas.ts.
Do: Understand the ScaffoldManifest interface (field names, types, required fields) and the validation sequence.
Step 2 โ Format and validate IaC
Do:
- Run
az bicep build --file infra/main.bicep --stdout > $null(Bicep) orterraform validate(TF). Process output for BCP errors and warnings. Record pass/fail.
Step 3 โ Check RBAC completeness
Do: Verify every managed identity โ resource pair in the IaC has a corresponding Microsoft.Authorization/roleAssignments resource with the correct role GUID. Cross-reference with the review findings from Steps 6โ9 input.
Step 3b โ Azure runtime constraint check (Container Apps)
Skip if no Container Apps in the plan.
For each Container App resource in the generated Bicep:
- cpu/memory combo โ verify
cpu(must be typestring) +memoryis one of:0.25/0.5Gi,0.5/1Gi,0.75/1.5Gi,1/2Gi,1.25/2.5Gi,1.5/3Gi,1.75/3.5Gi,2/4Gi. FIXABLE: adjust to nearest valid combo (use smallest valid combo for sidecars/companions). - secretRef coverage โ every
secretRefin container env vars must have a matching entry inconfiguration.secrets[]. Every KV secret URL insecrets[]must reference aMicrosoft.KeyVault/vaults/secretsresource that exists in the generated modules. Missing secret resource โ FIXABLE: add it to the KV module. - probe path โ if
prereq-output.json.healthEndpointis non-null, verifyprobePathmatches it. If null AND anyplainEnvVarsentry is namedBASEorPATH_PREFIX, verifyprobePathstarts with that value (not bare/). If null AND no BASE var: verify the app has a route handler for the probe path (check source entry point forapp.get('/')or framework root handler) โ bare/on a REST API with only sub-path routes (e.g.,/users,/messages) returns 404 and blocks revision activation. FIXABLE: updateprobePathto a known GET endpoint from the app.
FIXABLE errors: fix the Bicep โ re-run az bicep build โ proceed to Step 3c.
Step 3b2 โ App Service security constraint check
Skip if no App Service or Functions in the plan.
For each App Service / Functions resource in the generated Bicep:
- basicPublishingCredentialsPolicies โ verify both child resources exist:
basicPublishingCredentialsPolicies/scm(withallow: true) andbasicPublishingCredentialsPolicies/ftp(withallow: false). Missing โ FIXABLE: add the child resources per bicep-patterns-security.md ยง Publishing Credential Lockdown. - uniqueString in naming โ verify the App Service name uses
uniqueString()or a unique suffix (not a hardcoded literal). Hardcoded names cause global collisions. Missing โ FIXABLE: wrap name withuniqueString(resourceGroup().id).
FIXABLE errors: fix the Bicep โ re-run az bicep build โ proceed to Step 3c.
Step 3c โ Record plan conformance result
The main thread (SKILL.md Step 10a-conf) already ran the conformance script and passed you its JSON. Record it in scaffold-manifest.json.conformance = { passed, failures, source: "script" }. โ Do NOT set validationResult.status: "Validated" while any BLOCK failure is unresolved.
Fallback (only if the caller passed NO result AND infra/main.bicep exists โ the gate is Bicep-only, skip for Terraform): run {scaffoldDir}/scripts/scaffold-conformance.ps1 -SessionPath "{sessionPath}" -InfraPath infra (or .sh on bash) yourself, then record with source: "script". Never hand-judge when a shell is available.
Step 4 โ Write scaffold-manifest.json
Read scaffold-schemas.ts for exact field names.
Do: Write scaffold-manifest.json to the session folder with: sessionId, scaffoldCompletedUtc, iacFormat, targetScope, entryPoint, parametersFile, files[], deployCommand, twoPhaseWiring (if Container Apps), phase2Steps (if applicable), selfReview (from caller input), validationResult (from Steps 2โ3). Use the exact field names from scaffold-schemas.ts ยง ScaffoldManifest.
Step 5 โ Handle failures (if any)
Read scaffold-healing-rules.md ONLY if validation failed.
Do: Classify errors as FIXABLE or BLOCKING. FIXABLE: auto-fix IaC โ re-validate (max 3 attempts before asking user). BLOCKING: surface to user and halt. PLAN_LEVEL_CHANGE: requires re-approval โ do NOT auto-fix.
Step 6 โ Verify deploy checklist exists
Do: Check that .copilot-azure/sessions/{id}/deploy-checklist.md exists (written by the parallel checklist subagent at scaffold Step 5b). If missing, read deploy-checklist-template.md and write it now as a fallback โ fill {placeholders} from prepare-plan.json, delete non-applicable sections. This file survives conversation compaction
Step 7 โ Create deploy-result.json skeleton (MANDATORY)
Read deploy-schemas.ts โ specifically the DeployResult interface.
Do: Create .copilot-azure/sessions/{id}/deploy-result.json conforming to the DeployResult interface. Populate fields from all session artifacts already written (prepare-plan.json, context.json, scaffold-manifest.json, prereq-output.json). Use sensible defaults for fields the deploy phase will fill later. The deploy main agent updates this file in-place at Step 8 with real values.
Step 8 โ Return results
Do: Return validation status (Validated or Failed) to the caller. Confirm deploy-checklist.md exists. Keep status report โค500 tokens.