Day 25 of 29 · Wednesday · Learning

Classify + Probe — how raw input becomes an S/M/L tierCapability

How JARBUS decides what to do with anything you drop in: classify.py reads the capture, assigns an S/M/L tier and an intent, scores its own confidence, and only bothers you when the decision is genuinely ambiguous. Today you'll find the one rule that keeps an orphaned Plaud recording from nagging you.

Catch-up progress
25/29
Why this matters to you

Your whole pipeline starts here. When this file mis-tiers something or fires a useless 'pick a route' card, you feel it as Inbox noise — and you've hit exactly that twice this month (orphaned -recording.* files on 6/07 and 6/09). Today's automation fire is downstream plumbing; classify.py is the brain that decides whether work even enters the system. Knowing its rules means you can tell 'the router did the right thing silently' from 'the router is broken'.

Every capture lands as a 'batch' — the text plus metadata (word count, content format, source). classify.py asks the Claude API for three things: a tier (S = quick one-shot, M = multi-step protocol, L = full project), an intent (action / note / proposal / etc.), and a confidence score 0.0–1.0. The tier maps straight onto a workflow: S → quick-deliver, M → run-protocol, L → spawn-project.

The load-bearing design choice is bias-to-ship. As of 2026-05-19 the default is auto-fire: the router just acts, because most routes are reversible and you can re-classify from the dashboard. It only stops to ask you (emits a 'route-approval' card) when should_auto_fire() returns False — i.e. Claude flagged requires_decision, OR confidence fell below CONFIDENCE_SANITY_FLOOR (0.35, meaning Claude is basically guessing).

But 'below the confidence floor' isn't enough to justify interrupting you. A second gate, should_hold_silently(), catches captures that are too empty or too thin to be answerable. The dominant case: an orphaned Plaud -recording.* file. The small transcript/summary siblings classify and archive before the ~1MB audio finishes downloading, so the audio arrives alone, looks like a fresh input, scores ~0.3 confidence — and without this gate would fire a card asking you to route an empty audio file. is_empty_capture() catches it (word_count 0, no content, format in {audio-only, needs_manual, unknown}) and holds it to data/holding/ instead. Nothing is lost; you just aren't pinged.

Worked example

Find the exact rule that suppresses the orphaned-recording card — this is today's hands-on answer:

grep -n "def is_empty_capture\|def should_hold_silently\|THIN_CAPTURE_MAX_WORDS\|CONFIDENCE_SANITY_FLOOR" \
  ~/Claude/JARBUS/scripts/classify.py

# Then read the two gates back-to-back:
sed -n '585,636p' ~/Claude/JARBUS/scripts/classify.py

# See what's actually been held (suppressed) recently:
ls -t ~/Claude/JARBUS/data/holding/ | head
cat ~/Claude/JARBUS/data/holding/$(ls -t ~/Claude/JARBUS/data/holding/ | head -1)
▶ Do it now
  1. Open ~/Claude/JARBUS/scripts/classify.py and read should_hold_silently() (around line 616). Say out loud the two conditions that trigger a hold.
  2. Answer the curriculum's question: which rule keeps an orphaned Plaud recording from firing a route-approval card? (It's is_empty_capture — the word_count==0 + empty-content + audio-only-format check.)
  3. List ~/Claude/JARBUS/data/holding/ and open the most recent file. Confirm with your own eyes that held captures are logged, not discarded — that's the safety guarantee that makes silent suppression OK.

Gotchas

Go deeper: classify.py — the file itself · Optimized workflow architecture (route handlers + dispatch)
One-card takeaway

Auto-fire by default, ask only on genuine ambiguity, and never ask about a capture too empty to answer — that three-tier filter is why your Inbox isn't full of 'route this 1MB audio file' noise.