{"slug":"minutes-tag-2","title":"minutes-tag","summary":"Lightweight outcome tagging for meetings — won, lost, stalled, great, or noise. Use whenever the user says \"tag this meeting\", \"mark that as a win\", \"that one was a loss\", \"tag yesterday's call as stalled\", \"mark this great\", \"that meeting was noise\", \"label that meeting\", or any","platform":"opencode","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-08-27T16:57:51.097209Z","repo":{"url":"https://github.com/silverstein/minutes","stars":1501,"forks":165,"license":"MIT","updatedAt":"2026-09-25T06:14:41Z"},"bodyHtml":"<hr>\n<h2>name: minutes-tag\ndescription: Lightweight outcome tagging for meetings — won, lost, stalled, great, or noise. Use whenever the user says \"tag this meeting\", \"mark that as a win\", \"that one was a loss\", \"tag yesterday's call as stalled\", \"mark this great\", \"that meeting was noise\", \"label that meeting\", or any time they describe a meeting outcome in passing. Tagging takes 5 seconds and unlocks /minutes-mirror correlation analysis — the more meetings get tagged, the smarter mirror gets at telling the user what behavior patterns lead to wins. Surface this skill any time the user mentions a meeting result, win, loss, or wasted time.\ncompatibility: opencode</h2>\n<h2>Skill Path</h2>\n<p>Before running helper scripts or opening bundled references, set:</p>\n<pre><code>export MINUTES_SKILLS_ROOT=\"$(git rev-parse --show-toplevel)/.opencode/skills\"\nexport MINUTES_SKILL_ROOT=\"$MINUTES_SKILLS_ROOT/minutes-tag\"\n</code></pre>\n<h1>/minutes-tag</h1>\n<p>Lightweight outcome tagging — adds an <code>outcome:</code> field to a meeting's frontmatter so <code>/minutes-mirror</code> can correlate the user's behavior with their results over time.</p>\n<p>The whole point of this skill is <strong>speed</strong>. Tagging should take 5 seconds, not 5 questions. Don't be precious about it — most users will never adopt tagging if it feels like data entry.</p>\n<h2>How it works</h2>\n<h3>Phase 1: Identify the meeting</h3>\n<p>Three patterns the user might use. <strong>Always filter to meetings, not voice memos</strong> — voice memos can't be \"won\" or \"lost\".</p>\n<p><strong>1. Most recent</strong> (\"tag this meeting\", \"mark that as a win\", \"tag the call I just finished\"):</p>\n<pre><code>minutes list --content-type meeting --limit 1\n</code></pre>\n<p>Use the most recent. <strong>Don't ask which one</strong> — that defeats the speed promise. The default behavior should always be \"the call you just had\".</p>\n<p><strong>2. By date</strong> (\"tag yesterday's call\", \"tag the Tuesday call\"):</p>\n<pre><code>minutes list --content-type meeting --limit 10\n</code></pre>\n<p>Pick the meeting matching the date. If multiple meetings match the same day, ask once: \"You had </p>\n<p><strong>3. By name</strong> (\"tag my call with Sarah as a win\"):</p>\n<pre><code>minutes search \"&lt;name&gt;\" --content-type meeting --limit 5\n</code></pre>\n<p>Pick the most recent. If ambiguous, ask once.</p>\n<h3>Phase 2: Identify the tag</h3>\n<p>If the user already named the outcome in their message (\"tag that as a win\"), use it directly. Don't ask again — they already told you.</p>\n<p>If they haven't, ask via AskUserQuestion with these standard options:</p>\n<ul>\n<li><strong>won</strong> — got the outcome you wanted (deal closed, decision made, agreement reached)</li>\n<li><strong>lost</strong> — didn't get what you wanted (deal lost, idea rejected, no decision)</li>\n<li><strong>stalled</strong> — neither — went sideways, no clear outcome, needs another meeting</li>\n<li><strong>great</strong> — high-quality conversation regardless of outcome (insight, real connection, energy, learned something)</li>\n<li><strong>noise</strong> — should have been an email; no value; time wasted</li>\n<li><strong>(custom)</strong> — let the user provide their own tag</li>\n</ul>\n<p>Standard tags are the only ones <code>/minutes-mirror</code> will correlate. Custom tags are stored faithfully but won't appear in correlation analysis — warn the user gently if they pick a custom one: \"Custom tags are saved, but mirror only correlates the standard five.\"</p>\n<h3>Phase 3: Capture a note <strong>only if the user gave one in their message</strong></h3>\n<p><strong>Do not ask an interactive note question.</strong> That's a second prompt and it breaks the speed promise.</p>\n<p>Parse the user's original message for a \"why\" or note. Common patterns:</p>\n<ul>\n<li>\"tag as won, <strong>note: Sarah committed to monthly billing</strong>\" → note = \"Sarah committed to monthly billing\"</li>\n<li>\"tag won — <strong>got the verbal commit on pricing</strong>\" → note = \"got the verbal commit on pricing\"</li>\n<li>\"tag stalled <strong>because Alex postponed the decision</strong>\" → note = \"Alex postponed the decision\"</li>\n</ul>\n<p>If you find a note in the message, use it. If you don't, <strong>leave <code>outcome_note</code> out of the frontmatter entirely</strong>. Don't insert an empty field. Don't ask. Users who want a fuller record have <code>/minutes-debrief</code> for that.</p>\n<h3>Phase 4: Edit the frontmatter via the bundled helper script</h3>\n<p><strong>Use the script — do not Edit the frontmatter manually.</strong> YAML frontmatter is fragile, and the script handles all the edge cases (no existing frontmatter, existing outcome that needs replacement, atomic write to prevent half-edits, preservation of all other fields).</p>\n<pre><code>python3 \"$MINUTES_SKILL_ROOT/scripts/tag_apply.py\" \\\n  \"&lt;absolute-path-to-meeting-file&gt;\" \\\n  --outcome &lt;won|lost|stalled|great|noise|custom&gt; \\\n  [--note \"the optional one-line note from Phase 3\"]\n</code></pre>\n<p>Pass <code>--note</code> only if Phase 3 found a note in the user's message. Skip the flag entirely otherwise — the script will omit <code>outcome_note</code> from the frontmatter rather than inserting an empty field.</p>\n<p><strong>What the script guarantees:</strong></p>\n<ul>\n<li>The new fields (<code>outcome</code>, <code>outcome_note</code> if a note was passed, <code>tagged_at</code>) are inserted just before the closing <code>---</code> of the frontmatter, after every other existing field.</li>\n<li>All other frontmatter fields are preserved <strong>byte-for-byte</strong> — no reordering, no reformatting, no whitespace changes.</li>\n<li>Re-tagging is fully idempotent: if <code>outcome:</code> already exists, the script removes the old outcome lines and re-inserts fresh ones at the end. Old <code>outcome_note:</code> is dropped if no new note is passed.</li>\n<li>The body of the meeting file is never touched — only the frontmatter block.</li>\n<li>Writes are atomic (temp file + rename) so an interrupted run can never leave a half-written meeting.</li>\n</ul>\n<p>The script prints <code>{\"status\": \"ok\", ...}</code> to stdout on success, or <code>{\"error\": \"...\"}</code> to stderr with non-zero exit on failure. Surface any error to the user.</p>\n<p><strong>Fallback if Python isn't available</strong> (extremely rare on macOS): use the <code>Edit</code> tool with surgical precision. Find the closing <code>---</code> of the frontmatter, anchor on a small unique block ending in it, and insert your new fields right before. This is brittle on unusual frontmatter — only do it if the script fails.</p>\n<h3>Phase 5: Confirm and nudge</h3>\n<p>Confirm in <strong>one line</strong>: \"Tagged <strong></strong> as <strong></strong>.\"</p>\n<p>Then verify the file is still parseable by Minutes after the edit. The slug is the filename minus <code>.md</code> (e.g., <code>2026-03-18-product-roadmap-with-case</code>):</p>\n<pre><code>minutes get \"&lt;filename-without-.md&gt;\" 2&gt;&amp;1 | head -3\n</code></pre>\n<p>If the output contains an error or warning about malformed frontmatter, surface it gently: \"Note: this meeting's frontmatter has a pre-existing schema issue. The tag was saved, but <code>/minutes-mirror</code> may skip this meeting until it's fixed.\" Don't try to fix the unrelated schema issue — that's not tag's job.</p>\n<p><strong>One-time lifetime nudge</strong> (idempotent — never repeats):</p>\n<pre><code>ls ~/.minutes/tag-nudge-shown 2&gt;/dev/null\n</code></pre>\n<p>If that marker file doesn't exist, this is the first time tag has run on this machine. Show the nudge once, then create the marker:</p>\n<blockquote>\n<p>\"First tag — nice. When you've tagged ~10 meetings, run <code>/minutes-mirror trends</code> and I'll show you what your winning meetings have in common.\"</p>\n</blockquote>\n<pre><code>mkdir -p ~/.minutes &amp;&amp; touch ~/.minutes/tag-nudge-shown\n</code></pre>\n<p>The marker file is the state. No counting, no edge cases, no risk of repeated nudges from re-tagging the same meeting.</p>\n<h2>Gotchas</h2>\n<ul>\n<li><strong>Speed is the entire feature.</strong> If tagging takes more than two questions (the tag, optionally the note), you've broken it. Default to \"most recent\". Skip the optional note unless the user clearly wants to add one.</li>\n<li><strong>Standard tags only correlate.</strong> Mirror's correlation analysis only works on the five standard tags: <code>won</code>, <code>lost</code>, <code>stalled</code>, <code>great</code>, <code>noise</code>. Custom tags are saved but won't be analyzed. Warn the user once if they pick a custom tag — don't lecture them, just let them know.</li>\n<li><strong>Don't touch the meeting body.</strong> Only edit the YAML frontmatter block between the first two <code>---</code> markers. Use <code>Edit</code> with surgical precision.</li>\n<li><strong>Re-tagging is intentional.</strong> If the user tags a meeting that's already tagged, overwrite it cleanly. They're either correcting themselves or seeing it differently after the fact. Both are valid.</li>\n<li><strong>Preserve existing frontmatter exactly.</strong> Some meetings have <code>action_items</code>, <code>decisions</code>, <code>intents</code>, <code>entities</code>, <code>people</code>, <code>calendar_event</code>, <code>captured_at</code>, <code>device</code>, <code>recorded_by</code>, etc. Don't reformat or reorder anything — only insert/update the three outcome fields.</li>\n<li><strong>Tag freshness matters.</strong> Tags are most valuable within ~24 hours, while the outcome is fresh in the user's head. Tagging two weeks later is fine but worth less. Don't enforce this — just don't make tagging feel like a chore that the user puts off.</li>\n<li><strong>Don't try to infer the tag from the transcript.</strong> If the user says \"tag this meeting\" without saying which outcome, ask. Don't guess from the transcript — your guess will be wrong in the cases that matter most (a meeting that looks like a win on paper but actually wasn't, or vice versa).</li>\n<li><strong>The note is optional for a reason.</strong> Most users will skip it. That's fine — the tag itself is the load-bearing data. Don't make the user feel like they're underperforming if they skip the note.</li>\n</ul>\n","files":[{"path":"scripts/tag_apply.py","sizeBytes":5792,"isText":true},{"path":"SKILL.md","sizeBytes":9020,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-08-27T17:01:24.464003Z","sha256":"84A9BB3A8E6BFA6632A9A7BEAE28FC5E20B12ABF3FBC0C8BBD5895BB1BB18A64","sizeBytes":6443},"review":null,"source":{"repositoryUrl":"https://github.com/silverstein/minutes","path":".opencode/skills/minutes-tag","license":"MIT","commit":"37d3440d4f132e2f3864fbe537e375fd546159ba","subtreeSha":"C9B02A518668A71441EE94A3CC9372DC635B2024FF168B5337CA0D9AD9B8AADD","lastSyncedAt":"2026-09-25T07:37:08.19899Z"},"reviewedAt":"2026-08-27T17:10:21.576505Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/silverstein/minutes/tree/main/.opencode/skills/minutes-tag"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install silverstein-minutes@llmmart"},{"target":"git","command":"git clone https://github.com/silverstein/minutes.git"}]}