Root cause found: the web app's recording URL slug is missing the 'of_' prefix the API's real file_id requires — direct lookup by URL id always 404'd regardless of which connector or account. Fixed by resolving the id via list_files(query=...) instead. Also: stop using the deprecated 'Plaud MCP' connector entirely, use the official 'Plaud' connector only. Verified live: pulled the 09-16 meeting transcript for real via the official connector, content matches the manually-uploaded transcript used to build the first brief. Recap mode's live data path is now confirmed working end-to-end, not just designed.
160 lines
9.8 KiB
Markdown
160 lines
9.8 KiB
Markdown
---
|
|
name: internal-meeting-brief
|
|
description: Generate an MPM-branded internal meeting briefing document as a single-file HTML artifact — covers internal planning sessions, executive leadership meetings, and project team meetings (e.g. APTA planning, status reviews, internal design discussions). Produces agenda-mode (pre-meeting prep, pulling the previous meeting's transcript) or recap-mode (post-meeting summary, pulling the current meeting's transcript). Always use this skill when the user asks to "brief this meeting," "recap the meeting," "prep me for [meeting]," "write up the [meeting name] meeting," or names an internal MPM meeting/topic and wants it documented or summarized — even if they don't say "internal-meeting-brief" by name or don't mention CoWork/Brief explicitly. Part of the CW-027 Brief plugin family; see git.mpm.to/mpm/brief.
|
|
---
|
|
|
|
# internal-meeting-brief
|
|
|
|
Generates a single self-contained HTML briefing document for an internal MPM meeting,
|
|
built on Brief's shared MPM-branded component library. Does the work of assembling the
|
|
brief itself — pulling from connected tools — rather than requiring the person to
|
|
hand-supply meeting notes.
|
|
|
|
Read `assets/brief-components.css` and `references/section-structure.md` before
|
|
generating any brief. The CSS is the canonical, only source of Brief's visual
|
|
language — never re-derive it inline. The section-structure doc is the fixed-vs-dynamic
|
|
contract for what this skill's output actually contains.
|
|
|
|
## Prerequisites
|
|
|
|
This skill uses, but does not own, the following connected tools — confirm they're
|
|
reachable before starting, and degrade gracefully (see Hard Rules) if one isn't:
|
|
- **Plaud** — meeting transcripts (recap: current meeting; agenda: previous meeting).
|
|
Use the official `Plaud` connector (`get_current_user`, `list_files`, `get_file`,
|
|
`get_transcript`, `get_note`) — **not** the older `Plaud MCP` connector, which
|
|
predates Plaud's own official one and should be treated as deprecated. Resolve a
|
|
recording's `file_id` via `list_files` (filter by `query`/`date_from`/`date_to`) —
|
|
never assume a Plaud web-app URL's slug is the API `file_id` directly; the API id
|
|
carries an `of_` prefix the web URL does not show. `get_transcript` paginates
|
|
(`next_cursor`) — loop until it's null before treating the transcript as complete.
|
|
`get_note` returns the AI summary/action items tab separately from the raw
|
|
transcript — worth pulling alongside `get_transcript`, not instead of it.
|
|
- **Odoo** (MCP) — linked Project/tasks, Sales/Purchase Orders, Knowledge Base,
|
|
Helpdesk tickets
|
|
- **Google Workspace** (MCP) — Gmail, Google Chat, Drive, Sheets
|
|
- **Google Drive** — the topic's continuity folder (`_topic-state.md` + brief history)
|
|
|
|
If any of these fail outright (not just "returns nothing," but errors or times out),
|
|
say so plainly in the generated brief's Notes & Flags section rather than silently
|
|
omitting that source. See "Known limitation" below for a real, currently-open example.
|
|
|
|
## Workflow
|
|
|
|
### 1. Resolve the topic
|
|
Every brief belongs to a project/topic, not just a meeting instance. Ask which
|
|
topic/project this meeting is about if it isn't obvious from context. Search Google
|
|
Drive for an existing topic folder (naming pattern: `<Topic Name> — Meeting Briefs`)
|
|
before creating a new one. If an Odoo Project already exists for this topic and has an
|
|
attached Drive folder, use that folder instead of creating a parallel one.
|
|
|
|
### 2. Read (or create) the continuity manifest
|
|
Open `_topic-state.md` in the topic folder. If it doesn't exist, this is the topic's
|
|
first run — create it with the schema below, and expect a fuller interview in the
|
|
following steps since there's no history to draw on yet.
|
|
|
|
`_topic-state.md` schema: linked Odoo Project ID / SO / PO, linked Google Chat Space,
|
|
Plaud recording ID/pattern, last-meeting date, running open-items/decisions ledger,
|
|
attendee list, learned spreadsheet task-registry column mapping (if this topic uses one
|
|
— see step 5), brief-history log (date/type/mode/link), and a "Related documents"
|
|
table for cross-referencing other MPM document types about the same real-world topic
|
|
(pre-mortems, BAI build docs, etc. — see CW-027 Concept.md's rewrap-vs-harvest
|
|
principle; don't merge their content into this ledger, just reference them).
|
|
|
|
### 3. Determine mode: Agenda or Recap
|
|
Agenda mode (pre-meeting prep) pulls the *previous* meeting's transcript and any
|
|
updates since. Recap mode (post-meeting) pulls the *current* meeting's transcript. Ask
|
|
if not specified by the request.
|
|
|
|
### 4. Capture and normalize attendees
|
|
- **First run for this topic:** ask who's attending / who attended.
|
|
- **Recurring topic:** pre-fill from the manifest's last attendee list and ask "same as
|
|
last time, or any changes?" — not a blank-slate interview.
|
|
- **Recap mode with a Plaud transcript available:** prefer *actual* attendance from the
|
|
transcript's speaker attribution over the pre-meeting expected list — someone who
|
|
showed up unexpectedly and spoke shouldn't be treated as absent.
|
|
- **Normalize into two groups:**
|
|
- Internal MPM attendees — record by name for the brief; no further resolution
|
|
needed (no external allowlist implications for this brief type).
|
|
- External attendees (rare for this brief type, but possible) — cross-reference
|
|
against Odoo contacts to resolve/confirm email addresses rather than trusting raw
|
|
input.
|
|
- **If Plaud's diarization didn't resolve a speaker to a name:** render the literal
|
|
transcript label ("Speaker 1," "Speaker 3"). Do not guess a name from context, even
|
|
when a guess feels obvious. Flag unresolved speakers in the Notes & Flags section.
|
|
|
|
### 5. Pull data, scoped to what this brief type actually needs
|
|
Not a monolithic "pull everything" — internal-meeting-brief's real needs, based on the
|
|
first run, are:
|
|
- Plaud transcript (per mode, above) — the primary source
|
|
- Gmail / Google Chat: updates since the manifest's last-meeting date, scoped by
|
|
project/topic keywords, never a blanket search
|
|
- Odoo Project tasks, if a linked project exists (expect this to be sparse or absent —
|
|
PM-tool adoption is inconsistent; fall back to a spreadsheet task registry if the
|
|
topic uses one, learned via a one-time interview on first use and stored in the
|
|
manifest, never assumed to follow a universal schema)
|
|
|
|
Sales/Purchase Orders and Helpdesk ticket review are not typically relevant to this
|
|
brief type (they matter more to vendor-partner-brief and status-update-brief) — don't
|
|
pull them by default.
|
|
|
|
### 6. Synthesize into the section structure
|
|
Follow `references/section-structure.md` exactly: six fixed sections in order, dynamic
|
|
sections only where the meeting's actual content has a structure that calls for one.
|
|
Real, verified content over generic summary — carry forward specific facts (names,
|
|
dates, exact technical decisions), not vague paraphrase.
|
|
|
|
### 7. Render
|
|
Single self-contained HTML file. Include `assets/brief-components.css` inline (don't
|
|
link out to it — the brief must survive as a standalone file). Include: sticky jump-nav,
|
|
a working light/dark toggle (`data-theme` attribute, default light), and the
|
|
`@media print` rules from the shared CSS (forces light, hides nav/toggle, avoids
|
|
awkward page breaks).
|
|
|
|
### 8. Archive
|
|
Save the generated HTML into the topic's Drive folder. Update `_topic-state.md`: append
|
|
to the brief-history log, update the running open-items/decisions ledger (carry forward
|
|
anything still open from this run), update the attendee list, update last-meeting date.
|
|
|
|
### 9. Present
|
|
Hand the file to the person. Don't silently skip presenting it even if archived — the
|
|
person needs to actually see and review it, not just trust it happened.
|
|
|
|
## Hard rules
|
|
|
|
- **Never fabricate.** No matching Plaud recording, no linked Odoo data, an empty
|
|
Gmail/Chat scan — say so plainly in Notes & Flags. A brief with visible gaps is
|
|
correct; a brief with invented content to fill them is not.
|
|
- **Bounded queries only.** Gmail/Chat scans are scoped by project keyword + date
|
|
window from the manifest. Never an open-ended search.
|
|
- **No live publishing yet.** This skill produces a local file only. Hosting/publishing
|
|
(a shareable link, external access control) is CW-029 (Brief Server) — deliberately
|
|
separate, deliberately not built yet. Don't attempt to stand up delivery
|
|
infrastructure as part of running this skill.
|
|
|
|
## Resolved limitation (was open 2026-09-21, fixed 2026-09-22)
|
|
|
|
Earlier attempts to pull this skill's first real test recording failed for two
|
|
compounding reasons, now both understood:
|
|
1. The deprecated `Plaud MCP` connector's `list`/`search` tools returned empty results
|
|
or timed out regardless of parameters — root cause not fully diagnosed, but moot:
|
|
don't use that connector at all (see Prerequisites above).
|
|
2. Direct lookup via the *official* `Plaud` connector's `get_file`/`get_transcript`
|
|
still 404'd, because the id taken from the Plaud web app's URL
|
|
(`b0df60b679f31383f770d91db6b5bf46`) was missing the `of_` prefix the API's real
|
|
`file_id` requires (`of_b0df60b679f31383f770d91db6b5bf46`). Resolving the id via
|
|
`list_files(query=...)` instead of reading it off a URL fixed this immediately.
|
|
|
|
Verified 2026-09-22: a live pull via the official connector for this same recording
|
|
returned content matching the manually-uploaded transcript used to build the first
|
|
real brief, confirming both that the fix works and that the original brief's content
|
|
was accurate. Recap mode's live data path is now confirmed working end-to-end.
|
|
|
|
## Provenance
|
|
|
|
Component library, tokens, and this workflow were derived from two real test runs
|
|
(2026-09-21): a recap brief for a real APTA 2026 booth planning meeting, and a
|
|
rewrap of an unrelated pre-mortem document to validate the component system against a
|
|
different content shape. See CW-027's Concept.md (Drive) for full design history and
|
|
the five other planned skills in this family (vendor-partner-brief, status-update-brief,
|
|
five-whys-brief, kickoff-brief, development-brief) — none built yet.
|