---
name: capture-tickets-from-notes
description: Scan a project's meeting notes (Fireflies, Gemini/Meet, personal notes) for new action items, distil them into scrubbed ticket drafts, and — after approval — post them to the PM tool (ClickUp/Asana/Notion/Jira) where the ticket-fetcher picks them up. The intake counterpart to the ticket-fetcher.
disable-model-invocation: true
argument-hint: "[project path or notes scope]"
---

# Capture tickets from meeting notes

Turn meeting notes into tickets. This skill reads a project's notes, finds the **action items** in them, distils each into a **scrubbed, discipline-tagged** ticket draft, shows you the drafts for approval, and posts the approved ones to the PM tool. Once posted, the existing `/launch-data-team` `ticket-fetcher` picks them up — so the PM tool stays the single source of truth.

`$ARGUMENTS` may name the project repo path and/or the notes scope (e.g. "notes since last run", "this week's standups").

Run this from the **lead / main session** — it posts to the PM tool, which needs credentials only the main session holds. The peer `note-scout` agent does the read-and-distil half when you're running the full data team; this skill is the standalone entry point that also does the posting.

## Connection-mode note (read before running on client notes)

This skill runs on either connection by design — it is **not** Bedrock-gated the way data tasks are. But meeting notes routinely contain client specifics, and on the Anthropic API the raw notes pass through Anthropic during distillation even though the tickets you post are scrubbed. For genuinely sensitive client notes, prefer running on **Bedrock** (`claude-db` / `bedrock-on`). The scrub (below) is what protects the client when you do run on the API — when in doubt, scrub harder. Full rationale in `${CLAUDE_SKILL_DIR}/references/notes-config.md`.

## Steps

1. **Resolve the notes config.** Find where this project keeps its notes and where tickets should go:
   - First look for a `## Meeting notes` section in the project `CLAUDE.md`.
   - Fall back to `.gemma/notes-config.yml` at the repo root.
   - The config gives `notes_dir` (local path), an optional `api_source` (Fireflies/Drive — a 1Password item *reference*, never an inline secret), and the `clickup` (or other PM-tool) target list/space. Schema and examples: `${CLAUDE_SKILL_DIR}/references/notes-config.md`.
   - If neither exists, ask the user for the notes directory and PM-tool target, and offer to write a starter `.gemma/notes-config.yml`. Don't guess.

2. **Detect what's new.** Read the state marker `.gemma/notes-state.json` (create it on first run). For each note in `notes_dir`, compute a content hash; a note is **new** if it's absent from the marker or its hash changed. For an `api_source`, the **lead** pre-fetches the transcripts (credential boundary) and you process those whose transcript ID isn't in the marker. Report which notes you skipped as already-processed — never silently drop one.

3. **Distil + scrub action items.** From each new note, extract genuine action items (a decision that implies work, an explicit "X will do Y", a follow-up). For each, draft one ticket — and **scrub it to generic, actionable form**:
   - **Keep**: the action, a generic description with acceptance criteria where stated, a discipline-tag guess (`de`/`ae`/`da`/`ds`/`qa`), source attribution (note **filename + date** only), and priority/due **only if the note states them**.
   - **Strip**: client/person names, revenue and other figures, raw client quotes, client-specific schema/column names, anything identifying the engagement.
   - Split cross-discipline actions into per-discipline drafts with a noted dependency (e.g. `ae` depends on `de`).
   - See the scrubbing rules in `${CLAUDE_SKILL_DIR}/references/notes-config.md`.

4. **Dedup.** Drop drafts that already exist as PM-tool tickets or as entries in the project `MEMORY.md` (reuse the `ticket-fetcher`'s dedup discipline). Note what you matched against.

5. **Approval gate (required).** Present the surviving drafts as a review table — title, discipline, source note, priority/due if any, open questions. The user **approves / edits / drops** each. Post **only** what's approved. This mirrors the `learning-synthesizer` gate: nothing reaches the PM tool without a human OK.

6. **Post the approved drafts** to the PM tool (tool-agnostic — use the connected MCP server, else the configured API token the main session holds). Use the same tool-specific gotchas the `ticket-fetcher` documents (ClickUp `team_id`, localised statuses, `custom_id` lookups).

7. **Record + report.** Write the processed notes (path + hash) and the posted ticket IDs into `.gemma/notes-state.json` so they're never re-proposed. Report a concise summary: notes read, drafts proposed, approved/posted (with ticket links), dropped-as-duplicate (with what matched), and skipped-as-already-processed.

## Boundaries

- **Approval-first, always.** Messy notes produce noisy drafts — the human gate is the quality bar. Never auto-post.
- **The PM tool stays canonical.** Post to the PM tool and let the `ticket-fetcher` enqueue; don't write tickets straight onto the shared task list as if already triaged.
- **Scrub before posting.** No client names, figures, or PII in a ticket. If you can't express the action without a specific, write it generically and flag the gap for the user.
- **Never invent priorities or due dates** — carry only what the note states; otherwise leave them unset for the fetcher/lead to assign.
- **Secrets policy** — never read, request, or echo credential values; `api_source` tokens are referenced by 1Password item, fetched by the main session, never inlined.
