Skills

meeting-notes-to-tasks

Productivity v1
@launifycorp 5 installs updated yesterday MIT license

Meeting Notes To Tasks

You own one outcome: a Notion meeting page becomes a task list that imports into a Notion database or task tool without hand-editing. Every row has one owner, a due date or an explicit blank, and a verbatim source quote. Someone who missed the meeting should be able to open the list, see who committed to what and by when, and trace every row to the sentence that produced it in under 10 seconds.

The core judgement is separating a commitment from discussion. Weak extraction turns every "we should" and "might be worth" into a task and produces a 30-row list nobody trusts. Strong extraction keeps only items where a named person accepted work or was assigned it without objection. It routes everything weaker to a review queue, and it never invents an owner or a date to make a row look complete. A 30-minute meeting typically yields 4–10 real tasks. More than 15 means the classification in step 2 is too loose.

When to use

  • A user pastes a Notion meeting page URL or export and asks for "the action items" or "tasks from this".
  • A recurring meeting page (weekly sync, sprint retro, client call) needs its follow-ups pushed into a Tasks database.
  • A Notion AI meeting-notes block or transcript summary has an "Action items" section with missing owners, missing dates, or items phrased as topics ("SOW", "webhooks") rather than actions.
  • A user wants a CSV to import into Notion, Linear, Asana, or Jira from a meeting record.
  • Before a follow-up meeting, someone asks "what did we commit to last time and who owns it?"

Do not use this when:

  • The user wants minutes or a narrative summary for distribution. Use a meeting-summary skill. Tasks are one section of that deliverable.
  • The source is a project plan, PRD, or roadmap page. Those hold planned work, not meeting commitments. Use a work-breakdown skill.
  • The user wants status on tasks that already exist. Query the Tasks database directly instead of re-extracting.
  • The source is a raw transcript with no speaker labels. Owners cannot be resolved from unlabelled first-person sentences. Ask for a labelled transcript first.

Inputs

Input Required If missing
Meeting page content (all blocks, including to-do blocks, toggles, synced blocks, @mentions) Yes Stop and ask for the page or an export. Do not work from a page title or a summary alone.
Meeting date Yes Use the page's Date property, then the page's created time. If neither exists, extract anyway, keep relative dates as written in Notes, leave Due blank, and put "Meeting date missing — relative dates unresolved" as the warning line.
Attendee list with full names Recommended Build it from @mentions and speaker labels on the page. Tag every owner resolved from a bare first name owner-inferred.
Target database schema (property names, Status options, Person vs text Owner) Recommended Use the 8 default columns in Output format and put "Schema assumed: default 8 columns" as the warning line.
Team date conventions (e.g. "EOW" = Thursday, sprint end date) Optional Apply the step 4 defaults. Each resolved row carries the original phrase in Notes, so the user can audit every default.
Open tasks from prior meetings Optional Skip deduplication against history and add "Not checked against prior meetings' open tasks" under the warning line.

The page plus the meeting date is enough to deliver a complete list. Never withhold the list because an optional or recommended input is missing. State the gap in the warning line and continue.

Method

  1. Read the page in full and map its structure. Expand every toggle and synced block before classifying anything. Record four facts: the meeting date, the attendee list, the cadence (title contains "Weekly", "Biweekly", "Daily", or "Monthly", or none), and the section headings in order. Section sets the default reading of every sentence under it:

    • "Action Items", "Next Steps", "To-dos", and any to-do block are high-signal. Every line is a candidate row.
    • "Discussion", "Notes", "Updates", and untitled blocks are mixed. Classify sentence by sentence.
    • "Decisions" yields no rows. It yields review items only where a decision implies work (step 2).
    • "Parking Lot", "Ideas", "Open Questions", and "Later" are excluded entirely, unless a sentence there names an owner and a date. Then extract it and put the section name in Source Section.
  2. Classify every candidate sentence into exactly one of five classes.

    • Commitment: first-person acceptance by a labelled speaker, such as "I'll", "I will", "I can have it by", "on me", "I'll take that", "leave it with me".
    • Assignment: a third-party directive with no objection on the page, such as "Priya to send", "@Marco owns the rollout", or a to-do block. A question addressed to a named person ("Marco, can you…?") is an Assignment unless that person declines or someone else takes it within the next 3 blocks.
    • Proposal: "we should", "might be worth", "someone needs to", "let's look into", "at some point", or a question addressed to the group ("Can someone…?", "Should we…?").
    • Decision: "we agreed", "going with", "decided", "we'll keep", "final answer is".
    • Info: a status report or observation with no future action, such as "retry queue is holding", "numbers are up 4%".

    Each class has a fixed destination:

    • Commitments and Assignments become rows.
    • A Proposal becomes a row only if a later block names a person for it. Otherwise it goes to the review queue only if it names a concrete object (pricing tiers, the SSO contract). Pure musing ("we should talk more") is excluded and counted.
    • Decisions never become rows. A Decision that implies build, buy, or configuration work ("going with Twilio") creates one review item asking who implements it. A Decision that keeps the status quo ("keep the Thursday slot") is excluded and counted.
    • Info never becomes a row or a review item. It is counted in Excluded.
    • A commitment withdrawn within 3 blocks ("actually, I can't get to that") is excluded. If someone else picks it up, extract the row for the new owner.
    • A conditional commitment ("if legal signs off, I'll send it") stays a row, with conditional: {condition} in Notes.
  3. Resolve one owner per row, using this order and stopping at the first match:

    1. @mention on the same block.
    2. Full name on the same block.
    3. The speaker label on a first-person Commitment.
    4. A first name matching exactly one person on the attendee list. This counts as explicit when the user supplied the attendee list, and gets owner-inferred when you built the list in step 1.

    "We", "the team", "eng", "someone", an unmatched first name, or a first name matching two attendees gives Owner: Unassigned and the tag owner-unassigned. Never default to the meeting organiser, the note-taker, or the person who raised the topic.

    • If two people are named and the sentence divides the work ("Ana takes content, Joe takes scheduling"), write one row per person. Each row gets the same quote and the tag split-from-shared.
    • If two people are named and the sentence does not divide the work ("Ana and Joe will draft it"), write one row. The owner is the first person named, and co-owner: {Full Name} goes in Notes.
    • If the owner is not on the attendee list but is named explicitly ("Sven from Halden IT will send…"), write the row with their name as given and tag it external-owner.
  4. Resolve the due date against the meeting date, never against today. Output ISO YYYY-MM-DD. Apply the first rule that matches:

    • Explicit date with year: use it.
    • Explicit date without a year ("May 31"): use the meeting year. If that date falls before the meeting date, use the next year. This counts as explicit, with no tag.
    • "Today" / "EOD": the meeting date.
    • "Tomorrow": meeting date +1 calendar day.
    • Weekday name ("by Thursday"): the next occurrence after the meeting date. If the weekday named is the meeting's own weekday, use +7 days.
    • "End of week" / "EOW" / "this week": the Friday of the meeting week. If the meeting is on a Friday, Saturday, or Sunday, use the following Friday.
    • "Next week": the Friday of the following week.
    • "End of month" / "EOM": the last calendar day of the meeting month. If the meeting is on that day, use the last day of the next month.
    • "Before the next sync" / "by next meeting": meeting date +7 for Weekly, +14 for Biweekly, +1 business day for Daily, and the same day next month for Monthly. With no cadence recorded in step 1, leave Due blank and tag date-missing.
    • "Soon", "ASAP", "when you can", "once X is done", or no time phrase: leave Due blank, tag date-missing, and keep the phrase in Notes. Never fill a +7 or +14 placeholder.

    Every date resolved by the relative rules (today through next sync) gets the tag date-default, plus the original phrase and result in Notes, written exactly as "by Thursday" → 2024-05-16.

    • A timing phrase about the object, not the work, is not a due date. "Check whether the contract renews in June" has no due date. June is when the contract renews.
  5. Write the task title and attach the source quote.

    • The title starts with an imperative verb (Send, Draft, Schedule, Update, Check, Confirm, Share, Fix, Book) and names the object and, where stated, the recipient. Keep it at 80 characters or fewer. "Send revised SOW to Halden Logistics" passes. "SOW", "Webhooks", and "Follow up" fail.
    • The quote is copied character-for-character from one block, with no more than 25 words. Drop the speaker label ("Priya:"). Trim with "…" at the start or end only. Never splice text from two blocks into one quote.
    • If the commitment spans blocks (a question in one, "Yep" in the next), quote the block containing the task's object and verb, and put the section heading in Source Section.
  6. Deduplicate and merge. Two rows are duplicates when they have the same owner and the same deliverable, however worded ("send deck" and "share slides with client" are the same; "draft postmortem" and "share postmortem" are not).

    • Keep the row with the more specific due date. An explicit date beats date-default, which beats blank. Join both quotes with " | ", join both section names with " | ", and add the tag merged-duplicate.
    • Same deliverable with different owners is not a duplicate. Keep both rows and tag each possible-conflict.
    • If prior-meeting open tasks were supplied, a new row matching an open task by owner and deliverable is dropped and listed in Excluded as "already open from {date}".
  7. Assign confidence and build the review queue.

    • high: owner explicit (step 3, rules 1–3, or rule 4 with a supplied attendee list), Due explicit, and the source is a Commitment or Assignment.
    • medium: exactly one of date-default, date-missing, or owner-inferred.
    • low: owner-unassigned, or two or more medium triggers on the same row.
    • external-owner, conditional, and possible-conflict do not change confidence. They do send the row to review.

    The review queue holds, in this order: every low row, every date-missing row, every external-owner row, every possible-conflict pair, every work-implying Decision, and every concrete ownerless Proposal. Each item gets one line ending in a question a human can answer in one word or one name.

    • If more than 40% of rows are low, the warning line reads: "Notes too thin for reliable assignment — recommend a 5-minute confirmation pass with {meeting owner}."

Judgement calls

Split vs keep compound tasks. Split only when the page gives the parts different owners or different due dates. "Draft and send the proposal by Friday" from one person is one row. "Ana takes content, Joe takes scheduling" is two rows sharing one quote. Never split on estimated effort. Effort is not on the page, and guessing it breaks the rule that every field traces to a sentence.

Question to a named person: Assignment or Proposal. "Priya, can you look into churn numbers?" is an Assignment once 3 blocks pass without Priya declining and without another name taking it. An explicit "yes", "sure", or "on it" from Priya within those 3 blocks makes the row high if a date exists. "Can someone look into churn?" is a Proposal. If the note-taker turned either version into a to-do block, treat it as an Assignment. The to-do block is the note-taker's record that work was handed out.

Checked to-dos. A checked to-do is completed work. Omit it and count it under "completed to-dos" in Excluded. Export it with Status: Done only when the user asked for a full record of the meeting. Do not reopen a checked item because the discussion suggests it is unfinished. Put a review item on it instead, quoting the conflicting sentence.

Infer vs leave blank. Infer only through the fixed rules in steps 3 and 4. They are deterministic and the tags make them reversible. Anything that needs knowledge from outside the page stays blank, such as "Marco usually handles infra" or "the SOW always goes out on Thursdays". A blank the human fills in costs 5 seconds. A wrong owner costs a deadline nobody noticed was missed.

Rules

  • Never create a row, owner, or due date without a source sentence on the page.
  • Every row carries a verbatim quote of 25 words or fewer from a single block. No paraphrase, no splicing.
  • Owner holds exactly one full name or the literal Unassigned. Co-owners go in Notes as co-owner: {Full Name}.
  • Due is ISO YYYY-MM-DD or empty. Every relative phrase you resolved appears in Notes as "{phrase}" → {date}.
  • Notes uses only these tags, separated by "; ": owner-inferred, owner-unassigned, date-default, date-missing, external-owner, split-from-shared, merged-duplicate, possible-conflict, co-owner: {Name}, conditional: {condition}, priority: {as written}. Free-text notes follow the tags.
  • Set priority only when the page states it ("P0", "blocker", "top priority"), and record it as priority: P0 in Notes. Do not invent a Priority column.
  • Status is Not started for every exported row, unless the target schema names a different default option.
  • Name a non-attendee as owner only when the page names them explicitly. Tag those rows external-owner.
  • Do not write to a Notion database unless the user explicitly asked for the import. The default deliverable is the CSV, the review queue, and the Excluded counts.
  • Double-quote every CSV field and double any internal quote ("by Thursday" → ""by Thursday""). Before handover, confirm every line has exactly 8 fields.

Output format

## Tasks from: {Meeting page title} ({YYYY-MM-DD})
Extracted {n} tasks · {h} high / {m} medium / {l} low confidence · {r} items need review
{Warning line, only if triggered: meeting date missing / >40% low / schema assumed / not checked against prior tasks}

### Import file (CSV)
Task,Owner,Due,Status,Source Quote,Source Section,Confidence,Notes
"{Verb + object, ≤80 chars}","{Full Name | Unassigned}","{YYYY-MM-DD | empty}","Not started","{verbatim, ≤25 words}","{Section heading}","{high|medium|low}","{tags; original date phrase}"

### Needs a human decision
- {Task or item} — {reason}; {question answerable with a name, date, or yes/no}

### Excluded (not tasks)
- {n} decisions ({k} moved to review), {n} proposals ({k} moved to review), {n} info items, {n} completed to-dos, {n} parking-lot items, {n} merged duplicates
  • Order rows by Due ascending, with blank dates last. Within a date, order by owner surname, with Unassigned last.
  • Over 40 rows: reduce Excluded to the single count line, then cut Notes to tags only. Never cut source quotes, rows, or review items.
  • The review queue holds at most 8 items. If there are more, list the first 8 in step 7's order, then add "+{k} more: {comma-separated item names}".

Worked example

Input: Notion page "Halden Logistics — Weekly Sync", Date property 2024-05-14 (Tuesday). Attendee list supplied by the user: Priya Raman, Marco Feld, Ana Ortiz, Joe Kim. No target schema supplied.

Agenda

  1. Onboarding timeline · 2. Webhook reliability · 3. Q3 training

Discussion Priya: Client pushed back on the onboarding timeline. I'll send them the revised SOW by Thursday. Marco: Webhook failures are back, ~3% of events since the 9th. I'll get a postmortem draft out end of week. Joe: Retry queue is holding, no data loss so far. Ana: We should probably revisit pricing tiers at some point. Priya: Marco, can you also share the postmortem with Halden's IT lead? Marco: Yep, once it's reviewed. Ana and Joe will put together the Q3 training plan — Ana takes content, Joe takes scheduling, both by May 31. Sven Ohlsson (Halden IT) will send us the SSO metadata file before the next sync.

Decisions Going with Twilio for SMS alerts. Keep the Thursday demo slot for Halden.

Action Items ☐ @Joe Kim update the shared runbook ASAP ☐ Someone to check whether the SSO contract renews in June ☑ @Priya Raman confirm attendee list for Thursday demo ☐ @Marco Feld postmortem draft

Parking Lot Migrate client dashboards to the new charting library.

Classification trace:

Block Class Result
Priya: "I'll send them the revised SOW by Thursday." Commitment Row. Speaker owner. Thursday after Tue 05-14 → 2024-05-16, date-default.
Marco: "I'll get a postmortem draft out end of week." Commitment Row. EOW → Fri 2024-05-17, date-default.
Joe: "Retry queue is holding…" Info Excluded.
Ana: "We should probably revisit pricing tiers…" Proposal (concrete object, no owner) Review queue.
Priya → Marco "can you also share…" + "Yep, once it's reviewed." Assignment, accepted Row. "once it's reviewed" → date-missing, conditional.
"Ana takes content, Joe takes scheduling, both by May 31." Assignment, work divided Two rows, split-from-shared. May 31 → 2024-05-31, explicit.
"Sven Ohlsson (Halden IT) will send us…" Assignment, non-attendee Row, external-owner. Weekly cadence → 2024-05-21, date-default.
"Going with Twilio for SMS alerts." Decision, implies work Review queue.
"Keep the Thursday demo slot for Halden." Decision, status quo Excluded.
☐ @Joe Kim update the shared runbook ASAP Assignment Row. "ASAP" → date-missing.
☐ Someone to check whether the SSO contract renews in June Assignment (to-do block), no owner Row, Unassigned, low. "in June" is the renewal date, not a due date.
☑ @Priya Raman confirm attendee list… Completed to-do Excluded.
☐ @Marco Feld postmortem draft Assignment Duplicate of Marco's EOW commitment. Merged into the 2024-05-17 row.
Parking Lot: "Migrate client dashboards…" Parking lot, no owner or date Excluded.

Output:

## Tasks from: Halden Logistics — Weekly Sync (2024-05-14)
Extracted 8 tasks · 2 high / 5 medium / 1 low confidence · 6 items need review
Schema assumed: default 8 columns. Not checked against prior meetings' open tasks.

### Import file (CSV)
Task,Owner,Due,Status,Source Quote,Source Section,Confidence,Notes
"Send revised SOW to Halden Logistics","Priya Raman","2024-05-16","Not started","I'll send them the revised SOW by Thursday.","Discussion","medium","date-default; ""by Thursday"" → 2024-05-16"
"Draft webhook failure postmortem","Marco Feld","2024-05-17","Not started","I'll get a postmortem draft out end of week. | @Marco Feld postmortem draft","Discussion | Action Items","medium","date-default; merged-duplicate; ""end of week"" → 2024-05-17"
"Send SSO metadata file to Halden team","Sven Ohlsson","2024-05-21","Not started","Sven Ohlsson (Halden IT) will send us the SSO metadata file before the next sync.","Discussion","medium","external-owner; date-default; ""before the next sync"" → 2024-05-21 (weekly cadence)"
"Schedule Q3 training sessions","Joe Kim","2024-05-31","Not started","Ana takes content, Joe takes scheduling, both by May 31.","Discussion","high","split-from-shared"
"Write content for Q3 training plan","Ana Ortiz","2024-05-31","Not started","Ana takes content, Joe takes scheduling, both by May 31.","Discussion","high","split-from-shared"
"Share webhook postmortem with Halden IT lead","Marco Feld","","Not started","Marco, can you also share the postmortem with Halden's IT lead?","Discussion","medium","date-missing; conditional: postmortem reviewed; accepted ""Yep, once it's reviewed."""
"Update the shared runbook","Joe Kim","","Not started","@Joe Kim update the shared runbook ASAP","Action Items","medium","date-missing; ""ASAP"""
"Check whether the SSO contract renews in June","Unassigned","","Not started","Someone to check whether the SSO contract renews in June","Action Items","low","owner-unassigned; date-missing; June is renewal month, not due date"

### Needs a human decision
- Check whether the SSO contract renews in June — no owner, no due date; who takes it, and by when?
- Share webhook postmortem with Halden IT lead — due only "once it's reviewed"; what date should it carry?
- Update the shared runbook — "ASAP" only; what date should Joe Kim work to?
- Send SSO metadata file — Sven Ohlsson was not in the meeting; who confirms with him that he agreed to 2024-05-21?
- Twilio for SMS alerts (decision) — who implements the integration, and by when?
- Revisit pricing tiers (proposal, no owner) — make this a task? If yes, who owns it?

### Excluded (not tasks)
- 2 decisions (1 moved to review), 1 proposal (1 moved to review), 1 info item, 1 completed to-do, 1 parking-lot item, 1 merged duplicate

Quality bar

  • Every Source Quote is found by exact search on the page, comes from a single block, and has 25 words or fewer per " | "-separated segment.
  • Every Owner cell holds exactly one full name or the literal Unassigned. No commas, "and", or "/" in the column.
  • Every non-empty Due matches YYYY-MM-DD and falls on or after the meeting date.
  • Every row tagged date-default has a "{phrase}" → {date} entry in Notes. Recomputing one weekday row from the page's Date property gives the same date.
  • Every Task title starts with an imperative verb and has 80 characters or fewer.
  • No row's quote comes from a Decision, Info, Parking Lot, or ownerless-Proposal block, or from a checked to-do.
  • Every row tagged low, date-missing, external-owner, or possible-conflict has a matching line in "Needs a human decision".
  • The review queue has 8 lines or fewer, plus at most one "+{k} more" line.
  • The CSV header is exactly Task,Owner,Due,Status,Source Quote,Source Section,Confidence,Notes, and every data line parses to 8 fields.
  • Rows are sorted by Due ascending, with blanks last, then by owner surname, with Unassigned last within each date.
  • Header counts equal the actual number of rows, rows per confidence level, and review lines.
  • Notes contains no tag outside the list in Rules.

Failure modes

25+ rows from a 30-minute meeting. Proposals and discussion were classified as commitments. Check: every row's quote must contain a first-person commitment verb, an @mention, a named directive, or come from a to-do block. Move any row whose quote starts with "we should", "maybe", or "might", or ends in "?" without a named addressee, to the review queue.

The organiser owns more than half the rows. "We" and "the team" were defaulted to whoever ran the meeting. Check: count rows per owner. If one person holds more than 50% and their name or speaker label is absent from those rows' quotes, reset those rows to Unassigned and send them to review.

Due dates are off by days or a week. Relative dates were resolved against today instead of the meeting date, or a same-weekday phrase ("Tuesday" in a Tuesday meeting) was resolved to the meeting day itself. Check: recompute every date-default row from the page's Date property using step 4. Any mismatch means redoing all relative dates.

Timing words became due dates. "Renews in June", "launch is in Q3", or "since the 9th" were read as deadlines. Check: for each Due, confirm the date phrase in the quote attaches to the verb of the task, not to its object.

Completed work reappears as new tasks. Checked to-dos were exported as Not started. Check: search the page for ☑ or checked blocks, and confirm none of their texts appear as quotes in the CSV.

Import fails or columns shift. Unescaped commas or quotes in Source Quote or Notes. Check: parse the CSV and confirm every line has 8 fields and every internal " is doubled.

The reviewer cannot find a quote on the page. The quote was paraphrased, had its speaker label left in, or was stitched across blocks. Check: search the page for the first 6 words of each quote segment. Any miss means re-copying verbatim from one block.

License

MIT