Files
Bryan Gilliom (via Claude) 2209a19eb7 Fix print CSS bug and fold in real-world findings from the first live invocation
First test run (Oshkosh GO Transit internal kickoff, via the actual
installed skill, not Claude manually walking the SKILL.md) surfaced real,
fixable gaps. All fixed here:

1. Print CSS bug (root cause, found by Bryan): section{break-inside:
   avoid-page} plus whole-table break-inside:avoid caused a 14-page,
   mostly-blank PDF. Fixed: sections can split across pages now; only
   cards/table-rows avoid splitting, with repeating table headers.

2. SO/PO lookup was wrongly scoped out of this brief type by default.
   Wrong -- an internal kickoff about a real sale needs the SO/PO as much
   as any external brief would. Scope is now by topic nature (commercial
   vs. purely internal), not by brief-type name.

3. Contact-info lookup (not just name resolution) is now an explicit
   standing step in attendee capture, starting from a linked SO/PO's own
   Odoo contacts when one exists.

4. Added the MPM Technical Reference System (a 131-file Drive registry:
   brand, platform, display tech, products, engineering, concepts, proof)
   as a standing reference for part-number/product verification --
   previously unknown to this skill.

5. Pulled the real run's improved _topic-state.md schema back into the
   spec: confidence tags (verified/stated/open), a folder-layout header,
   numbered-vs-proposed open items, a Findings/flags section. These
   emerged from real use and are now documented, not one-off.

6. Meeting transcript archival (a Meeting Transcripts/ subfolder) is now
   a standing step, not something that has to be asked for.

7. section-structure.md: flow and specbar are now marked validated (real
   examples: Oshkosh deployment sequence, billing milestones). Added the
   meeting-vs-proposed open-items badge pattern and a standard
   confidentiality footer note for this brief type.

None of this was a failure of judgment in the moment -- these are gaps
between what the file said and what real use needed, now closed.
2026-09-22 21:34:20 +00:00

20 KiB

name, description
name description
internal-meeting-brief 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.

Meeting record — the source varies. Ask, don't assume Plaud. Recap mode needs some record of what was discussed; which kind depends on how MPM actually recorded that particular meeting, which isn't fixed. In rough order of how much structure they give you, and check whichever plausibly applies rather than defaulting to the first one tried before:

  • Plaud — if used, the official Plaud connector (get_current_user, list_files, get_file, get_transcript, get_note) — not the deprecated Plaud MCP connector. Resolve a recording's file_id via list_files(query=...) — never assume a Plaud web-app URL's slug is the API file_id directly; the real id carries an of_ prefix the web URL doesn't show. get_transcript paginates (next_cursor) — loop until null. get_note returns the AI summary/action-items tab separately — worth pulling alongside the transcript.
  • Google Meet transcript — typically lands as a Google Doc in Drive (often in a "Meet Recordings" folder or attached to the Calendar event) — search Drive/Calendar, don't assume it doesn't exist just because Plaud has nothing.
  • Teams transcript, or any other recording tool MPM starts using — same principle: ask where it lives before concluding no record exists.
  • No transcript at all — perfectly valid. Fall back to whatever does exist for that meeting: the person's own notes, a task registry, prior emails/Chat about it. State plainly in Notes & Flags that no transcript was available and the brief is built from secondary sources — this is the never-fabricate rule applying to the source, not just the content.

If it's not obvious which source applies, ask the person rather than trying each connector in sequence and treating empty results as "nothing exists here." An empty result from one source is not evidence the meeting has no record at all.

Other tools this skill uses:

  • Odoo (MCP) — linked Project/tasks, Sales/Purchase Orders, Knowledge Base, Helpdesk tickets, and contacts (customer/partner/sales-rep records tied to an SO/PO)
  • Google Workspace (MCP) — Gmail, Google Chat, Drive, Sheets
  • Google Drive — the topic's continuity folder (_topic-state.md + brief history
    • Meeting Briefs/ + Meeting Transcripts/)
  • MPM Technical Reference System — a Drive-based product/technical knowledge registry (131 entity files as of 2026-09-22: brand voice, platform/software, display technologies, products, engineering, concepts, proof/evidence). Read _INDEX.md first — it's the routing table — then only the specific files a claim actually needs. This is where part numbers, model codes, and product/technical claims get verified; it is not this skill's content to maintain, only to reference.

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 — ALWAYS, before anything else

Open _topic-state.md in the topic folder. This is not optional and does not need to be asked about — do it automatically, every run, as the first real action. If it doesn't exist, this is the topic's first run: create it immediately with the schema below, then expect a fuller interview in the following steps since there's no history to draw on yet.

Schema — refined 2026-09-22 against a real production run (Oshkosh GO Transit kickoff), which improved on the original design in ways worth keeping permanently:

  • Confidence tags on every factual claim: verified (checked against a source document — an SO, a PO, an Odoo record), stated (said by someone in the meeting or by the person running the brief, not independently confirmed), open (unresolved — including outright conflicts between two sources, e.g. an address that differs between a PO and its matching SO). Do not present a stated fact with the same confidence as a verified one.
  • Folder layout section at the top of the manifest, documenting what's actually in the topic folder (including subfolders Brief didn't create, like a pre-existing Financial/ folder) — self-documenting, so opening the manifest alone orients someone to the whole folder.
  • Links table: linked Odoo Project ID, SO, PO, Chat Space, Plaud recording pattern, relevant Gmail thread(s), and — critically — the actual people resolved from those records (customer contact, reseller/partner contact, MPM sales rep), each with role, email, phone, and its confidence tag. See step 4.
  • Decisions ledger and Open items ledger as two separate tables. Open items get sequential numbers (1, 2, 3...) for things actually assigned/committed in the meeting, and a separate P-prefixed series (P1, P2...) for things suggested during the meeting but not yet formally assigned — don't conflate a live suggestion with a committed action item.
  • Findings / flags section for meta-observations worth carrying forward that don't fit the ledgers — e.g. "this topic's Plaud AI summary is unreliable, build from the raw transcript" or a specific diarization error spotted at a timestamp. This is where operational lessons about the data sources themselves get recorded, not just facts about the topic.
  • Related documents table for cross-referencing other MPM document types about the same real-world topic (pre-mortems, BAI build docs, a technical reference registry, etc. — see CW-027 Concept.md's rewrap-vs-harvest principle; don't merge their content into this ledger, just reference them).
  • Brief history log (date/type/mode/file link(s) — both HTML and PDF if a PDF exists).

Append to this file; don't rewrite history. On every subsequent run, read the whole thing before doing anything else — it's the difference between starting fresh and starting from zero.

3. Determine mode: Agenda or Recap

Agenda mode (pre-meeting prep) pulls the previous meeting's record and any updates since. Recap mode (post-meeting) pulls the current meeting's record. Ask if not specified by the request. "Record" — see Prerequisites above — is whatever source actually applies for that meeting, not necessarily Plaud.

4. Capture and normalize attendees — and resolve real contact info, always

  • 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 transcript available (any source): 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 — cross-reference against Odoo to resolve real contact info (email, phone, title, company), not just a confirmed spelling of a name. This is a standing step, not something to be asked to do: if the topic has a linked SO or PO, pull the Odoo contacts tied to those records first (customer contact, reseller/partner PM, sales rep) — this is usually faster and more accurate than a generic contact search, and surfaces exactly who the real counterparts are even if they weren't in the meeting. If someone's name as heard doesn't match Odoo cleanly (a misheard surname, a title mismatch), flag it in Findings/flags as open rather than silently picking one.
  • If a speaker's diarization didn't resolve 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," but scope by what the topic actually is, not a fixed list per brief type:

  • The meeting record (per mode, above) — the primary source, whichever tool it actually lives in
  • 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 Order / Purchase Order — pull whenever the topic is a real customer or reseller engagement, not just for vendor-partner-brief/status-update-brief. Correction from initial design: an internal kickoff meeting about a real sale (an internal-meeting-brief, by audience) still needs the SO/PO — that's where the scope, the customer, the reseller/partner, and the real contacts actually live. The dividing line is the topic's nature (commercial engagement vs. purely internal process work like a booth build), not the brief type's name. Search Odoo by customer/topic name if not already linked in the manifest.
  • Part numbers / product/technical claims — check them against the MPM Technical Reference System (a Drive-based registry; read _INDEX.md first, then _RULES.md for the confidence-tag contract, then only the specific entity files the topic needs — e.g. 30-products/model-code-grammar.md for verifying a model number's structure, or the relevant 30-products/* file for a named display family). Don't guess at whether a model number or part number is right — verify it here, or flag it open if the registry doesn't resolve it (e.g. a variant with no assigned code yet). This registry is a genuine dependency, not this skill's own content to maintain — see Dependencies.

Helpdesk ticket review is still a deliberate, manual exception (see below) — not pulled automatically regardless of topic type.

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). Small brief-specific CSS additions beyond the shared stylesheet (e.g. a status-source badge, a role subtitle under an attendee's name) are fine — append them, don't fork the canonical rules to get the same effect.

Footer confidentiality note — standard for this brief type. internal-meeting-brief is, by definition, internal content. End the footer with an explicit statement of that (e.g. "Internal. Do not forward to [named external party]." when the topic has one) — validated in the Oshkosh brief, where this genuinely matters: the brief discusses a reseller/customer deal in more candid terms than anyone would want forwarded to that customer.

8. Archive — the brief, the transcript, and the manifest update

  • Save the generated HTML into the topic folder's Meeting Briefs/ subfolder (YYYY-MM-DD <Meeting> - <Mode> Brief.html). If a PDF was also generated, save it alongside with the matching name.
  • Save a plain-text copy of the meeting record into a Meeting Transcripts/ subfolder (YYYY-MM-DD <source name> - Transcript.txt) — a standing step, not something to be asked for. This matters beyond convenience: it makes the topic resilient to the source connector being unavailable later (Plaud specifically has had real, live connector problems this project — see Resolved limitation below), and it's the raw material a future brief needs if it has to re-derive something the original brief didn't capture.
  • Update _topic-state.md: append to the brief-history log (both file links), update the decisions and open-items ledgers (carry forward anything still open, close anything resolved, add new items with the correct sequential/P-prefixed numbering — see step 2), update the attendee list and any newly-resolved contact info, update Findings/flags with anything learned this run, 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.

First real invocation — findings (2026-09-22)

The first time this skill ran from an actual installed invocation (not Claude manually walking through this file) — a recap brief for an Oshkosh GO Transit internal kickoff. Real, valuable findings, each fixed in this revision:

  1. Print CSS bug — fixed. section{break-inside:avoid-page;} and whole-table break-inside:avoid in the shared stylesheet's @media print block caused a 14-page, mostly-blank PDF: any section taller than the remaining space on a page got pushed whole to the next page, leaving the gap behind blank. Fixed in assets/brief-components.css: sections can split across pages now; only the small atomic elements (cards, individual table rows) avoid splitting, with table headers repeating on each new page. A correctly-generated PDF from the same content came out 6 clean pages.
  2. SO/PO lookup was wrongly scoped out by default — fixed. Original design said Sales/Purchase Orders "aren't typically relevant" to this brief type. Wrong: an internal kickoff about a real sale needs them just as much as an external brief would. Corrected in step 5 — the deciding factor is whether the topic is a commercial engagement, not which brief type is generating the document.
  3. Contact-info lookup had to be manually requested — now a standing step. Resolving attendee names wasn't enough; real contact info (email, phone, title) for external counterparts needed to be pulled from Odoo, and doing that well meant starting from the linked SO/PO's own contacts rather than a generic search. Now explicit in step 4, not something that needs to be asked for.
  4. Part number / product verification wasn't referenced at all — now is. The actual run needed to check a model variant and part number against MPM's product catalog. The right source turned out to be the MPM Technical Reference System (see Prerequisites) — added as a standing reference, not previously known to this skill.
  5. The manifest schema got meaningfully better in real use — pulled back into the spec. Confidence tags (verified/stated/open), a folder-layout header, split numbered-vs-proposed open items, and a Findings/flags section for operational observations (e.g. "this topic's Plaud AI summary is unreliable, build from the raw transcript") all emerged from the real run and are now part of the documented schema in step 2, not a one-off improvisation.
  6. Meeting transcript wasn't being archived — now a standing step. The raw transcript needed to be saved alongside the brief so future runs don't depend on the source connector still being reachable. Now explicit in step 8.

None of these were failures of judgment in the moment — they're gaps between what this file said and what turned out to actually be needed, now closed.

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.