{"slug": "show-hn-voicecard-a-cli-that-resolves-contradictions-in-rambling-voice-notes", "title": "Show HN: Voicecard – a CLI that resolves contradictions in rambling voice notes", "summary": "Voicecard, a new command-line tool by an independent developer, resolves contradictions in rambling voice-note transcripts, achieving 15 of 18 on its adversarial test suite with the local qwen2.5:7b model. The tool, installable via npm, runs fully offline by default or with a user-provided OpenAI API key, and is designed to keep only the final intended action, not earlier retracted statements.", "body_md": "Turn a rambling voice-note transcript into resolved, actionable items. The part every \"AI extracts your tasks\" tool gets wrong: when you talk yourself out of something mid-sentence, voicecard keeps only what you actually meant at the end.\n\n``` bash\n$ echo \"I'm going to the store to get grapes today, no actually I'm getting apples.\" | voicecard\n{\n  \"items\": [\n    { \"kind\": \"card\", \"text\": \"Get apples from the store\" }\n  ]\n}\n```\n\nNot \"grapes and apples.\" Not \"grapes\" (caught the first mention and stopped listening). The model has to track the note as a whole and understand that grapes was retracted, not just transcribe and keyword-extract. Most meeting-note and voice-memo tools are built for accurate transcription and summarization, not for noticing that a speaker overturned their own earlier statement. This one is built specifically for that.\n\nGrew out of a working personal system for turning voice notes into board tickets: dictate on the go, get it auto-sorted, never lose a thought to \"I'll write it down later.\" The one thing that decides whether that's trustworthy is contradiction handling. A tool that files the version of the task you talked yourself out of creates noise instead of removing it.\n\n```\nnpm install -g voicecard\n```\n\nNeeds Node 18+. That's the only hard dependency. Everything else is either already on your machine (a local model) or a key you bring yourself.\n\n```\nvoicecard notes.txt              # from a file\ncat notes.txt | voicecard        # from stdin\nvoicecard --help                 # all options\n```\n\nTwo modes, your choice, zero hosting on my end either way:\n\n**Local**(default): runs against a local[Ollama](https://ollama.com)model.`ollama pull qwen2.5:7b`\n\nand it works out of the box, fully offline. Nothing leaves your machine.**Bring your own key**:`OPENAI_API_KEY=sk-... voicecard notes.txt --provider byok`\n\nuses your own OpenAI (or OpenAI-compatible) account. Your cost, your data relationship with that provider, not mine.\n\nNo hosted backend, no account, no telemetry. I don't see your transcripts either way.\n\nCurrent score: **15 of 18** on my adversarial suite, running the small local model (qwen2.5:7b). The suite covers revisions, full retractions, partial list edits, chained double reversals, quantity changes, filler words that sound like corrections but aren't, and negative controls to catch over-correction (a tool that invents corrections would be worse than one that misses them).\n\nYou can run it yourself: `node experiments/adversarial-test.mjs`\n\n(needs Ollama with qwen2.5:7b pulled). The suite imports the same prompt the CLI ships with, so it can't silently drift from what you're actually running.\n\nWhat passes: substitutions, full retractions, double reversals, quantity changes, multi-topic notes where only one topic gets revised, additions that must not be mistaken for replacements, whole-note cancellations, repetition-for-emphasis staying one item, and both negative controls.\n\nThe three current misses, plainly:\n\n- \"Grab milk from the store, wait, what was I saying, anyway, also grab bread\" drops the milk. The filler \"wait\" gets over-read as a retraction. This is the worst class of failure (silently losing an item) and it appeared as a side effect of fixing an earlier bug, which is documented below because that's how prompt tuning actually goes.\n- \"Call John, actually let's email instead\" resolved to a card that still leads with \"Call John\" and puts the correction in parentheses. The retracted verb should not be the headline.\n- Clearly actionable items occasionally come back classified as\n`note`\n\ninstead of`card`\n\n. The resolution is right, the label is too cautious.\n\nI don't have a clean comparison against a frontier-class model. The one I tried (ox-alpha, on a free API tier) rate-limited on 3 of 7 calls mid-run, and that run was against an earlier prompt revision anyway. On the calls that went through, it agreed with the local model. What I can say honestly: a 7B model handles most of this task, which surprised me.\n\nI also fed it a test meeting transcript I wrote: a PM and two devs argue over whether a feature is too big for one ticket, decide to split it, and negotiate who owns what. It split the tickets correctly, put the right details in each, and ignored a proposal that got argued down mid-meeting. It also dropped one explicitly stated assignee and flattened a specific scheduling reason into a generic priority claim. (That test uses its own task-specific prompt, in `experiments/meeting-transcript.mjs`\n\n.)\n\nThe first prompt version failed two cases: a full retraction (\"we still have milk, scratch that\") produced a placeholder item describing the retraction itself, and repetition-for-emphasis split into two items with \"it's urgent\" becoming its own nonsense task. Both got fixed with worked examples in the prompt, and both fixes held on re-testing.\n\nA third worked example fixed list merging (\"milk, eggs, bread, and coffee\" now comes back as four items, not one). But the retraction example now over-triggers on filler words in at least one case, which is miss number 1 above. Fixing a prompt failure by example can cause a different failure. If you fork this and tune further, re-run the whole suite, not just the case you fixed.\n\nLonger term I'd like to wire this into Jira, Linear, or Monday-style boards, and possibly into [Zuuna](https://zuuna.de), a project management tool I run. None of that is required to use the CLI. Also on the list: bundled transcription (audio in, not just text), though the interesting problem here is resolving what you meant, and good Whisper wrappers already exist for the speech-to-text part.\n\nThe personal system this grew from: iPhone Shortcut, webhook, local Whisper transcription, this classification logic, auto-filed onto a project board. That setup depends on my own hardware and isn't what's published here. This CLI is the general, reusable core of it, rebuilt to run anywhere.\n\nMIT", "url": "https://wpnews.pro/news/show-hn-voicecard-a-cli-that-resolves-contradictions-in-rambling-voice-notes", "canonical_source": "https://github.com/kenzotp/voicecard", "published_at": "2026-08-25 10:56:59+00:00", "updated_at": "2026-08-25 11:15:44.216962+00:00", "lang": "en", "topics": ["artificial-intelligence", "natural-language-processing", "ai-tools", "developer-tools"], "entities": ["Voicecard", "Ollama", "qwen2.5:7b", "OpenAI"], "alternates": {"html": "https://wpnews.pro/news/show-hn-voicecard-a-cli-that-resolves-contradictions-in-rambling-voice-notes", "markdown": "https://wpnews.pro/news/show-hn-voicecard-a-cli-that-resolves-contradictions-in-rambling-voice-notes.md", "text": "https://wpnews.pro/news/show-hn-voicecard-a-cli-that-resolves-contradictions-in-rambling-voice-notes.txt", "jsonld": "https://wpnews.pro/news/show-hn-voicecard-a-cli-that-resolves-contradictions-in-rambling-voice-notes.jsonld"}}