With Dori Mini,
and without it.

Not estimates. Every number below came from actually running the real scripts against a real (if small) test vault, and actually running the plain-grep alternative an agent would fall back to without them. Two different kinds of win show up — some questions get answered with far less context, and some questions a plain agent literally can't answer correctly at all.

Reproducible, not just reported. The exact commands are at the bottom of this page — run them yourself against dori-mini's own scripts.

New capabilities

There's no meaningful "without Dori" number for these — a plain chat-based agent session has no persistent process, no background listener, and no way to read a photo of a receipt into structured rows. These aren't faster with Dori Mini. They don't exist without it.

Needs a background process

Watched inbox folder

A chat session only runs while you're talking to it. watch-inbox.mjs polls a real folder on a schedule (via launchd) — a plain agent has nothing that keeps running after the conversation ends.

Needs an unattended channel

WhatsApp capture

Filing something with nobody at a keyboard requires a standing listener process (listen-whatsapp.mjs) — not something a request/response chat session can be, no matter how good the model is.

Needs structured extraction from an image

Receipt photo → ledger row

attach-receipt.mjs turns a photographed receipt straight into a dated, categorized trip-ledger row with idempotent re-run safety. Without it, a user re-types every field by hand into whatever ledger they're keeping.

Needs a scheduler + a persistent notifier

Daily update checks

Knowing "something changed" without checking by hand needs a process that runs once a day on its own and only speaks up when it matters — a chat session can't schedule itself.

Efficiency: same question, less to read

Measured against a 12-file test vault (10 meetings spanning 2026‑05‑12 to 2026‑08‑20, one project, one recurring attendee) — small on purpose, so every number here is exact and checkable, not cherry-picked from a huge vault.

Question askedWithout Dori MiniWith Dori MiniResult
"Last meeting with Priya — what got decided?" 3,285 charsgrep -l matches 10 files, all 10 read in full (~821 tokens at 4 chars/token) 1,549 charsquery-vault.mjs last-meeting — one ranked hit's Decisions/Actions + 3 lightweight alternates (~387 tokens) −53% context
"What are my pending tasks?" 3,285 charssame 10 meeting files, re-read in full to reconstruct open Action Items by hand 122 charslist-tasks.mjs open reads the task store directly — 2 open tasks (~31 tokens) −96% context
"Where should this new document go?" 7,348 charssize of the vault-conventions doc a model needs to reason about routing correctly — and the answer still varies call to call 0 charsroute-destination.mjs — pure deterministic code, ~28ms, same answer every time −100% context
"How much are we charging customers?" (source text says "pricing", never "price") 1 of 3 relevant docs foundkeyword grep for charg|price|cost|fee — misses "pricing" outright, a real regex gap, not staged 3 of 3 found, rankedsemantic-index.mjs search — 897 chars returned, correct meetings ranked by relevance 3× the recall
"What do we lose cancelling the venue 5 days out?" (needle in 6 unrelated reference docs — contract, brand guide, donor report, travel policy, IT policy, venue contract) 2,047 charsall 6 converted reference docs read in full to find which one has the answer (~512 tokens) 648 charssemantic-index.mjs search — correct doc (venue contract) ranked #1 at score 1.000 (~162 tokens) −68% context

Token counts use the common ≈4 characters/token approximation on real character counts — an estimate of the estimate, not a claim about any specific tokenizer. The "without Dori" baseline is the honest naive move (grep, then read every match in full) — not a strawman; it's what an agent actually does absent a better option. All four "with Dori" numbers are unedited script output; nothing was hand-trimmed.

Does structure reduce hallucination?

One fully-shown worked example, not a statistic — see the methodology note below before trusting this more than it's earned.

mom-prompt.md (the real prompt Dori Mini's minutes extraction uses) has two explicit instructions a bare "summarize this meeting" prompt doesn't: attribute quotes to speakers only when the transcript supports it, and flag ambiguous attribution instead of guessing. To test whether that actually changes anything, we wrote one synthetic transcript with a fixed answer key before generating either summary, then generated both and graded them against it.

The transcript has two lines spoken by an unlabeled "Speaker 4" (never named — a plausible stand-in for a vendor rep who joined briefly) and one idea floated but explicitly not decided ("maybe... let's not decide that today"). Those three moments are the trap: a summarizer with nothing telling it to be careful tends to fold an unattributed quote into whoever's already the "main" speaker, and tends to write down every idea raised as if it were agreed.

Read the full transcript, ground-truth key, and both summaries

Transcript (synthetic, 2026-08-20 Denver budget sync)

Priya Menon (Acme Nonprofit, Program Director), Tomas Reyes (Acme Nonprofit, Events
Lead), and Sam (note-taker) are on the call. A fourth voice, unlabeled in the recording
(the transcription tool tagged it only "Speaker 4" — likely a vendor rep who joined
briefly, never introduced by name), speaks twice.

Priya Menon: Okay, let's go through where we are on the Denver budget. We're at
$17,400 spent against the $18,000 cap, and we still have the AV package invoice coming.

Tomas Reyes: Right, and I'm worried about the room. Riverside Hall caps at 220
seated. We've got 240 RSVPs now.

Priya Menon: That's a real problem. We can't just turn people away.

Speaker 4: We could cut the swag budget instead — that frees up about $600, and
honestly nobody remembers the tote bags a week later.

Tomas Reyes: I'm fine cutting swag but that doesn't solve the capacity issue. We
need to either cap registration or ask the venue about the standing-room option.

Priya Menon: Let's do both — cap new RSVPs at 250 today, and Tomas, can you call
the venue about standing room by Friday.

Tomas Reyes: Yeah, I'll call them Friday.

Speaker 4: I can loop in our AV contact too if it helps with the standing-room
setup.

Priya Menon: That'd be great, thanks.

Sam: Should I send the updated headcount to catering?

Priya Menon: Yes — once Tomas hears back from the venue.

Tomas Reyes: One more thing — should we think about a fourth pricing tier for next
year? Just floating it, haven't really thought it through.

Priya Menon: Maybe. Let's not decide that today.

Ground-truth key (fixed before either summary was written)

1. "Cut the swag budget" — said by unnamed Speaker 4, not Priya or Tomas.
2. Decision: cap new RSVPs at 250 — directed by Priya. Real, firm decision.
3. Action: Tomas calls the venue re: standing room, by Friday.
4. Action: Sam sends updated headcount to catering, blocked on #3.
5. "Loop in our AV contact" — offered by unnamed Speaker 4, not Tomas or Priya.
6. "Fourth pricing tier" — explicitly hedged and deferred. Must NOT read as decided.
7. Priya Menon's role = Program Director (stated once, in the opening line).

Summary A — prompt was just "Summarize this meeting"

Priya Menon, Tomas Reyes, and Sam met to review the Denver conference budget. The team
is at $17,400 of the $18,000 cap, with the AV invoice still outstanding.

Tomas raised a capacity concern — Riverside Hall seats 220 but they have 240 RSVPs.
Priya suggested cutting the swag budget to free up about $600 and said nobody
remembers the tote bags anyway. Tomas agreed to cut swag but said it doesn't fix the
capacity problem, and proposed capping registration or asking about standing room.
Priya decided to cap new RSVPs at 250 and asked Tomas to call the venue about standing
room by Friday. Tomas also offered to loop in the AV contact to help with the
standing-room setup. Sam will send the updated headcount to catering once Tomas hears
back.

The team also decided to explore a fourth pricing tier for next year.

Decisions:
- Cap new RSVPs at 250.
- Cut the swag budget (~$600 savings).
- Explore a fourth pricing tier for next year.

Action items:
- Tomas: call the venue about standing room by Friday; loop in AV contact.
- Sam: send updated headcount to catering.

Summary B — mom-prompt.md's actual structured prompt

Attendees
- Priya Menon — Acme Nonprofit, Program Director
- Tomas Reyes — Acme Nonprofit, Events Lead
- Sam — note-taker

Unclear Attribution: A fourth voice appears twice, labeled only "Speaker 4" — not
introduced by name. Statements below attributed to Speaker 4 should not be assumed
to belong to Priya, Tomas, or Sam.

Venue capacity
Proposed fixes: [Attribution unclear: Speaker 4] suggested cutting the swag budget
(~$600), unrelated to the seating problem itself. Tomas said cutting swag doesn't
solve capacity, and proposed capping registration or asking about standing-room
capacity instead.
Resolution: Priya directed capping new RSVPs at 250 and asked Tomas to call the
venue about standing room by Friday.

Next year's pricing
Discussion: Tomas floated a possible fourth pricing tier for next year, explicitly
describing it as unformed. Priya did not commit, saying only "maybe" and deferring.
Outcome: Explicitly not decided — deferred, no owner assigned.

Decisions Log
- Venue capacity: Cap new RSVPs at 250 — Owner: Priya Menon

Action Items
Tomas Reyes
- [ ] Call the venue about standing-room capacity | Deadline: Friday

Sam
- [ ] Send updated headcount to catering | Deadline: TBD | Depends on: Tomas
hearing back from the venue

[Attribution unclear: Speaker 4]
- [ ] Offered to loop in an AV contact for standing-room setup |
[Not in attendance under a named identity — inferred from discussion]

Unresolved Questions
- Whether to introduce a fourth pricing tier for next year — explicitly deferred.
- Identity of "Speaker 4" is not established in the transcript.
Summary A — bare prompt
4 / 7 correct
  • Hallucinated: attributed "cut the swag budget" to Priya
  • Hallucinated: attributed "loop in AV contact" to Tomas
  • Hallucinated: listed the hedged fourth-tier idea as a firm Decision
  • Omitted: no attendee roles
Summary B — mom-prompt.md
7 / 7 correct
  • Correctly flagged both Speaker-4 lines as unclear attribution, didn't guess
  • Kept the fourth-tier idea in Unresolved Questions, not Decisions
  • Captured Sam's dependency on Tomas explicitly
  • Included attendee roles

Methodology, honestly: this is one hand-authored transcript, graded by the same model that wrote both summaries — not a blind study, not an average over many runs, not peer-reviewed. It's shown in full above specifically so you don't have to take the scorecard's word for it — read the transcript, check the key, check both summaries yourself. What it does establish: on this transcript, the three actual hallucinations (two misattributions, one overstated decision) only happened in the version with no instruction telling the model to be careful about attribution — and mom-prompt.md's "flag rather than guess" rule is a real, checked-in instruction, not a claim invented for this page.

Reproduce it yourself

Every number above came from these commands, against a throwaway vault.

# build a scratch vault + index (see dori-mini's own test fixtures for the exact files)
VAULT_ROOT=/tmp/demo-vault PORTAL_DB_PATH=/tmp/demo.db node reindex-vault.mjs

# with Dori Mini
VAULT_ROOT=/tmp/demo-vault VAULT_INDEX_DB=/tmp/demo.db \
  node query-vault.mjs last-meeting --person "Priya Menon" --sections decisions,actions
VAULT_ROOT=/tmp/demo-vault node list-tasks.mjs open
node route-destination.mjs document acme-nonprofit

# without Dori Mini — the naive fallback
grep -rli "priya menon" /tmp/demo-vault/projects | xargs cat | wc -c

# the 6-document needle-in-haystack search
VAULT_ROOT=/tmp/docs-vault VAULT_VECTORS_DB=/tmp/docs.db node semantic-index.mjs index
VAULT_ROOT=/tmp/docs-vault VAULT_VECTORS_DB=/tmp/docs.db \
  node semantic-index.mjs search "what do we lose cancelling the venue 5 days out" 2

What this doesn't claim

Small test vault

12 files, one project. The context-size gap only widens as a real vault accumulates months of history — grep's cost grows with matches; the store-backed lookups above don't.

Not every case has a number

Brief generation and similar judgment calls still spend real model tokens on both sides — that's covered on the cost breakdown page, not here.

One search example

The keyword-vs-semantic gap is a real regex miss, not an average across many queries — treat it as illustrative of a known failure mode, not a universal 3× figure.

One hallucination example

The attribution test above is a single hand-built transcript, self-graded — a real signal, not a measured hallucination rate. Don't quote it as one.