Date: March 12, 2026 Scope: How
azure-prepareuses recipes, runtimes, and service references through progressive disclosure Walkthrough prompt: "Create a Node.js Express API with Cosmos DB that I can deploy to Azure Container Apps"
Progressive disclosure means load only what you need, when you need it. The skill never loads all 45+ reference files upfront — it follows a staged pipeline where each phase loads the minimum context required before moving to the next.
┌──────────────────────────────────────────────────────────────────────────┐
│ SKILL.md (always loaded) │
│ ─ Triggers, rules, 2-phase workflow, output contract │
│ ─ Token budget: < 5000 tokens │
│ ─ Contains: WHAT to do + WHEN to load each reference │
│ ─ Does NOT contain: HOW to do it (that's in references) │
└───────────────────────────────┬──────────────────────────────────────────┘
│
Phase 1: Planning (references loaded on demand)
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────────┐
│analyze.md│ │ scan.md │ │requirements │
│ │ │ │ │ .md │
└────┬─────┘ └────┬─────┘ └──────┬───────┘
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌───────────────┐ ┌──────────────┐
│recipe- │ │architecture │ │plan-template │
│selection.md │ │ .md │ │ .md │
└──────┬──────┘ └───────┬───────┘ └──────┬───────┘
│ │ │
└─────────────────┼─────────────────┘
▼
┌──────────────────────┐
│ .azure/plan.md │
│ (user approval) │
└──────────┬───────────┘
│
Phase 2: Execution (references loaded per component)
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ RECIPES │ │ SERVICES │ │ RUNTIMES │
│ (1 loaded) │ │ (per svc) │ │ (per lang) │
└─────────────┘ └──────────────┘ └──────────────┘
Key principle: SKILL.md is the router. It tells the agent which reference to load at each step via table links. The references themselves contain the deep content.
Recipes define the deployment methodology. Only one recipe is loaded per project.
| Recipe | When Selected | Key Files Loaded |
|---|---|---|
| AZD (Bicep) | Default for new projects | recipes/azd/README.md → azure-yaml.md, docker.md, iac-rules.md |
| AZD (Terraform) | User mentions Terraform + Azure | recipes/azd/README.md → terraform.md, azure-yaml.md, docker.md |
| AZCLI | Existing az scripts, imperative control | recipes/azcli/README.md → commands.md, scripts.md |
| Bicep | IaC-first, no CLI wrapper | recipes/bicep/README.md → patterns.md |
| Terraform | Multi-cloud, complex TF modules | recipes/terraform/README.md → patterns.md |
Progressive loading within a recipe:
recipe-selection.md → selects AZD
│
recipes/azd/README.md (overview + generation steps)
│
┌───────────────┼───────────────┐
▼ ▼ ▼
azure-yaml.md docker.md iac-rules.md
(config schema) (Dockerfile (Bicep generation
templates) rules + MCP tools)
The recipe README is loaded first. Sub-files (docker.md, iac-rules.md) are loaded only when the generation step needs them.
Services are Azure resources. Each service follows a consistent structure:
services/<service>/
├── README.md ← Always loaded first (when to use, SKU, env vars)
├── bicep.md ← Loaded if recipe uses Bicep
├── terraform.md ← Loaded if recipe uses Terraform
└── <specific>.md ← Loaded only if relevant (scaling.md, partitioning.md, etc.)
Progressive loading within a service:
research.md (mapping table)
│
├── "Container Apps needed"
│ └── services/container-apps/README.md ← LOAD (overview)
│ ├── bicep.md ← LOAD (AZD+Bicep recipe)
│ ├── scaling.md ← LOAD (API needs scaling)
│ ├── health-probes.md ← LOAD (production readiness)
│ └── environment.md ← SKIP (not needed yet)
│
├── "Cosmos DB needed"
│ └── services/cosmos-db/README.md ← LOAD
│ ├── bicep.md ← LOAD
│ ├── partitioning.md ← LOAD (must pick partition key)
│ └── sdk.md ← SKIP (app code, not infra)
│
└── "Key Vault needed"
└── services/key-vault/README.md ← LOAD
└── bicep.md ← LOAD
The research.md file acts as the service router — it maps Azure services to their reference paths and related skills.
Runtimes handle the gap between "app runs locally" and "app runs on Azure."
runtimes/
└── nodejs.md ← Loaded when containerized Node.js app detected
What a runtime reference provides:
- Trust proxy settings (Azure load balancers)
- Cookie configuration for Azure environments
- Health check endpoint patterns
- Port binding from environment variables
- Production Dockerfile templates
- Common "works locally, fails on Azure" fixes
When loaded: During Phase 2, Step 3 (Generate Artifacts), after the recipe and services are established but before generating the Dockerfile and app configuration.
"Create a Node.js Express API with Cosmos DB that I can deploy to Azure Container Apps"
Reference loaded: SKILL.md inline routing table Result: No specialized tech detected (no Lambda, copilot SDK, etc.) → continue
Reference loaded: analyze.md
Decision: Empty workspace → Mode: NEW
analyze.md decision tree:
What does the user want to do?
└── Create new application → Mode: NEW
Reference loaded: requirements.md
Gathered:
- Classification: API service
- Scale: Standard (single region)
- Budget: Not specified → default
- Compliance: None specified
Reference loaded: scan.md
Result: No existing code → greenfield project
Detected components from prompt:
- Node.js Express API (compute)
- Cosmos DB (data)
Reference loaded: recipe-selection.md
recipe-selection.md decision:
Found in Workspace │ Suggested Recipe
────────────────────┼───────────────────
None │ AZD (Bicep) - default
Decision: AZD (Bicep) — default for new projects
Reference loaded: architecture.md
Service mapping:
| Component | Azure Service | Justification |
|---|---|---|
| Express API | Container Apps | Serverless containers, HTTP ingress |
| Database | Cosmos DB | Flexible schema, managed NoSQL |
| Secrets | Key Vault | Store connection strings securely |
| Monitoring | Application Insights | Telemetry + distributed tracing |
| Logging | Log Analytics | Container Apps requirement |
| Images | Container Registry | Container Apps requirement |
Reference loaded: plan-template.md
Output: .azure/plan.md created and presented for approval
Total references loaded in Phase 1: 6 (analyze, requirements, scan, recipe-selection, architecture, plan-template)
User approves the plan. Now the heavy loading begins.
Reference loaded: research.md (the master routing table)
From research.md, the agent identifies what to load:
research.md mapping:
Container Apps → services/container-apps/README.md
Related skills: azure-diagnostics, azure-observability
Cosmos DB → services/cosmos-db/README.md
Related skills: azure-security
Key Vault → services/key-vault/README.md
Related skills: azure-security, azure-keyvault-expiration-audit
App Insights → services/app-insights/README.md
Related skills: appinsights-instrumentation
Progressive service loading — Container Apps:
1. services/container-apps/README.md ← LOADED (overview)
Learns: host type = containerapp, needs Environment + ACR + Log Analytics
Learns: API → External ingress, Min Replicas = 1, HTTP scaling
2. services/container-apps/bicep.md ← LOADED (recipe = Bicep)
Gets: Complete Bicep patterns for Container Apps Environment,
Container App resource, Container Registry, managed identity
3. services/container-apps/scaling.md ← LOADED (API needs scaling rules)
Gets: HTTP scaling rule patterns, min/max replicas
4. services/container-apps/health-probes.md ← LOADED (production readiness)
Gets: Liveness, readiness, startup probe configurations
5. services/container-apps/environment.md ← NOT LOADED (default config sufficient)
Progressive service loading — Cosmos DB:
1. services/cosmos-db/README.md ← LOADED
Learns: Serverless mode for dev, Session consistency recommended
Learns: Key Vault recommended for connection strings
2. services/cosmos-db/bicep.md ← LOADED
Gets: Account, database, container Bicep patterns
Gets: Autoscale throughput, backup policy
3. services/cosmos-db/partitioning.md ← LOADED
Gets: Partition key selection guidance (critical design decision)
4. services/cosmos-db/sdk.md ← NOT LOADED (app code generation,
not infra — handled separately)
Progressive service loading — Key Vault:
1. services/key-vault/README.md ← LOADED
2. services/key-vault/bicep.md ← LOADED
Gets: Vault, secrets, role assignments, Key Vault references
Related skill invocations:
appinsights-instrumentation→ invoked for telemetry setup guidanceazure-security→ invoked for managed identity + RBAC patterns
Reference loaded: azure-context.md
Action: Prompts user for subscription and location via ask_user
Recipe references loaded:
recipes/azd/README.md ← LOADED (generation workflow)
recipes/azd/azure-yaml.md ← LOADED (azure.yaml schema for Container Apps)
recipes/azd/docker.md ← LOADED (Node.js Dockerfile template)
recipes/azd/iac-rules.md ← LOADED (Bicep generation rules, naming, modules)
Runtime reference loaded:
runtimes/nodejs.md ← LOADED (Node.js production config)
This is the critical runtime reference that ensures the Express app works on Azure:
// From runtimes/nodejs.md — trust proxy for Azure load balancers
const app = express();
app.set('trust proxy', true); // Required: Azure LB forwards requests
// Health check endpoint (required for Container Apps probes)
app.get('/health', (req, res) => res.status(200).json({ status: 'healthy' }));
// Port from environment variable
const port = process.env.PORT || 3000;Without the runtime reference, common failures include:
req.ipreturns load balancer IP instead of client IP- Cookies rejected because
secureflag fails behind HTTP proxy - Container Apps health probes fail (no
/healthendpoint) - App listens on hardcoded port instead of
PORTenv var
Artifacts generated:
| File | Source References |
|---|---|
.azure/plan.md |
plan-template.md |
azure.yaml |
recipes/azd/azure-yaml.md |
infra/main.bicep |
recipes/azd/iac-rules.md + service bicep.md files |
infra/app/api.bicep |
services/container-apps/bicep.md |
infra/core/database/cosmos.bicep |
services/cosmos-db/bicep.md |
infra/core/security/keyvault.bicep |
services/key-vault/bicep.md |
src/api/Dockerfile |
recipes/azd/docker.md + runtimes/nodejs.md |
Reference loaded: security.md
- Applies managed identity (no connection strings)
- Adds Key Vault references for Cosmos DB credentials
- Sets RBAC role assignments
Plan updated → status changed to Ready for Validation
Hand off → invokes azure-validate skill
| Phase | References Loaded | Purpose |
|---|---|---|
| Always | SKILL.md | Router + workflow |
| Phase 1 | 6 planning refs | analyze, requirements, scan, recipe-selection, architecture, plan-template |
| Phase 2 | ~15 execution refs | research, 3× service READMEs, 3× service bicep, 2× service specifics, 4× recipe files, 1× runtime, security, azure-context |
| Total | ~22 of 45+ | Less than half the reference library |
| Reference | Why Skipped |
|---|---|
recipes/azcli/* |
AZCLI recipe not selected |
recipes/terraform/* |
Terraform recipe not selected |
recipes/bicep/* |
Standalone Bicep not selected (AZD+Bicep instead) |
services/aks/* |
AKS not in architecture |
services/app-service/* |
App Service not selected |
services/static-web-apps/* |
No frontend component |
services/functions/* |
No serverless functions |
services/event-grid/* |
No event-driven patterns |
services/service-bus/* |
No messaging needed |
services/logic-apps/* |
No workflow automation |
services/foundry/* |
No AI services |
runtimes/ (other langs) |
Only Node.js detected |
cosmos-db/sdk.md |
SDK patterns for app code, not infra generation |
container-apps/environment.md |
Default environment config sufficient |
apim.md |
No API Management needed |
aspire.md |
Not a .NET Aspire project |
User prompt arrives
│
├─ SKILL.md loaded (always) ─── triggers matched? ──── No → skill not activated
│ │
│ Yes
│ │
│ ┌── Step 0: Specialized tech? ──── Yes → delegate to other skill
│ │ │
│ │ No
│ │ │
│ PHASE 1 ├── Step 1: analyze.md ─────────── determines NEW/MODIFY/MODERNIZE
│ (Planning) ├── Step 2: requirements.md ────── classification, scale, budget
│ ├── Step 3: scan.md ─────────────── detect code, frameworks, existing infra
│ ├── Step 4: recipe-selection.md ─── pick ONE recipe
│ ├── Step 5: architecture.md ─────── map components → Azure services
│ ├── Step 6: plan-template.md ────── write .azure/plan.md
│ └── Step 7: present to user ─────── BLOCKING: wait for approval
│ │
│ User approves
│ │
│ PHASE 2 ┌── Step 1: research.md ────────── service router (loads per-service refs)
│ (Execution) │ │
│ │ ├── services/<svc>/README.md (always, per service)
│ │ ├── services/<svc>/bicep.md (if Bicep recipe)
│ │ ├── services/<svc>/terraform.md (if Terraform recipe)
│ │ └── services/<svc>/<specific>.md (if relevant)
│ │
│ ├── Step 2: azure-context.md ────── subscription + location
│ │
│ ├── Step 3: generate.md
│ │ │
│ │ ├── recipes/<selected>/README.md (generation steps)
│ │ ├── recipes/<selected>/*.md (schema, templates, rules)
│ │ └── runtimes/<lang>.md (production config)
│ │
│ ├── Step 4: security.md ─────────── hardening pass
│ ├── Step 5: update plan ─────────── status → "Ready for Validation"
│ └── Step 6: hand off ────────────── invoke azure-validate
│ │
│ ┌─────┴─────┐
│ ▼ ▼
│ azure-validate → azure-deploy
By loading ~22 of 45+ references instead of all, the skill stays well within context limits. Each reference is kept under ~1000 tokens.
The same service references (services/cosmos-db/bicep.md) are reused regardless of which recipe is selected. The recipe determines how to wire them; the service reference provides what to generate.
Adding a new Azure service = add a new services/<service>/ folder + add a row to research.md. No changes to SKILL.md or the planning references.
Phase 1 catches misconfigurations (wrong recipe, missing requirements, unsupported regions) before any code is generated. The user approval gate ensures alignment before heavy reference loading begins.
"Create a Node.js Express API with Cosmos DB on Container Apps"
│
▼
┌───────────────────┐
│ SKILL.md │ ─── routes to Phase 1
└────────┬──────────┘
│
┌─────────────────┼──────────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌──────────────┐
│ analyze.md │ │ scan.md │ │recipe-sel.md │
│ Mode: NEW │ │ Express+ │ │ → AZD+Bicep │
└────────────┘ │ CosmosDB │ └──────┬───────┘
└────────────┘ │
│ │
┌────────┴────────┐ │
│ architecture.md │─────────┘
│ Maps to: │
│ • Container Apps│
│ • Cosmos DB │
│ • Key Vault │
│ • App Insights │
└────────┬───────┘
│
┌────────┴───────┐
│ plan-template │ → .azure/plan.md → user approves
└────────┬───────┘
│
┌────────┴───────┐
│ research.md │ (service router)
└────────┬───────┘
│
┌──────────────────────┼──────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌──────────────┐ ┌──────────────┐
│Container Apps │ │ Cosmos DB │ │ Key Vault │
│ README.md │ │ README.md │ │ README.md │
│ bicep.md │ │ bicep.md │ │ bicep.md │
│ scaling.md │ │ partition │ └──────────────┘
│ health-probes │ │ .md │
└───────┬───────┘ └──────┬───────┘
│ │
└─────────┬─────────┘
▼
┌──────────────────────────────┐
│ recipes/azd/ │
│ README.md + azure-yaml.md │
│ + docker.md + iac-rules.md │
└──────────────┬───────────────┘
│
┌────────┴────────┐
│ runtimes/ │
│ nodejs.md │
│ trust proxy, │
│ health checks, │
│ Dockerfile │
└────────┬────────┘
│
┌──────┴──────┐
│ security.md │ → managed identity, RBAC, Key Vault refs
└──────┬──────┘
│
▼
azure-validate → azure-deploy