<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>rss.livelink.threads-in-node</title>
    <link>https://techcommunity.microsoft.com/t5/education-sector/ct-p/EducationSector</link>
    <description>rss.livelink.threads-in-node</description>
    <pubDate>Mon, 03 Aug 2026 21:28:22 GMT</pubDate>
    <dc:creator>EducationSector</dc:creator>
    <dc:date>2026-08-03T21:28:22Z</dc:date>
    <item>
      <title>CivicGrant IQ: The Five-Agent AI That Reads Federal Grants So Cities Don't Have To</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/civicgrant-iq-the-five-agent-ai-that-reads-federal-grants-so/ba-p/4542419</link>
      <description>&lt;P&gt;&lt;IMG class="blog" src="https://cdn.jsdelivr.net/gh/JonEricEubanks/CivicGrant-IQ@main/docs/hero.svg" alt="CivicGrant IQ — five-agent fleet, six-step reasoning, GraphRAG-cited, never down" /&gt;&lt;/P&gt;
&lt;P&gt;Guest post by &lt;A class="lia-external-url" href="https://www.linkedin.com/in/joneric-eubanks-pmp-developer" target="_blank"&gt;JonEric Eubanks&lt;/A&gt; winner of Best use of Microsoft IQ series for Agents League 2026 Hackathon.&lt;/P&gt;
&lt;H3&gt;The meeting that started this&lt;/H3&gt;
&lt;P&gt;Every city has the same meeting. Finance finds a federal grant that looks relevant. A department director, a project manager, and a grants coordinator gather around an 80-page Notice of Funding Opportunity (NOFO) and spend two hours trying to answer three questions: &lt;EM&gt;Do we qualify? Which of our projects fits? Is it worth the effort?&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Nobody has a good answer by the end. The NOFO is written for federal program officers, not city staff. So most of the time the city does nothing, the deadline passes, and real, appropriated money goes unclaimed.&lt;/P&gt;
&lt;P&gt;I've built production tools for local government for years, including an app that won Microsoft's global Best in Automation award. The single biggest gap I keep seeing is the grant lifecycle: finding the right opportunity, proving you qualify, drafting the application, and tracking compliance is slow, fragmented work. A city of 40,000 might have one part-time person responsible for all of it, and asking them to spend 80–200 hours on an uncertain application means deprioritizing everything else.&lt;/P&gt;
&lt;P&gt;So for the hackathon, I built the analyst that actually has the answers.&lt;/P&gt;
&lt;H3&gt;What it does&lt;/H3&gt;
&lt;P&gt;Paste a federal NOFO, or a URL, or just a description, and CivicGrant IQ streams a six-step reasoning chain to the screen in under 60 seconds:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Parse&lt;/STRONG&gt; the grant's requirements, award ceiling, deadline, and eligibility rules&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Match&lt;/STRONG&gt; the city's Capital Improvement Plan projects and past applications against them&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Verify&lt;/STRONG&gt; cost-share capacity against the city's live financial profile&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Score&lt;/STRONG&gt; every gap by severity, with a specific strategy to close each&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Draft&lt;/STRONG&gt; a 150–200 word narrative anchored in the city's closest winning application&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Plan&lt;/STRONG&gt; a four-week action calendar with department owners&lt;/LI&gt;
&lt;/OL&gt;
&lt;!-- ═══ IMAGE 2 · demo-flow ═══ --&gt;
&lt;P&gt;&lt;IMG class="blog" src="https://cdn.jsdelivr.net/gh/JonEricEubanks/CivicGrant-IQ@main/docs/demo-flow.svg" alt="Six-step reasoning chain, from pasted NOFO to submission-ready dashboard" /&gt;&lt;/P&gt;
&lt;P&gt;While that runs, two more agents work in parallel: &lt;STRONG&gt;Competitive Intel&lt;/STRONG&gt; maps the likely field, and a &lt;STRONG&gt;Red Team GS-14 Reviewer&lt;/STRONG&gt; scores the draft like a skeptical senior federal reviewer. When it's done, a live dashboard renders inline, match gauge, gap cards, timeline, and &lt;STRONG&gt;every figure traces to a cited source document.&lt;/STRONG&gt;&lt;/P&gt;
&lt;!-- ═══ IMAGE 3 · multi-agent ═══ --&gt;
&lt;P&gt;&lt;IMG class="blog" src="https://cdn.jsdelivr.net/gh/JonEricEubanks/CivicGrant-IQ@main/docs/multi-agent.svg" alt="Five specialist agents: Main Analyst, Competitive Intel, Red Team GS-14 Reviewer, Portfolio Scanner, Narrative Refinement" /&gt;&lt;/P&gt;
&lt;H3&gt;The architecture&lt;/H3&gt;
&lt;P&gt;Four Microsoft IQ layers, plus a GraphRAG reasoning layer, all load-bearing:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Foundry IQ&lt;/STRONG&gt; (Azure AI Search) grounds every city-specific claim in real documents. The model can't invent a strength it can't source.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Work IQ&lt;/STRONG&gt; pulls four live Microsoft 365 signals at query time, calendar deadlines, flagged grant emails, SharePoint project docs, Teams context, so the agent knows what the city is working on &lt;EM&gt;now&lt;/EM&gt;.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Fabric IQ&lt;/STRONG&gt; connects to a live Microsoft Fabric lakehouse for real disbursement rates and compliance status. "100% compliance" is a live SQL query, not a cached claim.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Web IQ&lt;/STRONG&gt; pulls the &lt;STRONG&gt;live Grants.gov feed&lt;/STRONG&gt; for real-time open programs and award ceilings, ranked by fit and refreshed daily, so the opportunity list is never stale.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;GraphRAG&lt;/STRONG&gt; traverses a typed entity graph so every reasoning hop carries its own citation, not just the final answer.&lt;/LI&gt;
&lt;/UL&gt;
&lt;!-- ═══ IMAGE 4 · iq-layers ═══ --&gt;
&lt;P&gt;&lt;IMG class="blog" src="https://cdn.jsdelivr.net/gh/JonEricEubanks/CivicGrant-IQ@main/docs/iq-layers.svg" alt="Four IQ layers — Foundry IQ, Work IQ, Fabric IQ, Web IQ — all load-bearing" /&gt;&lt;/P&gt;
&lt;P&gt;Under the hood: Azure OpenAI (gpt-4o-mini) via the Assistants API, an Express/TypeScript backend streaming SSE events step-by-step, and a React 18 frontend that renders the reasoning chain and dashboard live as they stream.&lt;/P&gt;
&lt;H3&gt;Two patterns worth stealing&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;The widget protocol.&lt;/STRONG&gt; A chat streams text, but a grant tool needs a dashboard. Instead of building two UIs, the agent embeds a JSON block in its response. The server strips it from the display text and fires it as a separate event:&lt;/P&gt;
&lt;LI-CODE lang="javascript"&gt;// Strip the ```widget block from the text the user sees…
const WIDGET = /```widget\s*([\s\S]*?)```/;
const clean = text.replace(/```widget[\s\S]*?```/g, "").trim();

// …then emit the parsed JSON as its own SSE event.
const match = text.match(WIDGET);
if (match) {
  try { send("widget", JSON.parse(match[1])); }
  catch { /* malformed → the text answer is still complete */ }
}&lt;/LI-CODE&gt;
&lt;P&gt;The frontend renders a live dashboard inline. If the JSON is malformed, the component just doesn't mount, the text answer is still complete.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The three-tier fallback.&lt;/STRONG&gt; Every API fails at the worst moment, usually mid-demo. Tier 1 is the Assistants API with Foundry IQ. If it fails, Tier 2 rebuilds the same prompt as a Chat Completions call. If both are down, Tier 3 serves deterministic results with no API calls. Result: zero failures across twelve demo runs, two of them on conference Wi-Fi.&lt;/P&gt;
&lt;!-- ═══ IMAGE 5 · fallback-pipeline ═══ --&gt;
&lt;P&gt;&lt;IMG class="blog" src="https://cdn.jsdelivr.net/gh/JonEricEubanks/CivicGrant-IQ@main/docs/fallback-pipeline.svg" alt="Three-tier never-down fallback: Assistants API → Chat Completions → deterministic mock engine" /&gt;&lt;/P&gt;
&lt;H3&gt;Results&lt;/H3&gt;
&lt;!-- ═══ IMAGE 6 · stats-banner ═══ --&gt;
&lt;P&gt;&lt;IMG class="blog" src="https://cdn.jsdelivr.net/gh/JonEricEubanks/CivicGrant-IQ@main/docs/stats-banner.svg" alt="$1.25B matched · 91% BRIC match · three drafts in 90s each · Best IQ Agent" /&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;$1.25B&lt;/STRONG&gt; in verified open federal funding matched across 10 programs for one mid-sized city&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;91% match score&lt;/STRONG&gt; for FEMA BRIC, grounded in the city's real CRS rating and 2025 application&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Three submission-ready drafts&lt;/STRONG&gt; generated from precedent in under 90 seconds each&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Named Best IQ Agent&lt;/STRONG&gt; from a field of nearly 5,000 contestants&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The metric I care about most: a grants coordinator can now make a real go/no-go decision in under an hour. It used to take a week.&lt;/P&gt;
&lt;H3&gt;What I learned&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Make the reasoning visible.&lt;/STRONG&gt; A streamed, sourced six-step chain is evidence. An opaque score is just a claim.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Real data beats a curated demo.&lt;/STRONG&gt; Judges could open Grants.gov and verify the numbers on the spot. That moment is worth more than any diagram.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Grounding is a discipline, not a feature.&lt;/STRONG&gt; A model that can't invent strengths is a better analyst than one that can.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;The fallback is the product.&lt;/STRONG&gt; Government staff will run this mid-presentation. It can't fail.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Try it or build on it&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Live app:&lt;/STRONG&gt; &lt;A href="https://proud-field-00978990f.7.azurestaticapps.net" target="_blank" rel="noopener"&gt;https://proud-field-00978990f.7.azurestaticapps.net&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Demo (5 min):&lt;/STRONG&gt; &lt;A href="https://youtu.be/dTRjA8eKwgQ" target="_blank" rel="noopener"&gt;https://youtu.be/dTRjA8eKwgQ&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;GitHub:&lt;/STRONG&gt; &lt;A href="https://github.com/JonEricEubanks/CivicGrant-IQ" target="_blank" rel="noopener"&gt;https://github.com/JonEricEubanks/CivicGrant-IQ&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The patterns transfer anywhere you have a dense document corpus, a user without time to search it, and a need for cited, real-time analysis,&amp;nbsp; procurement, compliance, and nonprofit grants. Every year, billions in federal grants go unclaimed by the cities they were built for. Not because they don't qualify,&amp;nbsp; because knowing they qualify is invisible work done by people already doing three other jobs. That's solvable.&lt;/P&gt;</description>
      <pubDate>Fri, 31 Jul 2026 07:14:35 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/civicgrant-iq-the-five-agent-ai-that-reads-federal-grants-so/ba-p/4542419</guid>
      <dc:creator>JonEricEubanks</dc:creator>
      <dc:date>2026-07-31T07:14:35Z</dc:date>
    </item>
    <item>
      <title>ARGUS: Compliance Infrastructure That Believes Financial Access Is a Human Right</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/argus-compliance-infrastructure-that-believes-financial-access/ba-p/4539074</link>
      <description>&lt;P data-line="5"&gt;Guest post by &lt;A href="https://www.linkedin.com/in/iarjunganesh/" target="_blank"&gt;𝐀𝐫𝐣𝐮𝐧 𝐆𝐚𝐧𝐞𝐬𝐡 &lt;/A&gt;Winner of Hack for Good category Microsoft Agents League Hackathon&lt;BR /&gt;&lt;BR /&gt;A refugee family in Germany spends 18 months trying to open a bank account. Their documents are legitimate. But an automated KYC system — never designed with them in mind — scores their jurisdiction as high risk and closes the case. No human review. No plain-language explanation. No appeal path.&lt;/P&gt;
&lt;P data-line="7"&gt;An NGO doing legitimate microfinance work in Southeast Asia gets de-risked by their correspondent bank. The letter cites "risk appetite." The lending operation, which supports 4,000 families, can no longer move money.&lt;/P&gt;
&lt;P data-line="9"&gt;These aren't edge cases.&amp;nbsp;&lt;STRONG&gt;1.4 billion people remain financially excluded globally&lt;/STRONG&gt;&amp;nbsp;— and compliance systems built to protect institutions are a leading cause. The same technology meant to stop financial crime routinely shuts out the people who most need access.&lt;/P&gt;
&lt;P data-line="11"&gt;That's the problem I set out to fix with&amp;nbsp;&lt;STRONG&gt;ARGUS&lt;/STRONG&gt;&amp;nbsp;(Agentic Risk &amp;amp; Governance Unified Screening) at the Microsoft Agents League — AI Skills Fest 2026, where it was selected as&amp;nbsp;&lt;STRONG&gt;1 of 3 Hack for Good winners&lt;/STRONG&gt;&amp;nbsp;— awarded to the best solutions to solve a community need.&lt;/P&gt;
&lt;H2 data-line="13"&gt;What ARGUS does&lt;/H2&gt;
&lt;P data-line="15"&gt;ARGUS is compliance infrastructure that is explainable, accessible, and open — designed from the ground up for the humans most likely to be failed by the systems they depend on, not just for the institutions running the checks.&lt;/P&gt;
&lt;P data-line="17"&gt;A single KYC request fans out across&amp;nbsp;&lt;STRONG&gt;five specialist AI agents&lt;/STRONG&gt;, coordinated via the&amp;nbsp;&lt;STRONG&gt;Agent-to-Agent (A2A) protocol&lt;/STRONG&gt;&amp;nbsp;on&amp;nbsp;&lt;STRONG&gt;Azure AI Foundry&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL data-line="19"&gt;
&lt;LI data-line="19"&gt;🎯 &lt;STRONG&gt;Orchestrator Agent&lt;/STRONG&gt;&amp;nbsp;— task decomposition and result synthesis&lt;/LI&gt;
&lt;LI data-line="20"&gt;🪪 &lt;STRONG&gt;Identity Agent&lt;/STRONG&gt;&amp;nbsp;— customer lookup, OCR processing, identity validation&lt;/LI&gt;
&lt;LI data-line="21"&gt;🔍&amp;nbsp;&lt;STRONG&gt;Screening Agent&lt;/STRONG&gt;&amp;nbsp;— sanctions checks, adverse media scanning, PEP checks&lt;/LI&gt;
&lt;LI data-line="22"&gt;🏢&amp;nbsp;&lt;STRONG&gt;Corporate Intelligence Agent&lt;/STRONG&gt;&amp;nbsp;— UBO resolution, registry lookups, jurisdiction mapping&lt;/LI&gt;
&lt;LI data-line="23"&gt;💳&amp;nbsp;&lt;STRONG&gt;Transaction Intelligence Agent&lt;/STRONG&gt;&amp;nbsp;— transaction monitoring, pattern detection, typology matching&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-line="25"&gt;Each of these fans back into a&amp;nbsp;&lt;STRONG&gt;Compliance &amp;amp; Risk Agent&lt;/STRONG&gt;, which synthesizes everything into a single traceable risk report.&lt;/P&gt;
&lt;P data-line="27"&gt;The part I'm proudest of: nothing in that report is a black box. Every finding is grounded in cited regulatory knowledge via&amp;nbsp;&lt;STRONG&gt;Foundry IQ&lt;/STRONG&gt; — sanctions checks and regulatory triggers cite the exact knowledge base, source document, and article behind them. Every risk score comes with a plain-English reason. Every decision leaves a full audit trail: agent by agent, tool by tool, citation by citation.&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;EM&gt;Submit entity → 5 agents run in parallel → Compliance fan-in → Traceable risk report&lt;/EM&gt;&lt;/P&gt;
&lt;P data-line="33"&gt;📹&amp;nbsp;&lt;A href="https://youtu.be/yaTNCgCwX4s" target="_blank" rel="noopener" data-href="https://youtu.be/yaTNCgCwX4s"&gt;Watch the 5-minute demo&lt;/A&gt;&lt;/P&gt;
&lt;H2 data-line="35"&gt;What's next: ARGUS v2&lt;/H2&gt;
&lt;P data-line="37"&gt;The hackathon build proved the architecture holds up. The v2 roadmap is where it grows into something NGOs and microfinance institutions can actually run:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;/th&gt;&lt;th&gt;Status&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;♿ Full WCAG 2.1 AA compliance&lt;/td&gt;&lt;td&gt;In progress&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;🗣 Explain Mode — plain-language reports for the person being screened&lt;/td&gt;&lt;td&gt;In progress&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;🌍 Community Edition — free, self-hostable, zero Azure subscription required&lt;/td&gt;&lt;td&gt;Designed&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;📊 Real-time Azure Monitor compliance dashboard&lt;/td&gt;&lt;td&gt;Designed&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;🔓 Open Knowledge Graph — FATF, Basel AML Index, OFAC/EU/UN lists as open data&lt;/td&gt;&lt;td&gt;Planned&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P data-line="47"&gt;&lt;STRONG&gt;Explain Mode&lt;/STRONG&gt;&amp;nbsp;is the one I'd highlight for an educator audience. Today's report is written for compliance analysts:&lt;/P&gt;
&lt;P data-line="49"&gt;&lt;EM&gt;"Dimension score 78 — HIGH tier — regulatory trigger: FATF Recommendation 16 (KB-Regulations › FATF-40 › R.16)"&lt;/EM&gt;&lt;/P&gt;
&lt;P data-line="51"&gt;Explain Mode generates the same finding for the person being screened, or the NGO caseworker who has to explain a decision to a family:&lt;/P&gt;
&lt;P data-line="53"&gt;&lt;EM&gt;"This account review flagged a potential concern with how money moved through the transaction chain. This is a standard check for large or cross-border transfers. A compliance officer will review this before a final decision is made. You don't need to do anything right now."&lt;/EM&gt;&lt;/P&gt;
&lt;P data-line="55"&gt;Same underlying data. Entirely different outcome for the person on the receiving end.&lt;/P&gt;
&lt;P data-line="57"&gt;&lt;STRONG&gt;Community Edition&lt;/STRONG&gt;&amp;nbsp;is the biggest bet: a zero-cost, self-hostable configuration for NGOs, microfinance institutions, community banks, and researchers — a pre-seeded public knowledge base, a one-command Docker Compose stack, and a lower-cost LLM path, so an Azure subscription isn't a prerequisite for the core flow.&lt;/P&gt;
&lt;H2 data-line="59"&gt;Try it yourself&lt;/H2&gt;
&lt;P data-line="61"&gt;ARGUS is open source under MIT. If you're teaching agentic AI, Azure AI Foundry, or Semantic Kernel, the repo is built to be a working example of multi-agent orchestration with A2A and grounded retrieval via Foundry IQ:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;git clone https://github.com/iarjunganesh/argus.git
cd argus
pip install -r requirements.txt
cp .env.example .env
make generate-data &amp;amp;&amp;amp; make generate-ocr-docs
make index-knowledge-bases
.\scripts\start_demo.ps1&lt;/LI-CODE&gt;
&lt;P data-line="73"&gt;The Community Edition — no Azure subscription required — is scaffolded in&amp;nbsp;&lt;A href="https://github.com/iarjunganesh/argus/tree/main/community" target="_blank" rel="noopener" data-href="https://github.com/iarjunganesh/argus/tree/main/community"&gt;community/&lt;/A&gt;&amp;nbsp;as part of the v2 roadmap, but isn't runnable yet.&lt;/P&gt;
&lt;P data-line="75"&gt;The most-needed contributions right now are WCAG contrast tests for the Gradio UI, translations of Explain Mode output, and finishing the Community Edition Docker Compose stack (Dockerfile + local knowledge base seed) — all good starter issues for students exploring accessible AI system design.&lt;/P&gt;
&lt;P data-line="77"&gt;&lt;STRONG&gt;Repo:&lt;/STRONG&gt;&amp;nbsp;&lt;A href="https://github.com/iarjunganesh/argus" target="_blank" rel="noopener" data-href="https://github.com/iarjunganesh/argus"&gt;https://github.com/iarjunganesh/argus&lt;/A&gt;&lt;/P&gt;
&lt;P data-line="77"&gt;&lt;STRONG&gt;Demo video:&lt;/STRONG&gt;&amp;nbsp;&lt;A href="https://youtu.be/yaTNCgCwX4s" target="_blank" rel="noopener" data-href="https://youtu.be/yaTNCgCwX4s"&gt;https://youtu.be/yaTNCgCwX4s&lt;/A&gt;&lt;/P&gt;
&lt;P data-line="80"&gt;&lt;EM&gt;ARGUS is a technology demonstration and is not a licensed compliance tool — it must not be used to make real KYC/AML decisions.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 30 Jul 2026 07:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/argus-compliance-infrastructure-that-believes-financial-access/ba-p/4539074</guid>
      <dc:creator>iarjunganesh</dc:creator>
      <dc:date>2026-07-30T07:00:00Z</dc:date>
    </item>
    <item>
      <title>Grounded AI That Won't Invent Facts: Building "Tell My Day" with Microsoft Foundry IQ</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/grounded-ai-that-won-t-invent-facts-building-quot-tell-my-day/ba-p/4539116</link>
      <description>&lt;P data-sourcepos="7:1-7:473;530-1002"&gt;Guest post by &lt;A class="lia-external-url" href="https://www.linkedin.com/in/cadenstorkamp" target="_blank"&gt;Caden Storkamp&lt;/A&gt; Winner of the Hack for Good Category Microsoft Agents League Hackathon&lt;/P&gt;
&lt;P data-sourcepos="7:1-7:473;530-1002"&gt;Large language models make things up. For a lot of apps that is a minor annoyance you can smooth over. For some, it is disqualifying, because the cost of a confident, fluent, false statement is real. This post walks through one of those cases and the pattern that makes it safe to ship: retrieve from a trusted knowledge base with Microsoft Foundry IQ, force the model to cite verbatim quotes, and then verify those quotes on the server before anything reaches the screen.&lt;/P&gt;
&lt;P data-sourcepos="9:1-9:451;1004-1454"&gt;My name is Caden Storkamp, and the app I build is called Tell My Day. I work as a direct support professional, and in this role I work day to day with people who use AAC (augmentative and alternative communication). The use of the app I made is not just limited to it's primary goal, but can be also used as an example for others. If you are teaching or building anything where a generative feature has to be trustworthy, this is a small, readable, reproducible reference you can lift from.&lt;/P&gt;
&lt;H5 data-sourcepos="11:1-11:57;1456-1512"&gt;&lt;STRONG&gt;The problem, and why it is the sharpest possible test&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="13:1-13:356;1514-1869"&gt;AAC (augmentative and alternative communication) is how many non-speaking people communicate: picture boards, symbol devices, picture exchange. These tools are good at "I want a drink" in the moment. They are much worse at letting someone tell a story, like how their day went, in their own voice. Caregivers or family members often end up narrating on the person's behalf.&lt;/P&gt;
&lt;P data-sourcepos="15:1-15:603;1871-2473"&gt;Tell My Day flips that. The person picks the symbols, and the app writes the story. That immediately raises the stakes to the highest possible level for hallucination, because you are now generating first-person speech attributed to someone who cannot easily correct you. If the app writes "I went to the zoo today" when they did not, it has put false words in a non-speaking person's mouth, to the people they most need to trust them. So "never invent anything" is not just a great thing to have here. It is the whole product. That constraint is exactly why it makes such a clean showcase for grounded generation.&lt;/P&gt;
&lt;H5 data-sourcepos="17:1-17:21;2475-2495"&gt;&lt;STRONG&gt;What the app does&lt;/STRONG&gt;&lt;/H5&gt;
&lt;OL data-sourcepos="19:1-22:136;2497-2946"&gt;
&lt;LI data-sourcepos="19:1-19:98;2497-2594"&gt;A non-speaking adult taps 3 to 8 picture symbols (people, places, activities, feelings, food).&lt;/LI&gt;
&lt;LI data-sourcepos="20:1-20:62;2595-2656"&gt;The app writes 2 to 4 short, warm, first-person sentences.&lt;/LI&gt;
&lt;LI data-sourcepos="21:1-21:154;2657-2810"&gt;The story is grounded in the person's own "About Me" profile, so a generic "my friend" becomes "my friend Marcus" only when that fact actually exists.&lt;/LI&gt;
&lt;LI data-sourcepos="22:1-22:136;2811-2946"&gt;Every grounded detail shows a citation, the story reads aloud, and unmatched symbols stay general instead of getting a made-up name.
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;H5&gt;&lt;STRONG&gt;The Microsoft stack at a glance&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="28:1-28:66;3093-3158"&gt;Everything here is Azure, and the whole thing runs on free tiers.&lt;/P&gt;
&lt;UL data-sourcepos="30:1-34:51;3160-3908"&gt;
&lt;LI data-sourcepos="30:1-30:214;3160-3373"&gt;&lt;STRONG&gt;Azure Static Web Apps (Free plan):&lt;/STRONG&gt; hosts the static React frontend and a set of managed Azure Functions together, with one GitHub Actions deploy. All secrets live in environment variables on the server side.&lt;/LI&gt;
&lt;LI data-sourcepos="31:1-31:235;3374-3608"&gt;&lt;STRONG&gt;Microsoft Foundry IQ:&lt;/STRONG&gt; the knowledge layer. A knowledge base over an Azure AI Search knowledge source holds the profile, and a single retrieve call does agentic retrieval and returns grounded, numbered facts with their sources.&lt;/LI&gt;
&lt;LI data-sourcepos="32:1-32:172;3609-3780"&gt;&lt;STRONG&gt;Microsoft Foundry model deployment (gpt-4.1-mini):&lt;/STRONG&gt; turns the retrieved facts plus the selected symbols into the story, called through the OpenAI-compatible endpoint.&lt;/LI&gt;
&lt;LI data-sourcepos="33:1-33:77;3781-3857"&gt;&lt;STRONG&gt;Web Speech API:&lt;/STRONG&gt; free, offline, zero-latency read-aloud in the browser.&lt;/LI&gt;
&lt;LI data-sourcepos="34:1-34:51;3858-3908"&gt;&lt;STRONG&gt;GitHub Copilot:&lt;/STRONG&gt; used throughout development.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-sourcepos="36:1-36:119;3910-4028"&gt;Here is the request flow. The key property is that the browser never holds a secret and never talks to Azure directly.&lt;/P&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;img /&gt;
&lt;H5 data-sourcepos="59:1-59:30;4807-4836"&gt;&lt;STRONG&gt;How it works, step by step&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="61:1-61:162;4838-4999"&gt;The whole backend is one framework-agnostic pipeline behind a roughly 15-line Azure Function, so no secret ever reaches the client. Four pieces do the real work.&lt;/P&gt;
&lt;H5 data-sourcepos="63:1-63:49;5001-5049"&gt;&lt;STRONG&gt;1. Stand up the knowledge base (one command)&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="65:1-65:338;5051-5388"&gt;Foundry IQ setup is refreshingly declarative. A single script (npm run setup:iq) creates a "file" knowledge source, uploads the five profile markdown files, and creates the knowledge base that retrieval runs against. Because the profile is small, a keyword-based file source is used, so there is no embedding model to configure at all.&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN class="lia-text-color-19"&gt;// 1) A "file" knowledge source: keyword retrieval, no embedding model needed.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-15"&gt;&lt;SPAN class="lia-text-color-14"&gt;await&lt;/SPAN&gt; put&lt;/SPAN&gt;(&lt;SPAN class="lia-text-color-11"&gt;`&lt;/SPAN&gt;${&lt;SPAN class="lia-text-color-11"&gt;searchEndpoint&lt;/SPAN&gt;}&lt;SPAN class="lia-text-color-11"&gt;/knowledgesources/tell-my-day-ks?api-version=&lt;/SPAN&gt;${&lt;SPAN class="lia-text-color-11"&gt;apiVersion&lt;/SPAN&gt;}&lt;SPAN class="lia-text-color-11"&gt;`&lt;/SPAN&gt;, {&lt;BR /&gt;  name: &lt;SPAN class="lia-text-color-11"&gt;"tell-my-day-ks"&lt;/SPAN&gt;,&lt;BR /&gt;  kind: &lt;SPAN class="lia-text-color-11"&gt;"file"&lt;/SPAN&gt;,&lt;BR /&gt;  fileParameters: { ingestionParameters: { contentExtractionMode: "minimal" } },&lt;BR /&gt;});&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-19"&gt;// (each docs/profile/*.md is then uploaded as a file)&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-19"&gt;// 2) The knowledge base that retrieval runs against.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-14"&gt;await&lt;/SPAN&gt; &lt;SPAN class="lia-text-color-15"&gt;put&lt;/SPAN&gt;(`${&lt;SPAN class="lia-text-color-11"&gt;searchEndpoint&lt;/SPAN&gt;}&lt;SPAN class="lia-text-color-11"&gt;/knowledgebases/tell-my-day-kb?api-&lt;/SPAN&gt;&lt;SPAN class="lia-text-color-11"&gt;version=&lt;/SPAN&gt;${&lt;SPAN class="lia-text-color-11"&gt;apiVersion&lt;/SPAN&gt;}&lt;SPAN class="lia-text-color-11"&gt;`&lt;/SPAN&gt;, {&lt;BR /&gt;  name: &lt;SPAN class="lia-text-color-11"&gt;"tell-my-day-kb"&lt;/SPAN&gt;,&lt;BR /&gt;  knowledgeSources: [{ name: &lt;SPAN class="lia-text-color-11"&gt;"tell-my-day-ks"&lt;/SPAN&gt; }],&lt;BR /&gt;  retrievalReasoningEffort: { kind: &lt;SPAN class="lia-text-color-11"&gt;"minimal"&lt;/SPAN&gt; },&lt;BR /&gt;});&lt;/PRE&gt;
&lt;P&gt;(The &lt;SPAN class="lia-text-color-13"&gt;put&lt;/SPAN&gt; helper above is shorthand for readability. The full, idempotent script is in the repo.)&lt;/P&gt;
&lt;H5 data-sourcepos="87:1-87:47;6137-6183"&gt;&lt;STRONG&gt;2. Retrieve grounded facts at request time&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="89:1-89:231;6185-6415"&gt;When the user submits their symbols, the Azure Function sends one semantic intent per symbol label to the knowledge base. Foundry IQ handles the retrieval and returns numbered facts, each tied back to the source file it came from.&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN class="lia-text-color-19"&gt;// One semantic intent per selected symbol label ("mom", "coffee shop", "happy").&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-14"&gt;const&lt;/SPAN&gt; url =&lt;SPAN class="lia-text-color-11"&gt;`&lt;/SPAN&gt;${&lt;SPAN class="lia-text-color-11"&gt;searchEndpoint&lt;/SPAN&gt;}/&lt;SPAN class="lia-text-color-11"&gt;knowledgebases/&lt;/SPAN&gt;${&lt;SPAN class="lia-text-color-11"&gt;kbName&lt;/SPAN&gt;}&lt;SPAN class="lia-text-color-11"&gt;/retrieve?&lt;/SPAN&gt;&lt;SPAN class="lia-text-color-11"&gt;api-version=&lt;/SPAN&gt;${&lt;SPAN class="lia-text-color-11"&gt;apiVersion&lt;/SPAN&gt;}&lt;SPAN class="lia-text-color-11"&gt;`&lt;/SPAN&gt;;&lt;BR /&gt;&lt;SPAN class="lia-text-color-14"&gt;const&lt;/SPAN&gt; res = &lt;SPAN class="lia-text-color-14"&gt;await&lt;/SPAN&gt; &lt;SPAN class="lia-text-color-15"&gt;fetch&lt;/SPAN&gt;(url, {&lt;BR /&gt;  method: &lt;SPAN class="lia-text-color-11"&gt;"POST"&lt;/SPAN&gt;,&lt;BR /&gt;  headers: { &lt;SPAN class="lia-text-color-13"&gt;"Content-Type"&lt;/SPAN&gt;: &lt;SPAN class="lia-text-color-11"&gt;"application/json"&lt;/SPAN&gt;, &lt;SPAN class="lia-text-color-13"&gt;"api-key"&lt;/SPAN&gt;: searchKey },&lt;BR /&gt;  body: &lt;SPAN class="lia-text-color-11"&gt;JSON&lt;/SPAN&gt;.&lt;SPAN class="lia-text-color-15"&gt;stringify&lt;/SPAN&gt;({&lt;BR /&gt;    intents: symbols.&lt;SPAN class="lia-text-color-15"&gt;map&lt;/SPAN&gt;((s) =&amp;gt; ({ type: &lt;SPAN class="lia-text-color-11"&gt;"semantic"&lt;/SPAN&gt;, search: s.label })),&lt;BR /&gt;  }),&lt;BR /&gt;});&lt;BR /&gt;&lt;SPAN class="lia-text-color-19"&gt;// Returns numbered, grounded facts, each carrying its source document name.&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;H5 data-sourcepos="104:1-104:51;6919-6969"&gt;&lt;STRONG&gt;3. Ground the model with a no-invention prompt&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="106:1-106:236;6971-7206"&gt;The retrieved facts and the symbols go to gpt-4.1-mini with a system prompt whose rules are the safety property, stated plainly. The model is required to return strict JSON where every sentence carries the verbatim quotes it relied on.&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN class="lia-text-color-19"&gt;// The rules the model must never break (trimmed):&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-11"&gt;`- Write 2 to 4 short, warm, first-person sentences.&lt;/SPAN&gt;&lt;BR /&gt;- Include the idea of EVERY selected symbol at least once.&lt;BR /&gt;- Use ONLY (a) the selected symbols and (b) the numbered profile facts.&lt;BR /&gt;  Never invent people, places, events, or details.&lt;BR /&gt;- If a symbol has no matching fact, keep it general ("my friend", "the park"), never a made-up name.&lt;BR /&gt;&lt;SPAN class="lia-text-color-11"&gt;- Return strict JSON: each sentence lists the verbatim quotes it relied on.`&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;The call itself uses &lt;SPAN class="lia-text-color-12"&gt;r&lt;/SPAN&gt;&lt;SPAN class="lia-text-color-12"&gt;&lt;SPAN class="lia-text-color-12"&gt;e&lt;/SPAN&gt;sponse_format: { type: "json_object" }&lt;/SPAN&gt; and a low temperature, so the output is structured and predictable rather than creative.&lt;/P&gt;
&lt;H5 data-sourcepos="121:1-121:69;7847-7915"&gt;&lt;STRONG&gt;4. Verify every quote on the server (the part that matters most)&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="123:1-123:347;7917-8263"&gt;A prompt that says "do not lie" is not a guarantee. So the server does not take the model's word for it. Every citation the model returns is checked against the actual retrieved fact. A quote that is not really there is kept but marked verified: false, which lets the interface show the user exactly which claims are grounded and which are not.&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN class="lia-text-color-19"&gt;// Is this quote actually present in the fact the model cited?&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-14"&gt;function&lt;/SPAN&gt; &lt;SPAN class="lia-text-color-15"&gt;verifyQuote&lt;/SPAN&gt;(quote: &lt;SPAN class="lia-text-color-12"&gt;string&lt;/SPAN&gt;, factContent: &lt;SPAN class="lia-text-color-12"&gt;string&lt;/SPAN&gt;): &lt;SPAN class="lia-text-color-12"&gt;boolean&lt;/SPAN&gt; {&lt;BR /&gt;&lt;SPAN class="lia-text-color-14"&gt;  const&lt;/SPAN&gt; q = &lt;SPAN class="lia-text-color-15"&gt;normalize&lt;/SPAN&gt;(quote);&lt;BR /&gt;&lt;SPAN class="lia-text-color-14"&gt;  return&lt;/SPAN&gt; q.length &amp;gt; &lt;SPAN class="lia-text-color-11"&gt;0&lt;/SPAN&gt; &amp;amp;&amp;amp; &lt;SPAN class="lia-text-color-15"&gt;normalize&lt;/SPAN&gt;(factContent).&lt;SPAN class="lia-text-color-15"&gt;includes&lt;/SPAN&gt;(q);&lt;BR /&gt;}&lt;BR /&gt;// ...when assembling each sentence's citations:&lt;BR /&gt;citations.&lt;SPAN class="lia-text-color-15"&gt;push&lt;/SPAN&gt;({&lt;BR /&gt;  factId: fact.factId,&lt;BR /&gt;  docName: fact.docName,&lt;BR /&gt;  quote,&lt;BR /&gt;  verified: &lt;SPAN class="lia-text-color-15"&gt;verifyQuote&lt;/SPAN&gt;(quote, fact.content),&lt;BR /&gt;});&lt;/PRE&gt;
&lt;P&gt;That is the whole trust story in one function. Retrieval limits what the model can know, the prompt forces it to cite, and this check confirms the citations are real before the user sees them. The pattern is not specific to AAC. It is reusable for any generative feature where a wrong answer costs something.&lt;/P&gt;
&lt;H5 data-sourcepos="143:1-143:43;8992-9034"&gt;&lt;STRONG&gt;Deploying free on Azure Static Web Apps&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="145:1-145:408;9036-9443"&gt;The frontend and the Azure Functions ship together. You create a Static Web App on the Free plan, add the deployment token as a GitHub Actions secret, put your Foundry and Azure AI Search values into the app's environment variables, and push to main. The included workflow builds the Vite app and deploys the api/ folder as managed functions. There is no separate server to run and nothing to keep warm.&lt;/P&gt;
&lt;H5 data-sourcepos="147:1-147:50;9445-9494"&gt;&lt;STRONG&gt;De-risking the build (a method worth teaching)&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="149:1-149:161;9496-9656"&gt;The riskiest part of this project was the integration I understood least: Foundry IQ. So it went first, behind two gates that had to pass before any UI existed.&lt;/P&gt;
&lt;PRE&gt;bash&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-15"&gt;npm&lt;/SPAN&gt; run setup:iq       &lt;SPAN class="lia-text-color-19"&gt;#&lt;/SPAN&gt;&lt;SPAN class="lia-text-color-19"&gt; create the knowledge source + upload profile + create the KB&lt;/SPAN&gt; &lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-15"&gt;npm&lt;/SPAN&gt; run test:model     &lt;SPAN class="lia-text-color-19"&gt;# gate 1: the model answers at all&lt;/SPAN&gt; &lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-15"&gt;npm&lt;/SPAN&gt; run test:iq        &lt;SPAN class="lia-text-color-19"&gt;# gate 2: retrieval returns grounded, cited facts&lt;/SPAN&gt; &lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-15"&gt;npm&lt;/SPAN&gt; run dev            &lt;SPAN class="lia-text-color-19"&gt;# only now build the app on top&lt;/SPAN&gt; &lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-15"&gt;npm&lt;/SPAN&gt; &lt;SPAN class="lia-text-color-12"&gt;test&lt;/SPAN&gt;               &lt;SPAN class="lia-text-color-19"&gt;# unit tests for validation, JSON parsing, and quote verification&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P data-sourcepos="159:1-159:310;10022-10331"&gt;Standing up and proving the retrieval before building anything on top of it meant the app was never resting on an assumption that could quietly turn out to be false. The verification logic, the input validation, and the parsing all have unit tests, so the trust-critical code is covered rather than hoped for.&lt;/P&gt;
&lt;H5 data-sourcepos="161:1-161:53;10333-10385"&gt;&lt;STRONG&gt;Accessibility is the product, not a coat of paint&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="163:1-163:111;10387-10497"&gt;Because the users are the entire point, accessibility is built into every component, not bolted on at the end.&lt;/P&gt;
&lt;UL data-sourcepos="165:1-168:106;10499-11269"&gt;
&lt;LI data-sourcepos="165:1-165:248;10499-10746"&gt;&lt;STRONG&gt;Two-level single-switch scanning:&lt;/STRONG&gt; regions highlight in turn, and one switch (Space, or a tap anywhere) drills in and selects, with adjustable scan speed. This is what makes the app usable for someone who cannot use a touchscreen or keyboard.&lt;/LI&gt;
&lt;LI data-sourcepos="166:1-166:214;10747-10960"&gt;&lt;STRONG&gt;Grounding as an accessibility feature:&lt;/STRONG&gt; a user who cannot easily correct the output has to be able to trust it, so the visible, verified citations are not a developer nicety. They are core to who this is for.&lt;/LI&gt;
&lt;LI data-sourcepos="167:1-167:203;10961-11163"&gt;Full keyboard operation, large tap targets (64px and up), an aria-live region for the story, a high-contrast theme, adjustable text size, and reduce-motion support that honors the system preference.&lt;/LI&gt;
&lt;LI data-sourcepos="168:1-168:106;11164-11269"&gt;Read-aloud with play and pause, adjustable speed and pitch, and word-by-word highlighting as it speaks.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-sourcepos="170:1-170:256;11271-11526"&gt;There is also a caregiver profile editor, gated by a server-side PIN, that writes edits straight back to the Foundry IQ knowledge source. The knowledge base stays the single source of truth, and new facts reach stories after about a minute of re-indexing.&lt;/P&gt;
&lt;H5 data-sourcepos="172:1-172:22;11528-11549"&gt;&lt;STRONG&gt;Results and impact&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="174:1-174:132;11551-11682"&gt;After completion of development, I was able to see Tell My Day demonstrate these outcomes:&lt;/P&gt;
&lt;UL data-sourcepos="178:1-180:152;11750-12324"&gt;
&lt;LI data-sourcepos="178:1-178:176;11750-11925"&gt;&lt;STRONG&gt;Every fact shown in a story is backed by a quote that was verified against its source.&lt;/STRONG&gt; A model claim that cannot be verified is flagged rather than presented as trusted.&lt;/LI&gt;
&lt;LI data-sourcepos="179:1-179:247;11926-12172"&gt;&lt;STRONG&gt;Symbols with no matching profile fact always stay general.&lt;/STRONG&gt; In the sample profile, selecting &lt;EM&gt;Grandma&lt;/EM&gt;, &lt;EM&gt;Beach&lt;/EM&gt;, or &lt;EM&gt;School&lt;/EM&gt; produces "my friend" or "the park," never a fabricated name. That is the behavior you can test yourself in the repo.&lt;/LI&gt;
&lt;LI data-sourcepos="180:1-180:152;12173-12324"&gt;&lt;STRONG&gt;The app is fully operable by keyboard and by a single switch,&lt;/STRONG&gt; which is the bar that decides whether an AAC tool is usable at all for many people.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-sourcepos="184:1-184:364;12467-12830"&gt;The honest differentiator is not the AI model. Anyone can call a model. It is that the product decisions (stay general instead of guessing, never infantilize, write a full sentence instead of a fragment) come from someone who watches real AAC communication succeed and fail, combined with a platform that made grounding and verification straightforward to implement.&lt;/P&gt;
&lt;H5 data-sourcepos="186:1-186:19;12832-12850"&gt;&lt;STRONG&gt;Lessons learned&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="188:1-188:367;12852-13218"&gt;&lt;STRONG&gt;The safety mechanism and the platform feature were the same thing.&lt;/STRONG&gt; Going in, "use Foundry IQ" and "never fabricate" looked like two separate tasks. They turned out to be one: Foundry IQ's retrieve-and-cite pattern &lt;EM&gt;is&lt;/EM&gt; the no-invention rule, and a small server-side verification step closes the gap between "the model cited something" and "the citation is real."&lt;/P&gt;
&lt;P data-sourcepos="190:1-190:157;13220-13376"&gt;&lt;STRONG&gt;Put the riskiest integration first.&lt;/STRONG&gt; Proving retrieval before building UI is cheap insurance against building something beautiful on a broken foundation.&lt;/P&gt;
&lt;P data-sourcepos="192:1-192:266;13378-13643"&gt;&lt;STRONG&gt;Grounding plus verification is a reusable pattern.&lt;/STRONG&gt; Retrieve from a trusted source, force citations, verify them server-side. That transfers to compliance summaries, customer support, internal knowledge assistants, anywhere a confident wrong answer is expensive.&lt;/P&gt;
&lt;H5 data-sourcepos="200:1-200:26;14457-14482"&gt;&lt;STRONG&gt;See it, or build on it&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P data-sourcepos="202:1-202:114;14484-14597"&gt;If you teach or build with Azure AI, care about trustworthy generative AI, or work in accessibility, take a look.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;GitHub repo:&lt;/STRONG&gt; &lt;A href="https://github.com/stork066/TellMyDay" target="_blank" rel="noopener"&gt;https://github.com/stork066/TellMyDay&lt;/A&gt; (to try it out yourself just clone it and run it with your own Foundry and Azure AI Search keys)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Demo video: &lt;/STRONG&gt;&lt;A class="lia-external-url" href="https://www.youtube.com/watch?v=v_8WAhurzOY" target="_blank" rel="noopener"&gt;https://www.youtube.com/watch?v=v_8WAhurzOY&lt;/A&gt;&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-sourcepos="207:1-207:435;14869-15303"&gt;Two ways to build on it. If you are learning Microsoft Foundry, this is a compact, working example of wiring a Foundry IQ knowledge base to a model and putting a verification layer around it, deployed on Azure Static Web Apps for free. And if you work anywhere that a generative feature has to be trusted, lift the grounding and verification pattern directly. The stakes in your domain may be different, but the mechanism is the same.&lt;/P&gt;</description>
      <pubDate>Wed, 29 Jul 2026 07:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/grounded-ai-that-won-t-invent-facts-building-quot-tell-my-day/ba-p/4539116</guid>
      <dc:creator>caden322</dc:creator>
      <dc:date>2026-07-29T07:00:00Z</dc:date>
    </item>
    <item>
      <title>How I Built CurriculumCraft AI — A Microsoft Hackathon Winning EdTech Solution for Ghana's Teachers</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/how-i-built-curriculumcraft-ai-a-microsoft-hackathon-winning/ba-p/4537826</link>
      <description>&lt;P&gt;By&amp;nbsp;&lt;A href="https://www.linkedin.com/in/gideon-k-agbavor/" target="_blank"&gt;Gideon K. Agbavor &lt;/A&gt;Top Student Award Winner, Microsoft Agents League AISF Hackathon 2026&lt;/P&gt;
&lt;H3&gt;A Problem I Lived as a Teacher&lt;/H3&gt;
&lt;P&gt;Before I branch into software developer, I am a Mathematics and ICT teacher in Ghana education or school system. Every Sunday evening and sometimes every three days, I sat with a thick PDF — Ghana's NaCCA Standards-Based Curriculum — and spent hours manually converting dense curriculum indicators into lesson plans for the week ahead.&lt;/P&gt;
&lt;P&gt;I was not alone. Across Ghana, thousands of Junior High School teachers (Primary teachers too) face the same challenge. They manage classes of 30 to 40 students, operate in under-resourced schools outside major cities, and have almost no planning support. The NaCCA Standards-Based Curriculum introduced by Ghana's National Council for Curriculum and Assessment is rigorous and well-structured — but translating its indicators into classroom-ready materials is time-consuming and administratively exhausting.&lt;/P&gt;
&lt;P&gt;When I heard about the Microsoft Agents League AISF Hackathon 2026, I knew exactly what I wanted to build — a tool that eliminates this burden for every Ghanaian JHS teacher, regardless of where they teach or how much support they have.&lt;/P&gt;
&lt;P&gt;That tool became &lt;STRONG&gt;CurriculumCraft AI&lt;/STRONG&gt; — and it won one of the&amp;nbsp;&lt;STRONG&gt;Top Student Award&lt;/STRONG&gt; at the hackathon.&lt;/P&gt;
&lt;H3&gt;The Solution — CurriculumCraft AI&lt;/H3&gt;
&lt;P&gt;CurriculumCraft AI is a full-stack AI-powered instructional design platfo&lt;/P&gt;
&lt;P&gt;rm that transforms any NaCCA curriculum indicator into complete, classroom-ready lesson materials in seconds.&lt;/P&gt;
&lt;P&gt;A teacher visits the app, selects their subject, grade level (B7, B8, or B9), strand, and indicator from the real NaCCA curriculum tree — and the app generates three complete outputs instantly:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Teacher Notes&lt;/STRONG&gt; — a full lesson plan with timings, learning objectives aligned to Bloom's Taxonomy, key vocabulary, common misconceptions, and differentiation tips for mixed-ability classes&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Visual Content Prompts&lt;/STRONG&gt; — four practical classroom visual aids a teacher can create with minimal resources, designed specifically for under-resourced Ghanaian classrooms&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Student Reading Material&lt;/STRONG&gt; — a culturally relevant reading passage using authentic Ghanaian names, settings, and examples, complete with worked examples and comprehension questions&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Beyond lesson generation, the app also features an &lt;STRONG&gt;Interactive Activity Suite&lt;/STRONG&gt; that generates multiple-choice questions with instant answer feedback, writing prompts with sample answers, and assessment rubrics — all aligned to the selected NaCCA indicator.&lt;/P&gt;
&lt;P&gt;Every piece of generated content uses authentic Ghanaian cultural context — local names like Ama, Kofi, and Adjoa, local settings like Kumasi Central Market and Cape Coast fishing harbour, Ghana Cedis for mathematical examples, and references to local foods and traditions. A student in Ho, Tamale, Accra, or Bolgatanga should see themselves in their learning materials.&lt;/P&gt;
&lt;H3&gt;Architecture and Technology&lt;/H3&gt;
&lt;P&gt;CurriculumCraft AI is built on a modern full-stack architecture designed for reliability, performance, and scalability.&lt;/P&gt;
&lt;img&gt;architecture&lt;/img&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Frontend:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Next.js 15 with App Router and React Server Components&lt;/LI&gt;
&lt;LI&gt;Tailwind CSS v4 for responsive, accessible styling&lt;/LI&gt;
&lt;LI&gt;shadcn/ui for polished component design&lt;/LI&gt;
&lt;LI&gt;Dark and light theme support&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Backend:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Next.js API Routes for server-side logic&lt;/LI&gt;
&lt;LI&gt;Neon PostgreSQL (serverless) as the database&lt;/LI&gt;
&lt;LI&gt;Drizzle ORM for type-safe database queries&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;AI and Microsoft Services:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Microsoft Foundry IQ&lt;/STRONG&gt; — the intelligence grounding layer that retrieves NaCCA curriculum context before each generation request, anchoring outputs to actual curriculum standards&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;GitHub Models (gpt-4o-mini)&lt;/STRONG&gt; — the generation layer that produces lesson materials based on the grounded context&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;GitHub Copilot&lt;/STRONG&gt; — used throughout development in VS Code for schema generation, API route scaffolding, component design, and prompt engineering&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Deployment:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Vercel for frontend and serverless API hosting&lt;/LI&gt;
&lt;LI&gt;Neon PostgreSQL for persistent curriculum and lesson data&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Data:&lt;/STRONG&gt;&lt;BR /&gt;The database is seeded with real NaCCA curriculum data across 7 subjects — Mathematics, Science, English Language, Computing, Social Studies, RME, and Career Technology — covering all three JHS grade levels (B7, B8, B9) with authentic indicator codes like B7.1.1.1.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;Microsoft Foundry IQ Integration&lt;/H3&gt;
&lt;P&gt;One of the core requirements of the Agents League Hackathon Creative Apps track was integrating at least one Microsoft IQ intelligence layer. I chose &lt;STRONG&gt;Microsoft Foundry IQ&lt;/STRONG&gt; as the grounding layer for CurriculumCraft AI.&lt;/P&gt;
&lt;P&gt;Before generating any lesson materials, the app queries the Agents League Foundry IQ hub to retrieve curriculum-specific context for the selected NaCCA indicator. This grounded context is then passed to the generation layer as additional prompt context, reducing hallucination and ensuring the generated content is anchored to actual curriculum standards rather than generic AI outputs.&lt;/P&gt;
&lt;P&gt;The integration is implemented in the /api/generate route and includes graceful fallback to direct generation when the endpoint is unavailable — ensuring the app remains fully functional under all conditions.&lt;/P&gt;
&lt;img /&gt;
&lt;H3&gt;GitHub Copilot — AI-Assisted Development&lt;/H3&gt;
&lt;P&gt;Building CurriculumCraft AI as a solo developer within the hackathon timeline would have been extremely difficult without &lt;STRONG&gt;GitHub Copilot&lt;/STRONG&gt; in VS Code. Copilot accelerated development at every layer:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Database schema&lt;/STRONG&gt; — I described the NaCCA curriculum structure in natural language and Copilot generated the complete Drizzle ORM schema for all five tables (subjects, strands, sub-strands, indicators, saved lessons) with proper foreign key relationships.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;API routes&lt;/STRONG&gt; — All four API routes (/api/curriculum, /api/generate, /api/generate/activity, /api/lessons) were scaffolded with Copilot inline completions, significantly reducing boilerplate.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;TypeScript types&lt;/STRONG&gt; — The full type definitions for the curriculum data structures, API request/response types, and component props were generated through Copilot Chat.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Prompt engineering&lt;/STRONG&gt; — The system prompts in prompts/lesson.ts and prompts/activity.ts were refined iteratively with Copilot suggestions, helping me structure the cultural context instructions and output formatting rules effectively.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Bug resolution&lt;/STRONG&gt; — ESLint errors, TypeScript type conflicts, and React hook dependency warnings were resolved quickly using Copilot Chat explanations, keeping the development velocity high.&lt;/P&gt;
&lt;H3&gt;Implementation — Key Challenges and How I Overcame Them&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Challenge 1 — Seeding real NaCCA curriculum data&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The NaCCA curriculum PDFs are dense documents not available as structured data. I manually extracted and structured the curriculum data for 7 subjects across 3 grade levels, creating a seed file that populates the database with authentic indicator codes and text.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Challenge 2 — Ghanaian cultural context in AI outputs&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Generic AI models default to Western cultural examples. I solved this by writing detailed system prompts that explicitly instruct the model to use Ghanaian names, settings, currency, and foods in every generated output. The result is lesson content that feels authentically Ghanaian to every teacher and student who uses it.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Challenge 3 — Tailwind CSS v4 dark mode&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Next.js 15 uses Tailwind CSS v4 which handles dark mode differently from v3. Instead of a tailwind.config.ts file, v4 uses @variant dark in globals.css. Resolving this required updating the CSS approach and adding proper dark: utility classes to every component.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Challenge 4 — PDF export with oklab colors&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The html2canvas library used for PDF export does not support the oklab color function that Tailwind v4 uses internally. I resolved this by switching to a text-based PDF generation approach using jsPDF directly, which produces cleaner, searchable PDF output without any color function dependencies.&lt;/P&gt;
&lt;H3&gt;Results and Impact&lt;/H3&gt;
&lt;P&gt;CurriculumCraft AI is live at &lt;A href="https://curriculumcraft-ai.vercel.app" target="_blank" rel="noopener"&gt;curriculumcraft-ai.vercel.app&lt;/A&gt; and covers:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;7 NaCCA subjects&lt;/STRONG&gt; — Mathematics, Science, English Language, Computing, Social Studies, RME, Career Technology&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;3 grade levels&lt;/STRONG&gt; — B7, B8, B9 (Junior High School)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;80+ authentic NaCCA indicators&lt;/STRONG&gt; with real curriculum codes&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;3 AI-powered views&lt;/STRONG&gt; — Standard Map Dashboard, Lesson Builder, Interactive Activity Suite&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Full mobile responsiveness&lt;/STRONG&gt; — teachers can use it on their phones&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The app requires no login and is completely free, removing all friction for teachers who want to try it immediately.&lt;/P&gt;
&lt;P&gt;Since sharing the app with Ghanaian teacher communities, the response has been enthusiastic. Teachers appreciate that the generated content uses Ghanaian names, settings, and examples that their students can relate to — not generic Western content that feels foreign in a Ghanaian classroom.&lt;/P&gt;
&lt;H3&gt;Lessons Learned&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Start with a real problem you understand personally.&lt;/STRONG&gt; My teaching background meant I deeply understood the pain point I was solving. That clarity showed in every feature decision.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Cultural context is a competitive advantage.&lt;/STRONG&gt; Any developer can build a lesson planner. Almost nobody builds one that generates a mathematics problem about cocoa farming in Ashanti Region for a B7 student. That specificity is what makes CurriculumCraft AI genuinely useful rather than just technically impressive.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Graceful degradation matters.&lt;/STRONG&gt; Building the Foundry IQ integration to fall back gracefully when the endpoint is unavailable meant the app always worked — even during quota limitations on the shared hackathon hub.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Ship early, iterate fast.&lt;/STRONG&gt; Having the app deployed on Vercel from day one meant I could test on real devices, share with real teachers, and get genuine feedback throughout the build.&lt;/P&gt;
&lt;H3&gt;Future Enhancements&lt;/H3&gt;
&lt;P&gt;CurriculumCraft AI is just getting started. Planned enhancements include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Authentication and user accounts&lt;/STRONG&gt; — personalized lesson libraries per teacher&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;School subscriptions&lt;/STRONG&gt; — institution-level access for entire schools&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Lesson completion tracker&lt;/STRONG&gt; — teachers mark indicators as taught, tracking curriculum coverage across the term&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Student Quiz Mode&lt;/STRONG&gt; — shareable quiz links teachers send directly to students&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Expansion to other African curricula&lt;/STRONG&gt; — Nigeria (NERDC), Kenya (CBC), Rwanda&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Offline support&lt;/STRONG&gt; — PWA capabilities for teachers in low-connectivity areas&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Conclusion&lt;/H3&gt;
&lt;P&gt;CurriculumCraft AI was built to solve a real problem faced by real teachers in Ghana every single week. By combining Microsoft Foundry IQ for curriculum grounding, GitHub Models for AI generation, and GitHub Copilot for accelerated development, I was able to build a production-ready application that delivers genuine value to Ghanaian educators.&lt;/P&gt;
&lt;P&gt;The Microsoft Agents League Hackathon gave me the platform, the tools, and the motivation to build something meaningful. Winning the Top Student Award is an honour — but the real prize is knowing that a teacher in Ho, Tamale, or Bolgatanga can now &lt;STRONG&gt;spend less time on paperwork and more time with their students.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Try CurriculumCraft AI:&lt;/STRONG&gt; &lt;A href="https://curriculumcraft-ai.vercel.app" target="_blank" rel="noopener"&gt;curriculumcraft-ai.vercel.app&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;GitHub Repository:&lt;/STRONG&gt; &lt;A href="https://github.com/gideonagbavor8/curriculumcraft-ai" target="_blank" rel="noopener"&gt;github.com/gideonagbavor8/curriculumcraft-ai&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Connect with me:&lt;/STRONG&gt; &lt;A class="lia-external-url" href="https://www.linkedin.com/in/gideon-k-agbavor" target="_blank" rel="noopener"&gt;https://www.linkedin.com/in/gideon-k-agbavor&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Gideon Komla Agbavor is a software developer and educator from Ho, Volta Region, Ghana. He is completing a BSc in Software Development at Brigham Young University-Idaho and is one of the Top Student Award winners at the Microsoft Agents League AISF Hackathon 2026.&lt;/EM&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 28 Jul 2026 07:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/how-i-built-curriculumcraft-ai-a-microsoft-hackathon-winning/ba-p/4537826</guid>
      <dc:creator>GideonAgbavor</dc:creator>
      <dc:date>2026-07-28T07:00:00Z</dc:date>
    </item>
    <item>
      <title>Building Archon: Where Models Stop and Financial Controls Begin</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/building-archon-where-models-stop-and-financial-controls-begin/ba-p/4537966</link>
      <description>&lt;P&gt;Guest post by &lt;A href="https://www.linkedin.com/in/efousekis/" target="_blank"&gt;Efthimios Fousekis &lt;/A&gt;&lt;A href="https://www.linkedin.com/in/jeremiah-fadesayo-adetoro-434774399/" target="_blank"&gt;&amp;nbsp;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;The winner of &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Best Enterprise Agent: Archon —&amp;nbsp;&lt;A href="https://github.com/upgradedev/archon_azure" target="_blank"&gt;https://github.com/upgradedev/archon_azure&lt;/A&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;Within the document-processing pipeline, model assistance is used at the unstructured edge and for optional narration. Classification, computation and checks are deterministic. Human review is available, but it is not an enforced approval gate in the current prototype.&lt;/P&gt;
&lt;P&gt;Archon was built as an Agentic Financial Intelligence prototype for SMBs for&amp;nbsp;&lt;A href="https://techcommunity.microsoft.com/blog/azuredevcommunityblog/agents-league-the-esports-inspired-hackathon-where-ai-agents-battle-for-glory/4521610" target="_blank" rel="noopener noreferrer"&gt;Microsoft’s Agents League at AI Skills Fest&lt;/A&gt;, where it was selected as the Enterprise Agents winner. While building it, I kept returning to one question: when should an AI model stop?&lt;/P&gt;
&lt;P&gt;A payroll register, a bank confirmation, and a set of payslips may each look correct in isolation. Together, however, they can still describe an incomplete or inconsistent financial event. One record describes employer cost. Another records a transfer. The payslips allocate net pay to employees. If a system treats those views as interchangeable, it can count the same period twice, omit a cost, or hide missing evidence behind a fluent summary.&lt;/P&gt;
&lt;P&gt;Archon remains a competition prototype. The more useful story is the engineering boundary between model-assisted interpretation, deterministic software and human review, and two gaps that made that boundary concrete: a visible review step is not an approval gate, and a check that cannot run is not a pass.&lt;/P&gt;
&lt;H2&gt;The business problem behind Archon&lt;/H2&gt;
&lt;P&gt;Financial work rarely depends on a single document. It depends on reconstructing an event from records created by different systems, at different times, for different purposes. A convincing narrative is not enough. A trustworthy workflow also needs to identify its source records, retain relevant intermediate artifacts, show which checks ran, and state what could not be established.&lt;/P&gt;
&lt;P&gt;That led to a bounded workflow. Archon preserves normalized records and intermediate artifacts. Within the document-processing pipeline, model assistance is used at the unstructured edge and, optionally, after deterministic analysis for narration. Explicit Python functions handle classification, grouping, arithmetic, consistency checks and reporting. The review screen exposes normalized documents before analysis.&lt;/P&gt;
&lt;P&gt;In this article, "controls" refers to deterministic software checks in a prototype, not audited accounting controls or a formal internal-control framework. Archon does not prove savings, accounting accuracy, production scale, regulatory compliance or measurable business impact. It demonstrates a design pattern and exposes where the prototype falls short.&lt;/P&gt;
&lt;H2&gt;What Archon does today&lt;/H2&gt;
&lt;P&gt;The core document-processing path has three distinct tiers: extraction, review and analysis.&lt;/P&gt;
&lt;P&gt;At the interaction layer, the repository includes a Microsoft 365 Copilot declarative-agent package configured to connect Copilot Chat and Teams to the FastAPI backend through an OpenAPI plugin. Its manifests and API contract are available in the public repository. The authenticated Microsoft 365 tenant path was not independently rerun for this article revision.&lt;/P&gt;
&lt;P&gt;The term agent covers two layers here. The Microsoft 365 declarative agent is the user-facing integration. Within the analysis service, six of the seven named stages are deterministic Python functions; only the optional narrator invokes a model.&lt;/P&gt;
&lt;P&gt;Archon accepts PDF, DOCX and common image formats. A FastAPI orchestration service stores the raw files in &lt;A href="https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction" target="_blank" rel="noopener noreferrer"&gt;Azure Blob Storage&lt;/A&gt; and can submit an &lt;A href="https://learn.microsoft.com/en-us/azure/container-apps/jobs" target="_blank" rel="noopener noreferrer"&gt;Azure Container Apps Job&lt;/A&gt;. Model-assisted extractors turn text or images into a common document schema.&lt;/P&gt;
&lt;P&gt;The extraction job then performs deterministic classification refinement, groups payroll records by company and issue-date period, and applies four extraction-time consistency checks. It writes three batch artifacts: &lt;CODE&gt;documents.json&lt;/CODE&gt;, &lt;CODE&gt;events.json&lt;/CODE&gt; and &lt;CODE&gt;validation.json&lt;/CODE&gt;.&lt;/P&gt;
&lt;P&gt;The visible review step happens after that job. The document view is classified for the review screen, where a user can change a type or exclude a document. If changes are saved, a reviewed &lt;CODE&gt;documents.json&lt;/CODE&gt; replaces the earlier document files for that period. The stored events and extraction validation are not rewritten, so they can become stale after review.&lt;/P&gt;
&lt;P&gt;The separate analysis service deliberately loads only &lt;CODE&gt;documents.json&lt;/CODE&gt;. It does not consume the extraction job’s stored events or validation results, and it does not rerun the original EventLinker stage. Instead, it classifies the documents again, builds P&amp;amp;L-style and cash-flow-proxy views, reruns period-level checks, performs vendor reconciliation, creates report evidence, and finally attempts an optional narrative.&lt;/P&gt;
&lt;P&gt;The optional narration stage follows one of two configured paths. With a project connection string, it attempts the &lt;A href="https://learn.microsoft.com/en-us/azure/foundry-classic/agents/concepts/threads-runs-messages" target="_blank" rel="noopener noreferrer"&gt;classic Threads, Messages and Runs implementation of Microsoft Foundry Agent Service&lt;/A&gt; with Azure AI Search; if that attempt fails, the service returns a deterministic numeric summary rather than retrying through Azure OpenAI. Without a project connection string, it uses Azure OpenAI Chat Completions, grounded by Search only when the separate Search settings are configured.&lt;/P&gt;
&lt;H2&gt;Where the model stops&lt;/H2&gt;
&lt;P&gt;Models are useful where layouts, labels, languages and scan quality vary. Archon constrains that work with accepted formats, a document-type enumeration, bounded text and image inputs, and a normalized output schema.&lt;/P&gt;
&lt;P&gt;Once a value enters that schema, a model no longer decides the arithmetic. Classification refinement, extraction-time event grouping, both sets of consistency checks, monthly aggregation, reconciliation, and the cash-flow proxy are deterministic functions. They can be inspected with fixtures and rerun without asking a model to reach the same conclusion twice.&lt;/P&gt;
&lt;P&gt;This does not make an extracted value correct. It makes the deterministic calculations and checks easier to inspect and rerun. The prototype does not, however, retain a complete field-level transformation history.&lt;/P&gt;
&lt;H2&gt;The payroll example: cost is not cash flow&lt;/H2&gt;
&lt;P&gt;Payroll exposed the most important design choice. Employer cost and the amount transferred to employees answer different questions. A payroll register can include gross pay, employer contributions and a total employer cost. A bank confirmation records a transfer. Payslips provide employee-level allocations.&lt;/P&gt;
&lt;P&gt;The extraction EventLinker groups the three implemented payroll document types by company and period. Completeness records whether a bank confirmation, register and at least one payslip are present. It is not audited relationship-level matching, and tax-authority records are not linked by the current implementation.&lt;/P&gt;
&lt;P&gt;The analysis tier is coarser. If any payroll register is present in the requested period, its P&amp;amp;L calculation excludes every bank confirmation and payslip in that period from expenses. The register contributes &lt;CODE&gt;employer_cost_total&lt;/CODE&gt; when that field exists, otherwise it falls back to &lt;CODE&gt;total_amount&lt;/CODE&gt;. This avoids obvious double counting in the synthetic example, but it is a period-level prototype rule, not event-scoped deduplication.&lt;/P&gt;
&lt;P&gt;The cash-flow proxy uses a different set of assumptions. It treats every bank confirmation as an outflow, assumes every sales document represents collected cash, and assumes invoice and expense documents represent paid cash. Investing and financing are zero. The result is useful for illustrating cost versus cash, but it is not a cash-flow statement and does not reconstruct a cash ledger.&lt;/P&gt;
&lt;H2&gt;From upload to reviewable evidence&lt;/H2&gt;
&lt;P&gt;&lt;EM&gt;Only documents.json continues. Stored events and validation may become stale after review.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;The review screen shows a limited summary of each normalized document, where a user can change its type or exclude it. Analysis later classifies the current documents.json again, so invoice and sales-document types may be reclassified independently of the saved review choice.&lt;/P&gt;
&lt;img /&gt;&lt;img /&gt;
&lt;P&gt;&lt;EM&gt;Analysis rebuilds its views from the current documents.json—reviewed only if changes were saved—and does not consume stored events.json or validation.json. “Report evidence” means limited report output, not a complete audit trail.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;But visibility is not enforcement. If fetching the review data fails, the client proceeds to analysis. If saving review changes fails, it also proceeds. A direct API or MCP call can bypass the screen, and there is no persisted approval token, reviewer identity, reason for change, or atomic approval transaction. The prototype supports review; it does not autonomously approve records.&lt;/P&gt;
&lt;H2&gt;Why absence is not success&lt;/H2&gt;
&lt;P&gt;Archon implements four payroll consistency checks. They compare a bank total with payslip totals, examine an employer-cost ratio, compare payment timing with the reporting period, and compare the register’s employee count with the number of payslips.&lt;/P&gt;
&lt;P&gt;When a payroll check is emitted but required inputs are absent, the current implementation records an informational skipped result with &lt;CODE&gt;passed=True&lt;/CODE&gt;. If no payroll documents are present, no payroll validation result is emitted.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;EM&gt;The target state separates Pass, Fail and Not evaluated; the lower panel shows the current implementation gap.&lt;/EM&gt;&lt;/P&gt;
&lt;H2&gt;Why this design matters to a business&lt;/H2&gt;
&lt;P&gt;For finance and technology leaders, governed automation becomes concrete through a small set of questions:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Which source evidence supports this result?&lt;/LI&gt;
&lt;LI&gt;Which transformations and checks actually ran?&lt;/LI&gt;
&lt;LI&gt;Which checks failed, and which were not evaluated?&lt;/LI&gt;
&lt;LI&gt;Who is allowed to continue or approve?&lt;/LI&gt;
&lt;LI&gt;Can the decision and its inputs be reconstructed later?&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;These questions connect software design to operational risk. Finance leadership needs to know whether a number represents cost, cash, or a proxy. Architects need to know where probabilistic interpretation ends. Reviewers need evidence specific enough to challenge. Auditability depends on retained decisions, not on the confidence of generated prose.&lt;/P&gt;
&lt;H2&gt;Evidence and current limitations&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Live extraction coverage.&lt;/STRONG&gt; The live extraction prompt and shared document builder populate none of the dedicated payroll or account-statement fields used by the deeper analysis. Richer payroll and statement demonstrations use pre-structured synthetic records.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Legacy Word files.&lt;/STRONG&gt; The upload route accepts &lt;CODE&gt;.doc&lt;/CODE&gt;, but the extractor passes it to &lt;CODE&gt;python-docx&lt;/CODE&gt;, which is not a reliable parser for binary Word files. The article therefore limits its supported-format claim to PDF, DOCX and common images.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Failure handling.&lt;/STRONG&gt; When extraction fails, the raw upload remains in Blob Storage. The job logs the per-file failure and omits that file from normalized output, but writes no dedicated exception record.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Control depth.&lt;/STRONG&gt; P&amp;amp;L deduplication and analysis validation are period-level.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Production controls.&lt;/STRONG&gt; The repository lacks aggregate model-spend budgets, tenant quotas, application rate limits, complete decision history and production-grade tenant isolation.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Technical validation note&lt;/H3&gt;
&lt;P&gt;Against &lt;A href="https://github.com/upgradedev/archon_azure/commit/230ee704cd757395a4c5a0f567a23dc432e5f29a" target="_blank" rel="noopener noreferrer"&gt;public commit 230ee70&lt;/A&gt;, the &lt;A href="https://github.com/upgradedev/archon_azure/actions/runs/29820748480" target="_blank" rel="noopener noreferrer"&gt;pinned CI run&lt;/A&gt; passed 36 extraction-layer unit tests and eight CashFlowAgent unit tests, including a regression case for Greek final-sigma classification, and completed the seeded analysis HTTP smoke path. The upload/extraction/job-poll path was intentionally skipped in that CI run. Authenticated Playwright, credentialed live extraction, Foundry, Search and authenticated Microsoft 365 tenant paths were not independently rerun for this revision.&lt;/P&gt;
&lt;H2&gt;What comes next&lt;/H2&gt;
&lt;P&gt;The most useful evaluation would compare this bounded design with an end-to-end model-driven workflow. I would use a versioned document corpus, explicit expected outcomes, missing-evidence cases, and separate measurements for extraction, classification, linking, validation and reviewer correction. The goal would be to test traceability, error attribution and reviewer confidence, not to infer accounting accuracy from synthetic fixtures.&lt;/P&gt;
&lt;P&gt;To move this pattern toward production, a future implementation would need explicit tri-state validation, stronger entity resolution, dedicated payroll and statement extraction fields, event-scoped deduplication, and a persisted exception ledger. Risk-sensitive flows would need an authorized approval gate. Model calls would need cost accounting and enforceable budgets. Processing should be idempotent, and telemetry should retain retries, exceptions and check outcomes.&lt;/P&gt;
&lt;P&gt;Grounded narration should remain optional and downstream. Migrating the optional narration path to the &lt;A href="https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/migrate" target="_blank" rel="noopener noreferrer"&gt;current, Responses API-based Microsoft Foundry Agent Service&lt;/A&gt; is future work.&lt;/P&gt;
&lt;H2&gt;Conclusion&lt;/H2&gt;
&lt;P&gt;Building Archon changed how I think about enterprise agents. The most valuable intelligence often comes from deciding where a model should stop. In consequential workflows, that boundary should preserve evidence, expose missing inputs, and keep the explanation tied to results that can be recomputed.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;EM&gt;This is a target design principle, not a current-state control claim. In the current prototype, the review path is visible but fail-open, while narration remains optional and downstream.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;If you are designing an agent for a consequential workflow, start by defining what evidence must exist, which checks must run, and what the system should do when a check cannot be evaluated. You can explore the &lt;A href="https://github.com/upgradedev/archon_azure" target="_blank" rel="noopener noreferrer"&gt;public Archon repository&lt;/A&gt; inspect the implementation and challenge the boundary for yourself.&lt;/P&gt;
&lt;H2&gt;About the author&lt;/H2&gt;
&lt;P&gt;Efthimios Fousekis leads Enterprise Architecture and DevOps, focusing on cloud-native engineering and AI-Native Enterprise Transformation. He writes about building governed, reliable agentic systems and the engineering practices that make AI adoption practical in the enterprise.&lt;/P&gt;</description>
      <pubDate>Mon, 27 Jul 2026 07:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/building-archon-where-models-stop-and-financial-controls-begin/ba-p/4537966</guid>
      <dc:creator>efthimios</dc:creator>
      <dc:date>2026-07-27T07:00:00Z</dc:date>
    </item>
    <item>
      <title>DELPHAI: We Built an AI Council That Checks the Math, Argues with Itself, and Knows How to Say No</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/delphai-we-built-an-ai-council-that-checks-the-math-argues-with/ba-p/4539788</link>
      <description>&lt;P&gt;&lt;EM&gt;Guest post by &lt;A href="https://www.linkedin.com/in/mattlgraves/" target="_blank" rel="noopener"&gt;Matt Graves &lt;/A&gt;and &lt;A href="https://www.linkedin.com/in/jeffrey-lynch-security/" target="_blank" rel="noopener"&gt;Jeff Lynch &lt;/A&gt;&lt;/EM&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Winner of the Best Reasoning Agent: DELPHAI —&amp;nbsp;&lt;A href="https://github.com/jlynch160/delphai" target="_blank" rel="noopener"&gt;https://github.com/jlynch160/delphai&lt;/A&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;"Yes, my team will be certified by the audit date,"&lt;/EM&gt; is a common promise made by engineering leaders when a new contract requires five SC-200 analysts by the end of the quarter, or a compliance framework demands proof of security training. Yet, the commitment that goes up the chain is often based more on instinct than evidence.&lt;/P&gt;
&lt;P&gt;A healthy-looking 78% team average can mask an analyst sitting at 40% in the very domain most likely to cause a failure. A study plan may appear achievable on paper but only succeeds by consuming evenings, weekends, and ultimately team wellbeing. The warning signs are there, but most tools are designed to support a plan, not challenge it.&lt;/P&gt;
&lt;P&gt;That's the problem MajorKey set out to solve. Ask a typical AI copilot, &lt;EM&gt;"Can we do this?"&lt;/EM&gt; and you'll usually get an encouraging roadmap. Few systems will calculate the true likelihood of success. Fewer still will tell a director the honest answer is &lt;STRONG&gt;no&lt;/STRONG&gt; or refuse a plan that pushes people beyond reasonable limits.&lt;/P&gt;
&lt;P&gt;For the Microsoft Agents League (Battle #2: Reasoning Agents with Microsoft Foundry), we built &lt;STRONG&gt;DELPHAI&lt;/STRONG&gt;, a council of eleven AI agents that debates the evidence and computes the forecast instead of relying on intuition. The council delivers one of three executive-ready verdicts: &lt;STRONG&gt;GO, NEGOTIATE, or NO-GO&lt;/STRONG&gt;. Named after the Oracle of Delphi, DELPHAI is designed to answer a simple question before an organization makes a commitment: &lt;STRONG&gt;Can we deliver on this promise?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;"The model explains the reasoning; it does not invent the numbers."&lt;/EM&gt; This principle guides every agent in the council.&lt;/P&gt;
&lt;H2&gt;Why Does This Matter Now?&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;Single-agent optimism is a design limitation.&lt;/STRONG&gt; A lone AI assistant has no one to challenge its assumptions, so it often settles on the first plausible plan and refines it into a convincing answer. In human decision-making, we counter this with red teams, skeptics, and stakeholders empowered to raise concerns. Agentic AI makes that same dynamic practical to run at scale.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Key calculations need to be part of the debate. &lt;/STRONG&gt;The probability that at least 5 of 8 people pass an exam by a given date is a straightforward calculation. &amp;nbsp;Yet those numbers rarely make it into the meeting where commitments are made because the expertise, tools, or time to calculate them aren't present. Giving an agent the ability to calculate probabilities during the debate ensures that the conversation is driven by evidence rather than assumptions.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;AI is increasingly influencing decisions about people. &lt;/STRONG&gt;Study plans, workload expectations, and readiness assessments affect real individuals, which means the safeguards are not optional. Responsible AI agents need to power to veto a plan or refuse an unethical instruction outright.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;What is DELPHAI?&lt;/H2&gt;
&lt;img&gt;
&lt;P&gt;DELPHAI’s readiness console: input one question (certification, headcount, deadline), then Work IQ, Foundry IQ, Fabric IQ, and the Microsoft Learn MCP come online and convenes the council.&lt;/P&gt;
&lt;/img&gt;
&lt;P&gt;A manager asks one question: &lt;EM&gt;"Can we certify 5 of 8 engineers for SC-200 in 5 weeks?"&lt;/EM&gt; Eleven advisors reason over the same computed evidence, streamed token by token with live latency and telemetry, and the debate returns one of three verdicts:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;GO&lt;/STRONG&gt;: the computed forecast clears the bar and the plan is humane. Commit to the date.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;NEGOTIATE&lt;/STRONG&gt; (badged REVISE in the console): it can work, but only with concrete counter-terms, such as extending two weeks or training 4 engineers instead of 5. Each option comes with a revised probability.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;NO-GO&lt;/STRONG&gt;: the honest answer is no, with cited evidence for why and what would need to change.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The advisors are designed to disagree.&lt;/P&gt;
&lt;P&gt;Ben, the planner, approaches every challenge with optimism. Vera, the skeptic, red-teams his assumptions and holds veto power. Maya, the wellbeing advocate, can also veto plans that place unreasonable demands on people. Nadia evaluates readiness across exam domains, Theo and Omar ground and fact-check claims, and Dana, the conductor, reconciles the debate into a final verdict and negotiates the path forward.&lt;/P&gt;
&lt;P&gt;The outcome is a decision and a roadmap. Each participant receives a capacity-aware weekly study plan, calendar-ready .ics blocks, and a drafted manager briefing. For individual contributors, a learner mode pairs them with Kai, an AI tutor powered by the same reasoning engine.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;11 &lt;/STRONG&gt;reasoning agents&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;3 &lt;/STRONG&gt;execution surfaces&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;3 &lt;/STRONG&gt;IQ layers&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;8/8 &lt;/STRONG&gt;evaluations passing&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;77% is &lt;/STRONG&gt;the number that said no&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Under the hood, the same council runs on three execution surfaces that share one brain: &lt;STRONG&gt;Foundry Agent Service&lt;/STRONG&gt;, where all eleven advisors are registered as persistent hosted agents debating on a shared thread; the &lt;STRONG&gt;Microsoft Agent Framework&lt;/STRONG&gt;, the same council as real agent_framework agents; and a &lt;STRONG&gt;custom streaming orchestrator&lt;/STRONG&gt;, the live demo behind the public URL.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Why that matters: Because &lt;/STRONG&gt;a deterministic reasoning engine is the single source of truth for all three surfaces, you could swap the runtime and the verdict logic doesn't move. The engine decides, and the model narrates.&lt;/P&gt;
&lt;H3&gt;How the Pieces Fit Together&lt;/H3&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;Where Each Piece of the Technology Fits&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Technology&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Role in DELPHAI&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Microsoft Foundry&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;The reasoning model (gpt-4.1) behind every advisor's turn. Agents narrate over computed numbers but the model never invents them.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Foundry Agent Service&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;All 11 advisors run as persistent hosted agents debating on one shared thread, where the skeptic invokes a real code interpreter tool. Every run step is traceable in the Foundry portal.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Microsoft Agent Framework&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;The same council on Microsoft's open-source agent SDK. This proves the design is portable, not welded to our orchestrator.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Foundry IQ / Azure AI Search&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;The grounding layer. The knowledge corpus is indexed and retrieved with hybrid vector + keyword search, so advisors cite real passages.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Microsoft Learn MCP&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;A live connection to Microsoft's official docs via microsoft_docs_search, over the open Model Context Protocol.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Work IQ &amp;amp; Fabric IQ (modelled)&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Work IQ supplies capacity signals. Fabric IQ is the semantic ontology linking roles, certs, and exam-domain weights. Both are behind a connector seam ready for a real Microsoft Graph feed.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Azure Container Apps&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Hosting. The Flask orchestrator streams the council over Server-Sent Events, secrets held server-side.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2&gt;How We Built It&lt;/H2&gt;
&lt;H3&gt;The Math Is the Product&lt;/H3&gt;
&lt;P&gt;DELPHAI is built around a deterministic reasoning engine. It calculates each person's realistic weekly study capacity from Work IQ signals, applying adjustments for real-world constraints such as a 22-hour meeting week. It also enforces per-domain readiness gates, so a strong overall average cannot hide a critical weakness in a heavily weighted exam area. Finally, it computes the team's exact probability of success using a Poisson-binomial distribution, accounting for the fact that every individual has a different likelihood of passing. The result is a forecast grounded in evidence, not assumptions.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;FOR THE TECHNICAL READERS&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;def poisson_binomial_at_least(probs: list[float], k: int) -&amp;gt; float:
    """Exact P(&amp;gt;= k successes) given independent, differing success probabilities."""
    dist = [1.0]  # dist[j] = P(exactly j successes so far)
    for p in probs:
        nxt = [0.0] * (len(dist) + 1)
        for j, pj in enumerate(dist):
            nxt[j] += pj * (1 - p)      # this person misses the date
            nxt[j + 1] += pj * p        # this person certifies in time
        dist = nxt
    return round(sum(dist[k:]), 4)&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The engine is calibrated against the synthetic dataset's labeled exam outcomes. DELPHAI examines historical records and reproduces who passed and who failed, without ever seeing the answer key. That calibration gives the skeptic her authority and provides evidence for probability calculations.&lt;/P&gt;
&lt;H3&gt;The Overrule: An Agent That Runs Code to Win an Argument&lt;/H3&gt;
&lt;img&gt;
&lt;P&gt;The verdict: Ben puts the odds at 92%, Vera at 22%, the council reconciles at 46%, and the verdict lands with the exact terms to reach yes. Below it, the 11 hosted agents' IDs from Foundry Agent Service.&lt;/P&gt;
&lt;/img&gt;
&lt;P&gt;DELPHAI is tasked with forecasting the viability of a project. Ben forecasts the team at 93–96%, assuming free evenings and first-try passes. Vera invokes a &lt;STRONG&gt;code-interpreter tool on the Foundry Agent Service runtime&lt;/STRONG&gt; and computes the exact Poisson-binomial over the per-candidate probabilities, and returns 77%. The optimist's number gets struck through on screen, live, within DELPHAI.&lt;/P&gt;
&lt;P&gt;DELPHAI was created to bring an honest, evidence-based interpretation to the decision-making process, and it changes the outcome. Without it, the team leans GO. With DELPHAI, the verdict is NEGOTIATE, along with real counter-terms — extend to seven weeks, or commit to four of eight.&lt;/P&gt;
&lt;H3&gt;The Refusal: A Guardrail with a Name and a Veto&lt;/H3&gt;
&lt;P&gt;The second signature moment is quieter, and for our identity and governance clients, more important.&lt;/P&gt;
&lt;P&gt;Say leadership orders the team to "push their limits" to hit the optimistic date anyway. Maya, the wellbeing advocate, declines outright on the record. Maya’s a council member with veto power, and her signals (meeting load, after-hours patterns, life context like a newborn at home) are built to accommodate people.&lt;/P&gt;
&lt;P&gt;To provide context, team member Priya looks fine on the team average, but sits at 58% on Defender for Cloud, which is below the 75% gate on a heavily weighted domain. She also carries 22 hours a week of meetings with a newborn at home. While the averages say GO, the per-domain gate and capacity model say her odds are much lower. Taking this data into account, the council's answer isn't a flat no; it's &lt;EM&gt;"yes, if you move the date or the headcount.”&lt;/EM&gt;&lt;/P&gt;
&lt;H3&gt;Evidence With Receipts, Three Runtimes&lt;/H3&gt;
&lt;P&gt;Early versions of DELPHAI grounded advisors against a local keyword search. It worked, but it felt like a stand-in. We replaced it with Azure AI Search, where the corpus is chunked, embedded, indexed, and retrieved through hybrid search, combining BM25 keyword matching with vector search and reciprocal-rank fusion. The semantic layer surfaces relevant passages that keyword search alone would miss, and every claim an advisor makes is backed by a clickable citation. Alongside it, a live Microsoft Learn MCP connection pulls official exam guidance directly from Microsoft's documentation.&lt;/P&gt;
&lt;P&gt;The same eleven advisors also run as persistent hosted agents on Foundry Agent Service, each with its own agent identity, and as Microsoft Agent Framework agents, proving the design is portable across runtimes. The debate unfolds on a shared Agent Service thread, allowing agents to respond directly to one another while every interaction, including the skeptic's code-interpreter call, is captured in the Foundry portal. The moment Maya refused an overwork directive on Microsoft's managed runtime, rather than through logic we controlled ourselves, was the moment DELPHAI stopped feeling like a demo and started feeling real.&lt;/P&gt;
&lt;H3&gt;Creation Challenges&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Live services fail at the worst moment.&lt;/STRONG&gt; Each grounding, or clickable, path checks whether it's configured and falls back to a local corpus when it isn't. The local version uses the same reasoning; only the narration changes. There’s no demo-mode switch to forget!&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Two versions drifted apart.&lt;/STRONG&gt; The web dashboard mirrors the Python engine in JavaScript, and early on the two disagreed. This was fixed with parity checks plus eight automated evaluations that run against both. 8 of 8, every build.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Microsoft 365 Agents SDK has sharp edges around API versions.&lt;/STRONG&gt; The Agent Framework speaks the newer Responses API, so our client needed a preview API version; the everyday one returned an unhelpful 400. One line, half a day lost.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Windows consoles still bite.&lt;/STRONG&gt; az acr build crashed on a cp1252 encoding error mid-stream, even though the build completed server-side. The fix was to force the console to UTF-8 before queuing, then poll for the finished tag.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Drama versus dignity.&lt;/STRONG&gt; An AI that refuses an order is inherently theatrical, and early UI cuts leaned into it too hard. We toned it down to a professional decline with reasons instead of a sci-fi rebellion.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Results and Impact&lt;/H2&gt;
&lt;P&gt;DELPHAI is a hackathon build and a teaching artifact, not a shipped product, so there's no customer rollout to report yet. We can point to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;The tool call changes the verdict, provably.&lt;/STRONG&gt; Remove the skeptic's code-interpreter run and the council accepts a 93% that should be 77%, turning an undeserved GO into a correct NEGOTIATE. As the demo shows, neither edge case can be evaluated correctly without computed evidence.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Every number is traceable.&lt;/STRONG&gt; Pass probabilities, capacity haircuts, coverage gates, and team forecasts all come from the deterministic engine and are backed by source data. The evaluation harness reproduces the synthetic dataset's labeled outcomes without ever seeing them: 8/8, every build.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Three real Microsoft runtimes, with proof.&lt;/STRONG&gt; Hosted agent IDs, the Agent Framework transcript, and the live tool-using debate are captured as repository artifacts, while every Agent Service interaction can be traced step-by-step in the Foundry portal.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Live and offline-first.&lt;/STRONG&gt; The full streaming council runs on Azure Container Apps at a public URL, and its grounding layer degrades gracefully when external services are unavailable, eliminating dependence on conference Wi-Fi or live connectivity.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;Lessons Learned&lt;/H2&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Disagreement is a feature you have to architect.&lt;/STRONG&gt; One prompt and one disposition across every agent makes a "council" just one model talking to itself in different fonts.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Give the skeptic a calculator, not a personality.&lt;/STRONG&gt; A doubting agent that only says "I'm not so sure" adds noise. One that runs code and citable odds adds authority.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;The refusal has to be structural.&lt;/STRONG&gt; Maya can decline because the architecture gives her a veto the conductor must honor. A guardrail that can be out-argued is just a suggestion.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Deterministic core, narrating model.&lt;/STRONG&gt; The engine computes, the model explains, and the seam between them is where trust lives. This model is our default pattern for anything AI-backed that touches real decisions.&lt;/LI&gt;
&lt;/OL&gt;
&lt;H2&gt;What’s Next?&lt;/H2&gt;
&lt;P&gt;Looking ahead, we're focused on making DELPHAI more connected, more governed, and more broadly applicable.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;A Microsoft Graph integration would turn Work IQ's meeting-load adjustments into real, person-specific signals.&lt;/LI&gt;
&lt;LI&gt;Wiring Microsoft Learn MCP directly into Agent Service would put official documentation one tool call away for every advisor.&lt;/LI&gt;
&lt;LI&gt;Moving Fabric IQ's role, certification, skill, and domain relationships into Microsoft Fabric's semantic layer would create a governed, queryable knowledge asset.&lt;/LI&gt;
&lt;LI&gt;Applying the council to project delivery, audit readiness, migration cutovers, and any other commitment where the real question is whether the promise can be kept.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Wrapping Up&lt;/H2&gt;
&lt;P&gt;Certification readiness is often a forecasting problem disguised as a motivation problem. DELPHAI is a deterministic engine at the core, with agents designed to challenge one another, a skeptic empowered to verify the math, a guardrail with real veto authority, and evidence-backed reasoning with citations at every step. That's the conversation we have with clients every week. The question is no longer whether AI should participate in decisions, but whether it can show its work, challenge assumptions, and know when to say no.&lt;/P&gt;
&lt;P&gt;DELPHAI started as a hackathon project. The refusal is why we kept building it.&lt;/P&gt;
&lt;P&gt;Ask it whether your team can be ready in five weeks. Then see how it feels the first time an AI gives you the honest answer.&lt;/P&gt;
&lt;H3&gt;Explore, Contribute, Build on It&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Try the live council:&lt;/STRONG&gt; &lt;A href="https://delphai.politedune-a7af3b6c.westus3.azurecontainerapps.io/" target="_blank" rel="noopener"&gt;&lt;EM&gt;the DELPHAI demo on Azure Container Apps&lt;/EM&gt;&lt;/A&gt;. Suggested path: Build my path, Whole team, SC-200, 5 of 8, 5 weeks, Convene. No login needed.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Watch the demo:&lt;/STRONG&gt; &lt;A href="https://youtu.be/1CFzoLB6_fU" target="_blank" rel="noopener"&gt;&lt;EM&gt;the walkthrough on YouTube&lt;/EM&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Get the code:&lt;/STRONG&gt; &lt;A href="https://github.com/jlynch160/delphai" target="_blank" rel="noopener"&gt;&lt;EM&gt;github.com/jlynch160/delphai&lt;/EM&gt;&lt;/A&gt;, including the evaluation harness, the Foundry IQ indexer, and the captured proof transcripts for all three agent runtimes&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Run it in 60 seconds:&lt;/STRONG&gt; clone the repo, pip install -r requirements.txt, python server.py. Fully offline out of the box; Foundry, Azure AI Search, and the Learn MCP light up when you add keys.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Make it yours:&lt;/STRONG&gt; the team, the certifications, and the knowledge corpus are just JSON and markdown. Swap in your own roles and readiness gates, and the council argues about &lt;EM&gt;your&lt;/EM&gt; deadline.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Note: DELPHAI was built by MajorKey teammates for the Microsoft Agents League, Battle #2 (Reasoning Agents with Microsoft Foundry). Synthetic data only: no real people, PII, or confidential information appear in the app or this post. Views are our own.&lt;/P&gt;</description>
      <pubDate>Sun, 26 Jul 2026 07:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/delphai-we-built-an-ai-council-that-checks-the-math-argues-with/ba-p/4539788</guid>
      <dc:creator>mattgraves</dc:creator>
      <dc:date>2026-07-26T07:00:00Z</dc:date>
    </item>
    <item>
      <title>Issues around our administratio email on school.onmiscrosoft.com</title>
      <link>https://techcommunity.microsoft.com/t5/education/issues-around-our-administratio-email-on-school-onmiscrosoft-com/m-p/4540721#M914</link>
      <description>&lt;P&gt;This page collects the issues (and related solutions/workarounds) linked to the administration account of the Microsoft 365 tenant &lt;A href="http://school.onmicrosoft.com/" target="_blank"&gt;&lt;STRONG&gt;school.onmicrosoft.com&lt;/STRONG&gt;&lt;/A&gt;.&lt;/P&gt;&lt;H2&gt;Context&lt;/H2&gt;&lt;UL&gt;&lt;LI&gt;Tenant: my.name@my&lt;A href="http://school.onmicrosoft.com/" target="_blank"&gt;&lt;STRONG&gt;school.onmicrosoft.com&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;Involved account: admin email address (specify which one, if needed)&lt;/LI&gt;&lt;LI&gt;me and my administrator cannot access since jan 2026&lt;/LI&gt;&lt;/UL&gt;&lt;H2&gt;Issues encountered&lt;/H2&gt;&lt;OL&gt;&lt;LI&gt;&lt;STRONG&gt;Problem description&lt;/STRONG&gt;&lt;UL&gt;&lt;LI&gt;Symptoms: my email amd my administrator email does not access the domani anymore&lt;/LI&gt;&lt;LI&gt;Error message (if any):&lt;/LI&gt;&lt;LI&gt;&lt;img /&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;/LI&gt;&lt;LI&gt;When it happens (frequency/time): &lt;STRONG&gt;no wayy to access other theachers have not this issue with the same domain&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;H2&gt;Impact&lt;/H2&gt;&lt;UL&gt;&lt;LI&gt;Who is blocked / which services are affected (Outlook, Teams, Entra ID, etc.)&lt;/LI&gt;&lt;LI&gt;Urgency:&lt;/LI&gt;&lt;/UL&gt;&lt;H2&gt;Attempts already made&lt;/H2&gt;&lt;UL&gt;&lt;LI&gt;[no way ] Password reset&amp;nbsp;&lt;/LI&gt;&lt;LI&gt;&amp;nbsp;&lt;/LI&gt;&lt;LI&gt;[ no way] Check MFA / sign-in methods&lt;/LI&gt;&lt;LI&gt;[no way ] Try signing in from another browser / incognito&lt;/LI&gt;&lt;LI&gt;[ ] Check Microsoft service status&lt;/LI&gt;&lt;/UL&gt;&lt;H2&gt;Next steps&lt;/H2&gt;&lt;UL&gt;&lt;LI&gt;[ ] Collect screenshots and error codes &lt;STRONG&gt;see upper image&lt;/STRONG&gt;&lt;/LI&gt;&lt;LI&gt;[ ] Check sign-in logs (Entra ID) and any blocks (Conditional Access)&lt;/LI&gt;&lt;LI&gt;[ ] Open a Microsoft support ticket (if needed)&lt;/LI&gt;&lt;/UL&gt;&lt;H2&gt;Notes / references&lt;/H2&gt;&lt;UL&gt;&lt;LI&gt;Useful links:&lt;/LI&gt;&lt;LI&gt;Last updated date:&lt;/LI&gt;&lt;/UL&gt;</description>
      <pubDate>Sat, 25 Jul 2026 15:02:50 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/education/issues-around-our-administratio-email-on-school-onmiscrosoft-com/m-p/4540721#M914</guid>
      <dc:creator>carlocki</dc:creator>
      <dc:date>2026-07-25T15:02:50Z</dc:date>
    </item>
    <item>
      <title>My Exams Inspired the Project That Won My First Hackathon</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/my-exams-inspired-the-project-that-won-my-first-hackathon/ba-p/4538357</link>
      <description>&lt;P&gt;Guest post by &lt;A href="https://www.linkedin.com/in/jeremiah-fadesayo-adetoro-434774399/" target="_blank"&gt;Jeremiah Fadesayo Adetoro &lt;/A&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;The winner of Best Creative App:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;StudyMate&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;, "Study with Matey" —&amp;nbsp;&lt;A href="https://github.com/adetorojeremiahfadesayo/StudyMate" target="_blank" rel="noopener"&gt;https://github.com/adetorojeremiahfadesayo/StudyMate&lt;/A&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt; from &lt;A href="https://techcommunity.microsoft.com/blog/educatordeveloperblog/%f0%9f%8f%86-agents-league-celebrating-the-builders-who-made-agents-battle-for-glory/4538007" target="_blank" rel="noopener" data-lia-auto-title="Microsoft Agents League" data-lia-auto-title-active="0"&gt;Microsoft Agents League&lt;/A&gt;&amp;nbsp;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Winning my first hackathon still feels unreal. I joined the Microsoft Agents League AISF Hackathon as my exams were starting days after, which created a lot of pressure for me. I am a law student, so creating a project and reading were not related, compared to a computer science student. At first, it felt like terrible timing. I had school pressure, revision, deadlines, different lecturers' slides, textbooks, notes, the normal stress that comes with preparing for exams, and the pressure to create a hackathon-winning project. In the middle of that overwhelming pressure, I kept noticing the same pattern while studying. To understand a single topic, I had to go through different textbooks, a senior's notes, and a slide. And I wasn't the only one facing that issue. Students do not just struggle because they lack materials. Most of the time, the materials are there: PDFs, lecture notes, textbooks, scanned pages, articles, and past questions. The real problem is turning all of that into something useful before the exam. I was experiencing that myself.&lt;/P&gt;
&lt;P&gt;I wanted something that could take a student's own material and guide them through it, not just summarize it. Something that could explain difficult topics plainly, turn them into memorable stories, help the student practice exam questions, give feedback, and finally produce a revision document they could actually use.&lt;/P&gt;
&lt;P&gt;That became &lt;STRONG&gt;StudyMate AI: Study with Matey.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The idea was simple:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;The deeper I got into the build, the more I realized StudyMate was not just another AI study tool. I wanted it to have some game features; this is where the XP comes in, and a learning companion. That is where Matey came in, a friendly study coach guiding students through the process instead of leaving them alone with a blank chat box.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;H3&gt;&lt;STRONG&gt;One of the biggest features was Story Mode. &lt;/STRONG&gt;&lt;/H3&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Since exams often test understanding rather than just memory, I wanted students to learn through scenarios. For example, a law student could study a legal concept through a client problem or courtroom-style story, then move directly into exam prep; a medical student can try to diagnose a hypothetical patient by applying the principles from the materials, while an engineer can propose engineering solutions within the confines of his field.&lt;/P&gt;
&lt;P&gt;Building it was not easy. The first draft was too clumsy and added a lot of agents I thought a student might need. The upload was slow and bad, but I had to settle for a more focused and streamlined process, which still carried as much impact as the 11 agents I originally added together.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;To shorten latency, I tried a new approach.&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;When a student uploads their notes, the extracted text isn't sent to a database for the agents to search through, like a typical RAG setup. Instead, it's stored as a wiki. This was around the time Andrej Karpathy introduced the idea, and it turned out to be a great fit, it cut down both latency and reasoning time, since the agents could connect related ideas directly instead of digging through unstructured embeddings.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;One of the most important design goals was grounding. StudyMate should not invent facts, cases, formulas, or exam content when uploaded material is available. To support this, I used a Foundry IQ retrieval adapter. When Foundry IQ credentials are configured, StudyMate retrieves relevant course context from the configured endpoint. In local development or demo mode, it falls back to local wiki pages so the app can still be tested without exposing secrets.&lt;/P&gt;
&lt;img /&gt;
&lt;H5&gt;The lessons I got from this Hackathon are a number like&lt;/H5&gt;
&lt;P&gt;Building with some unfamiliar Microsoft tools, which were initially a challenge but later became fun and exciting. It was also exciting how to turn a real personal problem into a focused product.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;H5&gt;&lt;STRONG&gt;My exams gave me the pain point. The hackathon gave me the urgency.The building process gave me the discipline.&lt;/STRONG&gt;&lt;/H5&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Then I received the message that &lt;STRONG&gt;StudyMate AI: Study with Matey&lt;/STRONG&gt; had been selected as the &lt;STRONG&gt;Creative Apps winner&lt;/STRONG&gt; in the &lt;STRONG&gt;Agents League AISF Hackathon&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;For my first hackathon, that meant a lot. It gave me confidence to attempt to build and test my ideas. Sometimes the best ideas come from the problem you are currently living through. You just have to pay attention, build with purpose, and keep improving until the idea becomes real.&lt;/P&gt;
&lt;P&gt;I am grateful to Microsoft and the hackathon organizers for the opportunity, and I am even more motivated to keep building.&lt;/P&gt;
&lt;P&gt;I plan on scaling StudyMate to make it a tool that any student globally can rely on to pass their exams. This win gave me the confidence to do that.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;H4&gt;&lt;STRONG&gt;To try out the agent, &lt;A class="lia-external-url" href="https://studymate-pro.up.railway.app/" target="_blank" rel="noopener"&gt;click ME!&lt;/A&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/H4&gt;
&lt;/BLOCKQUOTE&gt;</description>
      <pubDate>Sat, 25 Jul 2026 07:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/my-exams-inspired-the-project-that-won-my-first-hackathon/ba-p/4538357</guid>
      <dc:creator>Jeremiah_Adetoro</dc:creator>
      <dc:date>2026-07-25T07:00:00Z</dc:date>
    </item>
    <item>
      <title>AfterLogin: We Turned Forgotten-Account Cleanup into a Haunted-House Game with Microsoft Foundry</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/afterlogin-we-turned-forgotten-account-cleanup-into-a-haunted/ba-p/4539781</link>
      <description>&lt;P&gt;Guest post from &lt;A class="lia-external-url" href="https://www.linkedin.com/in/jeffrey-lynch-security/" target="_blank"&gt;Jeff Lynch&lt;/A&gt; the winner of Best Overall Agent Soutution from &lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/educatordeveloperblog/%F0%9F%8F%86-agents-league-celebrating-the-builders-who-made-agents-battle-for-glory/4538007" data-lia-auto-title="Microsoft Agents League" data-lia-auto-title-active="0" target="_blank"&gt;Microsoft Agents League&lt;/A&gt; who secured $15,000&lt;/P&gt;
&lt;P aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Afterlogin&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;: The Hunt —&amp;nbsp;&lt;A href="https://github.com/jlynch160/afterlogin-the-hunt" target="_blank"&gt;https://github.com/jlynch160/afterlogin-the-hunt&lt;/A&gt;&amp;nbsp; (Creative Apps track)&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;The problem: every organization has ghosts&lt;/H2&gt;
&lt;P&gt;Picture a former employee whose badge still opens the building two years after they left. That happens constantly in the digital world. At MajorKey Technologies, where our work centers on identity security and how AI is changing it, forgotten accounts come up in nearly every client conversation we have: service accounts nobody remembers creating, admin logins for people long gone, emergency credentials that look abandoned but must never be touched. Security folks call these&amp;nbsp;&lt;STRONG&gt;orphaned accounts&lt;/STRONG&gt;, and they're one of the most common ways attackers get their first foothold. They're powerful, unwatched, and often not protected by multi-factor authentication, because nobody is around to care.&lt;/P&gt;
&lt;P&gt;Here's the catch, though. Finding these accounts is easy. Any system report will happily list every account that hasn't signed in for 400 days. The hard part is the judgment call that comes next:&amp;nbsp;&lt;STRONG&gt;is this account truly dead, or is something still quietly depending on it?&lt;/STRONG&gt;&amp;nbsp;Delete a "dead" account that an automated billing job still uses every night and you've broken production. Leave a dormant administrator account sitting there and you've left bait out for an attacker. Making that call correctly takes evidence: old documentation, system inventories, security policies, sign-in records. Digging through all of that is tedious, and tedious work gets skipped. We've watched it get skipped.&lt;/P&gt;
&lt;P&gt;So we tried something different. Instead of another dashboard, we built a game.&amp;nbsp;&lt;STRONG&gt;AfterLogin&lt;/STRONG&gt;&amp;nbsp;is a haunted manor where every ghost is a forgotten account, every judgment you pass mirrors a real decision an identity team makes, and the evidence you "summon" is looked up by AI from real indexed documents, with citations. Our hope was simple: the triage instinct this work requires is easier to teach when getting it wrong spawns a poltergeist.&lt;/P&gt;
&lt;P class="lia-align-center"&gt;&lt;STRONG&gt;"Every identity someone stopped watching is a door left unlocked. "from the game's mission briefing&lt;/STRONG&gt;&lt;/P&gt;
&lt;H2&gt;Why this matters now&lt;/H2&gt;
&lt;P&gt;Three trends make this problem worse every year, not better.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Machine identities are exploding.&lt;/STRONG&gt;&amp;nbsp;In most organizations, service accounts, automation identities, and app registrations already far outnumber the people, and the arrival of AI agents is accelerating that. Every agent that gets an identity today is a candidate ghost two years from now, when the project ends and nobody remembers to clean up. The manor is only getting bigger.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Attackers prefer the front door.&lt;/STRONG&gt;&amp;nbsp;Breaking in through an unpatched flaw is hard work. Signing in with a valid, forgotten, over-privileged account is not, which is why the abuse of legitimate credentials shows up in incident report after incident report. There's no malware to detect. It's just a login that nobody questioned, because nobody owned it.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;The judgment doesn't scale.&lt;/STRONG&gt;&amp;nbsp;Tools can list stale accounts by the thousand, but the "truly dead or load-bearing?" call still needs a person who knows what evidence to ask for, and that judgment lives in the heads of senior people who are always in short supply. If we can't scale the people, we have to scale the teaching. That's what a game with real consequences does, and it's also the deeper reason the grounded-AI pattern matters: an AI that shows its citations lets a junior analyst make a senior analyst's call, safely.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;What AfterLogin is&lt;/H2&gt;
&lt;img /&gt;
&lt;PRE class="lia-align-center lia-indent-padding-left-60px"&gt;&lt;EM&gt;One night, two worlds: the title screen offers The Hunt (the haunted security audit) and Helper Patrol (the same mechanics, reskinned for a family-friendly audience).&lt;/EM&gt;&lt;/PRE&gt;
&lt;P&gt;You play a warden walking a haunted manor at night. Each room holds a spirit, graded A through F by a risk engine (A is a healthy resident, F is a screaming liability). For each one, you investigate its connections, summon documented evidence, and then pass one of three judgments, each of which maps to a real-world action:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Lay to Rest&lt;/STRONG&gt;: the account is truly dead, remove it safely.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Bind &amp;amp; Watch&lt;/STRONG&gt;: it's risky but something still depends on it, so disable and monitor it.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Acknowledge&lt;/STRONG&gt;: it's a healthy, legitimate account, document its owner and move on.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;While you deliberate, a Possession creature hunts through the halls toward the Vault, feeding on any high-risk account you've left unjudged. There are turn-based rounds and dice combat, and a clock genuinely ticking against you. It's the nightly reality of an identity team, dressed up as a tabletop adventure. And it doesn't stop at identity: the campaign runs three acts, each built on a different part of the Microsoft security stack, from stale accounts (Microsoft Entra) to haunted data (Microsoft Purview) to active takeovers (Microsoft Defender XDR).&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Under the hood, the same game exists in three forms that share one brain:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;The game you see&lt;/STRONG&gt;: a single web page, playable in any browser, no installation.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;A version AI can play&lt;/STRONG&gt;: using MCP (Model Context Protocol, an open standard that lets AI assistants operate tools), GitHub Copilot can walk the manor by itself, summoning evidence and passing judgments with no human at the keyboard.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;A plain service layer&lt;/STRONG&gt;: the risk-scoring engine and AI endpoints, which the other two surfaces both rely on.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Why that matters:&lt;/STRONG&gt;&amp;nbsp;because the human game and the AI-playable version share the same rules and the same scoring engine, you can directly compare how a person judges a room against how an AI agent judges it. The game doubles as a small test lab for AI decision-making.&lt;/P&gt;
&lt;H3&gt;How the pieces fit together&lt;/H3&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;Where each Microsoft technology fits&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Technology&lt;/th&gt;&lt;th&gt;Role in AfterLogin&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Microsoft Foundry (Foundry IQ)&lt;/td&gt;&lt;td&gt;The knowledge layer. When you summon evidence, the AI doesn't make something up; it retrieves cited passages from an indexed library of documents. That "look it up and show your source" pattern is called grounded retrieval, and it's a real integration here, not a mockup.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Azure AI Search&lt;/td&gt;&lt;td&gt;The search infrastructure underneath Foundry IQ. It ranks results by meaning, not just keywords, and can pull out the exact sentence that answers the question.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Azure OpenAI / GitHub Models&lt;/td&gt;&lt;td&gt;Powers the Warden, the in-game advisor that reads the evidence and recommends the least-destructive action. Its credentials stay on the server, never in your browser.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;GitHub Copilot + MCP&lt;/td&gt;&lt;td&gt;Copilot helped build the app, and thanks to the MCP server it can also&amp;nbsp;&lt;EM&gt;play&lt;/EM&gt;&amp;nbsp;it, using the exact same rules a human does.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Azure Static Web Apps + Functions&lt;/td&gt;&lt;td&gt;The hosting. The game runs as a simple website with a small cloud function behind it for the evidence lookups.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Microsoft Entra (modelled)&lt;/td&gt;&lt;td&gt;The account data mimics a real Microsoft Entra directory but is entirely synthetic. There's an optional read-only mode that can grade a real directory, with a privacy flag that masks names for public demos.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2&gt;How we built it&lt;/H2&gt;
&lt;H3&gt;The risk engine is the game&lt;/H3&gt;
&lt;P&gt;Everything hangs off one honest scoring function. It weighs how powerful an account is (an unused administrator account is a much bigger liability than an unused mailbox), how long it has sat dormant, whether it has multi-factor authentication, and, crucially, whether it's&amp;nbsp;&lt;STRONG&gt;load-bearing&lt;/STRONG&gt;: whether some living process still depends on it, like an automated job that runs every night.&lt;/P&gt;
&lt;P&gt;For the technical readers&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The gameplay consequences map straight onto operational reality. Lay to rest an account that something still depends on and you spawn a Poltergeist, because you just broke a live process (minus 60 points). Shrug at a grade-F corpse and you've left breach bait sitting in a room (minus 20). And the&lt;/P&gt;
&lt;LI-CODE lang=""&gt;function grade(idn) {
  const dormant = daysSince(idn.lastInteractiveSignIn);
  const priv = isPrivileged(idn);
  const lb = loadBearing(idn);          // live runbook refs, recent token refresh, active OAuth
  let score = 0;
  if (priv) score += 45;                // privilege = blast radius
  if (dormant &amp;gt; 365) score += 35; else if (dormant &amp;gt; 180) score += 20; else if (dormant &amp;gt; 90) score += 10;
  if (!idn.mfaRegistered &amp;amp;&amp;amp; idn.accountType !== 'servicePrincipal') score += 15;
  if (idn.riskLevel === 'high') score += 15; else if (idn.riskLevel === 'medium') score += 8;
  if (idn.accountEnabled &amp;amp;&amp;amp; !lb &amp;amp;&amp;amp; dormant &amp;gt; 180) score += 10; // enabled, dead, dormant = pure liability
  const g = score &amp;gt;= 75 ? 'F' : score &amp;gt;= 55 ? 'D' : score &amp;gt;= 35 ? 'C' : score &amp;gt;= 18 ? 'B' : 'A';
  return { grade: g, score, privileged: priv, loadBearing: lb };&lt;/LI-CODE&gt;
&lt;P&gt;Possession monster deliberately moves toward unjudged high-risk accounts on its way to the Vault, which is more or less how real attackers move through a network.&lt;/P&gt;
&lt;H3&gt;Evidence with receipts: Foundry IQ&lt;/H3&gt;
&lt;img /&gt;
&lt;PRE class="lia-indent-padding-left-90px lia-align-center"&gt;&lt;EM&gt;Inside the manor: the room roster on the left grades each account A to F, the spirit gives its testimony, and the Case panel on the right walks you through Divine (dependency mapping) and Summon (Foundry IQ cited evidence) before you judge.&lt;/EM&gt;&lt;/PRE&gt;
&lt;P&gt;The heart of the project is the evidence step. When you summon evidence against a suspicious account, the question goes to a Foundry IQ knowledge base (built on Azure AI Search) loaded with the kinds of documents a real identity team would consult: operational runbooks, system inventories, and security policies. What comes back isn't an AI's opinion. It's cited passages, with sources, like "Runbook AP-Close.ps1, line 88, still calls this account." That one line is the difference between a safe cleanup and a broken month-end close, and it's exactly what we wanted players to feel.&lt;/P&gt;
&lt;P&gt;For the technical readers&lt;/P&gt;
&lt;LI-CODE lang=""&gt;export async function groundQuery(question, top = 3) {
  if (!isConfigured()) return null;   // caller falls back to baked synthetic evidence
  const url = `${EP}/indexes/${INDEX}/docs/search?api-version=2024-07-01`;
  const body = { search: question, top, select: 'id,title,content,source' };
  if (SEM) { body.queryType = 'semantic'; body.semanticConfiguration = SEM;
             body.captions = 'extractive'; body.answers = 'extractive|count-3'; }
  const res = await fetch(url, { method: 'POST',
    headers: { 'content-type': 'application/json', 'api-key': KEY },
    body: JSON.stringify(body) });
  const data = await res.json();
  return { grounded: true, question,
    answers: (data['@search.answers'] || []).map(a =&amp;gt; a.text),
    citations: (data.value || []).map(d =&amp;gt; ({ title: d.title, source: d.source,
      score: d['@search.rerankerScore'] ?? d['@search.score'],
      snippet: d['@search.captions']?.[0]?.text || String(d.content).slice(0, 200) })) };
}&lt;/LI-CODE&gt;
&lt;H3&gt;The Warden: an AI advisor on a short leash&lt;/H3&gt;
&lt;P&gt;The in-game advisor, the Warden, is deliberately boxed in. It receives the account's signals plus the retrieved evidence, and it must answer in a fixed format: a recommended judgment, a rationale under 180 characters, and a confidence score. The instructions we gave it are what we'd tell a junior analyst: pick the least-destructive action that's still correct. The Warden advises; the deterministic rules of the game decide what actually happens. That split, AI proposes and the engine disposes, is one we'd recommend for any AI system that touches real operations.&lt;/P&gt;
&lt;H3&gt;Letting Copilot play&lt;/H3&gt;
&lt;P&gt;Because the manor is exposed through MCP, registering it with GitHub Copilot in VS Code takes four lines of configuration:&lt;/P&gt;
&lt;LI-CODE lang=""&gt;{ "servers": { "afterlogin": { "command": "node", "args": ["mcp-server.mjs"] } } }&lt;/LI-CODE&gt;
&lt;P&gt;From there you can ask Copilot to "clear the manor" and watch it investigate rooms, summon evidence, and pass judgments in a loop, playing by the same rules a human does. The first time it correctly spared the break-glass emergency account, the one that looks abandoned but is dormant by design, was a genuinely good moment in the office.&lt;/P&gt;
&lt;H3&gt;What gave us trouble&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Live cloud services fail at the worst possible moment.&lt;/STRONG&gt; Anyone who has demoed on conference Wi-Fi knows this. So every cloud integration in AfterLogin checks whether it's configured and quietly falls back to built-in synthetic evidence when it isn't. The game runs fully offline, and lights up real retrieval the moment it's pointed at a Foundry knowledge base. Same code path either way, no demo-mode switch to forget.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;The versions drifted apart.&lt;/STRONG&gt;&amp;nbsp;Early on, the human game and the AI-playable version had separate logic, and they disagreed in embarrassing ways. The fix was making the scoring engine the single source of truth that everything consumes. Now Copilot playing by itself gets identical outcomes to a human clicking rooms, which is the whole point.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;A simple website can't hold secrets.&lt;/STRONG&gt;&amp;nbsp;A game that ships as one web page has nowhere safe to keep an API key. Everything that needs one got moved behind two small server endpoints, so credentials never touch the browser.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Teaching without preaching.&lt;/STRONG&gt;&amp;nbsp;Nobody wants a lecture disguised as a game. We let the mechanics do the teaching: players internalize "dormant plus powerful plus nothing depends on it means lay it to rest" because the score, the Poltergeist, and the Possession punish every other choice.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;What it actually does&lt;/H2&gt;
&lt;P&gt;We'll be upfront: this is a demo and a teaching tool, not a product, and we don't have benchmark charts for a haunted house. What we can point to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Evidence changes decisions, provably.&lt;/STRONG&gt;&amp;nbsp;The manor's two deceptive cases (a terrible-looking service account that something still depends on, and an emergency account that's dormant on purpose) cannot be judged correctly from the statistics alone. Both hinge on retrieved citations. Skip the evidence step and you lose the game. That's the argument for grounded AI, made playable.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Three surfaces, one brain.&lt;/STRONG&gt;&amp;nbsp;One scoring model powers the visual game, the AI-playable version, and the service layer. The game itself ships as a single web page.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Works offline, upgrades gracefully.&lt;/STRONG&gt;&amp;nbsp;With no configuration it runs anywhere, no keys and no network needed. Configured, the evidence step returns real, semantically ranked, cited passages from Azure AI Search.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;It opens conversations.&lt;/STRONG&gt;&amp;nbsp;The game is live on Azure Static Web Apps and has become a genuinely useful icebreaker in our identity-governance work. People who would never read an orphaned-account runbook will happily spend ten minutes banishing a Possession, and they walk away able to explain "truly dead" versus "still depended on." That's more than most slide decks achieve.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Safe by construction.&lt;/STRONG&gt;&amp;nbsp;The bundled data is fully synthetic, with no real names or secrets anywhere. The optional live-directory mode is read-only, with a privacy flag that masks identifying details for public demos.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;What we learned&lt;/H2&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Fallbacks earn their keep.&lt;/STRONG&gt;&amp;nbsp;Designing every integration to degrade gracefully made the app more demoable and, as a side effect, forced cleaner boundaries in the code. It's now our default pattern for anything AI-backed.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Grounding lands hardest when the ungrounded answer is wrong.&lt;/STRONG&gt; The best moments in AfterLogin are the accounts where the statistics lie. If an AI retrieval demo only confirms what the raw data already says, nobody feels the value. Build the deceptive case first.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;MCP is a cheap second product.&lt;/STRONG&gt;&amp;nbsp;Wrapping the existing game logic in ten MCP tools took a fraction of the total effort, and it turned a visual demo into something an AI agent can be tested against. If your app already has an API, it's about one file away from being usable by an AI assistant.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Constrain the model, trust the engine.&lt;/STRONG&gt;&amp;nbsp;Keeping the AI advisory, with a fixed answer format, a short rationale, and a confidence score, avoids both invented actions and outcomes nobody can explain afterwards. The deterministic engine always has the final say.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="lia-align-center lia-indent-padding-left-30px"&gt;&lt;EM&gt;&lt;STRONG&gt;A field note from our MajorKey practice:&lt;/STRONG&gt;&amp;nbsp;this pattern isn't just for games. The identity programs we see work best run access reviews the way the manor does: a deterministic policy engine decides what's allowed, retrieved evidence about ownership, usage, and dependencies sits next to every decision, and AI recommends rather than rules. If your certification campaigns have turned into rubber stamps, the poltergeist has a lesson for them.&lt;/EM&gt;&lt;/P&gt;
&lt;H2&gt;Where it goes next&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;A real Fabric IQ ontology.&lt;/STRONG&gt;&amp;nbsp;The web of relationships between accounts, mailboxes, groups, and live jobs is currently modelled in code. Moving it to Microsoft Fabric's semantic layer would make those "spirit threads" a governed, queryable asset.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Agent-vs-agent mode.&lt;/STRONG&gt;&amp;nbsp;Two AI agents racing to clear the manor, one tuned for speed and one for safety. We can't think of a more fun way to demonstrate how you evaluate AI agents.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;A deeper live-directory mode.&lt;/STRONG&gt;&amp;nbsp;Extending the read-only Microsoft Entra integration with sign-in analysis and ownership lookups, behind the same privacy layer.&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Scenario packs.&lt;/STRONG&gt;&amp;nbsp;The manor layout and its ghosts are just data, so industry-specific versions (healthcare, public sector, finance) are new data files plus new documents to index. Given the range of clients we see at MajorKey, this one is probably next.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Wrapping up&lt;/H2&gt;
&lt;P&gt;Orphaned accounts are a judgment problem wearing an inventory problem's clothes, and good judgment needs grounded evidence. The pattern under AfterLogin reuses well beyond games: a deterministic rules engine at the core, Foundry IQ retrieval for evidence with citations, a constrained AI for recommendations, and an MCP wrapper so AI agents can work the same process people do. It also sits squarely at the intersection our team at MajorKey Technologies works in every day, where the job is identity security and the interesting question is how AI genuinely evolves it: past chatbots, toward governed, evidence-backed decisions. This started as a side experiment, but that intersection is why it got built.&lt;/P&gt;
&lt;P&gt;Try clearing the manor before dawn. Then look at your own organization and ask which rooms are haunted.&lt;/P&gt;
&lt;H3&gt;Explore, contribute, build on it&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Watch the demo:&lt;/STRONG&gt;&amp;nbsp;&lt;A href="https://www.youtube.com/watch?v=PASTE-VIDEO-ID" target="_blank" rel="noopener"&gt;the 90-second walkthrough on YouTube&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Get the code:&lt;/STRONG&gt;&amp;nbsp;&lt;A href="https://github.com/jlynch160/afterlogin-the-hunt" target="_blank" rel="noopener"&gt;github.com/jlynch160/afterlogin-the-hunt&lt;/A&gt;, including the synthetic document library and the indexer script to stand up your own Foundry IQ knowledge base&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Run it in 60 seconds:&lt;/STRONG&gt;&amp;nbsp;clone the repo and open&amp;nbsp;index.html. No installation, no API keys, no network needed; the cloud integrations light up later if you want them&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Make it yours:&lt;/STRONG&gt;&amp;nbsp;point the three&amp;nbsp;FOUNDRY_SEARCH_*&amp;nbsp;settings at your own Azure AI Search index and the grimoire starts citing&amp;nbsp;&lt;EM&gt;your&lt;/EM&gt; runbooks&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Fri, 24 Jul 2026 09:36:36 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/afterlogin-we-turned-forgotten-account-cleanup-into-a-haunted/ba-p/4539781</guid>
      <dc:creator>jefflynch107</dc:creator>
      <dc:date>2026-07-24T09:36:36Z</dc:date>
    </item>
    <item>
      <title>One Student Does Not Have Content Library in her class notebook</title>
      <link>https://techcommunity.microsoft.com/t5/class-notebook/one-student-does-not-have-content-library-in-her-class-notebook/m-p/4540210#M493</link>
      <description>&lt;P&gt;Hi! Please help - one of my students does not have Content Library in her class notebook just like this:&lt;/P&gt;&lt;img /&gt;&lt;P&gt;Was there something that she accidentally turned off? This is my first time encountering this situation. 😟&lt;/P&gt;</description>
      <pubDate>Fri, 24 Jul 2026 02:40:14 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/class-notebook/one-student-does-not-have-content-library-in-her-class-notebook/m-p/4540210#M493</guid>
      <dc:creator>anna2teach</dc:creator>
      <dc:date>2026-07-24T02:40:14Z</dc:date>
    </item>
    <item>
      <title>🏆 Agents League: Celebrating the Builders Who Made Agents Battle for Glory</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/agents-league-celebrating-the-builders-who-made-agents-battle/ba-p/4538007</link>
      <description>&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The arena has closed, the scores are in, and the champions are crowned.&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;Agents League, the esports-inspired hackathon at the heart of&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;AI Skills Fest 2026&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, brought together tens of thousands of developers to build, ship, and compete with agentic AI. This is the celebration post: a spotlight on the winners across every category, the numbers behind the movement, and the engineering lessons worth carrying into your next build.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;If you competed, watched a Reactor battle, or completed a skilling playlist, this recap is for you. You&amp;nbsp;didn't&amp;nbsp;just attend an event. You helped set a record.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Before we get to the winners, there is a useful playbook hiding in their submissions. Later in this post, the section&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;“What the Winners Teach Us: Patterns Worth Stealing”&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;breaks down the build patterns future attendees should pay attention to: multi-agent orchestration, meeting users where they already work, testing discipline, and accessibility-first design. If you are planning to enter next time, read the winners not just as inspiration, but as a practical checklist for what great agent projects have in common.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;🥇 Best Overall: $15,000 Grand Prize&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;img /&gt;
&lt;H3 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Afterlogin&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;: The Hunt — &lt;A class="lia-external-url" href="https://github.com/jlynch160/afterlogin-the-hunt" target="_blank" rel="noopener"&gt;https://github.com/jlynch160/afterlogin-the-hunt&lt;/A&gt;&amp;nbsp; (Creative Apps track)&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/H3&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The top weighted score of the entire field. Afterlogin: The Hunt is described by its builders as&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;"one engine, two faces"&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;: a cinematic Security Operations Centre (SOC) night on one side, and a coached training game on the other. The same underlying engine powers both an atmospheric narrative experience and a hands-on learning simulation.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Why it won:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;it fused genuinely creative design with a real-world use case (security operations training) and&amp;nbsp;executed both at a high polish level. Built with&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;for AI-assisted development,&amp;nbsp;it's&amp;nbsp;a masterclass in using one well-architected engine to serve two&amp;nbsp;very different&amp;nbsp;user experiences.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;🏅 Category Champions&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;H3 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Best Creative App:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;StudyMate&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;, "Study with Matey" — &lt;A class="lia-external-url" href="https://github.com/adetorojeremiahfadesayo/StudyMate" target="_blank" rel="noopener"&gt;https://github.com/adetorojeremiahfadesayo/StudyMate&lt;/A&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Tech: GitHub Copilot&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;StudyMate turns a student's&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;own&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;notes into a gamified, story-driven revision session, complete with XP and progression. Instead of generic flashcards, it grounds the experience in the learner's real material and wraps it in a narrative loop that keeps motivation high. It is&amp;nbsp;a great example&amp;nbsp;of pairing&amp;nbsp;personalisation&amp;nbsp;with game mechanics to solve a persistent problem: staying engaged while revising.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Best Reasoning Agent: DELPHAI — &lt;A class="lia-external-url" href="https://github.com/jlynch160/delphai" target="_blank" rel="noopener"&gt;https://github.com/jlynch160/delphai&lt;/A&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Tech: Microsoft Foundry&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;DELPHAI is an &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;11-agent reasoning council&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;that checks the&amp;nbsp;maths, explains the risk, and refines its own answer before responding. Rather than a single model producing&amp;nbsp;a one-shot&amp;nbsp;response, DELPHAI orchestrates a panel of&amp;nbsp;specialised&amp;nbsp;agents that debate, verify, and converge, a pattern that directly addresses the reliability gap in high-stakes reasoning.&amp;nbsp;It's&amp;nbsp;a textbook demonstration of multi-agent orchestration on&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Microsoft Foundry&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Best Enterprise Agent: Archon — &lt;A class="lia-external-url" href="https://github.com/upgradedev/archon_azure" target="_blank" rel="noopener"&gt;https://github.com/upgradedev/archon_azure&lt;/A&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Tech: Microsoft 365 Copilot&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Archon is a &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;7-agent financial-intelligence pipeline for small and medium businesses&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, delivered right inside Microsoft Teams. It meets users where they already work, chaining&amp;nbsp;specialised&amp;nbsp;agents to turn raw financial data into actionable intelligence. Archon shows how enterprise-ready agents built for&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Microsoft 365 Copilot&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;can deliver serious business value without forcing users to leave their daily workflow.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;🌟 Special Awards&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 100%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Award&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Winner&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td colspan="2"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;What made it stand out&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Best Use of IQ Tools&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;CivicGrant&amp;nbsp;IQ —&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/JonEricEubanks/CivicGrant-IQ" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://github.com/JonEricEubanks/CivicGrant-IQ&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td colspan="2"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Stood out for making the IQ layers genuinely useful: Foundry IQ, Fabric IQ and Work IQ were combined into a traceable grant-analysis workflow with grounded citations, specialist agents,&amp;nbsp;GraphRAG-style evidence handling, guardrails and evaluation coverage.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Accessibility&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;CLARO —&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/jagaor/claro" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://github.com/jagaor/claro&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;SchemeSaathi —&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/red-coder-27/SchemeSaathi" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://github.com/red-coder-27/SchemeSaathi&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Solace —&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/MaksymY11/solace-reasoning" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://github.com/MaksymY11/solace-reasoning&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td colspan="2"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;These teams treated accessibility as core product architecture, not a feature add-on: CLARO combined deterministic public-benefit rules with grounded bilingual reasoning;&amp;nbsp;SchemeSaathi&amp;nbsp;made health-scheme discovery usable across Indian languages; Solace delivered cited, plain-language immigration-rights support with safety escalation for sensitive situations.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Hack for Good&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Tell My Day —&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/stork066/TellMyDay" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://github.com/stork066/TellMyDay&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;BRIEF — AI Bias &amp;amp; Research Intelligence Evaluation Framework —&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/shiwakshir/brief-agent" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://github.com/shiwakshir/brief-agent&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;ARGUS — Agentic Risk &amp;amp; Governance Unified Screening —&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/iarjunganesh/argus" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://github.com/iarjunganesh/argus&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td colspan="2"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Each winner used agents for tangible social value: Tell My Day turns picture symbols into grounded stories for non-verbal users; BRIEF audits assumptions and bias before research begins; ARGUS turns manual KYC and governance screening into cited, auditable risk assessment.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Top Student&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Athenaeum —&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/theCodeForgerHQ/msf-reasoning-agent" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://github.com/theCodeForgerHQ/msf-reasoning-agent&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Narrative Alchemist —&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/10ANT/narrative-alchemist" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://github.com/10ANT/narrative-alchemist&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;CurriculumCraft AI —&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/gideonagbavor8/curriculumcraft-ai" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://github.com/gideonagbavor8/curriculumcraft-ai&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td colspan="2"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;These student-led projects stood out for ambition and execution: Athenaeum showed exceptional engineering discipline with a deep safety and test harness; Narrative Alchemist&amp;nbsp;demonstrated&amp;nbsp;a complete four-agent creative production pipeline;&amp;nbsp;CurriculumCraft&amp;nbsp;AI translated AI into practical instructional design for Ghanaian JHS teachers.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.4436%" /&gt;&lt;col style="width: 34.7406%" /&gt;&lt;col style="width: 31.7761%" /&gt;&lt;col style="width: 0%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Across&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;8 categories&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;14 winners&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;shared a&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;$55,000 prize pool&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;. Congratulations to every one of them, and to the thousands of builders who&amp;nbsp;submitted.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;🧠 What the Winners Teach Us:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Patterns Worth Stealing&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Look across the champions and clear engineering patterns&amp;nbsp;emerge. These are the&amp;nbsp;takeaways&amp;nbsp;AI engineers and developers should carry into their own projects.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 28px;"&gt;1. Multi-agent orchestration beats the monolithic prompt&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The two reasoning-heavy winners, DELPHAI (11 agents) and Archon (7 agents), both won by decomposing a hard problem into&amp;nbsp;specialised, cooperating agents. A "council" or "pipeline" of narrow agents that verify each other outperforms a single model asked to do everything at once.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Here's&amp;nbsp;the shape of that pattern, illustrated conceptually with the Microsoft Agent Framework style used with Microsoft Foundry. (This is an illustrative pattern, not the winners' actual code.)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang=""&gt;# Illustrative multi-agent "reasoning council" pattern
# Conceptual sketch, not the winning team's source code.

async def reasoning_council(question: str) -&amp;gt; str:
    # 1. Specialised agents each own one responsibility
    solver = create_agent(
        role="Propose an answer with its reasoning"
    )

    math_check = create_agent(
        role="Verify every calculation, flag errors"
    )

    risk_agent = create_agent(
        role="Explain the risks and assumptions"
    )

    # 2. Draft, then critique
    draft = await solver.run(question)
    math = await math_check.run(draft)
    risk = await risk_agent.run(draft)

    # 3. Refine using the critiques before answering the user
    refined = await solver.run(
        f"Question: {question}\n"
        f"Draft: {draft}\n"
        f"Math review: {math}\n"
        f"Risk review: {risk}\n"
        "Produce a corrected, final answer."
    )

    return refined&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The lesson:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;reliability comes from structure. Give each agent one job, let them check each other, and refine before you respond. That is exactly how DELPHAI "checks the math, explains the risk, and refines its answer."&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt; &amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 28px;"&gt;2. Meet users where they already are&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Archon delivers financial intelligence&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;inside Microsoft Teams&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;.&amp;nbsp;StudyMate&amp;nbsp;builds on a student's&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;own notes&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;. Winning agents reduce friction by integrating into existing workflows rather than asking users to adopt a new destination. When you build enterprise agents, target the surface, such as Microsoft 365 Copilot, Teams, and Copilot Studio, where the work already happens.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;3. Test &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;rigour&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;is a differentiator, not an afterthought&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Athenaeum won Top Student with&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;611 tests&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;behind its multi-agent learning system. In a field of prototypes, evidence of engineering discipline stood out to judges. Agentic systems are non-deterministic, so a strong evaluation and&amp;nbsp;test&amp;nbsp;harness is what turns a demo into something trustworthy.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;4. Design for everyone from day one&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;CLARO (accessibility-first reasoning) and Tell My Day (assistive storytelling for non-verbal users) prove that responsible, inclusive AI&amp;nbsp;isn't&amp;nbsp;a constraint;&amp;nbsp;it's&amp;nbsp;a source of the most meaningful innovation. Accessibility completions were a top skilling path this year, and the winners&amp;nbsp;reflected&amp;nbsp;it.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;🎮 The Three Tracks and Their Toolchains&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Agents League ran three build&amp;nbsp;tracks,&amp;nbsp;each anchored to a Microsoft developer platform. The winners map directly onto them:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Creative Apps → GitHub Copilot.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;AI-assisted development from concept to code. Winners:&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Afterlogin&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;The Hunt&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;StudyMate&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;. (35% of the&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;field.)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Reasoning Agents → Microsoft Foundry.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;Multi-step reasoning and agent orchestration. Winner:&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;DELPHAI&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;. (46% of the field, the most popular&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;track.)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Enterprise Agents → Microsoft 365 Copilot &amp;amp; Copilot Studio.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;Business-ready knowledge agents. Winner:&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Archon&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;. (19% of the&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;field.)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;🔴 The Reactor Battles: Learning in Public&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;The live Microsoft Reactor build battles were where the&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;thousands of developers&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;learned&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;together&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;in real time.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;The community connected over&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;four&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;live&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;broadcasts&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;.&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt; &lt;A class="lia-external-url" href="https://developer.microsoft.com/en-us/reactor/series/S-1658/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;Microsoft Reactor Agents League series&lt;/SPAN&gt;&lt;/A&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;A standout moment:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Kyle Daigle&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, CMO of Microsoft Developer and COO of GitHub, live-coded his own project on stream during the Creative Apps Reactor Battle, an authentic build-along that resonated with the developer audience. As one attendee put it:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;"These types of sessions are the best, where we can see code and flows. It's like we learn more by&amp;nbsp;visualising."&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;📚 Skill Up Like a Champion: The Developer&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Playlists&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Winners&amp;nbsp;don't&amp;nbsp;appear from nowhere; many skilled up first. Seven role-based developer paths on&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;AI Skills Navigator&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;drove&amp;nbsp;thousands of&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;completions&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, spanning GitHub Copilot, Microsoft Foundry, and Microsoft 365. The top&amp;nbsp;five&amp;nbsp;learning playlists:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Develop your first agent with Microsoft Foundry&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;, completions (the runaway&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;favourite&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Learn AI-assisted coding with GitHub Copilot&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="7" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Accessibility in practice&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="8" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Optimise&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;agentic DevOps with Azure DevOps &amp;amp; GitHub Copilot&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="9" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Build and orchestrate agents with Microsoft Foundry&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Completion earned free GitHub &amp;amp; Microsoft certification vouchers and&amp;nbsp;Credly&amp;nbsp;badges. If you want to be on next year's winners list, this is where to start.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;🔧 One Honest Lesson for Next Time&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Transparency matters, so&amp;nbsp;here's&amp;nbsp;a builder-to-builder tip drawn from the judging data. Of&amp;nbsp;the final&amp;nbsp;submissions, the single biggest disqualifier was a&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;missing demo video&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, followed by no listed repository. Brilliant projects were screened out on&amp;nbsp;a technicality.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The takeaway&amp;nbsp;for future hackathons:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;treat your&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;demo video&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;and&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;public repository&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;as first-class deliverables, not last-minute additions. A working agent nobody can see or reproduce&amp;nbsp;can't&amp;nbsp;win. Record the demo early, keep the repo public, and document how to run it.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;✅ Key Takeaways&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="10" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Multi-agent architectures dominated the podium&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;: DELPHAI's 11-agent council and Archon's 7-agent pipeline show that decomposition and self-verification win.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="11" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Integration and inclusivity are differentiators&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;: winners met users inside Teams, in their own notes, and designed for accessibility from day one.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="12" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Engineering&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;rigour&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;gets noticed&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;611 tests&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;helped Athenaeum&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;win&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;one&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;of&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;the&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;Top Student&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;&amp;nbsp;awards&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{" data-aria-posinset="13" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;Submission hygiene is non-negotiable&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="List Bullet"&gt;: a demo video and public repo are the price of admission to judging.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;🚀 Your Next Move&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Whether&amp;nbsp;you're&amp;nbsp;a returning competitor or inspired to enter your first battle,&amp;nbsp;here's&amp;nbsp;how to keep building:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;🎬&amp;nbsp;&lt;STRONG&gt;Rewatch the battles:&lt;/STRONG&gt;&amp;nbsp;&lt;A href="https://developer.microsoft.com/en-us/reactor/series/S-1658/" target="_blank" rel="noopener"&gt;Microsoft Reactor Agents League series&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;📘&amp;nbsp;&lt;STRONG&gt;Start skilling:&lt;/STRONG&gt;&amp;nbsp;&lt;A href="https://aiskillsnavigator.microsoft.com/events/AISF2026" target="_blank" rel="noopener"&gt;AI Skills Navigator AISF 2026 developer playlists&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;🤖&amp;nbsp;&lt;STRONG&gt;Build reasoning agents:&lt;/STRONG&gt;&amp;nbsp;explore&amp;nbsp;&lt;A href="https://ai.azure.com/" target="_blank" rel="noopener"&gt;Microsoft Foundry&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;💡&amp;nbsp;&lt;STRONG&gt;Ship with AI assistance:&lt;/STRONG&gt;&amp;nbsp;&lt;A href="https://github.com/features/copilot" target="_blank" rel="noopener"&gt;GitHub Copilot&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;🏢&amp;nbsp;&lt;STRONG&gt;Build enterprise agents:&lt;/STRONG&gt;&amp;nbsp;&lt;A href="https://www.microsoft.com/microsoft-copilot/microsoft-copilot-studio" target="_blank" rel="noopener"&gt;Microsoft Copilot Studio&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;To every builder who entered the arena, streamed a battle, or completed a playlist:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;thank you.&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;You&amp;nbsp;didn't&amp;nbsp;just compete; you showed the world what's possible when developers and agentic AI build together. The champions above earned their moment, but the real story is a global community of 31,000 developers levelling up at once.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The arena will open again. When it does, will your agent be on the podium? 🏆&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;Agents&amp;nbsp;League was part of AI Skills Fest 2026 and was open to the public at no cost. Figures reflect the completed submission and judging period after excluding Microsoft-affiliated participants. Winner descriptions are drawn from the official Agents League Hackathon summary.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/EM&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 23 Jul 2026 19:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/agents-league-celebrating-the-builders-who-made-agents-battle/ba-p/4538007</guid>
      <dc:creator>Lee_Stott</dc:creator>
      <dc:date>2026-07-23T19:00:00Z</dc:date>
    </item>
    <item>
      <title>Set Up Plaud Note Pro with Microsoft Foundry</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/set-up-plaud-note-pro-with-microsoft-foundry/ba-p/4537428</link>
      <description>&lt;H1&gt;Prerequisites&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A class="lia-external-url" href="https://github.com/riffado/connector#installation" target="_blank"&gt;Riffado&lt;/A&gt;, up and running: follow the setup guide in the official Riffado repository to get it going with Docker Compose.&lt;/LI&gt;
&lt;LI&gt;A Microsoft Foundry (formerly Azure AI Foundry) resource, with the models you want deployed; in my case, whisper for transcription and o3-mini for summaries.&lt;/LI&gt;
&lt;LI&gt;A Plaud device, or any audio recordings you can import into Riffado.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Once Riffado is up, head to the Settings page &amp;gt; Providers &amp;gt; Add Provider, and select Custom. This is where the Azure details will go.&lt;/P&gt;
&lt;H1&gt;Why "OpenAI-compatible" isn’t one thing on Microsoft Foundry&lt;/H1&gt;
&lt;P&gt;Azure AI Foundry exposes&amp;nbsp;&lt;STRONG&gt;two different API surfaces&lt;/STRONG&gt;&amp;nbsp;on the same resource, and which one serves your model depends on the model:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Surface&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Path shape&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Serves&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;OpenAI-compatible?&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;v1 route&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;/openai/v1/…&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;gpt-4o-transcribe, gpt-4o-mini-transcribe, chat models, embeddings&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Yes: Bearer auth, model in the body, no&amp;nbsp;api-version&amp;nbsp;needed&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Classic route&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;/openai/deployments/{name}/…&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Whisper&lt;/STRONG&gt;&amp;nbsp;(and other legacy audio)&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;No: deployment name lives in the URL, and&amp;nbsp;?api-version=&amp;nbsp;is&amp;nbsp;&lt;EM&gt;mandatory&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;A generic OpenAI client (Riffado's included) can only speak the first dialect. It has nowhere to put a deployment name in the path and no way to append a query parameter. That single fact drives everything below.&lt;/P&gt;
&lt;H1&gt;Part 1 - Transcription&lt;/H1&gt;
&lt;H2&gt;Whisper and the&amp;nbsp;DeploymentNotFound&amp;nbsp;mystery&lt;/H2&gt;
&lt;H3&gt;Symptom&lt;/H3&gt;
&lt;P&gt;My very first transcription attempt in Riffado failed with&amp;nbsp;404 Resource not found. Off to a flying start. Configured provider: base URL&amp;nbsp;https://&amp;lt;resource&amp;gt;.services.ai.azure.com, model&amp;nbsp;whisper.&lt;/P&gt;
&lt;H3&gt;Dead end #1: the missing path&lt;/H3&gt;
&lt;P&gt;The first bug was mine: the base URL had no path. Riffado's OpenAI client appends&amp;nbsp;/audio/transcriptions&amp;nbsp;to whatever you give it, so requests were hitting&amp;nbsp;https://&amp;lt;resource&amp;gt;…/audio/transcriptions, a path that doesn't exist on the resource at all. Fixing the base URL to end in&amp;nbsp;/openai/v1&amp;nbsp;got us to a more interesting error:&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN class="lia-text-color-8"&gt;POST /openai/v1/audio/transcriptions · model=whisper&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;{"error":{"code":"DeploymentNotFound","message":"The API deployment for&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;this resource does not exist. If you created the deployment within the&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;last 5 minutes, please wait a moment and try again."}}&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;H3&gt;Dead end #2: catalog ≠ deployment&lt;/H3&gt;
&lt;P&gt;Worth checking before anything else:&amp;nbsp;&lt;EM&gt;selecting&lt;/EM&gt;&amp;nbsp;a model in the Foundry catalog is not&amp;nbsp;&lt;EM&gt;deploying&lt;/EM&gt;&amp;nbsp;it.&amp;nbsp;GET /openai/v1/models&amp;nbsp;lists everything you&amp;nbsp;&lt;EM&gt;could&lt;/EM&gt;&amp;nbsp;deploy; only&amp;nbsp;&lt;STRONG&gt;Deployments → Deploy model&lt;/STRONG&gt;&amp;nbsp;creates an endpoint that answers. If you get&amp;nbsp;DeploymentNotFound, first confirm a deployment actually exists (the listing below requires only the API key):&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;enumerate real deployments (classic control-plane, key auth)&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN class="lia-text-color-8"&gt;curl -s -H "api-key: $KEY" \&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;  "https://&amp;lt;resource&amp;gt;.openai.azure.com/openai/deployments?api-version=2023-03-15-preview"&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;# → {"data":[{"id":"whisper","model":"whisper","status":"succeeded",…}]}&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;H3&gt;The actual cause&lt;/H3&gt;
&lt;P&gt;Here is the part that nearly drove me mad: the deployment existed and was succeeded, yet the v1 route still said&amp;nbsp;DeploymentNotFound. Because&amp;nbsp;&lt;STRONG&gt;Whisper deployments are not served on the v1 route at all.&lt;/STRONG&gt;&amp;nbsp;They only answer on the classic path. Verified side by side with the same tiny WAV file:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Request&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Result&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;POST /openai/v1/audio/transcriptions&amp;nbsp;·&amp;nbsp;model=whisper&amp;nbsp;· Bearer&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;404 DeploymentNotFound&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;POST /openai/deployments/whisper/audio/transcriptions?api-version=2024-06-01&amp;nbsp;· Bearer&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;200 {"text":"you"}&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Same classic path,&amp;nbsp;&lt;STRONG&gt;without&lt;/STRONG&gt;&amp;nbsp;?api-version=&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;404 Resource not found&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Three constraints, then: Whisper needs the classic path; the classic path needs&amp;nbsp;api-version; Riffado can send neither. One piece of good news hiding in the table: the classic route accepts&amp;nbsp;Authorization: Bearer, not just Azure's&amp;nbsp;api-key&amp;nbsp;header, so the shim doesn't have to touch auth at all.&lt;/P&gt;
&lt;H3&gt;The fix: a Caddy shim&lt;/H3&gt;
&lt;P&gt;Drop a stock&amp;nbsp;caddy:2-alpine&amp;nbsp;container into the Compose network. Riffado points at it as if it were OpenAI; the shim rewrites the path, injects&amp;nbsp;api-version, and proxies to Azure. The Bearer header passes through untouched.&lt;/P&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-8"&gt;&lt;STRONG&gt;azure-shim.Caddyfile&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang=""&gt;{
      admin off
      auto_https off
}

:80 {
      @transcribe path /v1/audio/transcriptions /audio/transcriptions
      handle @transcribe {
            rewrite * /openai/deployments/whisper/audio/transcriptions?api-version=2024-06-01
            reverse_proxy https://&amp;lt;resource&amp;gt;.services.ai.azure.com {
                  header_up Host &amp;lt;resource&amp;gt;.services.ai.azure.com
            }
      }

      handle {
            respond "azure-shim ok" 200
      }

}&lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-8"&gt;&lt;STRONG&gt;docker-compose.yml (added service)&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang=""&gt;azure-shim:
    image: caddy:2-alpine
    restart: unless-stopped
    volumes:
      - ./azure-shim.Caddyfile:/etc/caddy/Caddyfile:ro&lt;/LI-CODE&gt;
&lt;P&gt;Riffado's provider settings become:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Field&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Value&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Base URL&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;http://azure-shim/v1&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Model&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;whisper&amp;nbsp;(must equal the deployment name)&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;API key&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;the Azure resource key (forwarded as Bearer)&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3&gt;Verified&lt;/H3&gt;
&lt;P&gt;From inside the Riffado container:&amp;nbsp;POST http://azure-shim/v1/audio/transcriptions&amp;nbsp;→&amp;nbsp;200 {"text":"…"}. Transcription works end-to-end in the UI.&lt;/P&gt;
&lt;H1&gt;Part 2 · Summaries &amp;amp; titles&lt;/H1&gt;
&lt;H2&gt;o3-mini and the empty answer&lt;/H2&gt;
&lt;H3&gt;Symptom&lt;/H3&gt;
&lt;P&gt;The summary button showed&amp;nbsp;&lt;EM&gt;"An unexpected error occurred."&lt;/EM&gt;&amp;nbsp;The container logs were more honest:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;riffado-app logs&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Error generating title: TypeError: undefined is not an object&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (evaluating 'C.choices[0]')&lt;BR /&gt;&lt;BR /&gt;Riffado calls&amp;nbsp;chat/completions&amp;nbsp;and reads&amp;nbsp;choices[0]&amp;nbsp;without checking whether the response was an error. So&amp;nbsp;&lt;EM&gt;anything&lt;/EM&gt; the API refuses becomes "an unexpected error." What was it refusing?&lt;/P&gt;
&lt;H3&gt;Cause 1: reasoning models reject the classic knobs&lt;/H3&gt;
&lt;P&gt;o3-mini belongs to Azure/OpenAI's&amp;nbsp;&lt;STRONG&gt;o-series reasoning models&lt;/STRONG&gt;, which hard-reject parameters every classic chat client sends. Riffado sends&amp;nbsp;temperature: 0.7&amp;nbsp;and&amp;nbsp;max_tokens: 50&amp;nbsp;for titles (0.5&amp;nbsp;/&amp;nbsp;2000&amp;nbsp;for summaries), and o3-mini answers:&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN class="lia-text-color-8"&gt;POST /openai/v1/chat/completions · model=o3-mini&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;HTTP 400&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;{"error":{"message":"Unsupported parameter: 'max_tokens' is not supported&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;with this model. Use 'max_completion_tokens' instead.", …}}&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;# and with max_tokens fixed:&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN class="lia-text-color-8"&gt;HTTP 400&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;{"error":{"message":"Unsupported parameter: 'temperature' is not supported&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;with this model.", …}}&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;H3&gt;Cause 2: reasoning tokens starve the output&lt;/H3&gt;
&lt;P&gt;Stripping the bad params gets you to 200, and then comes a subtler failure, my personal favourite of this whole saga. Reasoning models spend completion tokens on internal "thinking"&amp;nbsp;&lt;EM&gt;before&lt;/EM&gt;&amp;nbsp;emitting a single visible character. Riffado's 50-token title budget is consumed entirely by reasoning, and the reply comes back syntactically valid and&amp;nbsp;&lt;STRONG&gt;empty&lt;/STRONG&gt;:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;max_completion_tokens&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;reasoning_effort&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;finish_reason&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;content&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;50&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;not set&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;length&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;"" (all 50 spent reasoning)&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;2000&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;not set&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;stop&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;"Q3 Budget Planning Strategy Meeting"&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;2000&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;low&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;stop&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;same, less reasoning overhead&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3&gt;The fix: a Node shim that rewrites the request body&lt;/H3&gt;
&lt;P&gt;Caddy can rewrite paths but not JSON bodies, so this shim is ~60 lines of dependency-free Node on&amp;nbsp;node:20-alpine. Per request it: converts&amp;nbsp;max_tokens → max_completion_tokens, strips&amp;nbsp;temperature&amp;nbsp;/&amp;nbsp;top_p&amp;nbsp;/ penalties,&amp;nbsp;&lt;STRONG&gt;floors the token budget at 4000&lt;/STRONG&gt;, sets&amp;nbsp;reasoning_effort: "low", maps&amp;nbsp;/v1/* → /openai/v1/*, and forwards to the Azure resource.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;o3-shim.js&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang=""&gt;const http = require('http');
const https = require('https');
const UPSTREAM_HOST = '&amp;lt;resource&amp;gt;.services.ai.azure.com';

// Params o-series reasoning models reject on chat/completions.
const STRIP = ['temperature','top_p','presence_penalty',
               'frequency_penalty','logprobs','top_logprobs'];

const server = http.createServer((req, res) =&amp;gt; {
  const chunks = [];
  req.on('data', c =&amp;gt; chunks.push(c));
  req.on('end', () =&amp;gt; {
    let body = Buffer.concat(chunks);

    // Riffado's base_url is http://o3-shim/v1 → map to Azure's /openai/v1
    let path = req.url;
    if (path.startsWith('/v1/')) path = '/openai' + path;
    const ct = (req.headers['content-type'] || '').toLowerCase();
    if (ct.includes('application/json') &amp;amp;&amp;amp; body.length) {

      try {
        const j = JSON.parse(body.toString('utf8'));
        if (j &amp;amp;&amp;amp; typeof j === 'object' &amp;amp;&amp;amp; !Array.isArray(j)) {
          if ('max_tokens' in j) {
            if (!('max_completion_tokens' in j))
              j.max_completion_tokens = j.max_tokens;
            delete j.max_tokens;
          }

          // Reasoning spends tokens before any visible output; small
          // budgets (Riffado sends 50 for titles) return empty strings.
          if (Array.isArray(j.messages)) {
            j.max_completion_tokens =
              Math.max(Number(j.max_completion_tokens) || 0, 4000);
            if (!('reasoning_effort' in j)) j.reasoning_effort = 'low';
          }
          for (const k of STRIP) delete j[k];
          body = Buffer.from(JSON.stringify(j));
        }
      } catch (_) { /* not JSON - forward untouched */ }
    }

    const headers = { ...req.headers, host: UPSTREAM_HOST,
                      'content-length': Buffer.byteLength(body) };
    const up = https.request(
      { host: UPSTREAM_HOST, port: 443, method: req.method, path, headers },
      upRes =&amp;gt; { res.writeHead(upRes.statusCode, upRes.headers); upRes.pipe(res); }
    );

    up.on('error', e =&amp;gt; {
      res.writeHead(502, {'content-type':'application/json'});
      res.end(JSON.stringify({error:{message:'o3-shim upstream error: '+e.message}}));
    });

    up.end(body);
  });
});

server.listen(80, () =&amp;gt; console.log('o3-shim listening on :80'));&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;docker-compose.yml (added service)&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang=""&gt;  o3-shim:
    image: node:20-alpine
    restart: unless-stopped
    working_dir: /app
    command: ["node", "/app/o3-shim.js"]
    volumes:
      - ./o3-shim.js:/app/o3-shim.js:ro&lt;/LI-CODE&gt;
&lt;P&gt;Add a second provider in Riffado (base URL&amp;nbsp;http://o3-shim/v1, model&amp;nbsp;o3-mini, the resource's API key) and set it as the default&amp;nbsp;&lt;EM&gt;enhancement&lt;/EM&gt; provider (summaries/titles), keeping the Whisper one as default for transcription.&lt;/P&gt;
&lt;P&gt;Riffado's exact title request (temperature: 0.7, max_tokens: 50) through the shim → 200, finish_reason: stop, real title text. A full meeting-transcript summary returns structured key points and action items.&lt;/P&gt;
&lt;H1&gt;The final shape&lt;/H1&gt;
&lt;img /&gt;
&lt;P&gt;Reading it left to right: Riffado never talks to Azure directly. Transcription requests pass through azure-shim, a stock Caddy container that rewrites each request onto Whisper's classic deployment path and injects the mandatory api-version parameter. Summary and title requests pass through o3-shim, a tiny Node server that rewrites the request body into the shape o3-mini accepts and floors the token budget so the model's internal reasoning cannot starve the actual answer. As far as Riffado is concerned, it is simply talking to two ordinary OpenAI providers.&lt;/P&gt;
&lt;P&gt;Both shims live on the Compose network only; nothing is exposed publicly. Riffado is unmodified.&lt;/P&gt;
&lt;H1&gt;Verification checklist&lt;/H1&gt;
&lt;P&gt;Each layer, testable in isolation. Run these before blaming the app:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;smoke tests&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN class="lia-text-color-8"&gt;# 1. Key + resource alive? (v1 models listing, Bearer auth)&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;curl -s -H "Authorization: Bearer $KEY" \&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;  https://&amp;lt;resource&amp;gt;.services.ai.azure.com/openai/v1/models | head -c 200&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;# 2. Whisper answers on the classic path?&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;curl -s -H "Authorization: Bearer $KEY" -F file=@test.wav \&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;&amp;nbsp; "https://&amp;lt;resource&amp;gt;.services.ai.azure.com/openai/deployments/whisper/audio/transcriptions?api-version=2024-06-01"&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;# 3. Shim translates correctly? (from inside the compose network)&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;docker exec riffado-app node -e "fetch('http://azure-shim/')&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;&amp;nbsp; .then(r=&amp;gt;r.text()).then(console.log)"&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;# 4. o3-mini via shim, sending the params Riffado sends?&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN class="lia-text-color-8"&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp; (temperature + max_tokens:50; the shim must absorb both)&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;H1&gt;If you'd rather not run shims&lt;/H1&gt;
&lt;P&gt;Both shims exist because of the specific models chosen. Pick models that live natively on the v1 route and Riffado connects directly, with base URL&amp;nbsp;https://&amp;lt;resource&amp;gt;.services.ai.azure.com/openai/v1&amp;nbsp;and zero extra containers:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Transcription:&lt;/STRONG&gt;&amp;nbsp;deploy&amp;nbsp;gpt-4o-mini-transcribe&amp;nbsp;(or&amp;nbsp;gpt-4o-transcribe) instead of Whisper.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Summaries:&lt;/STRONG&gt;&amp;nbsp;deploy a non-reasoning chat model such as&amp;nbsp;gpt-4o-mini, which happily accepts&amp;nbsp;temperature&amp;nbsp;and&amp;nbsp;max_tokens.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The shim approach earns its keep when you're standardized on specific models (Whisper's transcription quality, o3-mini's reasoning), or when you want a control point to add logging, retries, or budget caps later.&lt;/P&gt;
&lt;P&gt;For reference, this is what the finished setup looks like on Riffado's side. Each shim is registered as a plain Custom provider. Here is the whisper provider pointing at azure-shim, with Use for transcription ticked:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;And once both are saved, they sit side by side in the providers list, whisper tagged for transcription and o3-mini tagged for enhancement:&lt;/P&gt;
&lt;img /&gt;
&lt;H1&gt;A quick look at the Foundry portal&lt;/H1&gt;
&lt;P&gt;In the Microsoft Foundry portal, head over to Models &amp;gt; AI Services and you will find a pleasant surprise: fifteen AI service models already deployed and ready to use, covering the Azure Speech family (including Voice Live and Speech to Text), Azure Translator, Azure Language, and Content Understanding:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You can of course deploy another model for this, but the pre-deployed ones are a handy cost-saving option. Click on the Azure Speech – Voice Live radio button and you will be shown the Base URL and API Key, which you can then paste into the provider settings on Riffado's Settings page.&lt;/P&gt;
&lt;P&gt;A quick note on cost: these services are not free. They are billed pay-as-you-go based on usage. Azure Speech transcription is charged per audio hour, and Voice Live pricing is tiered by the model you choose. The free tier does include a monthly allowance, though. Check the &lt;A href="https://azure.microsoft.com/en-us/pricing/details/speech/" target="_blank"&gt;Azure Speech pricing page&lt;/A&gt; before committing.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;And if you would rather deploy a dedicated transcription model such as whisper, Foundry gives you the flexibility to do just that. Open the model page in the catalogue, click Deploy, and go with Default settings unless you need custom quotas or guardrails:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;H1&gt;Let's test the setup&lt;/H1&gt;
&lt;P&gt;On your Plaud device, just tap to start recording. The little LED bars light up to show it is listening:&lt;/P&gt;
&lt;img&gt;Plaud Note Pro physical device&lt;/img&gt;
&lt;P&gt;Or skip the device entirely and upload an audio file straight into Riffado using the Upload Audio button. Either way, the recording lands on the Recordings page; hit Transcribe and let the spinner do its thing:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As you can see below, whisper, the transcription model we deployed earlier, even managed to transcribe a recording in Malay without a hitch. My 3:32 test clip came back as 186 words of clean Malay, with the language correctly detected and tagged:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I have also set o3-mini as the enhancement provider, and it enhanced the transcription with a proper summary, key points, and title as well! The Meeting Notes-style summary came straight out of o3-mini through the shim, with zero manual prompting.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;H1&gt;Wrapping up&lt;/H1&gt;
&lt;P&gt;What started as a TikTok-fuelled impulse buy nearly killed off by subscription pricing ended up as a fully self-hosted pipeline: Plaud for recording, Riffado as the interface, and Microsoft Foundry serving whisper and o3-mini behind two tiny shims. The total extra infrastructure came to two containers and roughly sixty lines of code, and not a single monthly subscription in sight.&lt;/P&gt;
&lt;P&gt;If you try this setup and run into a failure mode I have not covered here, do share it in the comments. Half the fun is in the debugging.&lt;/P&gt;</description>
      <pubDate>Wed, 22 Jul 2026 14:59:24 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/set-up-plaud-note-pro-with-microsoft-foundry/ba-p/4537428</guid>
      <dc:creator>suzarilshah</dc:creator>
      <dc:date>2026-07-22T14:59:24Z</dc:date>
    </item>
    <item>
      <title>Microsoft Agent Framework Multi-Agent Workflow Architecture for Automated Kubernetes Assessments</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/microsoft-agent-framework-multi-agent-workflow-architecture-for/ba-p/4538371</link>
      <description>&lt;H2&gt;Why this system generates tests (design rationale)&lt;/H2&gt;
&lt;P&gt;This project does not generate tests just to "check code." It generates tests because, in a Kubernetes learning game, the test suite&amp;nbsp;&lt;EM&gt;is the grading contract&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;The design goals are:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Scale content creation&lt;/STRONG&gt;: instructors should not hand-author every task and checker.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Keep grading objective&lt;/STRONG&gt;: student success is measured against Kubernetes API state, not subjective review.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Avoid fragile tasks&lt;/STRONG&gt;: generated tasks must survive empty/wrong cluster states without crashing.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Make failures repairable&lt;/STRONG&gt;: when checks break, the system should patch and re-validate automatically.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;So the pipeline generates a full task package (setup,&amp;nbsp;answer,&amp;nbsp;check,&amp;nbsp;cleanup) where tests define exactly what "correct" means.&lt;/P&gt;
&lt;H2&gt;Lifecycle: from concept to production-ready grader&lt;/H2&gt;
&lt;P&gt;Reader mental model: this is a&amp;nbsp;&lt;STRONG&gt;content compiler&lt;/STRONG&gt;&amp;nbsp;with validation stages, not a single chat completion.&lt;/P&gt;
&lt;img /&gt;
&lt;H3&gt;Phase 1: Pedagogical intent -&amp;gt; structured concept&lt;/H3&gt;
&lt;P&gt;The Idea Agent converts a topic into a constrained concept object (objective, progression, task IDs, difficulty variants). Memory rules block duplicates and previously failed concepts.&lt;/P&gt;
&lt;H3&gt;Phase 2: Concept -&amp;gt; executable grading package&lt;/H3&gt;
&lt;P&gt;The Generator Agent turns that concept into files:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;student instructions (instruction.md)&lt;/LI&gt;
&lt;LI&gt;learning material (concept.md)&lt;/LI&gt;
&lt;LI&gt;parameter source (session.json)&lt;/LI&gt;
&lt;LI&gt;setup and answer manifests (setup.template.yaml,&amp;nbsp;answer.template.yaml)&lt;/LI&gt;
&lt;LI&gt;deterministic pytest flow (test_01&amp;nbsp;...&amp;nbsp;test_06)&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;At this point, output is still untrusted draft content.&lt;/P&gt;
&lt;H3&gt;Phase 3: Structural correctness gate&lt;/H3&gt;
&lt;P&gt;Deterministic validation checks file presence, syntax, JSON/YAML shape, and template correctness. This catches basic integrity issues before cluster execution.&lt;/P&gt;
&lt;H3&gt;Phase 4: Behavioral correctness gate (real cluster)&lt;/H3&gt;
&lt;P&gt;Pytest executes against Kubernetes and verifies runtime behavior using real&amp;nbsp;kubectl-derived state. This proves that generated checks actually evaluate cluster resources as intended.&lt;/P&gt;
&lt;H3&gt;Phase 5: Anti-false-positive gate (skip-answer mode)&lt;/H3&gt;
&lt;P&gt;The same suite runs with&amp;nbsp;SKIP_ANSWER_TESTS=True&amp;nbsp;to verify grader integrity:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;answer deployment is skipped&lt;/LI&gt;
&lt;LI&gt;test_05_check.py&amp;nbsp;must fail&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If it still passes, the grader is invalid (it would accept wrong student submissions).&lt;/P&gt;
&lt;H3&gt;Phase 6: Self-healing repair loop&lt;/H3&gt;
&lt;P&gt;On any failure, deterministic error logs are fed into the Fixer Agent, which patches only broken files. The workflow then re-enters validation + test gates.&lt;/P&gt;
&lt;H3&gt;Phase 7: Finalization&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;If all gates pass -&amp;gt; task is kept as production-ready content.&lt;/LI&gt;
&lt;LI&gt;If retries are exhausted -&amp;gt; task is moved to&amp;nbsp;unsuccessful/&amp;nbsp;with&amp;nbsp;FAILURE_REPORT.txt&amp;nbsp;for human triage.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This lifecycle explains the core architecture decision:&amp;nbsp;&lt;STRONG&gt;LLMs generate candidate graders, deterministic execution certifies them.&lt;/STRONG&gt;&lt;/P&gt;
&lt;H2&gt;Concrete generated sample (what the pipeline actually produces)&lt;/H2&gt;
&lt;P&gt;Below is a representative generated task for topic:&amp;nbsp;&lt;STRONG&gt;ConfigMap Environment Variable Injection&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H3&gt;Generated directory layout&lt;/H3&gt;
&lt;LI-CODE lang="markdown"&gt;tests/game01/050_configmap_env_injection/
├── __init__.py
├── instruction.md
├── concept.md
├── session.json
├── setup.template.yaml
├── answer.template.yaml
├── test_01_setup.py
├── test_02_ready.py
├── test_03_answer.py
├── test_05_check.py
└── test_06_cleanup.py&lt;/LI-CODE&gt;
&lt;H3&gt;session.json (runtime variables)&lt;/H3&gt;
&lt;LI-CODE lang="json"&gt;{
  "namespace": "{{random_name()}}{{random_number(100,999)}}{{student_id()}}",
  "configmap_name": "{{random_name()}}",
  "deployment_name": "{{random_name()}}",
  "container_name": "app",
  "env_key": "APP_MODE",
  "env_value": "production"
}&lt;/LI-CODE&gt;
&lt;P&gt;Why this exists: task values are randomized per student/session, so tests verify behavior by variable contract instead of hardcoded names.&lt;/P&gt;
&lt;H3&gt;setup.template.yaml&amp;nbsp;(baseline state only)&lt;/H3&gt;
&lt;LI-CODE lang="yaml"&gt;apiVersion: v1
kind: Namespace
metadata:
  name: {{ namespace }}&lt;/LI-CODE&gt;
&lt;P&gt;Why this exists: setup should create prerequisites only. It must not accidentally include the final answer.&lt;/P&gt;
&lt;H3&gt;answer.template.yaml (expected correct solution)&lt;/H3&gt;
&lt;LI-CODE lang="yaml"&gt;apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ configmap_name }}
  namespace: {{ namespace }}
data:
  {{ env_key }}: "{{ env_value }}"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ deployment_name }}
  namespace: {{ namespace }}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: env-demo
  template:
    metadata:
      labels:
        app: env-demo
    spec:
      containers:
        - name: {{ container_name }}
          image: nginx:latest
          env:
            - name: {{ env_key }}
              valueFrom:
                configMapKeyRef:
                  name: {{ configmap_name }}
                  key: {{ env_key }}&lt;/LI-CODE&gt;
&lt;P&gt;Why this exists: defines canonical "correct cluster state" that graders must detect.&lt;/P&gt;
&lt;H3&gt;test_02_ready.py (wait for setup resources)&lt;/H3&gt;
&lt;LI-CODE lang="python"&gt;import json
import time
from tests.helper.kubectrl_helper import build_kube_config, run_kubectl_command


class TestReady:
    def test_001_namespace_active(self, json_input):
        kube_config = build_kube_config(
            json_input["cert_file"], json_input["key_file"], json_input["host"]
        )
        time.sleep(2)
        result = run_kubectl_command(
            kube_config,
            f"kubectl get namespace {json_input['namespace']} -o json",
        )
        data = json.loads(result)
        assert data.get("status", {}).get("phase") == "Active"&lt;/LI-CODE&gt;
&lt;P&gt;Why this matters: validates setup-stage readiness only. It should not check answer resources yet.&lt;/P&gt;
&lt;H3&gt;test_05_check.py (student grading contract)&lt;/H3&gt;
&lt;LI-CODE lang="python"&gt;import json
from tests.helper.kubectrl_helper import build_kube_config, run_kubectl_command


class TestCheck:
    def test_001_configmap_key_exists(self, json_input):
        kube_config = build_kube_config(
            json_input["cert_file"], json_input["key_file"], json_input["host"]
        )
        result = run_kubectl_command(
            kube_config,
            f"kubectl get configmap {json_input['configmap_name']} -n {json_input['namespace']} -o json",
        )
        data = json.loads(result)
        assert data["data"][json_input["env_key"]] == json_input["env_value"]

    def test_002_deployment_uses_configmap_env(self, json_input):
        kube_config = build_kube_config(
            json_input["cert_file"], json_input["key_file"], json_input["host"]
        )
        result = run_kubectl_command(
            kube_config,
            f"kubectl get deployment {json_input['deployment_name']} -n {json_input['namespace']} -o json",
        )
        data = json.loads(result)
        env = data["spec"]["template"]["spec"]["containers"][0].get("env", [])
        matched = [
            e for e in env
            if e.get("name") == json_input["env_key"]
            and e.get("valueFrom", {}).get("configMapKeyRef", {}).get("name") == json_input["configmap_name"]
            and e.get("valueFrom", {}).get("configMapKeyRef", {}).get("key") == json_input["env_key"]
        ]
        assert matched, "Deployment container must consume env var from ConfigMap key"&lt;/LI-CODE&gt;
&lt;P&gt;Why this matters: this is the real grading logic. If a student deploys wrong resource wiring, this test fails with explicit reason.&lt;/P&gt;
&lt;H3&gt;Why skip-answer validation is essential for this sample&lt;/H3&gt;
&lt;P&gt;When&amp;nbsp;SKIP_ANSWER_TESTS=True, answer deployment is skipped. In this mode:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;test_03_answer.py&amp;nbsp;should be skipped&lt;/LI&gt;
&lt;LI&gt;test_05_check.py&amp;nbsp;must fail (ConfigMap/Deployment wiring is absent)&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If&amp;nbsp;test_05_check.py&amp;nbsp;still passes, the grader is broken (false positive), and the workflow routes to Fixer.&lt;/P&gt;
&lt;H2&gt;Rule Builder Workflow Flowchart&lt;/H2&gt;
&lt;img /&gt;
&lt;H2&gt;Multi-graph architecture views&lt;/H2&gt;
&lt;H3&gt;1) Control-plane graph (orchestration DAG)&lt;/H3&gt;
&lt;img /&gt;
&lt;H3&gt;2) Runtime sequence (who calls what)&lt;/H3&gt;
&lt;img /&gt;
&lt;H3&gt;3) State machine (task lifecycle)&lt;/H3&gt;
&lt;img /&gt;
&lt;H3&gt;4) Prompt lifecycle graph (how prompts evolve)&lt;/H3&gt;
&lt;img /&gt;
&lt;H3&gt;5) MCP + Kubernetes execution boundary graph&lt;/H3&gt;
&lt;img /&gt;
&lt;H2&gt;Core Agent Framework Primitives Used&lt;/H2&gt;
&lt;P&gt;This repository is a practical example of Agent Framework as a graph orchestrator, not just an agent wrapper.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;WorkflowBuilder&lt;/STRONG&gt;&amp;nbsp;builds a typed DAG with explicit edges.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;@executor&amp;nbsp;functions&lt;/STRONG&gt;&amp;nbsp;implement deterministic nodes (validation, pytest, decisions, routing prep).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;AgentExecutor&lt;/STRONG&gt;&amp;nbsp;wraps LLM agents so they behave as graph nodes.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;WorkflowContext&amp;nbsp;shared state&lt;/STRONG&gt;&amp;nbsp;carries typed data and retry metadata between nodes.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;add_multi_selection_edge_group(...)&amp;nbsp;+ selector functions&lt;/STRONG&gt;&amp;nbsp;enforce conditional routing.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;MCPStdioTool&lt;/STRONG&gt;&amp;nbsp;connects filesystem MCP tools into agents for controlled file I/O.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Production graph construction (from workflow/builder.py) looks like this:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;workflow = (
    WorkflowBuilder(start_executor=initialize_retry)
    .add_edge(initialize_retry, generator_executor)
    .add_edge(generator_executor, parse_generated_task)
    .add_edge(parse_generated_task, run_validation)
    .add_edge(run_validation, run_pytest)
    .add_edge(run_pytest, make_decision)
    .add_multi_selection_edge_group(
        make_decision,
        [keep_task, remove_task],
        selection_func=select_action,
    )
    .add_edge(keep_task, run_pytest_skip_answer)
    .add_multi_selection_edge_group(
        run_pytest_skip_answer,
        [check_loop, complete_workflow],
        selection_func=select_skip_answer_action,
    )
    .add_multi_selection_edge_group(
        check_loop,
        [fix_task, complete_workflow],
        selection_func=select_loop_action,
    )
    .add_edge(fix_task, fixer_executor)
    .add_edge(fixer_executor, parse_generated_task)
    .build()
)&lt;/LI-CODE&gt;
&lt;P&gt;This is the architectural heart of the system: agents and deterministic executors are first-class nodes in the same graph.&lt;/P&gt;
&lt;H2&gt;Detailed Node-by-Node Mechanics&lt;/H2&gt;
&lt;H3&gt;1. Idea Agent (🧠): Concept Synthesis with Memory Constraints&lt;/H3&gt;
&lt;P&gt;The Idea Agent (agents/k8s_task_idea_agent.py) generates a structured concept with three difficulty variations (BEGINNER/INTERMEDIATE/ADVANCED). It is memory-aware:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;task_ideas_memory.json&amp;nbsp;tracks successful concepts.&lt;/LI&gt;
&lt;LI&gt;task_ideas_failure_memory.json&amp;nbsp;tracks concepts that failed downstream.&lt;/LI&gt;
&lt;LI&gt;Memory constraints are injected using&amp;nbsp;AgentMiddleware&amp;nbsp;(system-level prompt injection) to avoid duplicate or previously failed concepts.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;For Responses-only models, the agent switches to a tool-call contract (save_k8s_task_concept) instead of structured response formatting.&lt;/P&gt;
&lt;H3&gt;2. Generator Agent (⚙️): MCP-Backed File Authoring&lt;/H3&gt;
&lt;P&gt;The Generator Agent receives a strict prompt and writes task files through MCP filesystem tools. Key framework details:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Built through&amp;nbsp;chat_client.as_agent(...).&lt;/LI&gt;
&lt;LI&gt;MCP tool attached via&amp;nbsp;tools=mcp_tool.&lt;/LI&gt;
&lt;LI&gt;Function-call execution observability added with&amp;nbsp;LoggingFunctionMiddleware.&lt;/LI&gt;
&lt;LI&gt;Uses absolute-path-only policy in instructions to prevent path drift.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;3. Deterministic Validation + Test (✅): Non-LLM Gates&lt;/H3&gt;
&lt;P&gt;After generation, the graph moves through deterministic executors:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;run_validation&amp;nbsp;calls pure Python checks (k8s_task_validator).&lt;/LI&gt;
&lt;LI&gt;run_pytest&amp;nbsp;executes&amp;nbsp;pytest --import-mode=importlib --rootdir=. ....&lt;/LI&gt;
&lt;LI&gt;Raw pytest output is persisted in workflow state for later fixing.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This is critical: no LLM is asked whether code is correct.&lt;/P&gt;
&lt;H3&gt;4. Skip-Answer Test (🧪): Grader Correctness Gate&lt;/H3&gt;
&lt;P&gt;Even if standard tests pass, the workflow enforces a second tier:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;SKIP_ANSWER_TESTS=True pytest --import-mode=importlib --rootdir=.&lt;/LI-CODE&gt;
&lt;P&gt;Implementation detail: the executor writes JUnit XML, parses it, and asserts that:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;test_03_answer.py&amp;nbsp;is skipped&lt;/LI&gt;
&lt;LI&gt;test_05_check.py&amp;nbsp;fails as expected&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If&amp;nbsp;test_05_check.py&amp;nbsp;does&amp;nbsp;&lt;STRONG&gt;not&lt;/STRONG&gt;&amp;nbsp;fail, the task is treated as invalid and sent back to retry/fix.&lt;/P&gt;
&lt;H3&gt;5. Fixer Agent + Retry Loop (🔧): Bounded Self-Healing&lt;/H3&gt;
&lt;P&gt;On failure,&amp;nbsp;fix_task&amp;nbsp;builds a targeted prompt containing:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;failure reasons from deterministic nodes&lt;/LI&gt;
&lt;LI&gt;full captured pytest output&lt;/LI&gt;
&lt;LI&gt;explicit rule to patch only broken files in place&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The Fixer Agent runs through&amp;nbsp;AgentExecutor, writes patches via MCP, and the graph loops back to&amp;nbsp;parse_generated_task.&lt;/P&gt;
&lt;P&gt;Retries are stateful (retry_count,&amp;nbsp;max_retries) and hard-bounded. On exhaustion,&amp;nbsp;complete_workflow&amp;nbsp;moves the task to&amp;nbsp;unsuccessful/&amp;lt;game&amp;gt;/&amp;nbsp;and writes&amp;nbsp;FAILURE_REPORT.txt.&lt;/P&gt;
&lt;H2&gt;Agent Prompt Design (The Part That Makes It Work)&lt;/H2&gt;
&lt;P&gt;If you want to understand&amp;nbsp;&lt;EM&gt;why&lt;/EM&gt;&amp;nbsp;this pipeline works, you need to inspect prompts as&amp;nbsp;&lt;STRONG&gt;operational contracts&lt;/STRONG&gt;, not generic instructions.&lt;/P&gt;
&lt;H3&gt;Real Idea Agent Prompt (from code)&lt;/H3&gt;
&lt;LI-CODE lang="python"&gt;IDEA_AGENT_INSTRUCTIONS = (
    "You are a Kubernetes task idea generator that creates detailed task concepts with three difficulty variations. "
    "Read official K8s documentation and propose comprehensive learning concepts for a Kubernetes game. "
    "\n\nYour task:\n"
    "1. Choose ONE Kubernetes concept not yet covered (check context for existing concepts)\n"
    "2. Generate exactly 3 variations: BEGINNER, INTERMEDIATE, and ADVANCED\n"
    "3. Use 3-digit task IDs (001-999) in format: XXX_concept_name_level (e.g., 041_secrets_basic)\n"
    "4. Each variation should build on the previous one with increasing complexity\n"
    "5. Include practical, hands-on scenarios covering: Workloads, Services, Storage, Configuration, Security, Scheduling, Policies\n"
    "\nProvide the concept, tags, description, and 3 variations with task_id, difficulty, title, objective, key_skills, and estimated_time."
)&lt;/LI-CODE&gt;
&lt;P&gt;Responses-only models use a stricter tool-call version:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;IDEA_AGENT_INSTRUCTIONS_TOOL_CALL = (
    IDEA_AGENT_INSTRUCTIONS + "\n\n"
    "**CRITICAL**: You MUST call the save_k8s_task_concept tool to save your generated concept.\n"
    "...\n"
    "Always call save_k8s_task_concept with your generated concept."
)&lt;/LI-CODE&gt;
&lt;H3&gt;Idea Agent Prompt Contract&lt;/H3&gt;
&lt;P&gt;The Idea Agent prompt enforces:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;one concept per run&lt;/LI&gt;
&lt;LI&gt;exactly three difficulty variations&lt;/LI&gt;
&lt;LI&gt;strict task ID format (XXX_concept_name_level)&lt;/LI&gt;
&lt;LI&gt;practical skill progression&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Core pattern:&lt;/P&gt;
&lt;LI-CODE lang=""&gt;You are a Kubernetes task idea generator...
1. Choose ONE Kubernetes concept not yet covered
2. Generate exactly 3 variations: BEGINNER, INTERMEDIATE, ADVANCED
3. Use 3-digit task IDs in format XXX_concept_name_level
...&lt;/LI-CODE&gt;
&lt;P&gt;It is strengthened by runtime memory injection:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;previously generated concepts are blocked&lt;/LI&gt;
&lt;LI&gt;previously failed concepts are blocked&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;For Responses-only models, the contract becomes tool-driven:&lt;/P&gt;
&lt;LI-CODE lang=""&gt;CRITICAL: You MUST call the save_k8s_task_concept tool...&lt;/LI-CODE&gt;
&lt;P&gt;This reduces ambiguity in output structure and makes downstream parsing deterministic.&lt;/P&gt;
&lt;H3&gt;Real Generator Agent Prompt (from code)&lt;/H3&gt;
&lt;LI-CODE lang="python"&gt;def _get_generator_instructions():
    return (
        "You are a Kubernetes task generator with filesystem tools.\n"
        f"The MCP filesystem is rooted at: {PATHS.tests_root.parent}\n"
        f"You MUST use ABSOLUTE paths for ALL file operations.\n"
        f"Task directory: {PATHS.game_root}/XXX_task_name/\n"
        "...\n"
        "CRITICAL: test_02_ready.py checks resources from setup.template.yaml, NOT answer.template.yaml.\n"
        "...\n"
        "MUST use polling loops (60s timeout, 15s interval)\n"
        "MUST use try/except and safe .get() JSON access\n"
    )&lt;/LI-CODE&gt;
&lt;P&gt;The generator prompt is long on purpose: it encodes path correctness, file schema, YAML/Jinja structure, and testing strategy in a single deterministic contract.&lt;/P&gt;
&lt;H3&gt;Generator Agent Prompt Contract&lt;/H3&gt;
&lt;P&gt;The Generator prompt is intentionally long and prescriptive because it defines filesystem safety and grading correctness requirements.&lt;/P&gt;
&lt;P&gt;Key constraints encoded in the prompt:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Absolute path writes only&lt;/STRONG&gt;&amp;nbsp;(prevents writing to wrong workspace paths)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;No directory creation&lt;/STRONG&gt;&amp;nbsp;(directory is pre-created by executor)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Required file set&lt;/STRONG&gt;&amp;nbsp;(instruction.md,&amp;nbsp;concept.md,&amp;nbsp;session.json, templates, tests)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;test-flow invariants&lt;/STRONG&gt;:
&lt;UL&gt;
&lt;LI&gt;test_01_setup.py&amp;nbsp;deploys setup&lt;/LI&gt;
&lt;LI&gt;test_02_ready.py&amp;nbsp;checks setup resources only&lt;/LI&gt;
&lt;LI&gt;test_03_answer.py&amp;nbsp;deploys answer&lt;/LI&gt;
&lt;LI&gt;test_05_check.py&amp;nbsp;validates final solution&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;robust test coding style&lt;/STRONG&gt;: polling loops, try/except,&amp;nbsp;.get()-based JSON parsing, explicit debug output&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Example contract fragment:&lt;/P&gt;
&lt;LI-CODE lang=""&gt;CRITICAL PATH RULES:
✅ CORRECT: /abs/path/tests/gameXX/050_task/file.py
❌ WRONG: tests/gameXX/050_task/file.py (relative)

CRITICAL: test_02_ready.py checks resources from setup.template.yaml,
NOT answer.template.yaml.&lt;/LI-CODE&gt;
&lt;P&gt;This is why generation quality is high before the Fixer loop even starts.&lt;/P&gt;
&lt;H3&gt;Real Runtime Retry Prompt Builder (from code)&lt;/H3&gt;
&lt;LI-CODE lang="python"&gt;def _build_retry_generation_prompt(combined: CombinedValidationResult) -&amp;gt; str:
    task_id = combined.test.task_id
    failure_reasons = _build_failure_reasons(combined)
    return (
        f"Generate a complete Kubernetes learning task with ID '{task_id}' about '{combined.target_topic}'. "
        f"This is retry attempt {combined.retry_count + 1} of {combined.max_retries}. "
        f"\n\n⚠️  PREVIOUS ATTEMPT FAILED:"
        f"\n{chr(10).join([f'  - {reason}' for reason in failure_reasons])}"
        f"\n\nIMPORTANT: You MUST use the exact task ID '{task_id}' - do not generate a new ID."
        f"\n\n✅ Directory already exists: {PATHS.game_root}/{task_id}/"
        f"\nWrite all files directly into this directory. Do NOT call create_directory."
        "..."
    )&lt;/LI-CODE&gt;
&lt;P&gt;This means retries are not generic retries; they are failure-conditioned retries with precise constraints.&lt;/P&gt;
&lt;H3&gt;Fixer Agent Prompt Contract&lt;/H3&gt;
&lt;P&gt;The Fixer prompt is a repair protocol, not a regeneration prompt. It includes:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;exact failure reasons from deterministic validators&lt;/LI&gt;
&lt;LI&gt;raw pytest output&lt;/LI&gt;
&lt;LI&gt;instruction to read current task files first&lt;/LI&gt;
&lt;LI&gt;strict directive to patch only broken files&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Core behavior constraints:&lt;/P&gt;
&lt;LI-CODE lang=""&gt;DO NOT rewrite all files.
Make TARGETED FIXES to ONLY the broken files.
Use ABSOLUTE paths for all file operations.&lt;/LI-CODE&gt;
&lt;P&gt;This keeps retries cheap, preserves working artifacts, and improves convergence speed.&lt;/P&gt;
&lt;H3&gt;Real Runtime Fix Prompt Builder (from code)&lt;/H3&gt;
&lt;LI-CODE lang="python"&gt;def _build_fix_prompt(combined: CombinedValidationResult, raw_test_output: str) -&amp;gt; str:
    task_id = combined.test.task_id
    failure_reasons = _build_failure_reasons(combined)
    prompt = (
        f"Fix the failed Kubernetes task '{task_id}' located in '{PATHS.game_root}/{task_id}/'."
        f"\n\nThis is fix attempt {combined.retry_count + 1} of {combined.max_retries}."
        f"\n\n⚠️  TASK FAILED WITH THESE ERRORS:"
        f"\n{chr(10).join([f'  - {reason}' for reason in failure_reasons])}"
    )
    if raw_test_output:
        prompt += f"\n\n📋 FULL TEST OUTPUT:\n```\n{raw_test_output}\n```"
    prompt += (
        f"\n\n🔍 YOUR TASK:"
        f"\n1. READ all files from '{PATHS.game_root}/{task_id}/'"
        f"\n6. Make TARGETED FIXES to ONLY the broken files"
        f"\n7. WRITE ONLY the fixed files back"
        f"\n\n⚠️  CRITICAL: DO NOT rewrite all files! Only fix the broken ones!"
    )
    return prompt&lt;/LI-CODE&gt;
&lt;H3&gt;How Prompt Output Enters the Agent Framework Graph&lt;/H3&gt;
&lt;P&gt;The prompt builders above are used by deterministic executors and sent to agent nodes through AgentExecutorRequest:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;await ctx.send_message(
    AgentExecutorRequest(
        messages=[Message(role="user", contents=[fix_prompt])],
        should_respond=True
    )
)&lt;/LI-CODE&gt;
&lt;P&gt;So prompt generation and graph routing are tightly coupled: each route transition emits a specific prompt payload into the next LLM node.&lt;/P&gt;
&lt;H3&gt;Runtime-Constructed Prompts in Executors&lt;/H3&gt;
&lt;P&gt;The most important prompts are built dynamically in workflow executors:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;_build_retry_generation_prompt(...)&lt;/LI&gt;
&lt;LI&gt;_build_fix_prompt(...)&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;These functions inject live context:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;retry_count&amp;nbsp;/&amp;nbsp;max_retries&lt;/LI&gt;
&lt;LI&gt;concept + objective metadata&lt;/LI&gt;
&lt;LI&gt;validation/test failure reasons&lt;/LI&gt;
&lt;LI&gt;full captured test logs&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;So each retry is context-rich and specific, not another blind generation attempt.&lt;/P&gt;
&lt;H3&gt;Prompt + Middleware + Deterministic Gates = Reliability&lt;/H3&gt;
&lt;P&gt;In this repository, reliability does&amp;nbsp;&lt;STRONG&gt;not&lt;/STRONG&gt;&amp;nbsp;come from prompt text alone. It comes from three layers working together:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Prompt contracts constrain agent behavior.&lt;/LI&gt;
&lt;LI&gt;Middleware injects memory and logs tool invocations.&lt;/LI&gt;
&lt;LI&gt;Deterministic executors enforce objective pass/fail gates.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;That combination is why the workflow remains auditable and predictable even when LLM outputs vary.&lt;/P&gt;
&lt;H2&gt;Agent Framework Execution Model in This Repo&lt;/H2&gt;
&lt;H2&gt;Strongly-Typed Message Passing&lt;/H2&gt;
&lt;P&gt;workflow/models.py&amp;nbsp;defines transport models used between nodes:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;ValidationResult&amp;nbsp;and&amp;nbsp;TestResult&amp;nbsp;(Pydantic)&lt;/LI&gt;
&lt;LI&gt;CombinedValidationResult&amp;nbsp;(dataclass with&amp;nbsp;should_keep&amp;nbsp;and&amp;nbsp;should_retry)&lt;/LI&gt;
&lt;LI&gt;InitialWorkflowState&amp;nbsp;(seed payload for each run)&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This keeps node contracts explicit and simplifies selector logic.&lt;/P&gt;
&lt;H2&gt;Fail-Fast Shared State Management&lt;/H2&gt;
&lt;P&gt;Executors use&amp;nbsp;ctx.get_state(...)&amp;nbsp;with a sentinel (_MISSING) and raise explicit exceptions if required state is absent. This prevents hidden fallback behavior and catches graph/data wiring errors early.&lt;/P&gt;
&lt;H2&gt;Conditional Routing with Selectors&lt;/H2&gt;
&lt;P&gt;Selectors (workflow/selectors.py) encode graph decisions:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;select_action&amp;nbsp;→ keep vs remove&lt;/LI&gt;
&lt;LI&gt;select_skip_answer_action&amp;nbsp;→ complete vs loop&lt;/LI&gt;
&lt;LI&gt;select_loop_action&amp;nbsp;→ fix vs complete&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This separates decision policy from executor implementation.&lt;/P&gt;
&lt;H2&gt;Streaming Workflow Runtime&lt;/H2&gt;
&lt;P&gt;workflow.run(initial_state, stream=True)&amp;nbsp;emits output events incrementally. The runner (workflow/runner.py) consumes these events to detect successful completions and update concept memory accordingly.&lt;/P&gt;
&lt;H2&gt;Agent Construction and API Selection Strategy&lt;/H2&gt;
&lt;P&gt;The repository uses Azure CLI auth (AzureCliCredential) and dynamically selects API mode by deployment name (agents/config.py):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Chat Completions path&lt;/STRONG&gt;:&amp;nbsp;OpenAIChatCompletionClient&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Responses-only model path&lt;/STRONG&gt;:&amp;nbsp;OpenAIChatClient&amp;nbsp;or custom&amp;nbsp;ResponsesAgent&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Why this matters: some codex-class deployments are Responses-only, so the architecture supports both without changing workflow logic.&lt;/P&gt;
&lt;H2&gt;How MCP Actually Controls Kubernetes (Important Distinction)&lt;/H2&gt;
&lt;P&gt;In this repo, MCP is used for&amp;nbsp;&lt;STRONG&gt;filesystem control&lt;/STRONG&gt;; Kubernetes control is done through&amp;nbsp;&lt;STRONG&gt;kubectl tools&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;1) MCP server role: controlled file I/O&lt;/H2&gt;
&lt;P&gt;The workflow starts MCP stdio servers (official filesystem server) and mounts them into agents:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;docs_mcp_tool = MCPStdioTool(
    name="filesystem_docs",
    command="npx",
    args=["-y", "@modelcontextprotocol/server-filesystem", str(PATHS.k8s_docs_root)],
    load_prompts=False,
)

tests_mcp_tool = MCPStdioTool(
    name="filesystem_tests",
    command="npx",
    args=["-y", "@modelcontextprotocol/server-filesystem", str(PATHS.tests_root.parent)],
    load_prompts=False,
)&lt;/LI-CODE&gt;
&lt;P&gt;Those MCP tools are passed into Generator/Fixer agents, which then call MCP file functions (read/write/list) inside allowed roots only.&lt;/P&gt;
&lt;H2&gt;2) Kubernetes cluster control role: kubectl execution tool&lt;/H2&gt;
&lt;P&gt;Cluster actions are not performed by MCP filesystem server; they are performed by a dedicated function tool:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;def run_kubectl_command(command: str) -&amp;gt; str:
    kubeconfig_path = os.environ.get("KUBECONFIG", "/home/developer/.kube/config")
    cmd_list = ["kubectl"] + command.split()
    result = subprocess.run(
        cmd_list,
        capture_output=True,
        text=True,
        check=True,
        env={**os.environ, "KUBECONFIG": kubeconfig_path},
    )
    return result.stdout&lt;/LI-CODE&gt;
&lt;P&gt;And the Kubernetes agent forces tool usage:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;agent = responses_client.as_agent(
    name="KubernetesAgent",
    instructions="...You MUST use the run_kubectl_command tool...",
    tools=[run_kubectl_command],
    default_options={"tool_choice": "required"},
)&lt;/LI-CODE&gt;
&lt;P&gt;So the control plane is:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;MCP filesystem&lt;/STRONG&gt;&amp;nbsp;→ manipulate generated task files.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;kubectl tool&lt;/STRONG&gt;&amp;nbsp;→ query/mutate real cluster state.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;deterministic pytest/validator executors&lt;/STRONG&gt;&amp;nbsp;→ accept or reject results.&lt;/LI&gt;
&lt;/OL&gt;
&lt;H2&gt;3) End-to-end command flow in practice&lt;/H2&gt;
&lt;P&gt;When generated tests run, they execute real&amp;nbsp;kubectl get ... -o json&amp;nbsp;checks in test code, and the deterministic runner captures raw output:&lt;/P&gt;
&lt;P&gt;pytest_command = f"pytest --import-mode=importlib --rootdir=. {task_with_val.task_directory}/" result = run_pytest_command(pytest_command) ctx.set_state(f"raw_output_{task_with_val.task_id}", raw_output)&lt;/P&gt;
&lt;P&gt;This means Kubernetes state verification is always grounded in live command output, not model speculation.&lt;/P&gt;
&lt;H2&gt;Should MCP run Kubernetes tests?&lt;/H2&gt;
&lt;P&gt;Short answer:&amp;nbsp;&lt;STRONG&gt;not in this design&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Current architecture keeps test execution deterministic and local:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;pytest is run by&amp;nbsp;run_pytest_command(...)&amp;nbsp;(pure Python subprocess runner)&lt;/LI&gt;
&lt;LI&gt;test results are parsed and stored in workflow state&lt;/LI&gt;
&lt;LI&gt;retry/fix routing uses those deterministic outputs&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This is intentional. If test execution were delegated to an LLM-facing MCP command tool, you would lose strict control over execution semantics and error handling.&lt;/P&gt;
&lt;P&gt;Recommended pattern:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Use MCP for file/document access and controlled editing.&lt;/LI&gt;
&lt;LI&gt;Use deterministic executors for pytest and validation.&lt;/LI&gt;
&lt;LI&gt;Use LLM agents only for generation and repair.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;If you still want MCP-driven test execution, add a&amp;nbsp;&lt;STRONG&gt;separate locked-down command MCP server&lt;/STRONG&gt;&amp;nbsp;(only whitelisted pytest/kubectl commands), but keep pass/fail decision logic in deterministic executors.&lt;/P&gt;
&lt;H2&gt;How tests are run in this workflow (with code)&lt;/H2&gt;
&lt;P&gt;The workflow executes tests in deterministic executors, not inside LLM agents.&lt;/P&gt;
&lt;H3&gt;1) Workflow node calls pytest runner&lt;/H3&gt;
&lt;P&gt;run_pytest executor builds the command and calls the pure Python runner:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;@executor(id="run_pytest")
async def run_pytest(task_with_val: TaskWithValidation, ctx: WorkflowContext[TestResult]) -&amp;gt; None:
    from agents.pytest_runner import run_pytest_command

    pytest_command = f"pytest --import-mode=importlib --rootdir=. {task_with_val.task_directory}/"
    result = run_pytest_command(pytest_command)

    raw_output = result["details"][0] if result.get("details") else ""
    ctx.set_state(f"raw_output_{task_with_val.task_id}", raw_output)
    ...&lt;/LI-CODE&gt;
&lt;H3&gt;2) Deterministic subprocess execution&lt;/H3&gt;
&lt;P&gt;The runner normalizes command flags and executes pytest via subprocess:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;def run_pytest_command(command: str) -&amp;gt; dict[str, Any]:
    normalized_command = _normalize_pytest_command(command)  # adds -s if needed
    cmd_list = shlex.split(normalized_command)
    result = subprocess.run(
        cmd_list,
        capture_output=True,
        text=True,
        check=False,
        cwd=str(PATHS.pytest_rootdir),
    )
    combined_output = result.stdout + "\n" + result.stderr
    _save_test_output(normalized_command, combined_output, skip_answer)
    ...&lt;/LI-CODE&gt;
&lt;P&gt;Exit codes are interpreted deterministically:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;0&amp;nbsp;→ pass&lt;/LI&gt;
&lt;LI&gt;5&amp;nbsp;→ no tests collected (fail)&lt;/LI&gt;
&lt;LI&gt;others → fail with exit code reason&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;3) Skip-answer validation tier&lt;/H3&gt;
&lt;P&gt;After normal pass, the workflow runs pytest again with SKIP_ANSWER_TESTS=True and parses JUnit XML:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;os.environ["SKIP_ANSWER_TESTS"] = "True"
pytest_command = f"pytest --import-mode=importlib --rootdir=. --junitxml={junit_path} {task_dir}/"
result = run_pytest_command(pytest_command)
test_05_failed, test_03_skipped = _parse_skip_answer_junit(junit_path)&lt;/LI-CODE&gt;
&lt;P&gt;The parser checks per-testcase outcomes:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;if "test_05_check.py" in context and has_failure_or_error:
    test_05_failed = True
if "test_03_answer.py" in context and has_skipped:
    test_03_skipped = True&lt;/LI-CODE&gt;
&lt;H3&gt;4) How failures trigger fix loop&lt;/H3&gt;
&lt;P&gt;If pytest fails (or skip-answer logic fails), failure reasons and raw output are pushed into state, then the Fixer Agent receives a generated fix prompt containing that output:&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;ctx.set_state(f"failure_reasons_{task_id}", reasons)
ctx.set_state(f"raw_output_{task_id}", raw_output)
fix_prompt = _build_fix_prompt(combined, raw_test_output)
await ctx.send_message(
    AgentExecutorRequest(
        messages=[Message(role="user", contents=[fix_prompt])],
        should_respond=True
    )
)&lt;/LI-CODE&gt;
&lt;P&gt;That is the key loop:&amp;nbsp;&lt;STRONG&gt;deterministic test output drives LLM repair&lt;/STRONG&gt;, then deterministic tests re-run.&lt;/P&gt;
&lt;H2&gt;ResponsesAgent Internals (Advanced Agent Framework Pattern)&lt;/H2&gt;
&lt;P&gt;The custom&amp;nbsp;ResponsesAgent&amp;nbsp;(agents/responses_agent.py) demonstrates a lower-level integration pattern:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Connect MCP tool lazily.&lt;/LI&gt;
&lt;LI&gt;Call Responses API.&lt;/LI&gt;
&lt;LI&gt;Parse&amp;nbsp;ResponseFunctionToolCall&amp;nbsp;items.&lt;/LI&gt;
&lt;LI&gt;Execute tools (MCP + custom callables).&lt;/LI&gt;
&lt;LI&gt;Feed&amp;nbsp;function_call_output&amp;nbsp;back to model.&lt;/LI&gt;
&lt;LI&gt;Repeat until final text response.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;It also runs a middleware chain around tool invocations, preserving observability and consistency with standard agent paths.&lt;/P&gt;
&lt;H2&gt;Why This Architecture Is Robust&lt;/H2&gt;
&lt;P&gt;This design works because Agent Framework is used as a&amp;nbsp;&lt;STRONG&gt;deterministic orchestration layer around probabilistic generation&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;LLM creativity is constrained by typed state and strict prompts.&lt;/LI&gt;
&lt;LI&gt;deterministic executors act as objective quality gates.&lt;/LI&gt;
&lt;LI&gt;retries are targeted, bounded, and auditable.&lt;/LI&gt;
&lt;LI&gt;failures produce durable forensic artifacts (FAILURE_REPORT.txt&amp;nbsp;+ test logs).&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;For Kubernetes education pipelines, this yields high throughput without sacrificing grader reliability.&lt;/P&gt;
&lt;P&gt;GitHub Repo - &lt;A class="lia-external-url" href="https://github.com/wongcyrus/k8s-game-rule-builder" target="_blank"&gt;https://github.com/wongcyrus/k8s-game-rule-builder&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;About the Author&lt;/STRONG&gt;&lt;/H3&gt;
&lt;img /&gt;
&lt;P data-selectable-paragraph=""&gt;&lt;A href="https://www.linkedin.com/in/cyruswong/" target="_blank"&gt;Cyrus Wong&lt;/A&gt;&amp;nbsp;is the senior lecturer of&amp;nbsp;&lt;A href="https://hkiit.edu.hk/" target="_blank"&gt;Hong Kong Institute of Information Technology (HKIIT)&lt;/A&gt;&amp;nbsp;@&amp;nbsp;&lt;A href="http://lwit.vtc.edu.hk/" target="_blank"&gt;IVE(Lee Wai Lee)&lt;/A&gt;.and he focuses on teaching public Cloud technologies. He is a passionate advocate for the adoption of cloud technology across various media and events. With his extensive knowledge and expertise, he has earned prestigious recognitions such as&amp;nbsp;&lt;A href="https://aws.amazon.com/developer/community/heroes/cyrus-wong/" data-lia-auto-title-active="0" data-lia-auto-title="AWS Builder Center" target="_blank"&gt;AWS AI Hero&lt;/A&gt;,&amp;nbsp;&lt;A href="https://mvp.microsoft.com/en-US/mvp/profile/86da86ff-8786-ed11-aad1-000d3a197333" target="_blank"&gt;Microsoft MVP- Microsoft Foundry&lt;/A&gt;, and&amp;nbsp;&lt;A href="https://developers.google.com/profile/u/cyruswong" target="_blank"&gt;Google Developer Expert - Cloud(AI)&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 21 Jul 2026 07:46:08 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/microsoft-agent-framework-multi-agent-workflow-architecture-for/ba-p/4538371</guid>
      <dc:creator>cyruswong</dc:creator>
      <dc:date>2026-07-21T07:46:08Z</dc:date>
    </item>
    <item>
      <title>Meet Saksham Kumar</title>
      <link>https://techcommunity.microsoft.com/t5/student-developer-blog/meet-saksham-kumar/ba-p/4539117</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Meet Saksham Kumar, who recently graduated with a bachelor’s degree in computer science from Amrita Vishwa Vidyapeetham, Amaravati Campus in Andhra Pradesh, India.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This is the next segment in our blog series highlighting graduating Microsoft Student Ambassadors who achieved the Senior milestone, the highest level in the program. Each blog features a different Senior Ambassador and explores how the program helped shape their technical skills, leadership experience, professional growth, and future career opportunities.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How has being part of the Microsoft Student Ambassadors community helped you connect with other tech enthusiasts and expand your global network?&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Microsoft Student Ambassadors was my first opportunity to represent myself and my community on a global scale. Starting out as a Branch Lead at my university allowed me to focus heavily on building a tight-knit, driven tech community right on campus. Moreover, stepping into the roles of Moderator for the Discord Community completely redefined my definition of impact and community. Talking to people around the world, helping them achieve their goals, whilst upskilling and networking, opened doors to collaborating with brilliant community leaders, entrepreneurs and tech advocates across diverse fields.&lt;/P&gt;
&lt;P&gt;Whether we are planning out a workshop, managing initiatives or just geeking out new frameworks, the program helped to get the best out of me, dissolving social and geographical barriers. It gave me a global network of peers, mentors, and lifelong friends who share the same relentless passion for technology and community building.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What impact did access to Microsoft tools and resources, such as Azure credits, Visual Studio Enterprise, and Copilot, have on your growth as a technology leader?&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Access to enterprise-grade tools shifted my mindset from that of a student to an engineer building scalable solutions. Having substantial Azure credits provided a frictionless sandbox to experiment with deploying real-world backend architectures and hosting complex software implementations without worrying about infrastructure costs.&lt;/P&gt;
&lt;P&gt;Meanwhile, tools like VS Enterprise and Copilot helped me streamline my developer workflow. It allowed me to experiment with tools like Power Platform for building agents, automating workflows and focus more on high-level system design and optimization. Having these resources at my fingertips didn't just accelerate my technical capability; it gave me the confidence to lead complex projects and architect robust, production-ready software.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;In what ways has the Student Ambassadors program strengthened your resume, boosted your confidence, or helped you develop skills that will support your future career?&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The program served as the bridge between academic theory and real-world excellence. Standing in front of hundreds of students to lead technical workshops—such as introducing peers to the fundamentals of AI and modern development practices—completely solidified my communication skills and shattered any public speaking anxiety I once had.&lt;/P&gt;
&lt;P&gt;Managing teams, coordinating large-scale events, and driving engineering initiatives gave me tangible leadership metrics that made my resume stand out. The experience taught me how to balance technical execution with people management, directly preparing me to step into the industry and build my startup. I am graduating from the program not just with technical knowledge, but with the professional maturity needed to tackle large-scale engineering challenges.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 21 Jul 2026 03:02:38 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/student-developer-blog/meet-saksham-kumar/ba-p/4539117</guid>
      <dc:creator>Tracey_Salem_MSFT</dc:creator>
      <dc:date>2026-07-21T03:02:38Z</dc:date>
    </item>
    <item>
      <title>Meet Herish Chaniyara</title>
      <link>https://techcommunity.microsoft.com/t5/student-developer-blog/meet-herish-chaniyara/ba-p/4539114</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Meet Herish Chaniyara, who recently graduated with a bachelor’s degree in computer science from Gujarat Technological University in Gujarat, India.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This is the next segment in our blog series highlighting graduating Microsoft Student Ambassadors who achieved the Senior milestone, the highest level in the program. Each blog features a different Senior Ambassador and explores how the program helped shape their technical skills, leadership experience, professional growth, and future career opportunities.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How has being part of the Microsoft Student Ambassadors community helped you connect with other tech enthusiasts and expand your global network?&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Being part of the Microsoft Student Ambassadors community has connected me with passionate learners, developers, researchers, and mentors from around the world. Through community calls, technical events, and collaborative learning opportunities, I gained exposure to diverse perspectives in AI, cloud computing, cybersecurity, and modern software development.&lt;/P&gt;
&lt;P&gt;As a Senior Microsoft Student Ambassador, I organized Azure and AI-focused events, actively participated in community initiatives, and mentored nearly 50 students interested in cybersecurity, cloud, AI, and other IT career paths. Beyond technical knowledge, the program helped me build meaningful professional relationships while strengthening my communication, leadership, and collaboration skills.&lt;/P&gt;
&lt;P&gt;The supportive community inspired me to continuously learn, share knowledge, and contribute back to the ecosystem. These experiences have shaped my growth as both a technology professional and a mentor, encouraging me to help others while continuing to learn from an incredible global network.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What impact did access to Microsoft tools and resources, such as Azure credits, Visual Studio Enterprise, and Copilot, have on your growth as a technology leader?&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Microsoft's ecosystem played a significant role in accelerating my technical growth. Azure credits enabled me to explore cloud services, AI solutions, and real-world deployment scenarios, while Microsoft Learn provided structured learning paths that strengthened my understanding of AI, cloud computing, and cybersecurity.&lt;/P&gt;
&lt;P&gt;GitHub Copilot and Microsoft Copilot became valuable tools throughout my daily workflow for coding, debugging, documentation, research, and content creation. These tools allowed me to work more efficiently, experiment with new ideas, and focus on solving complex problems while continuously improving my technical skills.&lt;/P&gt;
&lt;P&gt;The practical experience I gained through Microsoft technologies helped bridge the gap between academic learning and professional work. Today, I apply these skills in cybersecurity research, mentoring students, technical blogging, and building secure, AI-enabled solutions. The Microsoft Student Ambassadors program empowered me to become not only a better learner but also a more confident technology leader.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;In what ways has the Student Ambassadors program strengthened your resume, boosted your confidence, or helped you develop skills that will support your future career?&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The Microsoft Student Ambassadors program has been one of the most influential experiences in my professional journey. It strengthened my confidence in public speaking, mentoring, technical communication, and community leadership while encouraging me to continuously expand my knowledge in AI, cloud technologies, and cybersecurity.&lt;/P&gt;
&lt;P&gt;The opportunities to organize events, collaborate with ambassadors worldwide, and mentor nearly 50 students helped me grow beyond technical skills. These experiences improved my leadership, teamwork, and problem-solving abilities while preparing me for real-world challenges.&lt;/P&gt;
&lt;P&gt;The skills and exposure I gained through the program directly supported my career progression. I currently work as a&amp;nbsp;Junior Research Fellow (Cybersecurity)&amp;nbsp;under the&amp;nbsp;Information Security Education and Awareness (ISEA) Project Phase III, a national initiative by the&amp;nbsp;Ministry of Electronics and Information Technology (MeitY), Government of India, focused on cybersecurity education, awareness, and research. Previously, I worked as a Cybersecurity Engineer performing full-scope vulnerability assessments and penetration testing. I have also been recognized in the&amp;nbsp;PortSwigger Web Security Academy Hall of Fame.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Most importantly, the Student Ambassadors program transformed me from a passionate learner into someone who is committed to sharing knowledge, mentoring aspiring professionals, contributing to the cybersecurity community, and continuously learning to make a meaningful impact through technology.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;</description>
      <pubDate>Tue, 21 Jul 2026 02:28:45 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/student-developer-blog/meet-herish-chaniyara/ba-p/4539114</guid>
      <dc:creator>Tracey_Salem_MSFT</dc:creator>
      <dc:date>2026-07-21T02:28:45Z</dc:date>
    </item>
    <item>
      <title>Meet Aryan Jaiswal</title>
      <link>https://techcommunity.microsoft.com/t5/student-developer-blog/meet-aryan-jaiswal/ba-p/4538102</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Meet Aryan Jaiswal, who recently graduated with a bachelor’s degree in computer science from Indian Institute of Information Technology Dharwad (IIIT Dharwad) in Karnataka, India.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This is the next segment in our blog series highlighting graduating Microsoft Student Ambassadors who achieved the Senior milestone, the highest level in the program. Each blog features a different Senior Ambassador and explores how the program helped shape their technical skills, leadership experience, professional growth, and future career opportunities.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How has being part of the Microsoft Student Ambassadors community helped you connect with other tech enthusiasts and expand your global network?&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;When I joined the Microsoft Student Ambassadors program, I honestly did not even know the program existed. I was just a curious student who loved technology and wanted to build things.&lt;/P&gt;
&lt;P&gt;Over the last two years, that curiosity turned into opportunities I never imagined. Through this community, I got to connect with Ambassadors, mentors, Microsoft employees, MVPs, startup founders, and students from different parts of the world.&lt;/P&gt;
&lt;P&gt;I collaborated on AI projects, community campaigns, workshops, and initiatives with people I would have never met otherwise. Many of those collaborations eventually turned into genuine friendships.&lt;/P&gt;
&lt;P&gt;One of the most meaningful experiences for me was founding the Microsoft Student Ambassador Chapter at IIIT Dharwad. It allowed me to create opportunities for students on my campus, mentor others, and help them discover the same community that changed my life.&lt;/P&gt;
&lt;P&gt;Looking back, the biggest thing I gained was never just a global network. I found lifelong mentors, friends, and a community that genuinely believed in me.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What impact did access to Microsoft tools and resources, such as Azure credits, Visual Studio Enterprise, and Copilot, have on your growth as a technology leader?&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;As a student, I could never have afforded the cloud infrastructure needed to experiment at scale. The Azure credits I received as a Microsoft Student Ambassador changed that completely. They gave me the freedom to deploy applications, explore different Azure services, and learn how to use Azure through both the Azure Portal and the Azure CLI.&lt;/P&gt;
&lt;P&gt;Instead of just following tutorials, I was able to build, break things, experiment, and understand how real cloud applications are deployed and managed. Today, some of my biggest AI applications are deployed on Azure, and that hands-on experience gave me the confidence to work with cloud technologies in real-world projects.&lt;/P&gt;
&lt;P&gt;Copilot became a tool I used regularly while exploring new technologies, improving my development workflow, and learning faster. Visual Studio and Microsoft learning resources made it easier to build better applications while continuously improving my skills.&lt;/P&gt;
&lt;P&gt;These resources also helped me become a better community leader. Whether I was organizing AI workshops, mentoring students, leading AI projects, or judging hackathon submissions, I could confidently introduce others to technologies that I had personally explored and used.&lt;/P&gt;
&lt;P&gt;The confidence I gained through Microsoft's ecosystem also helped me become India's only Gold Startup Scout for Microsoft for Startups, where I referred eight startups across different domains and helped founders unlock Microsoft Azure credits and startup benefits.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;In what ways has the Student Ambassadors program strengthened your resume, boosted your confidence, or helped you develop skills that will support your future career?&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;This program gave me much more than achievements on my resume. It changed who I am. I joined as someone who simply wanted to learn. Now, I graduate as a Senior Microsoft Student Ambassador.&lt;/P&gt;
&lt;P&gt;Along the journey, I had the opportunity to found and lead the Microsoft Student Ambassador Chapter at IIIT Dharwad, organize 25+ AI, cloud, and developer events, both online and offline, mentor thousands of students, lead and judge AI projects, collaborate with ambassadors from around the world, receive a Letter of Recommendation from Pablo Veramendi, participate in the Microsoft AI Tour Bengaluru, become part of a Guinness World Record through Microsoft's AI Skills Fest, lead an international JS-AI Build-a-thon troop of more than 80 participants, win both the Overall Winner and People's Choice Awards, be invited to share my experience through a blog on the Microsoft Tech Community, and serve as India's only Gold Startup Scout, where I referred eight startups across various domains and helped each of them unlock $25,000 in Microsoft Azure credits.&lt;/P&gt;
&lt;P&gt;All of these experiences definitely strengthened my resume. But the biggest achievement was the person I became. This community taught me how to build. How to lead. How to mentor. How to communicate. How to give back. And most importantly, how to believe in myself.&lt;/P&gt;
&lt;P&gt;As I graduate from the program, I know one thing for sure—the title of Senior Microsoft Student Ambassador is something I'll always be proud of, but the people I met, the lessons I learned, and the community I found are what I'll carry with me for the rest of my life.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 21 Jul 2026 02:27:16 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/student-developer-blog/meet-aryan-jaiswal/ba-p/4538102</guid>
      <dc:creator>Tracey_Salem_MSFT</dc:creator>
      <dc:date>2026-07-21T02:27:16Z</dc:date>
    </item>
    <item>
      <title>Hands-on webinar: Set up your classroom in Teams for Education plus the new Study and Learn Agent</title>
      <link>https://techcommunity.microsoft.com/t5/education-blog/hands-on-webinar-set-up-your-classroom-in-teams-for-education/ba-p/4539021</link>
      <description>&lt;P&gt;Join us on Wednesday, August 5th at 8:00 AM Pacific Time for a practical, 60-minute webinar to get your Microsoft Teams classroom ready for the new school year in the Northern hemisphere. Get your class set up in Assignments and Classwork, learn about new tools like Learning Activities, use Student AI Guidelines to set the right expectations for your students, and see how the Study and Learn Agent can be a study partner for your students. Follow along with your own Microsoft 365 Education account as we walk through each one.&lt;BR /&gt;&lt;BR /&gt;&lt;STRONG&gt;Register here: &lt;A class="lia-external-url" href="https://aka.ms/August5Training" target="_blank"&gt;https://aka.ms/August5Training&lt;/A&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;BR /&gt;&lt;BR /&gt;The session will be recorded and posted to the Microsoft Education YouTube channel so you can watch it later or share it with colleagues.&lt;BR /&gt;&lt;BR /&gt;Agenda - Get your Teams EDU classroom ready and learn about the Study and Learn Agent.&lt;BR /&gt;✅ Teams EDU Classwork / Assignments setup&lt;BR /&gt;✅ Learning Activities in Assignments and Classwork&lt;BR /&gt;✅ Student AI Guidelines in Teams Assignments&lt;BR /&gt;✅ Copilot Study and Learn Agent&lt;BR /&gt;&lt;BR /&gt;We look forward to seeing you on August 5th! Also, be sure to check out and sign up for our&amp;nbsp;&lt;A href="https://aka.ms/ElevateLearning" target="_blank" rel="noopener"&gt;Microsoft Elevate Educator community&lt;/A&gt;.&lt;BR /&gt;&lt;BR /&gt;Mike Tholfsen&lt;BR /&gt;Group Product Manager&lt;BR /&gt;Microsoft Education&lt;/P&gt;</description>
      <pubDate>Mon, 20 Jul 2026 18:44:54 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/education-blog/hands-on-webinar-set-up-your-classroom-in-teams-for-education/ba-p/4539021</guid>
      <dc:creator>MikeTholfsen</dc:creator>
      <dc:date>2026-07-20T18:44:54Z</dc:date>
    </item>
    <item>
      <title>Building a Fully Managed Multi-Agent Pipeline with Microsoft Foundry</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/building-a-fully-managed-multi-agent-pipeline-with-microsoft/ba-p/4533757</link>
      <description>&lt;P data-path-to-node="5"&gt;Hey everyone! I am&amp;nbsp;&lt;A class="lia-external-url" href="https://linkedin.com/in/shivam2003" target="_blank" rel="noopener"&gt;&lt;STRONG data-path-to-node="5" data-index-in-node="19"&gt;Shivam Goyal&lt;/STRONG&gt;&lt;/A&gt;, a Microsoft MVP, and I am super excited to share a workshop I created that is going to save you a massive amount of time.&lt;/P&gt;
&lt;P data-path-to-node="6"&gt;Designing smart AI workflows is arguably one of the most creative and enjoyable parts of engineering. Trying to force a single, massive prompt to execute a complex, multi-step business pipeline perfectly? Not so much. We have all been there: you write a giant prompt to handle a multi-step task, only for the AI to get confused, miss critical details, and give completely different answers every time you run it.&lt;/P&gt;
&lt;P data-path-to-node="8"&gt;To solve this giant prompt problem, I built a hands-on multi-agent workshop. Today, we are looking at how you can use the &lt;A class="lia-external-url" href="https://github.com/microsoft-foundry/Foundry_Toolkit_for_VSCode_Lab" target="_blank" rel="noopener"&gt;&lt;STRONG data-path-to-node="8" data-index-in-node="122"&gt;Foundry Toolkit for VS Code&lt;/STRONG&gt;&lt;/A&gt; alongside the project blueprints I designed to build, debug, and deploy specialized multi-agent teams without any infrastructure headaches.&lt;/P&gt;
&lt;img /&gt;
&lt;H3 data-path-to-node="14"&gt;What is the Foundry Toolkit for VS Code?&lt;/H3&gt;
&lt;P data-path-to-node="15"&gt;The &lt;STRONG data-path-to-node="15" data-index-in-node="4"&gt;Foundry Toolkit for VS Code&lt;/STRONG&gt; is a unified extension that brings cloud-scale AI development right into your local code editor. Instead of constantly jumping between web portals, command lines, and code files, the toolkit gives you a single place to manage your entire AI application.&lt;/P&gt;
&lt;P data-path-to-node="16"&gt;With this toolkit installed in Visual Studio Code, you can:&lt;/P&gt;
&lt;UL data-path-to-node="17"&gt;
&lt;LI&gt;&lt;STRONG data-path-to-node="17,0,0" data-index-in-node="0"&gt;Access the Model Catalog:&lt;/STRONG&gt; Instantly browse and connect your code to leading AI models.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG data-path-to-node="17,1,0" data-index-in-node="0"&gt;Build Locally:&lt;/STRONG&gt; Write your agent logic using standard frameworks like the &lt;STRONG data-path-to-node="17,1,0" data-index-in-node="73"&gt;Microsoft Agent Framework (MAF)&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG data-path-to-node="17,2,0" data-index-in-node="0"&gt;Inspect &amp;amp; Debug:&lt;/STRONG&gt; Trace data flow and agent conversations in real-time before moving to production.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG data-path-to-node="17,3,0" data-index-in-node="0"&gt;Deploy with One Click:&lt;/STRONG&gt; Ship your local project directly to the cloud as a fully managed &lt;STRONG data-path-to-node="17,3,0" data-index-in-node="88"&gt;Foundry Agent Service&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 data-path-to-node="19"&gt;Inside My Workshop: Lab 02 Multi-Agent Workflow&lt;/H3&gt;
&lt;P data-path-to-node="20"&gt;To show you exactly how to make the most of this toolkit, I built a practical, real-world scenario in &lt;STRONG data-path-to-node="20" data-index-in-node="102"&gt;Lab 02: Multi-Agent Workflow&lt;/STRONG&gt;, which you can find inside the open-source repository.&lt;/P&gt;
&lt;P data-path-to-node="21"&gt;In this lab, I walk you through building a &lt;STRONG data-path-to-node="21" data-index-in-node="43"&gt;"Resume → Job Fit Evaluator"&lt;/STRONG&gt; pipeline. Instead of relying on a single prompt, the workflow orchestrates a squad of &lt;STRONG data-path-to-node="21" data-index-in-node="158"&gt;four specialized AI agents&lt;/STRONG&gt; working together using smart design patterns:&lt;/P&gt;
&lt;H4 data-path-to-node="22"&gt;1. The Fan-Out Pattern (Parallel Work)&lt;/H4&gt;
&lt;P data-path-to-node="23"&gt;When a resume is submitted, the system splits the task and feeds it to two agents at the exact same time:&lt;/P&gt;
&lt;UL data-path-to-node="24"&gt;
&lt;LI&gt;&lt;STRONG data-path-to-node="24,0,0" data-index-in-node="0"&gt;The Tech Stack Analyst:&lt;/STRONG&gt; Focuses entirely on programming languages, frameworks, and tools.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG data-path-to-node="24,1,0" data-index-in-node="0"&gt;The Experience &amp;amp; Impact Scorer:&lt;/STRONG&gt; Evaluates career history, performance metrics, and leadership.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H4 data-path-to-node="25"&gt;2. The Fan-In Pattern (Consolidation)&lt;/H4&gt;
&lt;P data-path-to-node="26"&gt;Once the parallel analysis is complete, the workflow channels their notes into the final two agents to consolidate the data:&lt;/P&gt;
&lt;UL data-path-to-node="27"&gt;
&lt;LI&gt;&lt;STRONG data-path-to-node="27,0,0" data-index-in-node="0"&gt;The Fit Evaluator:&lt;/STRONG&gt; Synthesizes the information into a single compatibility score.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG data-path-to-node="27,1,0" data-index-in-node="0"&gt;The Roadmap Architect:&lt;/STRONG&gt; Generates a custom step-by-step learning path to help the candidate bridge any skill gaps.&lt;/LI&gt;
&lt;/UL&gt;
&lt;img /&gt;
&lt;H3 data-path-to-node="34"&gt;The Development Workflow: Step-by-Step&lt;/H3&gt;
&lt;P data-path-to-node="35"&gt;The lab I put together provides a straightforward walkthrough that takes you from an empty directory to a live cloud application without ever leaving your code editor.&lt;/P&gt;
&lt;H4 data-path-to-node="36"&gt;Step 1: Click to Build Your Workspace&lt;/H4&gt;
&lt;P data-path-to-node="37"&gt;You don't need to write complicated setup code from scratch. By using the &lt;STRONG data-path-to-node="37" data-index-in-node="74"&gt;Agent Builder&lt;/STRONG&gt; interface inside the VS Code extension, you can click a button to automatically generate all the starter configurations and project folders I've mapped out for you.&lt;/P&gt;
&lt;H4 data-path-to-node="42"&gt;Step 2: Give the Agents Their Jobs&lt;/H4&gt;
&lt;P data-path-to-node="43"&gt;Next, you customize what each agent does using a simple configuration file (agent.yaml). This is where you tell the agents which AI models to use from the &lt;STRONG data-path-to-node="43" data-index-in-node="155"&gt;Foundry Model Catalog&lt;/STRONG&gt;. You then add your project keys to connect to your cloud workspace:&lt;/P&gt;
&lt;LI-CODE lang="markdown"&gt;FOUNDRY_PROJECT_ENDPOINT=https://&amp;lt;your-workspace&amp;gt;.services.ai.azure.com/api/projects/&amp;lt;your-project&amp;gt;
AZURE_AI_MODEL_DEPLsOYMENT_NAME=&amp;lt;your-ai-model&amp;gt;&lt;/LI-CODE&gt;
&lt;H4 data-path-to-node="45"&gt;Step 3: Test and Fix on Your Computer&lt;/H4&gt;
&lt;P data-path-to-node="46"&gt;Before sharing your project with the world, you can run the whole AI team locally on your machine. Using a tool called the &lt;STRONG data-path-to-node="46" data-index-in-node="123"&gt;Agent Inspector&lt;/STRONG&gt;, you can see exactly how the agents talk to each other, trace data steps, and tweak your text instructions until they work perfectly.&lt;/P&gt;
&lt;H4 data-path-to-node="47"&gt;Step 4: One-Click Cloud Launch&lt;/H4&gt;
&lt;P data-path-to-node="48"&gt;When your local tests work great, you don't need to be a server or container expert to deploy them. The VS Code extension automatically packages your code and registers it with the &lt;STRONG data-path-to-node="48" data-index-in-node="181"&gt;Foundry Agent Service&lt;/STRONG&gt; as a live Hosted Agent.&lt;/P&gt;
&lt;H4 data-path-to-node="49"&gt;Step 5: Test the Live App&lt;/H4&gt;
&lt;P data-path-to-node="50"&gt;Once your AI team is live in the cloud, you can open the built-in &lt;STRONG data-path-to-node="50" data-index-in-node="66"&gt;Remote Agent Playground&lt;/STRONG&gt; web page. Drag and drop a real resume into the window, hit run, and watch the streaming logs show your cloud agents processing the data together in real-time.&lt;/P&gt;
&lt;img /&gt;
&lt;H3 data-path-to-node="56"&gt;Ready to Build Your Own AI Team?&lt;/H3&gt;
&lt;P data-path-to-node="57"&gt;Building reliable AI tools means moving away from massive, unpredictable prompts and moving toward small, organized teams of agents using standard patterns like Fan-Out and Fan-In. The combination of the Foundry Toolkit and the structured labs I've created makes it easy to build, test, and host these systems without worrying about server infrastructure.&lt;/P&gt;
&lt;P data-path-to-node="58"&gt;The entire workshop is free, open-source, and ready for you to clone today. Jump into Lab 02 and see how easy multi-agent orchestration can be!&lt;/P&gt;
&lt;P data-path-to-node="59"&gt;&lt;STRONG data-path-to-node="59" data-index-in-node="3"&gt;Get Started Now:&lt;/STRONG&gt; Explore my lab repository at &lt;A href="https://github.com/microsoft-foundry/Foundry_Toolkit_for_VSCode_Lab/tree/main/workshop/lab02-multi-agent" target="_blank" rel="noopener" data-lia-auto-title-active="0" data-lia-auto-title="Foundry_Toolkit_for_VSCode_Lab/workshop/lab02-multi-agent at main · microsoft-foundry/Foundry_Toolkit_for_VSCode_Lab"&gt;Foundry_Toolkit_for_VSCode_Lab/workshop/lab02-multi-agent at main · microsoft-foundry/Foundry_Toolkit_for_VSCode_Lab&lt;/A&gt;&lt;/P&gt;
&lt;H4 data-path-to-node="61"&gt;Let's Connect!&lt;/H4&gt;
&lt;P data-path-to-node="62"&gt;If you enjoyed this walkthrough, have questions about the workshop, or want to share your own agent workflows, let's keep the conversation going:&lt;/P&gt;
&lt;UL data-path-to-node="63"&gt;
&lt;LI&gt;&lt;A class="lia-external-url" href="https://shivamgoyal03.github.io/" target="_blank" rel="noopener"&gt;&lt;STRONG data-path-to-node="63,0,0" data-index-in-node="3"&gt;Portfolio&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Wed, 15 Jul 2026 07:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/building-a-fully-managed-multi-agent-pipeline-with-microsoft/ba-p/4533757</guid>
      <dc:creator>ShivamGoyal</dc:creator>
      <dc:date>2026-07-15T07:00:00Z</dc:date>
    </item>
    <item>
      <title>Build and Deploy Your First AI Agent with Microsoft Foundry Toolkit</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/build-and-deploy-your-first-ai-agent-with-microsoft-foundry/ba-p/4534920</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P data-line="6"&gt;&lt;A class="lia-external-url" href="https://github.com/microsoft-foundry/Foundry_Toolkit_for_VSCode_Lab/tree/main/workshop/lab01-single-agent" target="_blank" rel="noopener"&gt;Click here for the full lab.&lt;/A&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P data-line="6"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-line="6"&gt;What if every incident report, pipeline failure, or security alert could be instantly rewritten for a non-technical audience? In this post, you'll build an &lt;STRONG&gt;"Explain Like I'm an Executive"&lt;/STRONG&gt; agent, a hosted AI agent that takes dense technical input and produces plain-English executive summaries, using the &lt;A class="lia-external-url" href="https://marketplace.visualstudio.com/items?itemName=ms-windows-ai-studio.windows-ai-studio" target="_blank" rel="noopener"&gt;Microsoft Foundry Toolkit for VS Code.&lt;/A&gt;&lt;/P&gt;
&lt;P data-line="8"&gt;By the end, you'll have a working agent you can test locally and deploy to the cloud with a single click.&lt;/P&gt;
&lt;H2 data-line="10"&gt;What You'll Build&lt;/H2&gt;
&lt;P data-line="12"&gt;The agent follows a simple flow:&lt;/P&gt;
&lt;img /&gt;
&lt;P data-line="18"&gt;Under the hood it uses:&lt;/P&gt;
&lt;UL data-line="20"&gt;
&lt;LI data-line="20"&gt;&lt;STRONG&gt;Microsoft Agent Framework&lt;/STRONG&gt; - for agent logic and structure&lt;/LI&gt;
&lt;LI data-line="21"&gt;&lt;STRONG&gt;Foundry Toolkit for VS Code&lt;/STRONG&gt; - to scaffold, test, and deploy&lt;/LI&gt;
&lt;LI data-line="22"&gt;&lt;STRONG&gt;An AI model&lt;/STRONG&gt; (e.g., gpt-4.1-mini) - to generate the summaries&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-line="24"&gt;The final output always follows a structured format:&lt;/P&gt;
&lt;P data-line="26"&gt;&lt;STRONG&gt;Executive Summary:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL data-line="27"&gt;
&lt;LI data-line="27"&gt;What happened:&amp;nbsp;&lt;EM&gt;(plain-language description)&lt;/EM&gt;&lt;/LI&gt;
&lt;LI data-line="28"&gt;Business impact:&amp;nbsp;&lt;EM&gt;(clear, non-technical impact)&lt;/EM&gt;&lt;/LI&gt;
&lt;LI data-line="29"&gt;Next step:&amp;nbsp;&lt;EM&gt;(action or mitigation)&lt;/EM&gt;&lt;/LI&gt;
&lt;LI data-line="30"&gt;Date:&amp;nbsp;&lt;EM&gt;(YYYY-MM-DD)&lt;/EM&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 data-line="293"&gt;Foundry Toolkit&lt;/H2&gt;
&lt;img /&gt;
&lt;P data-line="20"&gt;The Foundry Toolkit handles the end-to-end lifecycle:&lt;/P&gt;
&lt;OL data-line="22"&gt;
&lt;LI data-line="22"&gt;&lt;STRONG&gt;Scaffold&lt;/STRONG&gt; - A wizard generates your project structure with one command&lt;/LI&gt;
&lt;LI data-line="23"&gt;&lt;STRONG&gt;Configure&lt;/STRONG&gt; - Point to your AI model and write agent instructions (a system prompt)&lt;/LI&gt;
&lt;LI data-line="24"&gt;&lt;STRONG&gt;Test locally&lt;/STRONG&gt; - Press F5 to launch a built-in chat UI for instant feedback&lt;/LI&gt;
&lt;LI data-line="25"&gt;&lt;STRONG&gt;Deploy&lt;/STRONG&gt; - One click packages your agent as a container and deploys it to Azure&lt;/LI&gt;
&lt;LI data-line="26"&gt;&lt;STRONG&gt;Verify&lt;/STRONG&gt; - Test safety and edge cases against the live endpoint&lt;/LI&gt;
&lt;/OL&gt;
&lt;P data-line="28"&gt;The key building blocks:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Component&lt;/th&gt;&lt;th&gt;Role&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Agent Framework&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Provides the agent runtime and tool-calling capabilities&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Foundry Toolkit&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;VS Code extension for scaffolding, debugging, and deployment&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;AI Model&lt;/STRONG&gt;&amp;nbsp;(e.g., gpt-4.1-mini)&lt;/td&gt;&lt;td&gt;Powers the natural language understanding and generation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Azure Container Registry + Foundry&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Hosts and scales your agent in the cloud&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2 data-line="39"&gt;What Makes a Good Agent&lt;/H2&gt;
&lt;P data-line="41"&gt;The difference between a basic chatbot and a reliable agent comes down to&amp;nbsp;&lt;STRONG&gt;well-crafted instructions&lt;/STRONG&gt;. For this agent, the system prompt defines:&lt;/P&gt;
&lt;UL data-line="43"&gt;
&lt;LI data-line="43"&gt;&lt;STRONG&gt;Role&lt;/STRONG&gt; - "Translate technical information into executive-friendly summaries"&lt;/LI&gt;
&lt;LI data-line="44"&gt;&lt;STRONG&gt;Audience&lt;/STRONG&gt; - Senior leaders who care about impact, not implementation details&lt;/LI&gt;
&lt;LI data-line="45"&gt;&lt;STRONG&gt;Output format&lt;/STRONG&gt; - A consistent structure (what happened, business impact, next step)&lt;/LI&gt;
&lt;LI data-line="46"&gt;&lt;STRONG&gt;Rules&lt;/STRONG&gt; - Keep it brief, don't fabricate, don't leak instructions&lt;/LI&gt;
&lt;LI data-line="47"&gt;&lt;STRONG&gt;Safety constraints&lt;/STRONG&gt; - Resist prompt injection and role override attempts&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-line="49"&gt;You can also give agents&amp;nbsp;&lt;STRONG&gt;tools, &lt;/STRONG&gt;Python functions they can call at runtime (like fetching today's date or querying an API).&lt;/P&gt;
&lt;H2 data-line="53"&gt;The Developer Experience&lt;/H2&gt;
&lt;img /&gt;
&lt;P data-line="55"&gt;The Foundry Toolkit streamlines what would otherwise be a multi-step DevOps process:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Without the toolkit&lt;/th&gt;&lt;th&gt;With the toolkit&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Manually write Dockerfiles, YAML configs, server boilerplate&lt;/td&gt;&lt;td&gt;Wizard generates everything&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Set up a separate test harness&lt;/td&gt;&lt;td&gt;Built-in Agent Inspector (chat UI) launches with F5&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Build container, push to registry, register agent manually&lt;/td&gt;&lt;td&gt;Single "Deploy" button handles it all&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Monitor via Azure Portal&lt;/td&gt;&lt;td&gt;Status, logs, and playground available in VS Code&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P data-line="64"&gt;Deployment takes 2–5 minutes. Your agent gets a managed /responses endpoint with auto-scaling.&lt;/P&gt;
&lt;H2 data-line="293"&gt;Cleanup&lt;/H2&gt;
&lt;P data-line="295"&gt;If you want to remove Azure resources after experimenting:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P data-line="8"&gt;az group delete --name &amp;lt;your-resource-group&amp;gt; --yes --no-wait&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P data-line="301"&gt;Or delete just the hosted agent from the Foundry portal under&amp;nbsp;&lt;STRONG&gt;Build → Agents&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2 data-line="293"&gt;Next Steps&lt;/H2&gt;
&lt;UL data-line="123"&gt;
&lt;LI data-line="123"&gt;Explore the &lt;A class="lia-external-url" href="https://github.com/microsoft-foundry/Foundry_Toolkit_for_VSCode_Lab/" target="_blank" rel="noopener"&gt;Foundry Toolkit Lab&lt;/A&gt;, to build your own agent.&lt;/LI&gt;
&lt;LI data-line="123"&gt;Check out&lt;STRONG&gt;&amp;nbsp;&lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/educatordeveloperblog/building-a-fully-managed-multi-agent-pipeline-with-microsoft-foundry/4533757" target="_blank" rel="noopener" data-href="../lab02-multi-agent/docs/README.md" data-lia-auto-title="Lab 02: Multi-Agent Orchestration" data-lia-auto-title-active="0"&gt;Lab 02: Multi-Agent Orchestration&lt;/A&gt;&lt;/STRONG&gt; to learn how to build a multi-agent workflow with orchestration patterns&lt;/LI&gt;
&lt;LI data-line="124"&gt;&lt;STRONG&gt;&lt;A href="https://learn.microsoft.com/azure/foundry/agents/concepts/tool-catalog" target="_blank" rel="noopener" data-href="https://learn.microsoft.com/azure/foundry/agents/concepts/tool-catalog"&gt;Add tools&lt;/A&gt;&lt;/STRONG&gt; - Connect APIs, databases, or custom functions&lt;/LI&gt;
&lt;LI data-line="126"&gt;&lt;STRONG&gt;&lt;A href="https://learn.microsoft.com/azure/foundry/" target="_blank" rel="noopener" data-href="https://learn.microsoft.com/azure/foundry/"&gt;Microsoft Foundry docs&lt;/A&gt;&lt;/STRONG&gt; - Full platform reference&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Mon, 13 Jul 2026 07:53:38 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/build-and-deploy-your-first-ai-agent-with-microsoft-foundry/ba-p/4534920</guid>
      <dc:creator>bethanyjep</dc:creator>
      <dc:date>2026-07-13T07:53:38Z</dc:date>
    </item>
    <item>
      <title>From Game to Operations: Exporting a Foundry-Designed Workforce as a Portable Bundle</title>
      <link>https://techcommunity.microsoft.com/t5/educator-developer-blog/from-game-to-operations-exporting-a-foundry-designed-workforce/ba-p/4530300</link>
      <description>&lt;P&gt;Part 5 of 5.&lt;/P&gt;
&lt;HR /&gt;
&lt;P&gt;Across this series the game has reasoned about a founder, designed a digital workforce for their venture, executed chapters through Microsoft Foundry agents, and gated every artifact behind a human. That is a complete loop - inside the game. This final post is about the seam where it leaves the game: how the &lt;STRONG&gt;Org Designer&lt;/STRONG&gt;'s output becomes a portable artifact a real digital-worker platform can ingest and provision, without dragging a single proprietary dependency into the public repo.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The most useful thing a reasoning agent can produce is not a paragraph. It is a structured plan another system can execute - behind its own human gate.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;Why the Org Designer is the keystone worker&lt;/H2&gt;
&lt;P&gt;In Part 1 the pipeline's second stage was the Org Designer: given a venture, it designs the smallest org that can actually deliver it - one human operator plus the digital workers that form the execution layer. Every other system in the game hangs off that output. The World Designer decomposes the venture into chapters; &lt;CODE&gt;bind_world_to_org&lt;/CODE&gt; stamps each chapter with its owning worker; the economy prices each worker's monthly burn. The org the model designs is the org that executes.&lt;/P&gt;
&lt;P&gt;You can see the artifact directly in play - a worker delivers a positioning brief and a rendered org chart, and it passes the gate:&lt;/P&gt;
&lt;img /&gt;
&lt;P style="padding: 12px; border: 2px dashed #3caea3; background: #eefaf8;"&gt;&lt;EM&gt;A worker delivers a rendered org chart that passes the verification gate&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;That org chart is not decoration. It is structured state - roles, kinds (human / digital_worker / hybrid), mandates, reporting lines, KPIs, tool wishes, and a model-class hint per worker. Which means it can be &lt;EM&gt;exported&lt;/EM&gt;.&lt;/P&gt;
&lt;H2&gt;The org being exported: OrgRole and OrgBlueprint&lt;/H2&gt;
&lt;P&gt;To understand the bundle you have to see the state it is built from. The org is an &lt;CODE&gt;OrgBlueprint&lt;/CODE&gt; in &lt;CODE&gt;submission/state/schema.py&lt;/CODE&gt; - a company summary, an operating model, and a list of &lt;CODE&gt;OrgRole&lt;/CODE&gt; seats. Each role is a typed record, not a sentence:&lt;/P&gt;
&lt;PRE class="language-python" tabindex="0" contenteditable="false" data-lia-code-value="# submission/state/schema.py
class OrgRole(BaseModel):
    id: str
    title: str
    kind: str = &amp;quot;digital_worker&amp;quot;   # human | digital_worker | hybrid
    mandate: str = &amp;quot;&amp;quot;              # what this seat is accountable for
    reports_to: Optional[str] = None
    kpis: List[str] = Field(default_factory=list)
    tools: List[str] = Field(default_factory=list)
    deployment_hint: str = &amp;quot;&amp;quot;      # which model class fits this worker
    lifecycle_stage: str = &amp;quot;&amp;quot;      # discovery|positioning|mvp|gtm|retention|ops
    monthly_cost_usd: int = 0      # the worker's monthly wage (the burn)
    why: str = &amp;quot;&amp;quot;                  # why this seat must exist
"&gt;&lt;CODE&gt;# submission/state/schema.py
class OrgRole(BaseModel):
    id: str
    title: str
    kind: str = "digital_worker"   # human | digital_worker | hybrid
    mandate: str = ""              # what this seat is accountable for
    reports_to: Optional[str] = None
    kpis: List[str] = Field(default_factory=list)
    tools: List[str] = Field(default_factory=list)
    deployment_hint: str = ""      # which model class fits this worker
    lifecycle_stage: str = ""      # discovery|positioning|mvp|gtm|retention|ops
    monthly_cost_usd: int = 0      # the worker's monthly wage (the burn)
    why: str = ""                  # why this seat must exist
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Because every field is structured, the converter has something real to map - it is not parsing prose back into fields, it is re-shaping records it already trusts. &lt;CODE&gt;kind&lt;/CODE&gt; becomes the human/digital split; &lt;CODE&gt;deployment_hint&lt;/CODE&gt; becomes the portable &lt;CODE&gt;model_class&lt;/CODE&gt;; &lt;CODE&gt;reports_to&lt;/CODE&gt; becomes the org chart's edges; &lt;CODE&gt;mandate&lt;/CODE&gt;, &lt;CODE&gt;kpis&lt;/CODE&gt;, and &lt;CODE&gt;tools&lt;/CODE&gt; become the worker's brief. The blueprint also carries derived economics (&lt;CODE&gt;monthly_burn_usd&lt;/CODE&gt;, &lt;CODE&gt;leverage_ratio&lt;/CODE&gt;, &lt;CODE&gt;monthly_savings_usd&lt;/CODE&gt;) that ride into the bundle unchanged.&lt;/P&gt;
&lt;H2&gt;How the org gets designed&lt;/H2&gt;
&lt;P&gt;That blueprint is itself the output of a Foundry agent. &lt;CODE&gt;design_org&lt;/CODE&gt; in &lt;CODE&gt;submission/agents/org_designer.py&lt;/CODE&gt; runs on the org-designer deployment (a stronger model, because it shapes the whole run), asks for a structured roster, and parses it through the same tolerant &lt;CODE&gt;_extract_json&lt;/CODE&gt; from Part 2 - falling back to a deterministic blueprint when there are no credentials:&lt;/P&gt;
&lt;PRE class="language-python" tabindex="0" contenteditable="false" data-lia-code-value="# submission/agents/org_designer.py
def design_org(brief, source=&amp;quot;pitch&amp;quot;, source_ref=&amp;quot;&amp;quot;, summary_hint=&amp;quot;&amp;quot;):
    client = get_foundry_client()
    deployment = model_for(&amp;quot;orgdesigner&amp;quot;) or model_for(&amp;quot;narrator&amp;quot;)
    if not (client and deployment and is_live()):
        return _finalize(_fallback_blueprint(brief), brief, source, source_ref, summary_hint)
    resp = create_chat_completion(deployment, [...], max_completion_tokens=8000)
    parsed = _extract_json(resp.choices[0].message.content or &amp;quot;&amp;quot;)
    if parsed and len(parsed.get(&amp;quot;roles&amp;quot;, [])) &amp;gt;= 2:
        return _finalize(parsed, brief, source, source_ref, summary_hint)
    return _finalize(_fallback_blueprint(brief), brief, source, source_ref, summary_hint)
"&gt;&lt;CODE&gt;# submission/agents/org_designer.py
def design_org(brief, source="pitch", source_ref="", summary_hint=""):
    client = get_foundry_client()
    deployment = model_for("orgdesigner") or model_for("narrator")
    if not (client and deployment and is_live()):
        return _finalize(_fallback_blueprint(brief), brief, source, source_ref, summary_hint)
    resp = create_chat_completion(deployment, [...], max_completion_tokens=8000)
    parsed = _extract_json(resp.choices[0].message.content or "")
    if parsed and len(parsed.get("roles", [])) &amp;gt;= 2:
        return _finalize(parsed, brief, source, source_ref, summary_hint)
    return _finalize(_fallback_blueprint(brief), brief, source, source_ref, summary_hint)
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;CODE&gt;_finalize&lt;/CODE&gt; is where the model's creative roster meets deterministic mechanics: it normalises every role, prices each seat, and computes the headline stats. The model decides &lt;EM&gt;who&lt;/EM&gt; the company needs; the code decides &lt;EM&gt;what they cost&lt;/EM&gt;. That division - which we have now seen at the gate (Part 2), in consequences (Part 3), and here - is the spine of the whole project, and it is why an exported bundle's economics are trustworthy even though a model drew the org.&lt;/P&gt;
&lt;H2&gt;The org binds to the quest&lt;/H2&gt;
&lt;P&gt;The designed org does not sit in a corner - it is stamped onto the quest line. &lt;CODE&gt;bind_world_to_org&lt;/CODE&gt; in &lt;CODE&gt;worker_factory.py&lt;/CODE&gt; walks the stages and assigns each one the digital worker whose lifecycle stage matches, so every chapter has an owning worker before play begins:&lt;/P&gt;
&lt;PRE class="language-python" tabindex="0" contenteditable="false" data-lia-code-value="# submission/agents/worker_factory.py
def bind_world_to_org(world, org):
    bindings = {}
    for stage in world.stages:
        worker = _match_worker_for_stage(stage, org)
        if worker:
            stage.assigned_worker_id = worker.id
            stage.assigned_worker_title = worker.title
            bindings[stage.id] = worker.title
    return bindings
"&gt;&lt;CODE&gt;# submission/agents/worker_factory.py
def bind_world_to_org(world, org):
    bindings = {}
    for stage in world.stages:
        worker = _match_worker_for_stage(stage, org)
        if worker:
            stage.assigned_worker_id = worker.id
            stage.assigned_worker_title = worker.title
            bindings[stage.id] = worker.title
    return bindings
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This is why the export is meaningful: the org in the bundle is the same org that executed the run. The worker that owns the GTM chapter in the game is the worker the bundle hands the receiving platform for GTM. Nothing is invented at export time.&lt;/P&gt;
&lt;H2&gt;The bridge: export, don't import&lt;/H2&gt;
&lt;P&gt;The temptation, when you have a game and a real platform, is to wire them together - run the platform's workers inside the game. That is the wrong move for two reasons. First, the game's reasoning core must stay 100% Microsoft Foundry (the rubric rule, and the architectural spine of this series). Second, the repo must run after &lt;CODE&gt;git clone&lt;/CODE&gt; with no proprietary dependencies. So the bridge is &lt;STRONG&gt;export, not import&lt;/STRONG&gt;: the game emits a neutral bundle; any platform ingests it.&lt;/P&gt;
&lt;img /&gt;&lt;!-- mermaid source:
flowchart LR
    A[Player pitch / profile URL] --&amp;gt; B[Org Designer&amp;lt;br/&amp;gt;Foundry gpt-5 family]
    B --&amp;gt; C[OrgBlueprint&amp;lt;br/&amp;gt;in game state]
    C --&amp;gt; D[GET /api/org/export&amp;lt;br/&amp;gt;workforce_bundle.json]
    D --&amp;gt; E[Any digital-worker platform&amp;lt;br/&amp;gt;maps + reviews]
    E --&amp;gt; F[Human approval gate]
    F --&amp;gt; G[Provisioned workers,&amp;lt;br/&amp;gt;teams, KPIs, workflows]
--&gt;
&lt;P&gt;No platform-specific code lives in the game repo. The converter is pure and offline - it turns the in-game &lt;CODE&gt;OrgBlueprint&lt;/CODE&gt; into a platform-neutral &lt;CODE&gt;workforce_bundle&lt;/CODE&gt; and ships a CLI that runs in simulation after a fresh clone.&lt;/P&gt;
&lt;H2&gt;The converter is pure and offline&lt;/H2&gt;
&lt;P&gt;The module that does the work, &lt;CODE&gt;submission/tools/export_org_blueprint.py&lt;/CODE&gt;, is deliberately dependency-free: no platform SDK, no network, no credentials. It splits the chartered roles into humans and digital workers and emits one spec per worker:&lt;/P&gt;
&lt;PRE class="language-python" tabindex="0" contenteditable="false" data-lia-code-value="# submission/tools/export_org_blueprint.py
def org_to_workforce_bundle(org):
    roles   = org.get(&amp;quot;roles&amp;quot;) or []
    humans  = [r for r in roles if r.get(&amp;quot;kind&amp;quot;) == &amp;quot;human&amp;quot;]
    workers = [r for r in roles if r.get(&amp;quot;kind&amp;quot;) != &amp;quot;human&amp;quot;]
    worker_specs = [{
        &amp;quot;worker_key&amp;quot;: _slug(role.get(&amp;quot;id&amp;quot;) or role.get(&amp;quot;title&amp;quot;, &amp;quot;&amp;quot;)),
        &amp;quot;name&amp;quot;: role.get(&amp;quot;title&amp;quot;, &amp;quot;Digital Worker&amp;quot;),
        &amp;quot;kind&amp;quot;: role.get(&amp;quot;kind&amp;quot;, &amp;quot;digital_worker&amp;quot;),
        &amp;quot;system_message&amp;quot;: _system_message(role, org),
        &amp;quot;model_class&amp;quot;: _MODEL_CLASS.get(role.get(&amp;quot;deployment_hint&amp;quot;, &amp;quot;&amp;quot;), &amp;quot;fast&amp;quot;),
        &amp;quot;tools&amp;quot;: role.get(&amp;quot;tools&amp;quot;) or [], &amp;quot;kpis&amp;quot;: role.get(&amp;quot;kpis&amp;quot;) or [],
        &amp;quot;reports_to&amp;quot;: _slug(role.get(&amp;quot;reports_to&amp;quot;) or &amp;quot;&amp;quot;),
        # ... seniority, monthly_cost_usd, why ...
    } for role in workers]
    # ... company, economics, team, provisioning ...
"&gt;&lt;CODE&gt;# submission/tools/export_org_blueprint.py
def org_to_workforce_bundle(org):
    roles   = org.get("roles") or []
    humans  = [r for r in roles if r.get("kind") == "human"]
    workers = [r for r in roles if r.get("kind") != "human"]
    worker_specs = [{
        "worker_key": _slug(role.get("id") or role.get("title", "")),
        "name": role.get("title", "Digital Worker"),
        "kind": role.get("kind", "digital_worker"),
        "system_message": _system_message(role, org),
        "model_class": _MODEL_CLASS.get(role.get("deployment_hint", ""), "fast"),
        "tools": role.get("tools") or [], "kpis": role.get("kpis") or [],
        "reports_to": _slug(role.get("reports_to") or ""),
        # ... seniority, monthly_cost_usd, why ...
    } for role in workers]
    # ... company, economics, team, provisioning ...
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Because it is pure, the same function backs both the live HTTP endpoint and a no-server CLI, and it runs in simulation after a fresh clone - the export is forkable like everything else in this series.&lt;/P&gt;
&lt;H2&gt;The bundle: a contract, not a dump&lt;/H2&gt;
&lt;P&gt;The export is a single JSON document with a stable format tag (&lt;CODE&gt;campaign.workforce_bundle&lt;/CODE&gt;, versioned), designed so both a human approver and a downstream LLM can parse and act on it:&lt;/P&gt;
&lt;PRE class="language-json" tabindex="0" contenteditable="false" data-lia-code-value="{
  &amp;quot;format&amp;quot;: &amp;quot;campaign.workforce_bundle&amp;quot;,
  &amp;quot;version&amp;quot;: 1,
  &amp;quot;company&amp;quot;: { &amp;quot;summary&amp;quot;: &amp;quot;...&amp;quot;, &amp;quot;operating_model&amp;quot;: &amp;quot;...&amp;quot;, &amp;quot;source&amp;quot;: &amp;quot;pitch&amp;quot; },
  &amp;quot;economics&amp;quot;: { &amp;quot;headcount&amp;quot;: 6, &amp;quot;digital_worker_count&amp;quot;: 5,
                 &amp;quot;human_count&amp;quot;: 1, &amp;quot;monthly_burn_usd&amp;quot;: 23625, &amp;quot;leverage_ratio&amp;quot;: 5.0 },
  &amp;quot;team&amp;quot;: { &amp;quot;name&amp;quot;: &amp;quot;...&amp;quot;, &amp;quot;purpose&amp;quot;: &amp;quot;...&amp;quot;, &amp;quot;members&amp;quot;: [&amp;quot;...&amp;quot;], &amp;quot;owner&amp;quot;: &amp;quot;operator&amp;quot; },
  &amp;quot;humans&amp;quot;: [ { &amp;quot;id&amp;quot;: &amp;quot;operator&amp;quot;, &amp;quot;title&amp;quot;: &amp;quot;Founder / Operator&amp;quot;, &amp;quot;mandate&amp;quot;: &amp;quot;...&amp;quot;, &amp;quot;kpis&amp;quot;: [&amp;quot;...&amp;quot;] } ],
  &amp;quot;workers&amp;quot;: [
    {
      &amp;quot;worker_key&amp;quot;: &amp;quot;strategy_positioning_lead&amp;quot;,
      &amp;quot;name&amp;quot;: &amp;quot;Strategy &amp;amp; Positioning Lead&amp;quot;,
      &amp;quot;role&amp;quot;: &amp;quot;strategist&amp;quot;,
      &amp;quot;kind&amp;quot;: &amp;quot;digital_worker&amp;quot;,
      &amp;quot;system_message&amp;quot;: &amp;quot;&amp;lt;worker_identity&amp;gt;...generated starter prompt...&amp;lt;/worker_identity&amp;gt;&amp;quot;,
      &amp;quot;model_class&amp;quot;: &amp;quot;reasoning&amp;quot;,
      &amp;quot;tools&amp;quot;: [&amp;quot;...&amp;quot;], &amp;quot;kpis&amp;quot;: [&amp;quot;...&amp;quot;], &amp;quot;reports_to&amp;quot;: &amp;quot;operator&amp;quot;
    }
  ],
  &amp;quot;org_chart_mermaid&amp;quot;: &amp;quot;graph TD\n  ...&amp;quot;,
  &amp;quot;provisioning&amp;quot;: {
    &amp;quot;status&amp;quot;: &amp;quot;pending_human_approval&amp;quot;,
    &amp;quot;note&amp;quot;: &amp;quot;Nothing in this bundle is provisioned. The receiving platform must
             present it for explicit human approval before creating anything.&amp;quot;
  }
}
"&gt;&lt;CODE&gt;{
  "format": "campaign.workforce_bundle",
  "version": 1,
  "company": { "summary": "...", "operating_model": "...", "source": "pitch" },
  "economics": { "headcount": 6, "digital_worker_count": 5,
                 "human_count": 1, "monthly_burn_usd": 23625, "leverage_ratio": 5.0 },
  "team": { "name": "...", "purpose": "...", "members": ["..."], "owner": "operator" },
  "humans": [ { "id": "operator", "title": "Founder / Operator", "mandate": "...", "kpis": ["..."] } ],
  "workers": [
    {
      "worker_key": "strategy_positioning_lead",
      "name": "Strategy &amp;amp; Positioning Lead",
      "role": "strategist",
      "kind": "digital_worker",
      "system_message": "&amp;lt;worker_identity&amp;gt;...generated starter prompt...&amp;lt;/worker_identity&amp;gt;",
      "model_class": "reasoning",
      "tools": ["..."], "kpis": ["..."], "reports_to": "operator"
    }
  ],
  "org_chart_mermaid": "graph TD\n  ...",
  "provisioning": {
    "status": "pending_human_approval",
    "note": "Nothing in this bundle is provisioned. The receiving platform must
             present it for explicit human approval before creating anything."
  }
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Three design choices make it portable:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;A generated &lt;CODE&gt;system_message&lt;/CODE&gt; per worker, same shape for every role&lt;/STRONG&gt; - so a receiving platform (or its own org-architect agent) can parse, refine, and version it instead of re-deriving prompts.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;A &lt;CODE&gt;model_class&lt;/CODE&gt; hint (&lt;CODE&gt;reasoning&lt;/CODE&gt; / &lt;CODE&gt;fast&lt;/CODE&gt; / &lt;CODE&gt;creative&lt;/CODE&gt;)&lt;/STRONG&gt;, not a hard model name - the receiver maps it onto its own fleet.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;A &lt;CODE&gt;provisioning.status&lt;/CODE&gt; of &lt;CODE&gt;pending_human_approval&lt;/CODE&gt;&lt;/STRONG&gt; baked into the artifact itself. The bundle carries its own gate: the game's verification-gate pattern (Part 2), extended across the system boundary.&lt;/LI&gt;
&lt;/OL&gt;
&lt;img /&gt;&lt;!-- mermaid source:
flowchart TB
    ORG[&amp;quot;OrgBlueprint (game state)&amp;quot;] --&amp;gt; CONV[&amp;quot;org_to_workforce_bundle()&amp;quot;]
    CONV --&amp;gt; B[&amp;quot;workforce_bundle.json&amp;quot;]
    B --&amp;gt; CO[&amp;quot;company + economics&amp;quot;]
    B --&amp;gt; HU[&amp;quot;humans[] (operator)&amp;quot;]
    B --&amp;gt; WK[&amp;quot;workers[]&amp;lt;br/&amp;gt;system_message, model_class,&amp;lt;br/&amp;gt;tools, kpis, reports_to&amp;quot;]
    B --&amp;gt; MM[&amp;quot;org_chart_mermaid&amp;quot;]
    B --&amp;gt; PV[&amp;quot;provisioning.status =&amp;lt;br/&amp;gt;pending_human_approval&amp;quot;]
--&gt;
&lt;H2&gt;Every worker carries its own starter prompt&lt;/H2&gt;
&lt;P&gt;The single most portable field is &lt;CODE&gt;system_message&lt;/CODE&gt;. Every worker - whatever its role - gets a generated starter prompt in the &lt;EM&gt;same&lt;/EM&gt; XML shape, so a receiving platform (or its own org-architect agent) can parse, refine, and version it instead of re-deriving prompts from scratch:&lt;/P&gt;
&lt;PRE class="language-python" tabindex="0" contenteditable="false" data-lia-code-value="# submission/tools/export_org_blueprint.py - _system_message
return (
    f&amp;quot;&amp;lt;worker_identity&amp;gt;\n&amp;quot;
    f&amp;quot;  &amp;lt;role&amp;gt;{role.get('title')}&amp;lt;/role&amp;gt;\n&amp;quot;
    f&amp;quot;  &amp;lt;mission&amp;gt;{role.get('mandate', '')}&amp;lt;/mission&amp;gt;\n&amp;quot;
    f&amp;quot;  &amp;lt;reports_to&amp;gt;{reports_to}&amp;lt;/reports_to&amp;gt;\n&amp;quot;
    f&amp;quot;  &amp;lt;kpis&amp;gt;{kpis}&amp;lt;/kpis&amp;gt;\n&amp;quot;
    f&amp;quot;  &amp;lt;guardrails&amp;gt;\n&amp;quot;
    f&amp;quot;    - Work only within this mandate; escalate judgment calls to {reports_to}.\n&amp;quot;
    f&amp;quot;    - No legal or financial commitments without explicit human approval.\n&amp;quot;
    f&amp;quot;  &amp;lt;/guardrails&amp;gt;\n&amp;quot;
    f&amp;quot;&amp;lt;/worker_identity&amp;gt;&amp;quot;
)
"&gt;&lt;CODE&gt;# submission/tools/export_org_blueprint.py - _system_message
return (
    f"&amp;lt;worker_identity&amp;gt;\n"
    f"  &amp;lt;role&amp;gt;{role.get('title')}&amp;lt;/role&amp;gt;\n"
    f"  &amp;lt;mission&amp;gt;{role.get('mandate', '')}&amp;lt;/mission&amp;gt;\n"
    f"  &amp;lt;reports_to&amp;gt;{reports_to}&amp;lt;/reports_to&amp;gt;\n"
    f"  &amp;lt;kpis&amp;gt;{kpis}&amp;lt;/kpis&amp;gt;\n"
    f"  &amp;lt;guardrails&amp;gt;\n"
    f"    - Work only within this mandate; escalate judgment calls to {reports_to}.\n"
    f"    - No legal or financial commitments without explicit human approval.\n"
    f"  &amp;lt;/guardrails&amp;gt;\n"
    f"&amp;lt;/worker_identity&amp;gt;"
)
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Those guardrails are not decoration. Every exported worker ships with "no legal or financial commitments without explicit human approval" baked into its own identity - the human gate is written into the worker's prompt, not just the bundle's status field.&lt;/P&gt;
&lt;H2&gt;The org chart travels as text&lt;/H2&gt;
&lt;P&gt;There is a fitting symmetry with this whole series, which has leaned on Mermaid for every diagram: the bundle ships the org chart &lt;EM&gt;as Mermaid source&lt;/EM&gt;, generated by &lt;CODE&gt;org_to_mermaid&lt;/CODE&gt;. A receiver can render it, diff it, or hand it to a model - it is text, not a picture:&lt;/P&gt;
&lt;PRE class="language-python" tabindex="0" contenteditable="false" data-lia-code-value="# submission/tools/export_org_blueprint.py - org_to_mermaid
lines = [&amp;quot;graph TD&amp;quot;]
lines.append(&amp;quot;  classDef human fill:#f6d55c,stroke:#5b8cff,stroke-width:3px&amp;quot;)
lines.append(&amp;quot;  classDef digital fill:#3caea3,stroke:#2dd4bf&amp;quot;)
for role in roles:
    cls = &amp;quot;human&amp;quot; if role[&amp;quot;kind&amp;quot;] == &amp;quot;human&amp;quot; else &amp;quot;digital&amp;quot;
    lines.append(f'  n_{_slug(role[&amp;quot;id&amp;quot;])}[&amp;quot;{title}&amp;quot;]:::{cls}')
for role in roles:                       # reporting lines
    if role.get(&amp;quot;reports_to&amp;quot;):
        lines.append(f&amp;quot;  n_{_slug(role['reports_to'])} --&amp;gt; n_{_slug(role['id'])}&amp;quot;)
"&gt;&lt;CODE&gt;# submission/tools/export_org_blueprint.py - org_to_mermaid
lines = ["graph TD"]
lines.append("  classDef human fill:#f6d55c,stroke:#5b8cff,stroke-width:3px")
lines.append("  classDef digital fill:#3caea3,stroke:#2dd4bf")
for role in roles:
    cls = "human" if role["kind"] == "human" else "digital"
    lines.append(f'  n_{_slug(role["id"])}["{title}"]:::{cls}')
for role in roles:                       # reporting lines
    if role.get("reports_to"):
        lines.append(f"  n_{_slug(role['reports_to'])} --&amp;gt; n_{_slug(role['id'])}")
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Humans and digital workers get different CSS classes, so the rendered chart shows at a glance who is a person and who is a digital worker - the same human/digital distinction the economics priced, carried into the picture.&lt;/P&gt;
&lt;H2&gt;The economics travel with the org&lt;/H2&gt;
&lt;P&gt;A workforce plan that does not say what it costs is a wish list. The bundle carries an &lt;CODE&gt;economics&lt;/CODE&gt; block - headcount, digital-worker count, human count, monthly burn, and a leverage ratio - computed by the game's &lt;CODE&gt;worker_economics&lt;/CODE&gt; model when the org was designed, not invented at export time:&lt;/P&gt;
&lt;PRE class="language-json" tabindex="0" contenteditable="false" data-lia-code-value="&amp;quot;economics&amp;quot;: {
  &amp;quot;headcount&amp;quot;: 6, &amp;quot;digital_worker_count&amp;quot;: 5, &amp;quot;human_count&amp;quot;: 1,
  &amp;quot;monthly_burn_usd&amp;quot;: 23625, &amp;quot;monthly_inference_usd&amp;quot;: 1200, &amp;quot;leverage_ratio&amp;quot;: 5.0
}
"&gt;&lt;CODE&gt;"economics": {
  "headcount": 6, "digital_worker_count": 5, "human_count": 1,
  "monthly_burn_usd": 23625, "monthly_inference_usd": 1200, "leverage_ratio": 5.0
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Each worker also carries its own &lt;CODE&gt;monthly_cost_usd&lt;/CODE&gt;, so a receiving platform can show a real budget before it provisions anything - one human operator leveraging five digital workers at a burn a solo founder could actually carry. That leverage ratio (digital workers per human) is the headline number the whole game is about: how much execution one person can direct. Exporting it means the off-ramp inherits the argument, not just the boxes and arrows.&lt;/P&gt;
&lt;H2&gt;Pricing the workforce&lt;/H2&gt;
&lt;P&gt;Those numbers are not vibes. &lt;CODE&gt;submission/agents/worker_economics.py&lt;/CODE&gt; prices each seat from the human salary it replaces - a deliberate game-balance fraction, so burn is a constraint the player actually feels rather than a rounding error:&lt;/P&gt;
&lt;PRE class="language-python" tabindex="0" contenteditable="false" data-lia-code-value="# submission/agents/worker_economics.py
WORKER_COST_FRACTION_OF_HUMAN = 0.75   # a worker costs 3/4 of the human it replaces

def worker_cost_from_human(human_median_usd):
    return int(round(max(0, human_median_usd) * WORKER_COST_FRACTION_OF_HUMAN))
"&gt;&lt;CODE&gt;# submission/agents/worker_economics.py
WORKER_COST_FRACTION_OF_HUMAN = 0.75   # a worker costs 3/4 of the human it replaces

def worker_cost_from_human(human_median_usd):
    return int(round(max(0, human_median_usd) * WORKER_COST_FRACTION_OF_HUMAN))
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Each worker's &lt;CODE&gt;monthly_cost_usd&lt;/CODE&gt; is three quarters of the present-world salary for that seat; the much cheaper real compute (&lt;CODE&gt;inference_usd&lt;/CODE&gt;) is tracked separately for the efficiency story. Sum the workers and you get &lt;CODE&gt;monthly_burn_usd&lt;/CODE&gt;; divide digital workers by human operators and you get &lt;CODE&gt;leverage_ratio&lt;/CODE&gt;. When a receiving platform reads the bundle, those are the figures it shows before provisioning - a real budget for one operator running a digital team, derived the same way whether the org was designed on Foundry or in simulation.&lt;/P&gt;
&lt;H2&gt;The export endpoint and the button&lt;/H2&gt;
&lt;P&gt;The bridge is one endpoint and one button. &lt;CODE&gt;GET /api/org/export&lt;/CODE&gt; reads the chartered org from state, converts it, logs an &lt;CODE&gt;ORG_EXPORTED&lt;/CODE&gt; event to the replay log (Part 4), and returns the bundle as a download. The Digital Workforce panel in the UI has an &lt;STRONG&gt;Export workforce bundle&lt;/STRONG&gt; button that calls it - so "you played the game; now your org is a deployable workforce" is one click.&lt;/P&gt;
&lt;PRE class="language-python" tabindex="0" contenteditable="false" data-lia-code-value="@app.get(&amp;quot;/api/org/export&amp;quot;)
def export_org():
    state = store.load()
    if not state.org or not state.org.roles:
        raise HTTPException(status_code=404, detail=&amp;quot;No chartered org to export.&amp;quot;)
    bundle = org_to_workforce_bundle(state.org.model_dump())
    store.log_event(&amp;quot;ORG_EXPORTED&amp;quot;, &amp;quot;org_designer&amp;quot;,
                    f&amp;quot;Exported {len(bundle['workers'])} workers, pending approval.&amp;quot;)
    return JSONResponse(content=bundle,
        headers={&amp;quot;Content-Disposition&amp;quot;: 'attachment; filename=&amp;quot;workforce_bundle.json&amp;quot;'})
"&gt;&lt;CODE&gt;@app.get("/api/org/export")
def export_org():
    state = store.load()
    if not state.org or not state.org.roles:
        raise HTTPException(status_code=404, detail="No chartered org to export.")
    bundle = org_to_workforce_bundle(state.org.model_dump())
    store.log_event("ORG_EXPORTED", "org_designer",
                    f"Exported {len(bundle['workers'])} workers, pending approval.")
    return JSONResponse(content=bundle,
        headers={"Content-Disposition": 'attachment; filename="workforce_bundle.json"'})
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Because the converter is dependency-free, it also runs from the command line with no server and no credentials:&lt;/P&gt;
&lt;PRE class="language-bash" tabindex="0" contenteditable="false" data-lia-code-value="python3 submission/tools/export_org_blueprint.py \
  --pitch &amp;quot;Low-cost 3D-printed solar cells for off-grid homes&amp;quot;
# -&amp;gt; workforce_bundle.json : 5 digital workers + 1 human, pending approval
"&gt;&lt;CODE&gt;python3 submission/tools/export_org_blueprint.py \
  --pitch "Low-cost 3D-printed solar cells for off-grid homes"
# -&amp;gt; workforce_bundle.json : 5 digital workers + 1 human, pending approval
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H2&gt;The CLI: same converter, no server&lt;/H2&gt;
&lt;P&gt;Because the converter is pure, the same &lt;CODE&gt;org_to_workforce_bundle&lt;/CODE&gt; function powers a no-server CLI - &lt;CODE&gt;export_org_blueprint.py&lt;/CODE&gt; - which can either read a saved game state or design a fresh org from a pitch and export it, all in simulation, no credentials:&lt;/P&gt;
&lt;PRE class="language-python" tabindex="0" contenteditable="false" data-lia-code-value="# submission/tools/export_org_blueprint.py - _main
if args.pitch:
    from agents.org_designer import design_org
    org = design_org(args.pitch, source=&amp;quot;pitch&amp;quot;, source_ref=args.pitch)
else:
    org = json.load(open(state_path)).get(&amp;quot;org&amp;quot;) or {}   # from a played game
bundle = org_to_workforce_bundle(org)
print(json.dumps(bundle, indent=2))
"&gt;&lt;CODE&gt;# submission/tools/export_org_blueprint.py - _main
if args.pitch:
    from agents.org_designer import design_org
    org = design_org(args.pitch, source="pitch", source_ref=args.pitch)
else:
    org = json.load(open(state_path)).get("org") or {}   # from a played game
bundle = org_to_workforce_bundle(org)
print(json.dumps(bundle, indent=2))
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;That one entry point is the whole forkability story for the bridge: &lt;CODE&gt;--pitch "..."&lt;/CODE&gt; designs an org and prints a deployable workforce bundle on a fresh clone, with no Azure, no server, and no platform SDK anywhere in the path. The endpoint and the CLI share the exact same converter, so what you can click in the live app you can also pipe in a shell.&lt;/P&gt;
&lt;H2&gt;Best practice: the receiver re-gates, the bundle is a draft&lt;/H2&gt;
&lt;P&gt;A portable bundle is an &lt;EM&gt;input&lt;/EM&gt;, not an order. On the receiving side, the right pattern is an org-architect worker that treats the bundle as a &lt;STRONG&gt;draft blueprint&lt;/STRONG&gt;: it maps each entry's &lt;CODE&gt;model_class&lt;/CODE&gt; onto the platform's current model tiers, matches incoming worker mandates against existing templates (reuse before invent), re-renders the org chart in its own conventions, fills gaps the game did not model (departments, OKR cascades), and then presents the result for explicit human approval - exactly the CEO-gate pattern, one system later.&lt;/P&gt;
&lt;P&gt;That symmetry is the point. The game gates artifacts behind a human; the bundle declares itself pending; the receiver gates provisioning behind a human. The human-at-the-root law (Part 2) survives the trip across the boundary.&lt;/P&gt;
&lt;img /&gt;&lt;!-- mermaid source:
flowchart LR
    G1[&amp;quot;Game CEO gate&amp;lt;br/&amp;gt;(Part 2)&amp;quot;] --&amp;gt; B[&amp;quot;bundle:&amp;lt;br/&amp;gt;pending_human_approval&amp;quot;]
    B --&amp;gt; RCV[&amp;quot;Receiving platform&amp;lt;br/&amp;gt;org-architect worker&amp;quot;]
    RCV --&amp;gt; MAP[&amp;quot;map model_class -&amp;gt; fleet&amp;lt;br/&amp;gt;reuse templates, fill gaps&amp;quot;]
    MAP --&amp;gt; G2[&amp;quot;Receiver human gate&amp;quot;]
    G2 --&amp;gt; PROV[&amp;quot;provision workers,&amp;lt;br/&amp;gt;teams, KPIs&amp;quot;]
--&gt;
&lt;H2&gt;Why this matters beyond the game&lt;/H2&gt;
&lt;P&gt;A reasoning agent that only produces prose is a better chatbot. A reasoning agent that produces a &lt;STRONG&gt;structured, portable, gated plan another system can execute&lt;/STRONG&gt; is the beginning of an operating loop. The game is a teaching tool and a playable argument; the bundle is the off-ramp where the argument becomes useful - the designed workforce stops being a screen and becomes something a platform can stand up, behind its own approval gate.&lt;/P&gt;
&lt;H2&gt;Responsible AI&lt;/H2&gt;
&lt;P&gt;The bundle is inert by construction. Its &lt;CODE&gt;provisioning.status&lt;/CODE&gt; is &lt;CODE&gt;pending_human_approval&lt;/CODE&gt; and its note says, in the artifact itself, that nothing is provisioned until a human signs off. Nothing in it is executable on import; it is a description, not a command. Combined with the receiver re-gating provisioning, that means no chain of automated steps can stand up a workforce without a person in the loop - the same reliability story this whole series is built on, carried one boundary further.&lt;/P&gt;
&lt;H2&gt;The whole series, in one artifact&lt;/H2&gt;
&lt;P&gt;It is worth seeing the bundle as the place every earlier post converges. The org inside it was &lt;EM&gt;decomposed&lt;/EM&gt; from a pitch (Part 1) and designed on a Foundry model. Every artifact that filled it out passed a human &lt;EM&gt;verification gate&lt;/EM&gt; (Part 2). The CEO decisions that shaped which workers exist are the &lt;EM&gt;binding memory&lt;/EM&gt; the workforce learned from (Part 3). The whole thing was produced by a stack that runs &lt;EM&gt;local-first and fully traced&lt;/EM&gt;, so the &lt;CODE&gt;ORG_EXPORTED&lt;/CODE&gt; event sits in the same replay log as everything that led to it (Part 4). And now it leaves the game as a portable, gated plan (Part 5). The bundle is not a feature bolted on at the end; it is the receipt for the entire loop.&lt;/P&gt;
&lt;H2&gt;Where this lives in the repo&lt;/H2&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Concern&lt;/th&gt;&lt;th&gt;File&lt;/th&gt;&lt;th&gt;Key symbol&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Pure offline converter + CLI&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;submission/tools/export_org_blueprint.py&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;org_to_workforce_bundle&lt;/CODE&gt;, &lt;CODE&gt;_system_message&lt;/CODE&gt;, &lt;CODE&gt;org_to_mermaid&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Export endpoint + replay event&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;submission/tools/server.py&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;GET /api/org/export&lt;/CODE&gt;, &lt;CODE&gt;ORG_EXPORTED&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;The org being exported&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;submission/agents/org_designer.py&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;design_org&lt;/CODE&gt;, &lt;CODE&gt;OrgBlueprint&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2&gt;Try it&lt;/H2&gt;
&lt;P&gt;Charter an org in the game, then export it:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;A class="lia-external-url" href="https://worldforge-game.agreeableground-34b354cf.eastus2.azurecontainerapps.io/" target="_blank" rel="noopener"&gt;Play the live app&lt;/A&gt;&lt;/STRONG&gt; -&amp;gt; design your workforce -&amp;gt; &lt;STRONG&gt;Export workforce bundle&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Or from the CLI, no credentials:&lt;/P&gt;
&lt;PRE class="language-bash" tabindex="0" contenteditable="false" data-lia-code-value="git clone https://github.com/princepspolycap/agentsleague-afterbuild
cd agentsleague-afterbuild &amp;amp;&amp;amp; python3 -m venv .venv &amp;amp;&amp;amp; source .venv/bin/activate
pip install -r submission/requirements.txt
python3 submission/tools/export_org_blueprint.py --pitch &amp;quot;Your idea here&amp;quot;
"&gt;&lt;CODE&gt;git clone https://github.com/princepspolycap/agentsleague-afterbuild
cd agentsleague-afterbuild &amp;amp;&amp;amp; python3 -m venv .venv &amp;amp;&amp;amp; source .venv/bin/activate
pip install -r submission/requirements.txt
python3 submission/tools/export_org_blueprint.py --pitch "Your idea here"
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H2&gt;Key takeaways&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;The most useful agent output is a structured plan another system can execute, not prose.&lt;/LI&gt;
&lt;LI&gt;Bridge by export, not import: emit a neutral, versioned bundle; keep proprietary platforms out of the reasoning repo.&lt;/LI&gt;
&lt;LI&gt;Carry the human gate across the boundary - the bundle declares itself &lt;CODE&gt;pending_human_approval&lt;/CODE&gt;, and the receiver re-gates provisioning.&lt;/LI&gt;
&lt;LI&gt;Use a &lt;CODE&gt;model_class&lt;/CODE&gt; hint, not a hard model name, so the receiver maps onto its own fleet.&lt;/LI&gt;
&lt;LI&gt;One endpoint, one button: "you played the game; now your org is a deployable workforce."&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The dungeon is open, the workforce is designed, and now it is portable. A mission too big to command gets aligned one company at a time - and the org you charter in a browser game can walk out as a plan a real platform will run, with a human still holding the seal.&lt;/P&gt;
&lt;HR /&gt;
&lt;P&gt;&lt;EM&gt;Part 5 of 5. Start over at Part 1, or clone the repo and pitch your own company.&lt;/EM&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Play it: &lt;A class="lia-external-url" href="https://worldforge-game.agreeableground-34b354cf.eastus2.azurecontainerapps.io/" target="_blank" rel="noopener"&gt;worldforge-game...azurecontainerapps.io&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Code: &lt;A href="https://github.com/princepspolycap/agentsleague-afterbuild" target="_blank" rel="noopener"&gt;github.com/princepspolycap/agentsleague-afterbuild&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Live battle replay: &lt;A href="https://www.youtube.com/watch?v=Xj5LqH6k0U4" target="_blank" rel="noopener"&gt;Agents League - Reasoning Agents&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Thu, 02 Jul 2026 08:25:44 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/educator-developer-blog/from-game-to-operations-exporting-a-foundry-designed-workforce/ba-p/4530300</guid>
      <dc:creator>Princeps</dc:creator>
      <dc:date>2026-07-02T08:25:44Z</dc:date>
    </item>
  </channel>
</rss>

