Skip to content

Copilot Monthly Blog — Screenshots & Vision-QA Playbook

Read this BEFORE capturing/placing screenshots for any monthly "What's New in M365 Copilot" recap blog. Distilled from the July 2026 recap (a ~40-image, 31-section session, 23 Jul 2026). Companion to whats-new-copilot-pack-playbook.md (the PPTX pack) and deployment-playbook.md. Sibling deliverable: the recap blog post (this doc) → then the pack + LinkedIn carousel are built from the same shots.


0. The workflow that works (Sush's preferred rhythm)

Go section-by-section in blog order (1→N), one feature at a time: 1. Atlas states what the feature is + what's changing (so Sush confirms understanding). 2. Sush captures a new shot OR Atlas reviews the existing one. 3. Atlas fixes/tweaks the notes if reality differs from the draft text. 4. Place → annotate → vision-QA → validate → move on.

Track progress in a SQL table (blog_sections: num, title, img_status, existing_imgs, review_verdict, notes) — gives instant "X of N done" visibility and a clean handoff. Worked great.

Deliver in small confirmable steps. Sush drops shots as he captures; grab the newest Downloads\*.png after a timestamp, don't re-scan everything.


1. Capture & verification (Rule #8 — never skip)

  • 🔴 Filenames LIE. Greenshot names files with the stale/active window title (e.g. ...-Notepad.png for a Copilot shot). ALWAYS view the actual pixels; never judge by filename. This bit us repeatedly — it's the #1 rule.
  • After placing every webp, view it and write a one-line pixel observation + verdict (✅ MATCH / ⚠️ PARTIAL / ❌ MISMATCH) to the session's image-audit-<date>.md. The written artifact is the compliance proof, not a verbal "I checked."
  • Large webps (>~1500px wide) fail the view tool ("Failed to view"). Render a downscaled PNG first: python -c "from PIL import Image; im=Image.open(r'<src>').convert('RGB'); w,h=im.size; im=(im.resize((1200,int(h*1200/w))) if w>1200 else im); im.save(r'$env:TEMP\_qa.png')" → view _qa.png.
  • Find newest captures fast: Get-ChildItem Downloads\*.png | Where LastWriteTime -gt <ts> | Sort LastWriteTime. Exclude your own temp files (_annot*, _comp*, _zoom*, _inspect*).

2. Annotation house style

  • Red = (222,45,38), width 3px, rounded (ImageDraw.rounded_rectangle([x0,y0,x1,y1], radius=8, outline=(222,45,38), width=3)). Box the single key element the section is about (the new model, the "Submit" option, the setting name, the toggle).
  • Verify placement by viewing the annotated PNG BEFORE converting to webp. Boxes often need 1–2 coordinate iterations (a box landed one text-line too low; a crop cut the icon in half). Cheap to redo, ugly if shipped.
  • Convert: Image.open(src).convert('RGB').save(dest,'WEBP',quality=88,method=6).
  • Tiny shots (taskbar icons, ~180px): don't ship them raw. Inspect at 6× zoom first to find the exact icon bounds (I cut the running icon in half by cropping x62 when it started at x40), then build a labeled composite — two states side-by-side (e.g. "Running — live gradient" / "Complete — green tick") on a dark canvas with Segoe UI labels (C:/Windows/Fonts/segoeui.ttf). Scale icons to equal height with Image.LANCZOS.
  • Paint out distractions (an error toast, an MCP-connection-failed banner) by sampling the bg pixel (im.getpixel()) and filling a rectangle with it — blends seamlessly on flat backgrounds.

3. PII discipline (tenant shots leak real data)

  • Mask corp emails (paint white/bg rectangle over user@microsoft.com), neutralise avatars (grey ellipse over the face), crop names off people-result lists. Watch for the signed-in real account appearing in Copilot Studio / share dialogs.
  • Demo-tenant fictional names (Emily Davis, Contoso, Zava, agent names) are fine. First name in a greeting ("Ready when you are, Susanth") is fine (author's own).
  • Never bundle full name + email + role in one visible shot.

4. When the feature ISN'T in Sush's tenant

Order of preference: 1. Search internal first — glob prior monthly-recap image folders (static/images/blog/copilot-<month>-2026/, m365-agent-builder/, etc.). We reused the scheduled-prompt config dialog and found a share-agents-teams shot from past blogs (Sush's own content — zero copyright risk). 2. Search external for an OFFICIAL Microsoft image — Microsoft-owned/marketing images (recognisable by the Zava/Contoso demo brand, "Preview" badges, marketing polish). Use with an official-* filename + alt="Official Microsoft image…". 3. Add an honest disclaimer caption when using a borrowed/official shot because the feature isn't in the tenant: <p style="font-size:0.9rem;opacity:0.8;border-left:3px solid var(--border);padding:… "><em>…hadn't rolled out to my demo tenant yet, so the screenshot is Microsoft's own — not one of mine.</em></p> - 🔴 REJECT third-party bloggers' screenshots (e.g. an MVP's capture that shows their copyrighted book/content). Copyright risk on a monetised blog; a disclaimer does NOT fix it. Sush initially picked one of these — flag it, offer the official alternative.

Official monthly-roundup image gate — mandatory from August 2026

The official Tech Community monthly roundup is an image source in its own right. Do not wait until a colleague sends it after publication.

  1. Search the current month + previous two months using the discovery gate in whats-new-copilot-pack-playbook.md.
  2. Extract every roundup image URL and Microsoft-provided alt text before selecting any.
  3. Build an inventory with:
  4. source article + image URL;
  5. published/modified date;
  6. Microsoft-owned provenance;
  7. literal pixel observation written while viewing;
  8. intended blog section;
  9. USE / SKIP + reason;
  10. required demo/official-image variance caption.
  11. Vision-review every USE candidate with view. Microsoft alt text helps discovery but is not proof of what the pixels show.
  12. Re-run the image inventory if the roundup's modified date changes.

June 2026 tuition: Microsoft's late roundup contained 30 first-party images. It published six days after Sush's June recap and changed again on 14 July. The future workflow therefore checks at month-end, +7, +14 and the next monthly run.

5. Accuracy reconciliation (fix the notes when reality differs)

  • UI name ≠ release-note name: the PowerPoint picker showed "MAI Image 2.5 Flash" but the release note said "MAI-Image-2-Efficient" (different models in the same family). Options: (A) match the UI, (B) keep the release-note name + a note, (C) neutral title + name both in body ← Sush's pick. Verify the official name via microsoft_docs_search before deciding.
  • 🔴 Verify "is it coming" BEFORE writing "coming soon" (Rule #13). Sush assumed Share-to-a-Teams-team was "a separate feature coming in future"; the roadmap showed it's GA (March 2026), just rolling out. Correct disclaimer = "rolling out, appears in this same dialog," NOT "future." Fast roadmap lookup: web_fetch https://mc.merill.net/message/RM<id> returns clean roadmap text incl. the GA date (much easier than the JS-heavy roadmap site).

6. Editorial calls

  • Under-representation > misleading (Rule #8): if a shot doesn't match the section, remove it rather than keep it. We removed a "Claude-in-Excel" image from the Agents roundup — it illustrated neither bullet. Leave a section text-only rather than force a wrong/generic shot.
  • Same prompt, different annotation is a legit way to illustrate two adjacent features (Teams-meeting ref boxed for #8, style-reuse ref boxed for #9 — same underlying shot).
  • Pair prompt→result where it tells the story (Agent Mode prompt + finished deck; brand-kit picker + on-brand output).
  • Portrait/phone shots: cap width so they don't dominate — max-width:340px (phone), 400–480px (narrow panels/composites), display:block; margin:… auto to centre.

7. "Fade off" reorder (image-less sections to the end)

Sush likes the blog to fade from image-rich → text-only. Group the no-image sections at the tail. - Usually only 1–2 sections are out of place (the rest are already at the end). Move them + renumber the H2 headings. - Renumbering changes the auto-generated anchors (## 24. Title#24-title). You MUST update every Quick-Jump / cross-ref link to the changed anchors. - Hugo/goldmark anchor rule: lowercase, drop punctuation (periods removed → "2.5"→"25"), spaces→hyphens, em-dash " — " → double-hyphen "--". - Filename≠section-number is fine after a reorder (e.g. lab-25-defender-agents under section #24). Don't rename — the blog refs by filename; renaming is cosmetic + risky.

8. Validation (every time)

  • node scripts\check-blog-html.mjs after EVERY image placement and after the reorder — it validates alt text, src file existence, and Quick-Jump anchor resolution. Must be 0 errors.
  • Verify anchors on the LIVE preview (Rule #14): fetch http://localhost:1314/blog/<slug>/ and confirm each changed id="…" heading + its href="#…" link both exist. check-blog-html passing ≠ rendered-correct until you check the surface.
  • Orphan cleanup: after swaps, grep the blog for the old filename → confirm 0 references → then delete. Deleted 6 orphans this session safely.

9. Rules that always apply

  • STAGED ONLY — Sush reviews before any deploy (Rule #2 / #14). No git push in the screenshot phase.
  • Plain English, no jargon — it's Sush's voice (mum / 12-yo test).
  • Ask before adding new content sections (credits, notes) — but fixing notes to match reality is expected and welcome.

10. Two-phase handoff pattern

This work spans sessions. Write a handoff with: current state, the section→image map, disclaimers/captions to check, the webp-view gotcha, validation commands, and the kickoff line. Save alongside image-audit-<date>.md. A deep SME + fresh-eyes vision-QA pass is best done in a fresh-context session after the placement session (context fills up fast on a 40-image run).


Set 23 Jul 2026 from the July recap. Update after each monthly run with any new gotcha.