From meeting transcript to action items, with a human check on every line
A reusable AI workflow for any project team. It turns meeting transcripts into minutes, decisions, action items, RAID updates, and Jira tickets, with review rules that keep every owner and date honest. Tested on a regulated medical device program, where every owner, date, and decision has to be right.
Simulated practice project. The test scenario is a fictional medical device software release, inspired by my work on surgical robotics programs at Medtronic. All names, products, and data are fictional, and no Medtronic information is used. Built with Claude, NotebookLM, Google Sheets, Apps Script, and Jira.
See the review step in action
Select a row to find its source quote. Switch views to see the kind of errors human review catches.
Weekly V&V status meeting, week 3 (excerpt)
Omar The camera latency fix is taking longer than we thought. We'll have build 2.4.1 to verification by Thursday the 12th.
Grace We can't run system-level protocols until the build is frozen. If it lands on the 12th, we'd need until the 21st to finish verification.
Priya Could V&V run anything in parallel?
Grace Maybe for the UI protocols. But protocol revision C isn't approved yet.
Tom Someone needs to route protocol revision C for approval this week. I'll check with document control who can sign.
Priya I'll pull the orphan requirements report from Polarion before Friday.
Grace It already shows 14 orphan requirements with no linked test. Somebody has to link those to test cases.
Action items
| Action | Owner | Due |
|---|
- 3
- regulated meeting types
- 5
- reusable prompts
- 8
- human review rules
- 15
- action items in the answer key
How the workflow runs
The same four steps for every meeting, so the output stays consistent no matter who runs it.
- Paste the transcriptDrop any meeting transcript, from a status meeting to a design review, under a saved prompt.
- AI drafts the documentsUnclear owners become UNASSIGNED and missing dates become TBD. Nothing is guessed.
- A person reviews every lineOwners, dates, and decisions are checked against source quotes with an 8-point checklist.
- Approve and sendReviewed notes go to the team and leadership, and action items flow into Jira.
Prompt library
Each prompt tells the AI to use only what was said, quote its sources, and mark gaps instead of filling them.
How I test accuracy
Instead of trusting the output, I built an answer key for all three meetings and score every AI run against it. Each meeting hides traps that a careless summary falls into.
What gets scored
- Owner accuracyShare of action items with the correct owner, including correct UNASSIGNED flags.
- Date accuracyShare of due dates that match the transcript or are correctly marked TBD.
- False decisionsOptions, status updates, or provisional calls wrongly logged as final decisions.
- Phantom actionsTasks the AI invented, such as work that only applies if a change is approved.
Traps built into the meetings
- Raising is not owningThree tasks are mentioned by people who never agree to do them.
- Provisional is not finalThe design review date is kept "for now," with a risk flag.
- Conditional workdFMEA and protocol updates only apply if the change order is approved. It is deferred.
- Status is not a decisionA regulatory letter to file is reported as done, not decided in the meeting.
Baseline prompt versus guarded prompt
Version 1: baseline
What most people type. Fast, but it invites guessing.
Summarize this meeting and list the action items with owners and due dates.
Version 2: guarded
Forces quotes and flags. Gaps show up instead of getting filled.
Use only what is stated. If no owner was clearly named, write UNASSIGNED. If no due date was stated, write TBD. Never guess. Quote the source line for every item.
Answer key 15 action items and 4 decisions across 3 meetings
| Meeting | Action | Owner | Due |
|---|---|---|---|
| V&V status | Deliver build 2.4.1 to verification | Omar | Thu the 12th |
| V&V status | Complete system verification | Grace | The 21st |
| V&V status | Explore parallel UI protocols | Grace | TBD |
| V&V status | Find who can sign protocol revision C | Tom | This week |
| V&V status | Route protocol revision C for approval | UNASSIGNED | This week |
| V&V status | Pull orphan requirements report | Priya | Before Friday |
| V&V status | Link 14 orphan requirements to tests | UNASSIGNED | TBD |
| Change control | Update Jira backlog and tell usability team | Leo | Wednesday |
| Change control | Find the supplier quality owner | Priya | Today |
| Change control | Obtain supplier certificate of conformance | UNASSIGNED | TBD |
| Change control | Start system verification | Grace | The 13th |
| Design review | Fix stale value anomaly | Omar | The 28th |
| Design review | Rerun failed protocol | Grace | The 29th |
| Design review | Risk assessment and DHF rationale for anomaly | UNASSIGNED | TBD |
| Design review | Send summary to leadership | Priya | Tonight |
Decisions: keep the 200 ms latency requirement (final), keep the design review on the 25th (provisional, risk flagged), defer ECO-0417 to release 2.5, and conditional approval to release on the 30th.
Team adoption plan
A one-page operating procedure so a program team can use the workflow safely, not just one person.
| Role | Responsibility |
|---|---|
| Project manager | Runs the prompts after each meeting and reviews every owner, date, and decision before sharing. |
| Team leads | Confirm or correct their own action items within one business day. |
| Quality and document control | Own the official meeting records, change orders, and DHF entries. AI drafts never replace them. |
| IT and compliance | Approve which AI tools may be used and what data may go into them. |
Rollout
- Pilot on one recurring meeting for two weeks, reviewing every draft against the transcript.
- Track the correction rate and time saved each week in the correction log.
- Expand to change control and design reviews once owner and date accuracy hold steady.
- Review the prompts monthly and update them based on the most common corrections.
Automated follow-ups
Reviewed action items go into a Google Sheet. A small Apps Script runs every morning, reminds owners of items due within two days, and emails the project manager a list of anything still UNASSIGNED or TBD.
function sendFollowUps() {
const sheet = SpreadsheetApp.getActive().getSheetByName('Action Items');
const rows = sheet.getDataRange().getValues().slice(1); // skip header row
const pmEmail = 'your.email@example.com';
const today = new Date();
const gaps = [];
rows.forEach(([action, owner, due, status, ownerEmail]) => {
if (status === 'Closed') return;
if (owner === 'UNASSIGNED' || due === 'TBD') {
gaps.push('- ' + action + ' (owner: ' + owner + ', due: ' + due + ')');
return;
}
const daysLeft = (new Date(due) - today) / 86400000;
if (ownerEmail && daysLeft <= 2) {
MailApp.sendEmail(ownerEmail, 'Reminder: ' + action,
'Hi ' + owner + ', this action is due ' + new Date(due).toDateString() + '.');
}
});
if (gaps.length) {
MailApp.sendEmail(pmEmail, 'Action items needing an owner or date', gaps.join('\n'));
}
}
Sheet columns: Action, Owner, Due, Status, Owner email. Set a daily time-driven trigger in Apps Script to run it each morning.
Automatic Jira tickets
Once action items pass human review, a second script turns each one into a Jira task. Owners are assigned automatically when they have a Jira account, and anything still UNASSIGNED gets a needs-owner label so it can't be lost.
- Review in the sheetReviewed action items land in the Action Items sheet with owner, due date, and status.
- Script creates ticketsEach open row becomes a Jira task with summary, due date, assignee, and labels.
- Ticket key written backThe new key, like MTG-12, is saved in the sheet, so the same item is never ticketed twice.
- Gaps stay visibleUnowned tasks carry a needs-owner label, ready for a saved Jira filter the PM checks daily.
Field mapping
| Sheet column | Jira field | Rule |
|---|---|---|
| Action | Summary | Copied as written after review. |
| Owner email | Assignee | Matched to a Jira account. Left unassigned if no match. |
| Owner | Labels | UNASSIGNED adds the needs-owner label. |
| Due | Due date | Set only when the sheet holds a real date. TBD stays blank. |
| Ticket | Issue key | Filled by the script. A filled cell means skip. |
The script
const JIRA_BASE = 'https://your-site.atlassian.net';
const PROJECT_KEY = 'MTG';
function createJiraTickets() {
const props = PropertiesService.getScriptProperties();
const auth = 'Basic ' + Utilities.base64Encode(
props.getProperty('JIRA_EMAIL') + ':' + props.getProperty('JIRA_TOKEN'));
const sheet = SpreadsheetApp.getActive().getSheetByName('Action Items');
const data = sheet.getDataRange().getValues();
for (let i = 1; i < data.length; i++) {
const [action, owner, due, status, ownerEmail, ticketKey] = data[i];
if (status === 'Closed' || ticketKey) continue; // skip closed rows and rows already ticketed
const fields = {
project: { key: PROJECT_KEY },
issuetype: { name: 'Task' },
summary: action,
labels: owner === 'UNASSIGNED' ? ['meeting-action', 'needs-owner'] : ['meeting-action'],
description: { type: 'doc', version: 1, content: [{ type: 'paragraph', content: [
{ type: 'text', text: 'From reviewed meeting action items. Owner: ' + owner + '. Due: ' + due + '.' }] }] }
};
if (due instanceof Date) fields.duedate = Utilities.formatDate(due, 'UTC', 'yyyy-MM-dd');
const accountId = ownerEmail ? findAccountId(ownerEmail, auth) : null;
if (accountId) fields.assignee = { id: accountId };
const res = UrlFetchApp.fetch(JIRA_BASE + '/rest/api/3/issue', {
method: 'post', contentType: 'application/json',
headers: { Authorization: auth }, payload: JSON.stringify({ fields }),
muteHttpExceptions: true
});
if (res.getResponseCode() === 201) {
sheet.getRange(i + 1, 6).setValue(JSON.parse(res.getContentText()).key); // write ticket key back
} else {
Logger.log('Row ' + (i + 1) + ' failed: ' + res.getContentText());
}
}
}
function findAccountId(email, auth) {
const res = UrlFetchApp.fetch(
JIRA_BASE + '/rest/api/3/user/search?query=' + encodeURIComponent(email),
{ headers: { Authorization: auth }, muteHttpExceptions: true });
const users = JSON.parse(res.getContentText() || '[]');
return users.length ? users[0].accountId : null;
}
Setup About 15 minutes on a free Jira Cloud site
- Create a free Jira Cloud site and a project with the key MTG, or change PROJECT_KEY in the script.
- Create an API token in your Atlassian account settings.
- In Apps Script, open Project Settings and add two script properties: JIRA_EMAIL and JIRA_TOKEN. The token never sits in the code.
- Add a sixth column named Ticket to the Action Items sheet.
- Make sure the Due date field is on the Task screen in your Jira project.
- Run createJiraTickets once to approve permissions, then add a time-driven trigger to run it after each review.
Works with your team's tools
The workflow does not depend on Jira. Transcript, AI draft, human review, and the tracker sheet stay the same. Only the last step changes: which tool receives the reviewed action items. Jira is built and tested. The others follow the same pattern with a different web address and field names.
| Tool | How action items arrive | What changes in the script | Status |
|---|---|---|---|
| Jira | REST API creates a task per row | Project key, summary, assignee, due date, labels | Built and tested |
| Smartsheet | REST API adds a row to the project sheet | Sheet ID and column IDs for task, owner, and due date | Same pattern |
| Monday.com | GraphQL API creates an item on a board | Board ID and column values for owner and date | Same pattern |
| ServiceNow | Table API creates a task record | Instance address, table name, and assignment fields | Same pattern |
| Asana | REST API creates a task in a project | Project ID, task name, assignee, due date | Same pattern |
| Wrike | REST API creates a task in a folder | Folder ID, title, responsible user, dates | Same pattern |
| Azure DevOps | REST API creates a work item | Organization, project, and work item fields | Same pattern |
| Microsoft Planner | Power Automate flow from the sheet or an Excel list | No code: map columns to Planner task fields | Same pattern |
No-code option: Zapier, Make, or Power Automate can send new tracker rows to any of these tools, so teams can adopt the workflow without maintaining scripts.
See it working
I ran the full workflow end to end on a free Jira Cloud site, using the 15 reviewed action items from the answer key. These screenshots are from that run. Personal email addresses are blurred.
- 15
- Jira tickets created by the script, KAN-4 to KAN-18
- 5
- gaps flagged to the PM: 4 unowned tasks and 1 missing date
- 1 click
- to run everything from a custom Meeting Actions menu in the sheet
Human review rules
AI drafts the documents. A person approves them. These rules apply before anything is shared.
- Verify every ownerRaising an issue is not the same as owning it.
- Verify every dateDates must come from the transcript, or they become TBD.
- Check decisions against quotesOptions that were only discussed stay out of the decision log.
- Chase every gapEach UNASSIGNED or TBD item gets a follow-up within one business day.
- No invented factsAnything the transcript doesn't support is deleted, even if it sounds right.
- Protect sensitive informationNo patient data, proprietary designs, or confidential company material goes into an AI tool. Approved tools only.
- Keep a correction logEvery edit to an AI draft is recorded to improve the prompts.
- AI notes are not quality recordsDesign decisions and change approvals are recorded through formal document and change control, not AI drafts.
The three test meetings
A fictional surgical robotics software release (Aurora SR-2, release 2.4), written with vague owners and shifting dates on purpose, so the review rules have real errors to catch.
Why it matters
Speed without losing accountability
AI drafts notes in seconds, but in a regulated program a wrong owner on a protocol approval can stall verification. This workflow makes every owner, date, and decision traceable to a quote before anything is shared.
What I'd build next
A Smartsheet connector to sit next to the Jira one, then a weekly leadership report that rolls up open tasks, decisions, and risks from every meeting into one on-track or at-risk summary.