Project status meeting agenda template
Last updated: · Reviewed quarterly
A project status meeting exists for one purpose: to change a date before it slips rather than after. Everything else on the agenda is the context that makes that possible. Its record has to survive a sponsor who remembers approving something differently. The template is below, free and complete. After it, how to stop typing it out: the meeting is already recorded on your device, and an agent writes this template from the transcript into a file you keep.
The project status meeting agenda template
Two blocks a status meeting needs that a kickoff does not. A date-change log, kept separately from the general record, because the sequence of date changes is the story of the project and it is invisible if each change is only mentioned in that week's notes. And an as-stated column on approvals, since "the sponsor approved it" and the sentence the sponsor actually said are two different pieces of evidence.
# <Project> status, <date>
**Present:**
**Absent:**
**Sponsor:**
## Status by workstream
| Workstream | RAG | Since last time | Confidence in the date |
| --- | --- | --- | --- |
## Dates that moved
| Milestone | Was | Now | Why | Who was told |
| --- | --- | --- | --- | --- |
## Risks and issues
| Item | Risk or issue | Owner | Mitigation | Since |
| --- | --- | --- | --- | --- |
## Decisions needed today
<the reason this meeting exists rather than a written update. Each one with the person who has to make it.>
## Decisions made
| Decision | Who approved | As stated | Date |
| --- | --- | --- | --- |
## Actions
| Action | Owner | Due |
| --- | --- | --- |
## Escalated out of this room
<what is going up, to whom, and by when>
## Next meeting
Confidence in the date is a separate column from RAG on purpose. A workstream can be green on the work and amber on the date, and collapsing the two into one status is how a project stays green until the week it does not.
What has to survive a project status meeting
What it decides. Whether each date still holds, and who gets told when one does not. A status meeting that only collects status is a written update being read aloud, and the room is the wrong medium for it.
Who is in it. The project manager, the workstream leads and, in the steering variant, the sponsor. The record is for the sponsor who denies the action weeks later, and for whoever has to reconstruct in six months why the date moved twice. What project managers keep covers why a paraphrase in your minutes is not evidence and everybody in the room knows it.
What must survive it. The revised date together with the reason given at the time, which is the pair that stops a slipped project looking like an unexplained one. The risk with a named owner and a mitigation, rather than a risk that was described and admired. And the approval in the words the approver used, because the disagreement later is never about whether they said yes, it is about what they said yes to.
What a status meeting's notes need that others do not. RAG per workstream with the date confidence kept separate. A dates-that-moved table that is appended to rather than rewritten, so the sequence survives. And an as-stated column on decisions, which is the one place in this pillar where a verbatim quote does more work than a summary.
A steering committee is the same meeting with a different room: fewer workstreams, more authority, and the escalation block carrying most of the weight. Use the same template and expect the decisions-needed-today block to be the whole agenda.
What the status pack misses
The status pack gets built, because somebody senior asked for one. It gets built in the two hours before the meeting, from a spreadsheet that was last accurate on Thursday, and it captures the state of the project rather than what the meeting did to it.
What does not get written is the twenty minutes after slide four, where the sponsor said the thing about the vendor and a date quietly moved. Writing that up means sitting down at seven in the evening with a mostly empty page, remembering a conversation that happened while you were chairing it. So the pack is filed, the discussion is not, and the next dispute about what was approved is settled by whoever sounds more certain.
Writing it from the recording
This half is a product feature. Exactly what it does, in four steps:
- The day is already recorded. Earkeep captures your microphone and your system audio continuously and transcribes on your device, and the audio is never written to disk at all. There is no start button and no bot joining the call. Always-on capture covers why, and private by design covers where the audio goes, which is nowhere.
- You mark the meeting once it is over. Select the range on the timeline and save it as a meeting. A weekly status on a connected calendar names and bounds its own span, which matters more here than elsewhere because the file name is how a year of them stays in order. Calendar connection has the detail.
- You pick a saved template in the composer. Settings → Templates holds instruction presets, each with a name, an agent, a working directory and the prompt text. Opening the agent panel on a saved meeting offers them, and the meeting and its transcript are attached to the prompt for you, as resources, so the preset itself is just the instruction.
- The agent writes the file. It runs on your machine, as your own CLI, with your own key, in the directory the preset names. Agents and MCP explains how that works.
The "one click" is picking the preset. Nothing fires a template because a meeting's title matched a pattern; Earkeep has no such matching.
The preset for this page, with ~/notes/projects as the directory:
Write this status meeting up as a new markdown file in this directory, named
<project-slug>/status-<yyyy-mm-dd>.md.
Use exactly these sections: Status by workstream, Dates that moved, Risks and issues,
Decisions needed today, Decisions made, Actions, Escalated out of this room, Next meeting.
Read the most recent previous status file for this project first. In "Since last time",
say what changed against it for each workstream, including "no change" where there was
none. Do not drop a workstream because it was not discussed; mark it not discussed.
A row goes in "Dates that moved" only when a date was actually restated. Record the old
date, the new one, the reason given, and who the room said would be told. If nobody was
named, write "nobody named".
In "Decisions made", the "As stated" column is a direct quote of the approving sentence.
Do not paraphrase it and do not tidy it. If approval was implied rather than stated,
record it as implied and quote what was actually said.
Carry every open risk from the previous file forward, with its date first raised, even if
it was not mentioned today.
Carrying unmentioned risks forward is the instruction that changes what these files are worth. A risk that stops being discussed has not stopped existing, and a record that only contains what was said this week will quietly lose it somewhere around week five.
Cross-linking a year of them, on your own schedule
Earkeep has no scheduler. There is no nightly job to switch on, no "run this agent every week" setting, and there is not one hidden in a menu either. What it has instead is a directory of plain markdown files and a read-only MCP server on loopback, which is everything a scheduler you already own needs.
The pattern on top of that is a compiled wiki: raw sources stay immutable, an agent writes one page per concept from them, and a schema file states the rules. The LLM Wiki is the pattern and from what was said to what you know is the pipeline a meeting travels along it. For a status meeting the destination is the project page the kickoff already created: the same page, gaining a dated status history, a date-change log that reads as one sequence, and a risk register whose entries carry the date they were first raised.
Keep the ingest instructions in a file so a scheduled run and a manual one read the same one. ~/wiki/INGEST.md:
Sources are the markdown files under ~/notes/projects. Never edit them.
Update the existing page for this project in ~/wiki/projects/. Do not create a second one.
Maintain a "Date history" section as one row per change, in order: milestone, old date,
new date, the reason as recorded, and a link to the write-up. Append only. The point of
this section is that the sequence is readable in one place.
Maintain a "Risk register" section: each risk with the date first raised, its owner, its
current mitigation, and the date it was last discussed. Move a risk to a "Closed" list
with a date rather than deleting it.
Copy approval quotes verbatim into a "Decisions" section with their dates. Never
paraphrase a quoted approval into a summary.
Every claim carries the date of the write-up it came from and links that file.
Then the schedule, which is yours. On macOS a LaunchAgent is the supported mechanism and it survives the laptop being asleep at the appointed minute, where a cron job simply misses it. Save this as ~/Library/LaunchAgents/com.yourname.wiki-ingest.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.yourname.wiki-ingest</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-lc</string>
<string>cd ~/wiki && /opt/homebrew/bin/claude -p "$(cat INGEST.md)"</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key><integer>19</integer>
<key>Minute</key><integer>30</integer>
</dict>
<key>StandardOutPath</key>
<string>/tmp/wiki-ingest.log</string>
<key>StandardErrorPath</key>
<string>/tmp/wiki-ingest.err</string>
</dict>
</plist>
Load it once with launchctl bootstrap gui/$(id -u) and the path to that file. Or, if you already keep a crontab, one line instead:
30 19 * * 1-5 cd $HOME/wiki && /opt/homebrew/bin/claude -p "$(cat INGEST.md)" >> /tmp/wiki-ingest.log 2>&1
Two things bite about that line. Cron runs with a minimal PATH, so the agent binary needs its absolute path or the job fails silently. And on current macOS a cron job that reads directories under ~/Documents or ~/Desktop needs Full Disk Access granted to /usr/sbin/cron in System Settings.
The join between a meeting and its write-up is the filename convention you chose, and nothing else: there is no field on a saved meeting recording where its notes landed. Halfway through a project the date history is the page you send instead of writing a narrative, because the narrative is already in it and it is dated.
What this does not do
- No speaker labels. There is no diarisation, so nothing in the transcript says who said which sentence, and the minutes cannot attribute a line to a person from the audio. Attribution comes from what was said out loud ("Sam will take the migration"), from a connected calendar's attendee list, or from you typing the names. The
**Present:**line is a line you fill in. - macOS only. macOS 13 or later. The Windows audio path is designed and not released, and the scheduling half of this page is macOS-specific by construction.
- The agent is yours. It runs as your own CLI with your own key. Earkeep does not resell model access and there is no per-meeting AI fee, which is what makes it €39 once. What the agent does with the context after Earkeep hands it over is a property of the agent you chose, not of Earkeep. Setting up Claude Code covers installing and signing in to one of them.
- Nothing writes back. The MCP server is read-only, with exactly two tools, so a scheduled agent can read your meetings and cannot create or edit a meeting, a note or a file through it. The wiki is a one-way derivative of the record.
Related
- Project kickoff meeting agenda template: the meeting that set the scope and the dates this one keeps revising.
- All-hands meeting agenda template: for when the date change has to be told to everybody rather than to the steering group.
- Local RAG in practice: when a year of status files gets big enough that grep stops being the fastest way in.
- All meeting minutes templates.
Frequently asked questions
Is there a free project status meeting agenda template?
The one above. It is complete, there is no email gate and nothing to sign up for. The two blocks worth keeping even if you cut the rest are the dates-that-moved table and the as-stated column on decisions.
What is the difference between RAG and RAID?
RAG is a status colour per workstream: red, amber or green. RAID is a register of Risks, Assumptions, Issues and Dependencies that lives across the whole project rather than in one meeting. This template uses RAG in the status table and folds the risk and issue half of RAID into its own block, because assumptions belong on the kickoff record where they were made.
How do I write steering committee minutes?
Use this template and expect the decisions-needed-today block to be most of the meeting. The two differences that matter are that a steering committee approves rather than reports, so the as-stated column carries the weight, and that what leaves the room escalated is the outcome somebody will ask about later. Everything else is the same shape.
Should the status meeting exist at all if we send a written update?
Only if it makes decisions. A status meeting whose agenda is entirely reports is a document being read aloud, and the honest fix is to send the document and keep a shorter meeting for the decisions it raises. Meeting overload covers the four verdicts an audit can reach and how to run one on a recurring invite.
Does this record the meeting without telling anyone?
Earkeep announces itself to nobody: there is no bot in the participant list and no banner on anyone's screen, so telling the room is yours to do and you should. What it changes is what you can honestly say when you do, because nothing leaves your device and no IT system gets a copy. Telling people you're recording covers how to say it in a sentence, and our privacy page covers what the app itself sends.
Can I get the minutes without letting an AI read the transcript?
Yes. The transcript is a plain text file on your own disk and the template above is a template: open one, fill in the other, and no model is involved at any point. The agent step is a convenience for people who do not want to type, not a dependency. Private by design covers what stays local either way.