Repository navigation
Module B Train-the-Trainer MicroHack — Zava multi-agent AI platform on Azure - #10
Conversation
Establish the shared foundation for the Module B Train-the-Trainer microhack: - .microhack/build-contract.md: authoritative shared spec (paths, env vars, HTTP API, agents, Azure + data contracts, coding standards, Module B map) - Root hygiene: README, LICENSE (MIT), .gitignore, .editorconfig, .gitattributes - .github: copilot-instructions, dependabot, CI/CodeQL/dependency-review/slides/infra-validate/setup workflows, issue templates - .devcontainer: polyglot (python 3.12, dotnet 9, node 20, az/azd/gh) - docs: index, overview, agenda, architecture, module-b-mapping; mkdocs.yml - data: Zava seed catalog/reviews/orders/customers + policy & supplier docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Deliverables ### src/mcp-zava/ — TypeScript MCP server - 7 tools: get_product, search_products, get_order, get_inventory, get_customers, search_knowledge, generate_evidence - STDIO transport (VS Code / GitHub Copilot agent mode) - HTTP/SSE transport (Azure Container Apps / azd service mcp-zava) - Multi-stage Dockerfile (non-root user, node:22-alpine) - Smoke test: builds + connects as MCP client + tests 3 tools - ESLint 9 flat config + TypeScript strict mode - Zero vulnerabilities (npm audit); all quality gates pass ### .github/agents/ - zava-builder.md — scaffolds/extends Zava app per build contract - zava-evidence.md — drives Module B evidence via generate_evidence tool ### .github/skills/ - seed-data.md — seeds Cosmos DB + PostgreSQL pgvector from data/ - run-local-github-mode.md — local dev with GitHub Models (free) - collect-evidence.md — assembles Module B audit evidence package ### mcp.json - Wires local zava server (STDIO + dev mode) - Wires Microsoft Learn Docs MCP server - Documents required env vars; no secrets Refs: #5 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Provisions full Zava AI platform on Azure using Azure Verified Modules (AVM): Resources: - User-Assigned Managed Identity (UAMI) with least-privilege RBAC - Log Analytics Workspace + Application Insights (OpenTelemetry -> App Insights) - Key Vault (RBAC auth, purge protection ON) - Azure Container Registry (admin OFF, anonymous pull OFF) - Azure AI Services (gpt-4o-mini + text-embedding-3-small deployments) - Azure AI Foundry Hub + Project - Azure AI Search (local auth disabled) - Document Intelligence + Content Safety - Cosmos DB NoSQL (local auth disabled, AAD RBAC data-plane, db: zava) - PostgreSQL Flexible Server (AAD-only, pgvector enabled, db: zava) - Container Apps Environment + 3 Container Apps (api-python, api-dotnet, mcp-zava) - Storage Account (AI Foundry Hub artifacts) Security: DefaultAzureCredential / Managed Identity everywhere. No API keys, no secrets in code or outputs. azd: azure.yaml wires all 3 services to Container Apps with Dockerfiles. All canonical build-contract env vars emitted as azd outputs. Validation: bicep build + bicep lint pass clean (exit code 0). AVM modules used (verified June 2026): - managed-identity/user-assigned-identity:0.5.1 - operational-insights/workspace:0.15.1 - insights/component:0.7.2 - key-vault/vault:0.13.3 - container-registry/registry:0.12.1 - cognitive-services/account:0.15.0 - machine-learning-services/workspace:0.13.2 - search/search-service:0.12.2 - document-db/database-account:0.19.0 - db-for-postgre-sql/flexible-server:0.15.4 - app/managed-environment:0.13.3 - app/container-app:0.22.1 Closes #3 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…/main.json main.json is the compiled ARM artifact, reproducible from main.bicep via azd/bicep build; gitignore it to keep the repo clean. Bicep validated: az bicep build exit 0, zero lint warnings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…crosswalk Deliverables for WS6 (Lab guides + Module B evidence): docs/labs/ - lab0.md Setup & GitHub Models (20 min) [B.3.1] - lab1.md First agent — Concierge (50 min) [B.1.1, B.3.1] - lab2.md RAG over Zava knowledge (50 min) [B.1.1, B.2.1, B.3.1] - lab3.md Deploy to Azure with azd (55 min) [B.1.1, B.2.1, B.3.1, B.4.2] - lab4.md Data agents: Merchandiser+Ops (45 min) [B.1.1, B.2.1, B.2.2, B.3.1] - lab5.md Trust, safety, observability (45 min) [B.1.1, B.3.1, B.4.1] - lab6.md Capstone + evidence gen (45 min) [B.1.1-B.4.2 all] docs/solutions/ - solution0.md through solution6.md (facilitator answer keys) docs/evidence-templates/ - README.md how generate_evidence populates templates - b11-capability-case-study.md (B.1.1) - b21-acr-pillar-worksheet.md (B.2.1) + Partner Center walkthrough - b22-customer-diversity.md (B.2.2) + DPOR/PAL/CSP explainer - b41-evidence-index.md (B.4.1) + pre-audit checklist - b42-onboarding-pack.md (B.4.2) + delivery runbook docs/cert-crosswalk.md AZ-204/AZ-400/AI-102/DP-420 + 5-person study plan (B.3.1) .markdownlint.json root config (MD013 off — matches .editorconfig max_line_length=off for md) All files: markdownlint exit 0. Build contract env vars, routes, ports, 1536-dim embeddings, provider names all consistent with .microhack/build-contract.md. Closes #7 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Postgres runtime is already Entra-only (passwordAuth disabled, UAMI as AAD admin). Default the mgmt-plane password to newGuid() and drop the parameter mappings so provisioning is fully hands-off with no human-handled secret. Bicep build + lint clean (exit 0, 0 warnings). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Marp deck (slides/zava-microhack-deck.md): - Full-day deck covering all agenda sections in canonical order - Sections: welcome/TTT, Zava story, AI Apps Advanced Specialization, Module B controls (B.1.1-B.4.2), solution architecture, 3 ACR pillars, modular inference (GitHub Models / Azure OpenAI / Azure AI Foundry), Microsoft Agent Framework (Python + .NET), GitHub agents/skills/MCP, per-lab intro slides (Lab 0-6), evidence review, TTT debrief - Self-contained Zava CSS theme via front-matter style block - Reusable theme also at slides/themes/zava.css for --theme-set usage - Builds cleanly to HTML + PDF via slides.yml workflow Facilitator guide (docs/facilitator-guide/): - index.md: overview and navigation hub - run-of-show.md: minute-by-minute timing for the full day - prerequisites.md: environment setup (devcontainer, GitHub token, azd) - pitfalls.md: common problems and fixes across all labs - av-room-checklist.md: A/V setup and room logistics checklist - ttt-notes.md: Train-the-Trainer re-delivery guide - talk-tracks/index.md: talk-tracks navigation table - talk-tracks/lab-00-welcome.md through lab-06-capstone.md: per-lab lecture notes, demo cues, expected outcomes, evidence checkpoints Quality gates: - markdownlint-cli2: 0 errors across all 18 files - Marp CLI: HTML + PDF build exit code 0 - OSS/license-free assets only (system fonts, SVG icons) Closes #2 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Disable cosmetic MD060 (table-pipe spacing) at repo root; tables render correctly in MkDocs/GitHub and the rule is markdownlint-version-sensitive - Remove redundant per-directory .markdownlint.json files (labs/solutions/ evidence-templates) so the root config governs all docs consistently - Point labs build-contract reference to the GitHub blob URL so it resolves in the published MkDocs site (file lives outside docs_dir) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implements the full Zava AI Agent Platform Python track (src/python/).
## Agents (Microsoft Agent Framework 1.9.0)
- concierge: order lookup, product Q&A, knowledge-base RAG, returns
- merchandiser: catalog search, reviews, sales trend analysis
- operations: inventory, supplier doc parsing (Doc Intelligence), restock
- trust: content safety, policy retrieval, Module B evidence (B.1.1-B.4.2)
- orchestrator: triage via specialist.as_tool() handoff pattern
## HTTP API (build-contract section 4)
- GET /health -> {"status":"ok"}
- GET /agents -> list of {key, name, description}
- POST /chat -> {reply, agent, citations[], traceId}
- POST /chat/stream -> SSE token stream with done event
## Modular Inference (section 3)
- github mode: AsyncOpenAI + GitHub Models endpoint + GITHUB_TOKEN
- azure-openai: AsyncAzureOpenAI + DefaultAzureCredential (no API keys)
- foundry: FoundryChatClient / AzureOpenAI fallback
- INFERENCE_PROVIDER / EMBEDDINGS_PROVIDER env vars control selection
- text-embedding-3-small (1536-dim) for all embeddings
## Data and Store
- LocalZavaStore: JSON+Markdown seed data, keyword+cosine search (github mode)
- AzureZavaStore: Cosmos DB NoSQL + pgvector + AI Search (Azure mode)
- scripts/seed.py to load data/ into Azure services
## Observability
- OpenTelemetry -> Application Insights (when APPLICATIONINSIGHTS_CONNECTION_STRING set)
- Every /chat reply returns real OTel traceId
## Quality gates (all passing)
- ruff check: 0 issues
- ruff format: 28 files formatted
- mypy: 0 errors in 22 source files
- pytest: 49/49 passed
- pip-audit: 0 known vulnerabilities
- bandit: 0 issues
## Infrastructure
- Dockerfile: multi-stage slim build, non-root user
- pyproject.toml: latest pinned deps (agent-framework==1.9.0)
- README.md: run instructions for github and Azure modes
Closes #8
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…erge Slides tooling (deterministic + Dependabot-tracked): - Add slides/package.json + lockfile pinning @marp-team/marp-cli@4.4.0 (0 vulnerabilities); the existing npm /slides Dependabot entry now resolves - slides.yml: build docs (mkdocs --strict) first, then render the deck into site/slides so mkdocs' clean step no longer wipes the decks; HTML export is required (blocking), PDF/PPTX remain best-effort; drop unpinned marp@latest Dependency hygiene: - dependabot.yml: fix src/mcp-zava ecosystem nuget -> npm (it is a TypeScript project) so its packages are actually scanned and updated Markdown quality (now genuinely clean, not advisory): - ci.yml markdownlint: pin markdownlint-cli2@0.22.1, robust nested excludes, and make it blocking (drop "|| true") - Consolidate config: remove redundant docs/facilitator-guide per-dir config so the root governs all docs; keep slides/ Marp-specific config - Fix all 91 real-file findings across .github, .microhack, data, docs, infra, and src/mcp-zava (blanks-around-headings/lists/fences, trailing newlines, and language tags on fenced blocks) -> 0 errors repo-wide - Point facilitator-guide out-of-docs links (build-contract, slides) at GitHub URLs so mkdocs build --strict passes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- ASP.NET Core 10 Minimal API with 4 routes matching build-contract §4: GET /health, GET /agents, POST /chat, POST /chat/stream (SSE) - 5 agents on Microsoft Agent Framework (ME.AI 1.11.1): concierge (RAG+FAQ), merchandiser (product search), operations (orders), trust (compliance + Module B evidence), orchestrator (triage + handoff) - Modular inference factory (INFERENCE_PROVIDER/EMBEDDINGS_PROVIDER): github (GitHub Models, default/free), azure-openai, foundry GitHub Models uses OpenAI-compatible client with DefaultAzureCredential skipped; Azure paths use Azure.Identity DefaultAzureCredential - ZavaDataStore: in-memory cosine-similarity RAG over products/orders/ customers/reviews/knowledge documents - ZavaSeeder: loads data/ JSON + MD seed files, batches embeddings - OpenTelemetry wired to Application Insights (optional); traceId in reply - 40 xUnit tests (no network): provider switch, agent tools, API routes - Dockerfile: multi-stage, non-root user (UID 1000), container-app ready - .editorconfig, README with both GitHub and Azure run modes - Quality gates: build (0 warn/err), format clean, tests green, 0 vulns Packages updated to latest stable: DotNetEnv 3.2.0, Newtonsoft.Json 13.0.4, OTel.*.AspNetCore 1.16.0, Pgvector 0.3.2, FluentAssertions 8.10.0, coverlet 10.0.1, SDK 18.7.0 Closes #1 (WS3 .NET deliverable) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…blocking WS2 integration hardening: - pyproject.toml: replace the 'agent-framework' meta-package (which resolves to agent-framework-core[all] and drags in the unversioned, pre-release-only agent-framework-azure-ai-search connector) with the three connectors actually used: agent-framework-core==1.9.0, agent-framework-openai==1.8.2, agent-framework-foundry==1.8.2. Installs are now deterministic and resolve under both pip and uv without a global --pre flag (the lone transitive pre-release, azure-ai-inference==1.0.0b9, is pulled via an explicit pre-release specifier). - ci.yml: drop advisory '|| true' escapes so the quality gates actually block. Python job now fails on mypy, bandit, and pip-audit findings (added bandit; removed dead requirements-dev.txt fallback). .NET job now fails on dotnet format drift and on any vulnerable NuGet package (parse 'dotnet list package --vulnerable'). Validated locally (Py 3.12.13): ruff check + format clean, mypy --strict 22 files clean, bandit clean, 49 tests pass, pip-audit reports no known vulnerabilities. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
WS3 integration hardening: - ci.yml: bump setup-dotnet from 9.0.x to 10.0.x; the projects target net10.0, so the .NET 9 SDK could not restore/build them. - src/dotnet/README.md: add language tags to two bare fences (SSE stream + ASCII architecture diagram) and surround fences with blank lines so the now-blocking markdownlint passes. Validated locally (SDK 10.0.301): dotnet build Release with TreatWarningsAsErrors + analyzers = 0 warnings/0 errors; dotnet format --verify-no-changes clean; 40 tests pass; dotnet list package --vulnerable = none; --outdated = none. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…racks link Close the last dependency-currency gaps from the final quality gate so every shipped dependency surface is pinned, reproducible, and vulnerability-tracked. Docs site tooling (MkDocs Material) - Add requirements-docs.txt pinning mkdocs-material==9.7.6 (pip-audit: no known vulnerabilities across its full transitive tree). - slides.yml now installs `-r requirements-docs.txt` instead of an inline pin, so the workflow and Dependabot read from one source of truth. - dependabot.yml: add a `pip` ecosystem entry for `/` (requirements-docs.txt), grouped as docs-deps, weekly. Markdown linter (intentionally left ephemeral) - markdownlint-cli2@0.22.1 stays an `npx` pin in ci.yml with NO committed lockfile. Its latest release transitively depends on js-yaml (<=4.1.1) and markdown-it (<=14.1.1), which carry moderate quadratic-complexity DoS advisories with no fixed upstream version (npm audit fix only downgrades the linter). Committing a root lockfile would surface permanent, unfixable open Dependabot alerts for a dev-only tool that processes trusted first-party Markdown. Keeping it ephemeral avoids the alert surface while pinning the exact linter version. Runtime apps (Python, .NET, mcp-zava, slides) remain 0-vuln. Docs fix - facilitator-guide/index.md: point the talk-tracks link at talk-tracks/index.md so `mkdocs build --strict` resolves the directory reference cleanly. Validation (local, CI-equivalent) - markdownlint-cli2 0.22.1: 0 errors across 64 files. - mkdocs build --strict via requirements-docs.txt: success, no broken links. - YAML parse: ci.yml, slides.yml, dependabot.yml all valid. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
| Area | Checks | Result |
|---|---|---|
Python (src/python) |
ruff check, ruff format --check, mypy --strict, bandit, pytest, pip-audit | ✅ 49 tests, 0 vulns |
.NET (src/dotnet, net10.0) |
restore, format --verify-no-changes, build Release (warnaserror+analyzers), test, list --vulnerable/--outdated | ✅ 0/0 build, 40 tests, 0 vulnerable + 0 outdated |
MCP server (src/mcp-zava) |
npm ci, eslint, tsc, build, smoke-test | ✅ 0 vulns, 7 tools |
Infra (infra/) |
az bicep build (→ARM), az bicep lint | ✅ exit 0, clean |
| Docs | mkdocs build --strict, markdownlint-cli2 (64 files), Marp build | ✅ no broken links, 0 lint errors |
Tooling versions: node 24.16, dotnet 10.0.301, uv 0.11.21, Bicep 0.44.1, markdownlint-cli2 0.22.1, mkdocs-material 9.7.6, marp-cli 4.4.0.
Overview
A complete 1-day, instructor-led Train-the-Trainer (TTT) MicroHack that covers all Module B controls of the Build and Modernize AI Applications on Microsoft Azure Advanced Specialization. Trainees build Zava, an intelligent athletic-apparel retailer powered by a multi-agent platform, in both Python and C# (.NET) on the Microsoft Agent Framework, with modular inference, full Azure deployment, and the latest GitHub agents / skills / MCP tooling.
Built by an orchestrator across 6 disjoint, parallel workstreams (path-isolated → conflict-free merges), each tracked as a GitHub Issue and validated to a strict quality bar before integration.
azd upinto real Azure.Module B coverage
docs/overview,docs/architecture,docs/module-b-mapping, lab0/1 + evidenceb11src/python+src/dotnet(5 agents, Agent Framework), lab2/3 + evidenceb21src/mcp-zava(7 tools), Cosmos + pgvector RAG, lab3/4 + evidenceb22infra/(AVM Bicep),azure.yaml, Container Apps, OTel, lab6 + evidenceb41b42Full matrix:
docs/module-b-mapping.md; certification crosswalk:docs/cert-crosswalk.md.Workstreams
infra/,azure.yaml):azd+ Bicep (AVM modules) — Container Apps, Cosmos DB, PostgreSQL Flexible Server (pgvector, Entra-only auth), AI Foundry + Azure OpenAI + AI Search + Document Intelligence + Content Safety. Managed identity throughout; local auth disabled; ACR anonymous pull off.src/python/): FastAPI + Microsoft Agent Framework; modular inference factory (GitHub Models / Azure OpenAI / Azure AI Foundry); 4 store backends; OpenTelemetry; 49 tests.src/dotnet/): ASP.NET Minimal API +Microsoft.Agents.AIon net10.0; modularIInferenceFactory; 40 xUnit tests;.slnx..github/agents/,.github/skills/,src/mcp-zava/,mcp.json): Zava MCP server (7 tools), Copilot custom agents + skills.slides/,docs/facilitator-guide/): Marp deck + facilitator guide with talk tracks.docs/labs/,docs/solutions/,docs/evidence-templates/): 7 student labs + 7 solutions + 5 control-mapped evidence templates.Modular inference (per requirement)
Every AI capability runs through a single factory abstraction selecting Azure AI Foundry, Azure OpenAI, or GitHub Models via configuration — no image generation, so all three are interchangeable. Labs default to free GitHub Models;
azdprovisions the Azure-native path.Quality gates — all green (local, CI-equivalent)
--strict✓, bandit ✓, pytest 49 passed ✓, pip-audit: 0 vulns ✓.dotnet format --verify-no-changes✓, build Release (TreatWarningsAsErrors+ analyzers) 0/0 ✓, 40 tests ✓, 0 vulnerable + 0 outdated packages ✓.npm ci(0 vulns) ✓, eslint ✓, tsc ✓, build ✓, smoke-test: all 7 tools ✓.az bicep build→ ARM (exit 0) ✓,az bicep lintclean ✓.mkdocs build --strict✓ (no broken links), markdownlint 0 errors across 64 files ✓, Marp deck builds ✓.CI (
.github/workflows/ci.yml,slides.yml) makes every one of these gates blocking on PRs tomain. Dependency currency is tracked by Dependabot across github-actions, pip (src/python+ docs), nuget, npm (src/mcp-zava+slides), devcontainers.Try it
GITHUB_TOKEN, run the Python or .NET app against GitHub Models, work throughdocs/labs/.azd upprovisions the full stack via AVM Bicep; redeploys the agent apps to Container Apps with managed identity.Closes #6 (Epic) and #4 (Quality gate). Workstream issues #1, #2, #3, #5, #7, #8 closed on merge.