Your system narrates everything it does into a daily event log. Today you learn to read that log — and to tell the difference between a card that's politely *waiting on you* and one that actually *broke*.
On 5/27 and 5/28 the language-lesson RemoteTrigger silently failed and you only found out because an email didn't arrive. The fix wasn't a smarter trigger — it was learning to look at the side-effect log instead of trusting that 'the job ran.' Every JARBUS action already writes itself down; the skill is knowing where, and how to read 'blocked' vs 'error' so you chase the right problems.
JARBUS keeps a running diary. Every time the engine does something meaningful — classifies a dropped file, fires a build, hands you a card to review — `reporter.py` appends one line to `PDB/data/jarbus-events/YYYY-MM-DD.jsonl`. The `.jsonl` extension means 'JSON Lines': one self-contained JSON object per line, so you can read the file top-to-bottom as a timeline and `tail` it live. This is the single source of truth for *what the engine actually did today*, as opposed to what you assume it did.
A review card has a lifecycle, and the folder it lives in IS its status. It's born when Claude drops an HTML into `FOR TOM/TOM TO REVIEW/` (the 'Your move' column). It lives there while it waits on you. When you mark it up and drop it back into `FOR TOM/DROP ZONE/`, the outbox handler processes it and moves it to `FOR TOM/_archive/YYYY-MM-DD/`. So 'where is the file' answers 'what state is this work in' — no database needed. A card still sitting in TOM TO REVIEW after a week isn't broken; it's just waiting on you (and the hygiene rule sweeps it to `_archive/.../_stale/`).
'Blocked' and 'error' are not the same word, and conflating them wastes your time. **Blocked** = the system is working correctly and is *deliberately* waiting — for your decision, for a PRD, for an input placeholder like `[INPUTS: business name]` to get filled. Nothing is wrong; the ball is in your court. **Error** = something the system expected to succeed did not — a script threw an exception, an API returned a non-2xx, a file that should exist is missing. Blocked is resolved by *you acting*; error is resolved by *something getting fixed*. When you scan the log, the first question is always 'is this thing stuck on me, or is it actually broken?'
Walk one day of engine activity, then watch a single card move through its lifecycle by where the file lives:
# 1. Read today's event timeline (pretty-printed, newest last)
cat "PDB/data/jarbus-events/$(date +%F).jsonl" | python3 -c 'import sys,json;\nfor l in sys.stdin:\n e=json.loads(l); print(e.get("ts","?")[11:19], e.get("event","?"), e.get("slug",""))'
# 2. What is currently waiting on YOU (the 'Your move' column)?
ls -1 "FOR TOM/TOM TO REVIEW/"
# 3. What got processed and filed away today?
ls -1 "FOR TOM/_archive/$(date +%F)/" 2>/dev/null
# 4. Watch the log live while you drop a file into DROP ZONE
tail -f "PDB/data/jarbus-events/$(date +%F).jsonl"
Trust the log, not the trigger: every action writes itself down, and 'where the file lives' tells you whether the ball is in your court (blocked) or something broke (error).