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) anddeployment-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.pngfor a Copilot shot). ALWAYSviewthe actual pixels; never judge by filename. This bit us repeatedly — it's the #1 rule. - After placing every webp,
viewit and write a one-line pixel observation + verdict (✅ MATCH / ⚠️ PARTIAL / ❌ MISMATCH) to the session'simage-audit-<date>.md. The written artifact is the compliance proof, not a verbal "I checked." - Large webps (>~1500px wide) fail the
viewtool ("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 withImage.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.
- Search the current month + previous two months using the discovery gate in
whats-new-copilot-pack-playbook.md. - Extract every roundup image URL and Microsoft-provided alt text before selecting any.
- Build an inventory with:
- source article + image URL;
- published/modified date;
- Microsoft-owned provenance;
- literal pixel observation written while viewing;
- intended blog section;
USE / SKIP+ reason;- required demo/official-image variance caption.
- Vision-review every
USEcandidate withview. Microsoft alt text helps discovery but is not proof of what the pixels show. - 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_searchbefore 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:… autoto 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.mjsafter 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 changedid="…"heading + itshref="#…"link both exist.check-blog-htmlpassing ≠ rendered-correct until you check the surface. - Orphan cleanup: after swaps,
grepthe 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 pushin 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.