Run Copilot
like a control room

Which model to switch to and what it costs, how to stand up a small crew of agents that prep your meetings and compile your work, and how to stop your Power BI reports from looking like defaults.

Prepared forDigital transformation advisor
ToolGitHub Copilot app (desktop)
ConstraintNo MCP connectors
Docs current as of21 Aug 2026

Part one

The operating manual

Billing, model switching, session modes, and the agent crew that preps your meetings.

Start here

Four things to know before you touch a setting

1. The app is a place to run agents, not a chat window. The Copilot desktop app is built for agent-driven work: you can run several agent sessions at once, each on its own branch, and pick the model and the level of autonomy per session.

2. You are billed by tokens now, not by "requests." On 1 June 2026 every Copilot plan moved to usage-based billing with GitHub AI Credits. One credit is one cent. Every model has a published per-million-token rate for input, output, and cached tokens.

3. Inline code completions are still free. Completions and next-edit suggestions are not billed in credits on paid plans. Only chat, agents, CLI, code review and similar features draw down credits.

4. Model choice is the single biggest cost lever you control. Cheapest to priciest on the menu is roughly 40× on output tokens. Everything else in this manual is downstream of that one habit.

Watch the meter

How the money actually works

A token is roughly three quarters of a word. Everything the model reads is input tokens, everything it writes is output tokens, and repeated context can be cached at a lower rate. Output is always the expensive side — usually 5–6× the input rate.

Your plan comes with a monthly allowance of credits. When it runs out, additional usage bills at the same published rates if your organization allows it, or stops if a budget cap is set.

PlanMonthly costIncluded AI creditsNotes
Pro$10$15Unlimited completions; light chat and agent use.
Pro+$39$70For heavy individual agent use.
Max$100$200Only worth it if agents run for hours daily.
Business$19 / user$19 / user, pooledMost corporate seats. Credits pool across the org.
Enterprise$39 / user$39 / user, pooledAdds SSO and admin controls.
Find out what you're actually on

You are almost certainly on a company Business or Enterprise seat, so your credits come from a shared pool and your admin may have set a budget. Ask two questions before you build anything ambitious: what is our monthly credit budget per user, and is additional paid usage enabled or hard-capped? That answer sets the ceiling on how many scheduled agents you can responsibly run.

Pick a model

The cost dial

A shortlist of what you'll actually reach for, positioned by price per million output tokens — the number that moves your bill. Every model and every rate is in the Model catalog tab.

Output rate, $ per 1M tokens Log scale · GitHub published rates, Aug 2026
$1
$5
$10
$25
$50
GPT-5.6 Luna$1.20
GPT-5.4 nano$1.25
GPT-5 mini$2.00
Gemini 3.7 Flash$3.75
GPT-5.4 mini$4.50
Claude Haiku 4.5$5.00
Grok 4.6$6.00
Claude Sonnet 5$10.00
GPT-5.6 Terra$12.00
GPT-5.3-Codex$14.00
GPT-5.4 / 5.6 Sol$15.00
Claude Opus 5$25.00
GPT-5.5$30.00
Claude Fable 5$50.00

Input rates run roughly one fifth of output. Two promotions are live: GPT-5.6 Sol at half price through 3 Sep 2026, and Gemini 3.6 / 3.7 Flash at reduced rates through 31 Dec 2026.

Which one for which job

Your taskUseWhy
Tidy notes, rename files, reformat a table, quick "what does this mean"GPT-5.6 Luna
GPT-5.4 nano
Lightweight work at a fraction of a cent. Never spend a frontier model on formatting.
Draft a status update, summarize a meeting, write a first-pass emailGPT-5 mini
Claude Haiku 4.5
Fast, competent prose. Good enough that you edit rather than rewrite.
Everyday agent runs: weekly digest, triage a list, follow a checklistClaude Sonnet 5
GPT-5.6 Terra
Grok 4.6
All three are classed as general-purpose coding and agent models. Your workhorse tier.
Reading a long document set and pulling out the through-lineGemini 3.1 ProBuilt for long context and technical analysis. Watch the long-context tier above 200K input tokens.
Writing or fixing Python, DAX, M, SQLGPT-5.3-Codex
Claude Sonnet 5
Codex is tuned for agentic engineering work and lands complex changes without long instructions.
Hard thinking: a vendor comparison, an architecture call, a business case you'll defendClaude Opus 5
GPT-5.6 Sol
Deep reasoning tier. Reach for it deliberately, on a fresh session, once you know what you're asking.
Long autonomous runs where you won't be watchingClaude Fable 5Built for first-attempt correctness over long horizons. Also the fastest way to burn a month of credits — set a session limit first.
Not sureAutoCopilot routes to a suitable model and paid plans get a discount on model cost for using it. The correct default.
The habit that matters

Start on Auto or a cheap model. Escalate only when the answer disappoints you. Most people do the reverse — pin the most powerful model and leave it there for a month. Escalating costs you one re-run; defaulting high costs you every run.

Steer the session

Modes, effort, and knowing when to stop

Each session has three dials: the model, the reasoning effort, and the autonomy mode. The modes matter as much as the model.

ModeWhat happensUse it when
Quick chatA conversation with no branch or workspace attached.Scoping and questions. Cheapest way to think out loud.
PlanThe agent writes a plan and waits for approval before acting.Anything unfamiliar or expensive. Catching a wrong plan costs one cheap turn.
InteractiveYou and the agent work together, step by step.Work where your judgment is part of the loop.
AutopilotThe agent runs to completion on its own.Only for tasks you've already run manually and trust. Pair with a cheaper model and a credit limit.

Three moves that save real money

  • Start a fresh session when you switch tasks. Context carries forward and you pay to re-read it every turn.
  • Let agents run to completion. Inside a run, the tool calls the agent makes on its own are part of the run — it's your prompts that start the meter. Ten interruptions cost more than one good brief.
  • Run /chronicle cost tips weekly. The app will tell you where your own usage is expensive.

Set up the shop

Give yourself a workspace the agents can see

The Copilot app works on repositories — folders of files tracked by Git. It has no idea what your job is until something is written down in a folder it can read. So the first build is not an agent. It's a private repository that acts as your work brain.

work-brain/ — folder layout
work-brain/
├── AGENTS.md                  # who you are, how you want output written
├── context/
│   ├── portfolio.md           # your initiatives, one section each
│   ├── stakeholders.md        # who cares about what, and how they like it
│   └── glossary.md            # your company's acronyms and systems
├── inbox/                     # raw paste-ins: notes, exports, transcripts
├── log/                       # your running work record
├── briefs/                    # agent output: meeting prep, digests
└── .github/
    └── agents/                # your agent definitions live here
        ├── meeting-prep.agent.md
        ├── weekly-digest.agent.md
        └── intake.agent.md

The AGENTS.md file at the root is read by every agent, every session. Highest-leverage file you will write.

AGENTS.md
# Working context

I am a digital transformation advisor at an oil and gas operator.
My audience is a mix of operations leaders, engineers, and IT.
I am not a software engineer — explain technical choices in plain language.

## How to write for me
- Lead with the decision or the answer. No throat-clearing.
- Short paragraphs. Bullets only when the content is genuinely a list.
- Flag assumptions explicitly. If a source is missing, say so — never invent
  a number, a date, a name, or a system of record.
- Use our terms from context/glossary.md. Spell out an acronym on first use.

## Standing rules
- Never write anything to files outside this repository.
- Never include personal data, credentials, or anything marked confidential
  in generated output.
- When you summarize, cite the file in inbox/ or log/ you took it from.

## Files worth reading before you start
- context/portfolio.md — what I'm currently working on
- context/stakeholders.md — who I write for
- log/ — my running record, newest file is most relevant

Build the crew

Three agents that earn their keep

A custom agent is a markdown file with a short header. It gives Copilot a role, a limited set of tools, and a fixed model. Commit it to your default branch and it appears in the picker.

Restricting tools isn't fussiness — an agent that can't edit files can't wreck anything, and it costs less because it does less. The model line is how you stop a routine job from silently running on your most expensive model.

1. Intake — turns a mess into a usable note

.github/agents/intake.agent.md
---
name: intake
description: Cleans raw pasted notes, transcripts, and exports into a
  structured note filed under log/, with decisions and actions pulled out.
tools: ["read", "search", "edit"]
model: GPT-5 mini
---

You normalize raw material into a consistent note. You never editorialize
and you never add facts that are not in the source.

When given a file in inbox/:

1. Read it in full before writing anything.
2. Produce a new file in log/ named YYYY-MM-DD-slug.md with this structure:

   # <Title> — <date>
   **Source:** <inbox filename>  **Attendees / origin:** <if stated>

   ## What happened
   Three to six sentences of plain summary.

   ## Decisions
   - Decision — who made it — date if known

   ## Actions
   - [ ] Action — owner — due date if known

   ## Open questions
   - Question — who can answer it

   ## Unclear
   - Anything ambiguous in the source. Do not resolve it yourself.

3. Leave the original file in inbox/ untouched.

If a section has no content, write "None recorded." Never guess an owner
or a date.

2. Meeting prep — the one you'll use every day

.github/agents/meeting-prep.agent.md
---
name: meeting-prep
description: Builds a one-page prep brief for a specific upcoming meeting
  from the work log, the portfolio, and stakeholder notes.
tools: ["read", "search", "edit"]
model: Claude Sonnet 5
---

You prepare me to walk into a meeting without re-reading everything.

Ask for the meeting name and attendees if I have not given them. Then read
context/stakeholders.md, context/portfolio.md, and the three most recent
files in log/ that mention the same topic or people.

Write briefs/YYYY-MM-DD-<meeting-slug>.md, one page maximum:

## Where we left off
Three sentences. What was agreed last time and what has moved since.

## What each person walks in caring about
One line per attendee, drawn from stakeholders.md. If someone is not in
that file, say "no prior context on file" — do not speculate.

## What I owe them
Open commitments from log/ where I am the owner, with the date promised.

## What they owe me
Open commitments where someone else is the owner, and how overdue.

## Three questions worth asking
Specific to this meeting. Not generic.

## Risks I should be ready for
Only risks evidenced in the log. Name the file each one came from.

Hard rules: no filler, no restating the agenda back to me, every claim
traceable to a file. If the log is thin on this topic, say so in one line
at the top instead of padding the brief.

3. Weekly digest — the "what have I been doing" machine

.github/agents/weekly-digest.agent.md
---
name: weekly-digest
description: Compiles the week's log files into a status update written for
  leadership, plus a short private list of what slipped.
tools: ["read", "search", "edit"]
model: Claude Sonnet 5
---

You compile, you do not embellish.

Read every file in log/ dated within the last seven days, plus
context/portfolio.md for initiative names and framing.

Write briefs/YYYY-Www-digest.md with two clearly separated parts.

PART ONE — Send-ready update (aim for 250 words)
Written for an operations leader who has fifteen seconds. Organized by
initiative, not chronologically. Each item: what moved, what it unblocks,
what happens next. Outcomes, not activity. No adjectives.

PART TWO — For my eyes only
- Commitments I made that I have not delivered, with days elapsed
- Items that appeared two weeks running with no movement
- Anything I flagged as a risk that no one has picked up

Never invent progress. If an initiative had no activity this week, list it
under a short "No movement" heading rather than dressing up old news.
Where these files go

Easiest path: in the app or on GitHub, open the agents view and choose Create an agent — it scaffolds a file in .github/agents/. Rename it, paste the content, commit to your default branch, and it shows up in the dropdown. Creating the files by hand works the same.

Put it on a timer

Automations: the agent runs without you

An automation is a saved prompt with a trigger — hourly, daily, weekly, or on a repository event. In the app: Automations tab, then New automation. You set the name, prompt, trigger, allowed tools, and model. Tokens bill to whoever created it, so a badly scoped daily automation is a standing order against your credit pool.

Before it will work
  • The repository must be private or internal. Not available on public repos.
  • Copilot cloud agent must be enabled for that repository.
  • On a Business or Enterprise seat, an admin may need to enable it first.

Three worth setting up, in order

Automation 1 — Monday 07:00, weekly · model: Claude Sonnet 5
Using the weekly-digest agent, compile last week's log files into
briefs/ following the agent's format exactly. Open a pull request titled
"Weekly digest — week of <date>" so I can review it before it counts as
final. If fewer than two log files exist for the period, stop and open the
PR with a single line saying the log is empty for that week.
Automation 2 — daily 06:30 · model: GPT-5 mini
Check inbox/ for files added in the last 24 hours that have no matching
note in log/. For each one, run the intake agent to produce the structured
note. Do not modify anything already in log/. If inbox/ has nothing new,
do nothing and end the run.
Automation 3 — Friday 15:00, weekly · model: GPT-5 mini
Scan log/ for every unchecked action item where I am the owner. Produce
briefs/open-commitments.md as a single table: item, who I promised it to,
date promised, days elapsed, and the source file. Sort by days elapsed,
oldest first. Overwrite the previous version. Add no commentary.
Sequence, not enthusiasm

Run each by hand three or four times before scheduling it. You will rewrite the prompt every one of those times. A scheduled automation producing mediocre output isn't neutral — it costs credits weekly and trains you to ignore its output.

Work around the wall

Feeding it your work without connectors

No MCP connectors means Copilot cannot reach into your mail, calendar, Teams, or SharePoint. The honest framing is a division of labor:

  • Microsoft 365 Copilot is your retrieval layer. It already has sanctioned access to your mail, meetings, and documents. Use it to gather and summarize.
  • The GitHub Copilot app is your production layer. It holds your accumulated context, runs the agents, keeps history, does the scheduled work.

The bridge is a copy-paste habit that takes about ten minutes a week.

The Friday ritual

  1. In M365 Copilot, ask for a summary of your meetings and mail for the week — decisions, commitments, open questions, with dates and owners.
  2. Paste it into inbox/ as a dated markdown file. Raw is fine; that's what intake is for.
  3. Add what M365 can't see: hallway conversations, your judgment calls, what you think is actually going on.
  4. Run intake, then the digest. Read Part Two before Part One.
Prompt for M365 Copilot — weekly harvest
Summarize my meetings and email from the past 7 days as a plain markdown
list, grouped by topic rather than by day. For each topic give me:

- Decisions made, with who made them and the date
- Commitments, with the owner and the date promised
- Open questions and who can answer them
- Anything that changed from a previous week

Use only what's in my mail and meetings. Where something is ambiguous, say
so rather than resolving it. No summary paragraph, no recommendations —
just the structured list.
Check this before you paste anything

You're moving company content from one sanctioned system into another system's storage. In oil and gas that question has real answers attached — production data, JV terms, safety incidents, personal data, anything export-controlled.

  • Confirm with IT or security that storing work content in a private GitHub repo under your company's organization is approved. Get it in writing.
  • Use a repo owned by the company organization, not your personal account. Private or internal only.
  • Keep names, credentials, and identifiable personal data out of what you paste.
  • Ask whether content exclusion rules are configured for your org and whether they cover this repo.

If the answer is no, the approach still works on your own non-confidential material: your notes, plans, drafts, judgment. That's most of the value anyway.

Keep the meter honest

Cost discipline, condensed

Do
  • Default to Auto; it routes sensibly and paid plans get a discount for using it.
  • Scope in a quick chat before opening a full session.
  • Use Plan mode for anything you haven't done before.
  • Pin a cheap model in every scheduled automation.
  • Start a new session per task.
  • Write one clear brief instead of ten corrections.
  • Set a credit limit on long autonomous sessions.
  • Run /chronicle cost tips every Friday.
Don't
  • Leave the most powerful model pinned as your default.
  • Run a frontier model on formatting or renaming.
  • Keep one giant session open all week.
  • Schedule an automation you haven't run manually several times.
  • Point a long-context model at a huge pile of files "just in case" — long-context tiers cost double.
  • Turn on automatic code review across repos without knowing the per-run cost.
  • Assume anything on this page is still accurate in three months.

A rough sense of scale

A meeting prep brief that reads ~15,000 tokens of context and writes ~1,200 tokens costs roughly 4 cents on Claude Sonnet 5 and roughly 9 cents on Claude Opus 5. Neither matters alone. Run it twice a day on the expensive model with a bloated session and you're at real money by month end — that's the actual failure mode. Use the estimator in the Model catalog tab to check your own numbers.

Four weeks

A ramp that doesn't overwhelm you

  1. Learn the dials

    Install the app. Do your normal work in quick chats only. Run the same question on a cheap model and an expensive one and notice where the difference actually shows up — for a lot of your work, it won't. Ask your admin about the credit budget.

  2. Build the workspace

    Create the private repo, write AGENTS.md and context/portfolio.md by hand. Paste a week of raw notes into inbox/. No agents yet.

  3. Add two agents

    Commit intake and meeting-prep. Run them manually before every meeting for a week. Edit the agent files as you go — fixing the prompt is the actual work.

  4. Schedule the boring parts

    Add weekly-digest. Schedule the two automations you've already proven by hand. Run /chronicle cost tips, look at your month's usage, decide what to cut. Then stop building and just use it.

Plain terms

Glossary

Token
A chunk of text, roughly ¾ of a word. Billing is measured in millions of them.
Context
Everything the model can see for one request: your prompt, the files it read, the conversation so far.
AI credit
GitHub's billing unit. One credit = one cent.
Repository (repo)
A tracked folder of files. Your workspace and your agents both live in one.
Branch
A parallel copy of the folder where work happens safely before it's accepted.
Pull request (PR)
A proposal to accept changes from a branch, with a review step. Your approval gate for agent output.
Agent
A model given a role, tools, and permission to act rather than just answer.
Custom agent
A markdown file in .github/agents/ defining one of those roles.
Automation
A saved agent task with a trigger, so it runs on a schedule or an event.
MCP
Model Context Protocol — the standard way to plug an AI tool into an outside system. Blocked at your company, hence the manual bridge.
Reasoning effort
A per-session dial for how much internal deliberation the model does. More effort, better hard answers, more output tokens.

Part two

Model catalog

All 31 models GitHub publishes a rate for, with a cost estimator for your own workload.

Every model, every rate

What a job costs, across the whole menu

Describe one typical task and the table below prices it on every model GitHub publishes a rate for. Adjust the numbers and the last two columns re-calculate live.

Rough token conversion: 1,000 tokens ≈ 750 words ≈ 1.5 pages of plain text. An agent run that reads a dozen files easily hits 50,000+ input tokens. Estimates ignore cache-write charges and any long-context tier, so treat them as a floor, not a quote.

Sort
ModelClassInputCached in Cache writeOutputYour runYour month
OpenAI
GPT-5 miniLightweight$0.250$0.025$2.00$0.0061$0.246
GPT-5.3-CodexPowerful$1.75$0.175$14.00$0.043$1.72
GPT-5.4
Long context >272K: 5.00 / 22.50
Versatile$2.50$0.250$15.00$0.055$2.22
GPT-5.4 miniLightweight$0.750$0.075$4.50$0.017$0.666
GPT-5.4 nanoLightweight$0.200$0.020$1.25$0.0045$0.180
GPT-5.5
Long context >272K: 10.00 / 45.00
Powerful$5.00$0.500$30.00$0.111$4.44
GPT-5.6 Luna
Long context >200K: 0.40 / 1.80
Lightweight$0.200$0.020$0.250$1.20$0.0044$0.178
GPT-5.6 Sol
Promo −50% to 3 Sep 2026 · long >272K: 5.00 / 22.50
Powerful$2.50$0.250$3.12$15.00$0.055$2.22
GPT-5.6 Terra
Long context >272K: 4.00 / 18.00
Versatile$2.00$0.200$2.50$12.00$0.044$1.78
Anthropic
Claude Haiku 4.5Versatile$1.00$0.100$1.25$5.00$0.021$0.840
Claude Sonnet 4Versatile$3.00$0.300$3.75$15.00$0.063$2.52
Claude Sonnet 4.5Versatile$3.00$0.300$3.75$15.00$0.063$2.52
Claude Sonnet 4.6Versatile$3.00$0.300$3.75$15.00$0.063$2.52
Claude Sonnet 5Versatile$2.00$0.200$2.50$10.00$0.042$1.68
Claude Opus 4.5Powerful$5.00$0.500$6.25$25.00$0.105$4.20
Claude Opus 4.6Powerful$5.00$0.500$6.25$25.00$0.105$4.20
Claude Opus 4.7Powerful$5.00$0.500$6.25$25.00$0.105$4.20
Claude Opus 4.8Powerful$5.00$0.500$6.25$25.00$0.105$4.20
Claude Opus 5Powerful$5.00$0.500$6.25$25.00$0.105$4.20
Claude Opus 4.8 fast mode
Preview
Powerful$10.00$1.00$12.50$50.00$0.210$8.40
Claude Fable 5Powerful$10.00$1.00$12.50$50.00$0.210$8.40
Google
Gemini 3.1 Pro
Public preview · long >200K: 4.00 / 18.00
Powerful$2.00$0.200$12.00$0.044$1.78
Gemini 3.5 FlashLightweight$1.50$0.150$9.00$0.033$1.33
Gemini 3.6 Flash
Promo rate to 31 Dec 2026
Versatile$0.750$0.075$3.75$0.016$0.630
Gemini 3.7 Flash
Promo rate to 31 Dec 2026
Versatile$0.750$0.075$3.75$0.016$0.630
xAI
Grok 4.5
Long context >200K: 4.00 / 12.00
Versatile$2.00$0.500$6.00$0.037$1.49
Grok 4.6
Long context >200K: 4.00 / 12.00
Versatile$2.00$0.500$6.00$0.037$1.49
Microsoft
MAI-Code-1-FlashLightweight$0.750$0.075$4.50$0.017$0.666
MAI-Code-1.1-FlashLightweight$0.200$0.020$1.20$0.0044$0.178
GitHub
Raptor miniVersatile$0.250$0.025$2.00$0.0061$0.246
Moonshot AI
Kimi K2.7 CodeVersatile$0.950$0.190$4.00$0.019$0.762
Kimi K3
See GitHub's model-specific safety note
Powerful$3.00$0.300$15.00$0.063$2.52

All rates in USD per 1 million tokens, from GitHub's published pricing table, retrieved 21 Aug 2026. "—" means no separate charge is published for that column.

How to read it

Notes on the fine print

Long-context tiers

Several models charge a second, higher rate once a single request's input crosses a threshold — 272K tokens for GPT-5.4, GPT-5.5, GPT-5.6 Sol and Terra; 200K for GPT-5.6 Luna, Gemini 3.1 Pro, Grok 4.5 and 4.6. The long-context rate is typically double. This is the trap behind "just point it at the whole folder."

Cache write

Anthropic models and the GPT-5.6 family charge a one-time premium to write context into cache, then a steep discount to read it back. Long sessions that reuse the same files come out ahead; sessions that touch different files each turn just pay the premium.

Promotions running now

  • GPT-5.6 Sol — 50% off standard rates through 3 September 2026. The rates in the table are the promotional ones.
  • Gemini 3.6 and 3.7 Flash — promotional rates through 31 December 2026.

What isn't priced here

Inline code completions and next-edit suggestions don't consume credits at all. Copilot code review is billed differently — token consumption in credits plus GitHub Actions minutes, and the model it uses isn't disclosed, so its per-review cost varies. Qwen2.5 appears in GitHub's model comparison but not on the published rate table; if it shows in your picker, check the rate before leaning on it.

What your admin controls

Which models appear in your picker is a policy setting. If GPT-5.4 and Codex are in your list but Fable 5 isn't, that's your enterprise policy, not an outage. Same goes for preview models like Gemini 3.1 Pro.

Sensible pairings

Four default setups

Rather than choosing fresh every time, pick a standing pair and only deviate deliberately.

SituationWorking modelEscalate toWhy this pair
Writing and summarizing all dayGPT-5 miniClaude Sonnet 5Ten-to-one cost gap, and mini handles most prose. Escalate when structure or nuance breaks down.
Scripting: Python, DAX, M, SQLGPT-5.3-CodexClaude Opus 5Codex is tuned for engineering work. Escalate when a bug survives two attempts.
Scheduled automationsGPT-5 mini or GPT-5.6 LunaNever escalate an unattended job. If it needs a better model, it needs your attention instead.
Thinking work you'll be judged onClaude Opus 5 or GPT-5.6 SolAlready the top. Control cost by scoping in a quick chat first, then opening one clean session.
One number worth memorizing

At 15,000 input and 1,200 output tokens, a single run costs about 0.6 cents on GPT-5 mini and about 10.5 cents on Claude Fable 5. Not a reason to avoid the expensive models — a reason to know which one you're on.

Part three

Power BI design

Why AI-built reports look plain, Injae Park's method, and the copy-paste kit to fix it.

The plainness problem

Why AI-built reports come out looking like defaults

When you ask an agent to rebuild a Power BI report, it does the part it can see: get the data in, build the measures, drop in visuals that answer the question. What it skips is everything that makes a report feel like a product — because that lives in five separate layers the agent was never pointed at.

The designers whose work looks like an app aren't using secret visuals. They're doing the same five things every time, in the same order. Most of it is one-time setup you reuse forever.

The reframe

Stop asking the agent to "make it look better." That's a taste instruction with nowhere to land. Instead, give it a theme file, a grid, and a component spec, and ask it to conform to them. Design becomes a constraint the agent can satisfy rather than an opinion it has to guess at.

The anatomy

The five layers of an app-like report

  1. Grid and canvas

    Set the page size deliberately (16:9 at 1280×720 is standard; go custom for a tall scrolling page). Then work on an 8-pixel grid with consistent outer padding — visuals aligned to a grid read as designed even when nothing else changes. Turn on Maintain layer order under General → Properties → Advanced so buttons stop jumping in front of charts when clicked, and turn off visual header icons across the board unless a specific visual needs them.

  2. Theme JSON — the highest-leverage hour you'll spend

    A theme file sets colors, fonts, corner radius, shadows, gridline behavior, and default formatting for every visual type, everywhere, forever. Most "plain" reports are plain because nobody wrote one. This is also the single easiest thing to hand to Copilot: it's a JSON file, and generating structured JSON from a spec is exactly what these models are good at. Starter file in the kit below.

  3. The frame — background instead of borders

    Pro dashboards mostly aren't drawing card borders in Power BI. They design the whole page frame — panels, section headers, sidebar, soft shadows — in Figma or PowerPoint, export it as one image, and set it as the canvas background at "Fit." Visuals sit on top with transparent backgrounds. That's the trick behind the app look. Keep live text out of the background image so it stays searchable and editable.

  4. Navigation and state

    This is what makes it feel like software rather than a slide. Page navigator and bookmark navigator for tabs; buttons with distinct default, hover, and pressed states; a slide-out filter panel built with two bookmarks; modal pop-ups for detail; drill-through for the deep dive. Microsoft's own training module for this is literally called "design reports that behave like apps."

  5. Signature visuals

    Where the personality comes from. Three tiers, in order of governance friendliness: SVG measures in native visuals (no custom visual required, works in table, matrix, new card, button slicer, image), Deneb for anything Vega-Lite can draw, and certified AppSource visuals last. Check your tenant's custom-visual policy before designing around anything from AppSource — many energy companies block uncertified visuals outright, and SVG measures sail past that entirely.

The person you're thinking of

Injae Park's actual method

The creator you're describing is Injae Park — @PowerBIPark on YouTube, Microsoft Data Platform MVP, Power BI World Championship finalist, and he posts sample files on GitHub. His conference sessions tell you exactly what the method is, and it's narrower than it looks from the outside:

  • SVGs inside native visuals. Custom chart shapes drawn as SVG and rendered inside ordinary tables, matrices, and cards — no custom visual, no AppSource approval.
  • LLM-generated SVGs. He doesn't hand-write the vector math. He describes the graphic and lets a model produce the SVG, then wires it into DAX. This is the part that's directly transferable to your Copilot setup.
  • Automation over repetition. C# scripts in Tabular Editor to generate SVG measures in bulk and set default properties, so a design system gets applied across a model rather than one measure at a time.
  • AI for the grunt work. Bulk measure creation, DAX documentation, mock datasets for prototyping — plus a clear-eyed view of where AI stops being useful.

Worth internalizing: the interactivity you're seeing is mostly bookmarks and buttons, and the polish is mostly theme plus background plus SVG. It reads as an app because those two things are done thoroughly, not because there's a hidden visual you don't have.

Copy-paste kit

Start with these four files

A. Theme starter

Save as theme.json, then View → Themes → Browse for themes. Swap the palette for your company colors. If the import errors, it's almost always a JSON syntax slip — paste the error back into Copilot and it'll fix it.

theme.json
{
  "name": "Ops Standard",
  "dataColors": ["#2C6C77","#F2B705","#9E4B2C","#4E93A0","#6B7F8C","#C6D0D6"],
  "background": "#F4F6F7",
  "foreground": "#131E27",
  "tableAccent": "#2C6C77",
  "textClasses": {
    "title":     { "fontFace": "Segoe UI Semibold", "fontSize": 14, "color": "#131E27" },
    "label":     { "fontFace": "Segoe UI", "fontSize": 10, "color": "#41535F" },
    "callout":   { "fontFace": "Segoe UI Light", "fontSize": 32, "color": "#131E27" }
  },
  "visualStyles": {
    "*": {
      "*": {
        "background":   [{ "show": true, "color": { "solid": { "color": "#FFFFFF" } }, "transparency": 0 }],
        "border":       [{ "show": true, "color": { "solid": { "color": "#E3E9EC" } }, "radius": 10 }],
        "dropShadow":   [{ "show": true, "preset": "BottomRight" }],
        "visualHeader": [{ "show": false }],
        "title":        [{ "show": true, "fontSize": 13, "fontColor": { "solid": { "color": "#131E27" } },
                           "alignment": "left" }],
        "padding":      [{ "top": 8, "bottom": 8, "left": 10, "right": 10 }]
      }
    },
    "card": {
      "*": { "labels": [{ "fontSize": 30 }], "categoryLabels": [{ "fontSize": 10 }] }
    },
    "columnChart": {
      "*": { "valueAxis": [{ "gridlineShow": false }], "categoryAxis": [{ "showAxisTitle": false }] }
    },
    "lineChart": {
      "*": { "valueAxis": [{ "gridlineShow": true, "gridlineColor": { "solid": { "color": "#EDF0F2" } } }] }
    }
  }
}

B. SVG progress bar — in any table or matrix row

Create the measure, then select it and set Measure tools → Data category → Image URL. Without that step it renders as text. Drop it into a table column.

DAX — Progress Bar SVG
Progress Bar SVG =
VAR _Pct     = DIVIDE( [Actual], [Target] )
VAR _Clamped = MIN( MAX( _Pct, 0 ), 1 )
VAR _Width   = 220 * _Clamped
VAR _Color   = SWITCH( TRUE(),
                   _Pct >= 1,    "%232C6C77",   -- teal   (%23 is an encoded #)
                   _Pct >= 0.8,  "%23F2B705",   -- amber
                                 "%239E4B2C" )  -- rust
VAR _Label   = FORMAT( _Pct, "0%" )
RETURN
"data:image/svg+xml;utf8," &
"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 280 28'>" &
    "<rect x='0' y='6' width='220' height='16' rx='8' fill='%23E3E9EC'/>" &
    "<rect x='0' y='6' width='" & _Width & "' height='16' rx='8' fill='" & _Color & "'/>" &
    "<text x='230' y='19' font-family='Segoe UI' font-size='13' fill='%2341535F'>" &
        _Label &
    "</text>" &
"</svg>"

C. SVG delta indicator — arrow plus variance in one cell

DAX — Delta Arrow SVG
Delta Arrow SVG =
VAR _Delta = DIVIDE( [This Period] - [Last Period], [Last Period] )
VAR _Up    = _Delta >= 0
VAR _Color = IF( _Up, "%232C6C77", "%239E4B2C" )
VAR _Path  = IF( _Up, "M8 3 L14 12 L2 12 Z", "M8 13 L14 4 L2 4 Z" )
VAR _Label = FORMAT( ABS( _Delta ), "0.0%" )
RETURN
"data:image/svg+xml;utf8," &
"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 90 16'>" &
    "<path d='" & _Path & "' fill='" & _Color & "'/>" &
    "<text x='20' y='13' font-family='Segoe UI' font-size='12' fill='" & _Color & "'>" &
        _Label &
    "</text>" &
"</svg>"

Escaping note: inside DAX you're already in double quotes, so use single quotes for SVG attributes, and encode # in hex colors as %23 — unencoded hashes are the most common reason an SVG measure silently fails to render.

D. Prompts that produce usable output

These work in Copilot chat, the Copilot app, or M365 Copilot. The pattern in all of them: give the model the constraint, the exact output format, and the acceptance test.

Prompt — generate a theme from a brand
Write a Power BI theme JSON file for an operations dashboard.

Constraints:
- Primary #2C6C77, accent #F2B705, alert #9E4B2C, neutral greys for everything else
- Segoe UI throughout; titles 13pt left-aligned, labels 10pt
- White visual containers, 10px corner radius, subtle bottom-right shadow
- Visual headers hidden by default
- No gridlines on column charts; faint gridlines on line charts
- Data colors ordered so the first three are distinguishable in greyscale

Output only the JSON, no explanation. It must import into Power BI Desktop
without error — validate the structure before you answer, and use only
properties that current Power BI theme files support.
Prompt — generate an SVG measure
Write a Power BI DAX measure that returns an SVG data URI for use in a
table column with Data Category set to Image URL.

The graphic: a horizontal bullet chart, 240x24 viewBox. Grey track, a
filled bar for [Actual] scaled against [Target], a thin vertical black
tick at the target position, and the variance percentage as text on the
right in 12px Segoe UI.

Rules:
- Prefix with "data:image/svg+xml;utf8,"
- Single quotes for all SVG attributes
- Encode every # in a hex colour as %23
- Handle blank and negative values without erroring
- Use VAR statements and comment each one

Return the DAX only.
Prompt — critique an existing report page
I'm attaching a screenshot of a Power BI page. Review it as a dashboard
designer, not as a data analyst.

Assess: visual hierarchy, alignment to a grid, use of colour, typography
consistency, chart-type fit, cognitive load, and whether the eye lands on
the right thing first.

Give me a numbered list of concrete changes, each one specific enough to
implement in Power BI in under five minutes. Order them by impact per
minute of effort. No compliments, no general design theory.

The unlock

PBIR: your reports are now editable code

This is the part that connects both halves of this manual, and most people haven't caught up to it yet.

Power BI reports used to be an opaque binary. Now, in the PBIR format inside a Power BI Project (.pbip), every visual, page, and bookmark is its own JSON file in a folder — each one validated against a published schema — with the semantic model alongside it as TMDL text files. It became the default for new reports in the Power BI Service in January 2026 and in Desktop from the March 2026 release, with full general availability expected later in 2026.

Which means: a Power BI report is now a repository your Copilot agents can read and edit. Restyling forty visuals to a new standard stops being forty manual edits and becomes one agent task with a diff you review in a pull request. People are already building AI skills that understand the PBIR schema and generate report pages from prompts.

.github/agents/pbir-stylist.agent.md
---
name: pbir-stylist
description: Applies our report design standard across the JSON files of a
  Power BI project in PBIR format. Never touches data, measures, or queries.
tools: ["read", "search", "edit"]
model: Claude Sonnet 5
---

You enforce a design standard across a Power BI project saved in PBIR
format. You are editing JSON, not designing from scratch.

Scope — you may edit only files under the .Report folder. You must never
modify anything under .SemanticModel, and never change a visual's fields,
filters, measures, or queries. Layout and formatting only.

The standard, from design/standard.md:
- 8px grid: every visual x, y, width, height is a multiple of 8
- Outer page padding 24px, gutter between visuals 16px
- Visual headers off; titles 13pt, left aligned, sentence case
- No visual-level colour overrides — colours come from the theme file
- Card visuals aligned in a single row across the top of the page

Method:
1. Read design/standard.md and the page JSON before changing anything.
2. List every deviation you found, grouped by page, before you edit.
3. Make the edits, one page at a time, preserving the schema declaration
   at the top of each file.
4. Open a pull request with a summary table: page, visual, what changed.

If a change would alter what the visual displays rather than how it looks,
skip it and note it in the PR instead.
Ground rules before you point an agent at a report
  • Work on a copy. Converting to PBIR is one-way — keep a backup of the original file.
  • The report must be in a Git repository so every agent edit is a reviewable diff you can revert.
  • Open the result in Power BI Desktop and click through every page before publishing. Schema-valid JSON is not the same as a working report.
  • Confirm your tenant hasn't opted out of PBIR, and check with your BI team before introducing a code-first workflow into a shared workspace.

Before you ship

Twelve-point polish pass

Run this on any report before it goes to a leader. Most items take under a minute and together they account for most of the gap between "an analyst made this" and "someone designed this."

Layout and type
  • Every visual snapped to the grid; equal gutters
  • One type family, three sizes maximum
  • Titles in sentence case, left aligned, consistent height
  • Numbers formatted and abbreviated consistently (1.2M, not 1,234,567 in one card and 1.2M in another)
  • Nothing overlapping or clipped at 100% zoom
  • The most important number is the largest thing on the page
Colour and behaviour
  • Colour used for meaning only — no rainbow categories
  • One accent colour, and it points at the thing that matters
  • Gridlines and axis lines dialled down or removed
  • Every chart legible in greyscale
  • Buttons have hover states; navigation works on every page
  • Tooltips customized on at least the primary visuals
Fastest single upgrade

If you only do one thing: write the theme file and remove chart junk (gridlines, axis titles, redundant legends, default headers). That alone moves a report most of the distance, and it costs you an hour once rather than an hour per report.

Where to go next

Sources worth your time

Part four

The memory bank

How to make the brain repo remember your work well enough that a project from four months ago can be demoed tomorrow.

The core idea

Two layers, and never confuse them

The instinct is to save everything into one pile. That fails twice over: it gets expensive to read (you pay tokens for every irrelevant file an agent opens) and it gets useless to search, because raw material buries the conclusions.

A memory bank that actually works has two layers with different rules.

LayerWhat it isRuleWho writes it
The log log/ — dated notes, one per event. What happened, when, who said what. Append-only. Never edited, never reorganized. It's evidence. Intake agent, from raw material
The dossiers memory/projects/ — one living file per project. What it is, why you built it that way, how to demo it. Rewritten continuously. Always reflects current truth, not history. Scribe agent, from the log, reviewed by you

The log answers "what happened on 8 May." The dossier answers "what is this thing and how do I explain it." You need both, and the dossier is the one that saves you in four months.

On top of those sits a third thing that isn't really a layer — memory/INDEX.md, a single table of every project with a one-line description. It exists so an agent can read one small file to decide which dossiers are worth opening. That's the whole token-economics trick from Part two applied to your own memory: cheap map first, expensive territory second.

The test for whether a memory is worth keeping

Would you want to read this line in six months, in a conversation about something else? Decisions, constraints, results, and "why we rejected the other option" pass. Status updates, meeting logistics, and the fact that you had a call on Tuesday do not — those live in the log and expire there.

The shape

What gets added to the brain repo

This extends the work-brain layout from Part one. Everything new is under memory/.

work-brain/ — with the memory bank added
work-brain/
├── AGENTS.md
├── context/
│   ├── portfolio.md
│   ├── stakeholders.md
│   └── glossary.md
├── inbox/                     # raw paste-ins, cleared after processing
├── log/                       # append-only dated notes  (LAYER 1)
│   └── 2026-08-21-ops-sync.md
├── memory/                    # curated, living memory   (LAYER 2)
│   ├── INDEX.md               # the map — every project, one line each
│   ├── projects/
│   │   ├── anomaly-detection.md
│   │   ├── work-order-automation.md
│   │   └── historian-migration.md
│   ├── decisions/             # why you chose what you chose
│   │   └── 2026-05-02-adr-anomaly-baseline-method.md
│   ├── people/                # working context on recurring collaborators
│   └── archive/               # retired projects, compressed to one page
├── briefs/                    # agent output: prep, digests, deck outlines
└── .github/
    └── agents/
        ├── intake.agent.md
        ├── meeting-prep.agent.md
        ├── weekly-digest.agent.md
        ├── scribe.agent.md        # keeps dossiers current
        ├── recall.agent.md        # answers "what did I do about X"
        ├── archivist.agent.md     # monthly consolidation + pruning
        └── deck-builder.agent.md  # dossier to slide outline

The dossier template

Fixed structure matters more than good writing here. A consistent schema is what lets an agent reliably find the demo script four months from now. The front matter is machine-readable; the body is for you.

memory/projects/anomaly-detection.md
---
id: anomaly-detection
title: ESP pump anomaly detection prototype
status: shipped              # exploring | building | shipped | paused | retired
started: 2026-04-08
last_touched: 2026-08-14
tags: [python, time-series, reliability, pilot]
systems: [historian, power-bi]
stakeholders: [maintenance-superintendent, reliability-lead]
repos: [ops-anomaly-detector]
one_liner: Flags abnormal vibration patterns on ESP pumps roughly two weeks
  before failure, using historian tag data and a seasonal-decomposition baseline.
---

## Problem it solves
Two or three sentences. What was broken before this existed, and who felt it.

## What I built
Five bullets maximum, plain language. The version you would say out loud.

## How it works
The walkthrough, one step per stage: where data comes in, what transforms it,
where the output lands, who consumes it. Name the actual systems and tables.

## Key decisions
Link to the ADR files. One line each on what was chosen and what was rejected.

## Results
Numbers if you have them, with the date and the source. "Caught 3 of 4 failures
in the June pilot" is worth more in six months than any description.

## Demo script — 5 minutes
1. Open with the problem, in the audience's language
2. Show <the thing to show>, click <the thing to click>
3. The one slide or screen that lands the value
4. Known limits, stated before anyone asks
5. What it would take to scale it

## What broke / gotchas
The things you'd forget and get burned by. Data quality issues, edge cases,
the tag that's mislabelled in the historian.

## Open threads
What's unfinished and what would come next.

## Where things live
Repo, folder, dashboard URL, the notebook, who else has access.
The field that does the heavy lifting

Demo script. Write it while the project is fresh, even in rough form. It's the single hardest thing to reconstruct later and the exact thing you get asked for. Everything else in the dossier can be rebuilt from the log; this one is pure judgment that only exists in your head.

memory/INDEX.md
# Project index

Read this first. Open a dossier only if the one-liner matches the question.

| id | title | status | last touched | one-liner |
|---|---|---|---|---|
| anomaly-detection | ESP pump anomaly detection | shipped | 2026-08-14 | Flags abnormal vibration ~2 weeks before pump failure |
| work-order-automation | Work order intake automation | building | 2026-08-19 | Auto-routes SAP work orders by asset class and priority |
| historian-migration | Historian tag migration | paused | 2026-06-30 | Consolidating legacy tag naming into the new standard |

## Conventions
- id matches the filename in memory/projects/
- status: exploring | building | shipped | paused | retired
- retired projects move to memory/archive/ and drop off this table

Getting work in

Three intake streams

Memory only works if capture is nearly free. Three streams feed the log, and only one of them requires you to think.

Stream 1 — What your repos already know

Your commit history is an accurate, timestamped record of what you actually built, and you're already writing it. This PowerShell script pulls last week's commits from every repo on your machine into a single file in inbox/. Schedule it with Task Scheduler for Friday afternoon, or just run it.

tools/harvest-git.ps1
# Collects the past week's commits from every git repo under $Root
# into one dated file in work-brain/inbox/.

$Root      = "C:\repos"                        # where your repos live
$BrainRepo = "C:\repos\work-brain"
$Since     = (Get-Date).AddDays(-7).ToString("yyyy-MM-dd")
$Stamp     = Get-Date -Format "yyyy-MM-dd"
$OutFile   = Join-Path $BrainRepo "inbox\$Stamp-git-harvest.md"

"# Git activity since $Since" | Out-File $OutFile -Encoding utf8

Get-ChildItem -Path $Root -Directory | ForEach-Object {
    $repo = $_.FullName
    if (-not (Test-Path (Join-Path $repo ".git"))) { return }

    $log = git -C $repo log --since=$Since --pretty=format:"- %ad %s" --date=short
    if ([string]::IsNullOrWhiteSpace($log)) { return }

    $files = git -C $repo log --since=$Since --name-only --pretty=format:"" |
             Where-Object { $_ -ne "" } | Sort-Object -Unique | Select-Object -First 25

    Add-Content $OutFile ""
    Add-Content $OutFile "## $($_.Name)"
    Add-Content $OutFile $log
    Add-Content $OutFile ""
    Add-Content $OutFile "Files touched:"
    Add-Content $OutFile ($files | ForEach-Object { "  - $_" })
}

Write-Host "Wrote $OutFile"

Stream 2 — What Microsoft 365 knows

Same bridge as Part one, but pointed at memory rather than status. This prompt asks M365 Copilot for the things a dossier needs and a digest doesn't: decisions, reasoning, and commitments with their justification.

Prompt for M365 Copilot — weekly memory harvest
Review my meetings, chats, and email from the past 7 days. I'm building a
long-term record of my work, so I need substance rather than a status update.

For each distinct project or workstream, give me:

- The project name as people actually refer to it
- Decisions made this week, with WHO decided and WHY — include the reasoning
  given at the time, and any alternative that was rejected
- New constraints, requirements, or blockers that emerged
- Numbers, dates, or results that were quoted, with the source
- Commitments made, by me or to me, with dates
- Anything a newcomer would need explained to understand the discussion

Plain markdown, grouped by project. Quote directly where the exact wording of
a decision matters. If something is ambiguous, mark it "unclear" rather than
resolving it. Do not summarize into generalities — specifics are the point.

Stream 3 — What only you know

Ten minutes on Friday, in a plain file in inbox/. The reasoning you never wrote down anywhere, the thing you decided in the truck on the way back from the field, the hunch about why the pilot worked. This is the highest-value input and the only one that can't be automated. Answer four questions:

  • What did I figure out this week that I didn't know last week?
  • What did I decide, and what did I decide against?
  • What would I need to remember to demo or defend this later?
  • What's likely to bite me?

The crew, extended

Four more agents

These follow the same rules as Part one: restricted tools, a pinned model, and a fixed output shape. Note the model choices — the scribe and archivist are cheap, the recall agent is mid-tier because retrieval quality matters, and only the deck builder gets a strong model.

Scribe — keeps dossiers current

.github/agents/scribe.agent.md
---
name: scribe
description: Updates project dossiers in memory/projects/ from new entries in
  log/, preserving the template structure and never inventing detail.
tools: ["read", "search", "edit"]
model: Claude Sonnet 5
---

You maintain the project dossiers. You are a records clerk, not an author.

Process:
1. Read memory/INDEX.md to learn which projects exist.
2. Read log/ entries newer than each dossier's last_touched date.
3. For each project with new material, update its dossier in place:
   - Keep the exact section structure of the template. Never add or rename
     sections. Never reorder them.
   - Update last_touched and status in the front matter.
   - Add new facts to the right section. Do not restate what's already there
     in different words.
   - Where a new fact contradicts an old one, replace it and note the change
     in one line: "(was X, changed <date>)". History matters.
4. If material implies a significant choice was made, do not bury it in the
   dossier — create memory/decisions/YYYY-MM-DD-adr-<slug>.md instead, using
   the ADR format, and link it from the Key decisions section.
5. Update the row in memory/INDEX.md.
6. If a project appears in log/ that has no dossier, create one from the
   template with everything you can fill and "TBD" everywhere else.

Hard rules:
- Every fact traceable to a log file. Cite the filename inline.
- Never write the Demo script section yourself. If it's empty, add the line
  "TBD — needs 10 minutes from me" and list it in your PR description.
- Never touch log/. It is append-only.
- Open a pull request. Never commit to the default branch directly.

Recall — answers "what did I do about X"

.github/agents/recall.agent.md
---
name: recall
description: Answers questions about past work by reading the index first,
  then only the dossiers and log entries that are actually relevant.
tools: ["read", "search"]
model: Claude Sonnet 5
---

You answer questions about work I have already done. You have no edit access
and you never guess.

Retrieval order — follow it exactly, it controls cost:
1. Read memory/INDEX.md. Nothing else yet.
2. Pick at most three candidate projects based on the one-liners.
3. Read those dossiers. Stop if they answer the question.
4. Only if the dossier is thin, search log/ for the project id and read the
   three most relevant dated entries.
5. Only if still unresolved, widen the search.

Answering:
- Lead with the direct answer in two sentences.
- Then the supporting detail, in the order I would need it.
- Cite the file each claim came from, inline.
- State clearly what you could NOT find. "The dossier has no results section"
  is a useful answer. Inventing a plausible number is not.
- If the question is about something that predates the memory bank, say so
  rather than reconstructing it from thin evidence.

Deck builder — dossier to slide outline

.github/agents/deck-builder.agent.md
---
name: deck-builder
description: Turns a project dossier into a slide-by-slide deck outline
  pitched at a named audience.
tools: ["read", "search", "edit"]
model: Claude Opus 5
---

You turn a dossier into a deck outline. Ask who the audience is and how long
the slot is before you start. Those two answers change everything.

Read the project dossier and any ADRs it links. Do not read the whole log.

Write briefs/<project-id>-deck-<audience>.md. One block per slide:

  ### Slide N — <title as it appears on the slide>
  **On the slide:** the three to five words or the single visual. Not prose.
  **What I say:** two or three sentences, in my voice, plain language.
  **Source:** which dossier section this came from.

Rules for the deck itself:
- Open with the problem in the audience's language, never with architecture.
- One idea per slide. If a slide needs two claims, it's two slides.
- Technical depth scaled to the audience: operations leaders get outcomes and
  one diagram; engineers get the method and the failure modes.
- Include a limits slide before the ask. Stating your own constraints first
  is what makes the rest credible.
- Last slide is the ask, and it must be specific.
- Flag anything the dossier can't support with: "NEEDS INPUT — <what>".
  Never fill a results slide with invented numbers.

At the end, list the screenshots or exports I need to grab, with the exact
path or dashboard where each one lives.

Archivist — the cleanup crew

.github/agents/archivist.agent.md
---
name: archivist
description: Monthly consolidation. Compresses stale log entries, flags
  contradictions, and proposes retirements. Proposes only — never deletes.
tools: ["read", "search", "edit"]
model: GPT-5 mini
---

You keep the memory bank from rotting. You are conservative by default.

Monthly pass:
1. Log compression — for log/ files older than 90 days whose content is fully
   captured in a dossier, replace the body with a three-line summary and a
   pointer to the dossier. Keep the filename and the date. Never compress a
   file containing a decision that has no ADR.
2. Contradictions — list any place where two dossiers or a dossier and a log
   entry disagree on a fact, date, or number. Do not resolve them yourself.
3. Staleness — list dossiers with status building or exploring that have not
   been touched in 60 days, and ask whether they are actually paused.
4. Gaps — list shipped projects whose Demo script or Results section is empty.
5. Retirement candidates — projects untouched for 6 months. For each, propose
   a one-page compression into memory/archive/.

Output a single PR with the compressions applied and a description containing
the lists from steps 2 through 5 as checklists for me.

Absolute rules:
- Never delete a file. Compress, move, or flag only.
- Never delete an ADR or a Results section, at any age.
- Never resolve a contradiction. Surface it and let me decide.

On a timer

The rhythm

Four scheduled jobs, at four different cadences. Note that everything writes a pull request rather than committing — memory you never reviewed isn't memory, it's noise you'll distrust later.

WhenWhat runsModelYour job
Daily 06:30intake — clears inbox/ into log/GPT-5 miniNothing
Friday 15:00Git harvest script, then your 10-minute brain dump10 minutes
Monday 07:00weekly-digest, then scribe updates dossiersClaude Sonnet 5Review the PR
1st of montharchivist — compress, flag, proposeGPT-5 miniWork the checklist
Automation — Monday 07:15, weekly · model: Claude Sonnet 5
Run the scribe agent. Update every project dossier in memory/projects/ that
has new material in log/ since its last_touched date, then update
memory/INDEX.md to match.

Open a single pull request titled "Memory update — week of <date>". In the PR
description, list: which dossiers changed and why, any new ADRs created, any
project that appeared in the log without a dossier, and every section still
marked TBD that needs input from me.

If no dossier needs updating, do not open a PR.
Automation — 1st of month, monthly · model: GPT-5 mini
Run the archivist agent for the monthly pass. Apply log compression where the
rules allow it, and open one pull request titled "Memory maintenance — <month>".

The PR description must contain four checklists: contradictions found, stale
dossiers, shipped projects missing a demo script or results, and retirement
candidates. Apply no retirements yourself — I approve those individually.

Retention policy

Worth writing into memory/RETENTION.md so the archivist has a rule to follow rather than a judgment to make.

ContentKeepThen
Decisions and their reasoning (ADRs)ForeverNever compressed, never deleted
Results, numbers, outcomesForeverNever compressed
Project dossiersForeverRetired ones compress to one page in archive/
Demo scripts and gotchasForeverThese are the whole point
Log entries90 days fullCompress to 3 lines + pointer once captured in a dossier
Raw inbox filesUntil processedDelete once the log entry exists
Weekly digests6 monthsDelete — the underlying log and dossiers survive

Worked example

"Can you demo that anomaly tool you built?"

Four months on, no memory of the details, three days' notice. Here's the sequence end to end.

  1. Ask recall what you built

    Quick chat, recall agent: "What was the anomaly detection tool? What does it do, how does it work, and what were the results?" It reads INDEX.md, opens one dossier, and hands you back the answer with citations. Cost: under a cent. This is the moment the whole system pays for itself.

  2. Check what's rotted

    "What's stale or unverified in the anomaly-detection dossier? What would I get caught out on?" Four months is long enough for the data source to have moved or the pilot numbers to be superseded. Better to find that now than on the call.

  3. Build the outline

    Deck-builder agent: "Audience is the reliability team plus the ops superintendent. Twenty minutes with questions, so about eight slides. Goal is getting approval to extend the pilot to a second pad." It returns slide-by-slide with speaker notes, sourced to the dossier, plus a list of the screenshots you need and honest NEEDS INPUT flags where the record is thin.

  4. Fill the gaps and generate

    Grab the flagged screenshots, answer the NEEDS INPUT items. Then hand the outline to Copilot to generate the actual file — a python-pptx script in the app is the reliable route, or M365 Copilot in PowerPoint if your template lives there. Either way you're generating from a reviewed outline, not from a vague prompt, which is the difference between a usable deck and a generic one.

  5. Feed the demo back in

    Afterward, drop the questions you got asked into inbox/. Audience questions are the best possible input for the gotchas section — they're the gaps in your explanation, found for free. Next time the dossier is better.

Why this works and a folder of old files doesn't

Not because the AI is clever. Because four months ago you wrote down why you chose the seasonal-decomposition baseline and what the pilot caught, in a fixed place with a fixed shape. The agent is just retrieval. The memory bank is the part that has to exist.

Making it stick

Rules that keep it honest

Do
  • Review every memory PR, even briefly. Unreviewed memory decays into confident nonsense.
  • Keep the log append-only. It's your evidence when a dossier and your recollection disagree.
  • Cite sources inside dossiers so any claim can be traced back.
  • Write the demo script while it's fresh, however rough.
  • Record what you rejected, not just what you chose.
  • Start with three projects, not your whole history.
Don't
  • Let an agent delete anything. Compress, archive, or flag.
  • Let the scribe write your demo script or invent results.
  • Backfill five years of history before the system has proven itself.
  • Store credentials, personal data, or anything confidential — same governance box as Part one, and it applies harder here because this is designed to persist.
  • Point a recall query at the whole repo. Index first, always.
  • Let dossiers and INDEX.md drift apart — that's what breaks retrieval.

Bootstrapping without the backlog

Don't try to reconstruct everything. Write dossiers for the two or three projects you're most likely to be asked about, from memory, in about twenty minutes each — TBD everywhere you can't recall. Then let the weekly rhythm fill in going forward. In three months you'll have a real bank; in a year you'll have something you'd genuinely miss.

One caution specific to memory

A memory bank is designed to outlive the context it was written in, which makes AI-generated inaccuracies far more dangerous here than in a throwaway summary. A wrong number in a status update is noticed that week. A wrong number in a dossier gets quoted confidently to a superintendent four months later. That's why every fact carries a citation, why the scribe can't write results, and why you review the PRs.