Back to profile Get in touch
Profile | Side project | Built and shipped solo | Updated October 16, 2026

taskbash

An AI chief of staff I built and use every workday. Each morning it reads my email, calendar, meetings and tools, and gives me one list of what needs me.

taskbash is a personal chief-of-staff app. Every morning at 7:00 AM Pacific it reads my Gmail, Google Calendar, Granola meeting notes, Linear and Slack. It pulls out the tasks that need me, removes duplicates and anything I already handled, and gives me one ranked list. It also drafts email replies in my voice, writes prep notes before meetings, and sends a summary and meeting reminders to WhatsApp.

I built it alone, starting May 12, 2026, and I use it every workday. This page covers how it works, how I test the AI inside it, and what changed release by release.

Contents
  1. How it works
  2. Design decisions
  3. How I evaluate it
  4. Changelog

How it works

One pipeline runs every morning and whenever I press Re-run. Gmail is also checked every 5 minutes, so new email turns into tasks during the day.

Gmail Google Calendar Granola meetings Linear Slack 7:00 AM run, plus Gmail every 5 minutes 1. Extract Claude reads each source in parallel and lists candidate tasks 2. Judge A second model keeps, drops, merges or nests each candidate 3. Classify Tags work areas, using preferences learned from my corrections 4. Deduplicate and store New, carried over, or suppressed if I already cleared it Learning loop I mark a wrong task as slop. A preference is saved and read by the classifier. Some marks become eval cases, rerun every 3 days. Observability Every model call is logged with tokens, cost and latency. Traces in Langfuse, errors in Sentry, 8 audit checks on the live database. Today list ranked, on /today Meeting prep with attendee research Reply drafts in Gmail, in my voice WhatsApp digest and reminders
Figure 1. The taskbash pipeline. Each step is a separate stage in code, and every model call in it is logged.
  1. Collect. Sources connect through Google sign-in, Nango, Composio and API keys. If a source is down, the run continues without it.
  2. Extract. Claude reads each email thread and meeting and lists candidate tasks. Sources run in parallel.
  3. Judge. A second model checks every candidate against the source and my open tasks. It keeps, drops, merges or nests each one.
  4. Classify. Each task gets work-area tags. The classifier reads preferences learned from my past corrections.
  5. Deduplicate and store. Each task is matched against stored tasks in Postgres. It is new, carried over, or suppressed because I already cleared it.
  6. Deliver. The ranked list on /today, prep notes with attendee research, reply drafts saved in Gmail, and WhatsApp messages.

Design decisions

How I evaluate it

My eval reported 0% for four months. The model was mostly fine. The test was asking the wrong question.

The setup

When taskbash shows me a wrong task, I mark it as "slop" and pick a reason. I have marked 257 tasks this way. The top reasons were duplicates (139 of 257) and old tasks with past dates (48 of 257).

Some slop marks become eval cases. The original email or meeting is saved, and a job reruns the current extraction prompt on it every 3 days. From June 16 to October 16, 2026, that job ran 86 times on 15 cases, for 599 checks.

What went wrong

0 of 599 checks passed. There were three causes.

  1. The wrong question. Each check required the email or meeting to produce no tasks at all. A real email usually holds other, legitimate tasks, so the check could almost never pass. Made-up example: I reject "Join the video call at 12:15" from an email that also asks me to send a proposal. A correct extraction still returns "Send the proposal," and the check called that a failure.
  2. A format mismatch. 180 of the 599 outputs did return zero tasks. They still failed, because the model returns {"items": []} and the check only accepted [] or {}.
  3. A silent alarm. The job alerts only when the pass rate drops more than 5 points from the last run. A rate stuck at 0% never drops, so it never fired.

The fix

I re-scored every stored output with the question the eval was meant to ask: did the extractor recreate the specific task I rejected? Titles are compared after removing filler words and folding verb variants, so "send the proposal" and "draft the proposal" count as the same task. The script reads the 599 outputs already saved, so the re-score needed no new model calls and cost nothing.

Results

0% 25% 50% 75% 100% Jun 16 Jul Aug Sep Oct Oct 16 Prompt overhaul, Jul 7 Shaded lines: 44% average before, 72% after Original check: 0% on every run Corrected pass rate, same 8 cases, each run
Figure 2. Pass rate of the same 8 cases on each run, June 16 to October 16, 2026, under the corrected check. Shaded lines show the average before and after the July 7 prompt overhaul. The dashed red line is the original check.
MeasurePass rate
All 599 checks70% (421 of 599)
Same 8 cases, before the July 7 prompt overhaul44% (27 of 62)
Same 8 cases, after the overhaul72% (203 of 280)
All 15 cases, last 10 runs (Sep 19 to Oct 16)72% (108 of 150)
Email extraction, last 10 runs82% (82 of 100)
Meeting extraction, last 10 runs52% (26 of 50)
Spam, duplicate, already-cleared and not-my-job cases100% (60 of 60)
Meeting logistics cases, like "join the call"54% (38 of 70)
Old tasks with past dates50% (10 of 20)

What this tells me:

Next steps

Changelog

October 11 to 12, 2026
The reply drafter now rates its own confidence. Linear pulls in high-priority, due-soon and in-review issues assigned to me. The Slack step skips cleanly when it is not set up. Fixed a broken check in the audit script.
July 31, 2026
Fixed morning runs timing out on Gmail and meetings (limit raised from 90 to 240 seconds). Cleared tasks can be restored. The Re-run button now runs the real pipeline.
July 6 to 7, 2026
Prompt overhaul: stricter email rules, meeting extraction that reads the transcript first, and suppression of tasks I already cleared. Judge version 2. Every model call moved to Claude Opus 4.7, and a temperature bug in the judge was fixed.
July 1, 2026
Added the judge, a second model that reviews every extractor's output. Tighter duplicate matching.
June 10 to 14, 2026
Built during the BuilderShip hackathon: Slack as a source through Composio, attendee research for meeting prep through Tavily, an optional Llama 3.3 70B classifier on Nebius, learned preferences through mem0, a public landing page, and a live view of each run's steps.
June 9 to 10, 2026
Five fixes from an audit that found about 22% of my open list was slop (39 of 173 tasks): Linear shows only issues assigned to me, meeting extraction skips tasks owned by someone else, calendar logistics are filtered out, duplicate matching folds verb variants, and the classifier tags more generously. Every new task now links to the model call that made it.
Earlier in June: WhatsApp morning summary and meeting reminders through Twilio, error tracking in Sentry, inline editing, and a full QA pass.
May 27 to 31, 2026
Added the slop button, priorities and one-click Gmail send. Every model call logged with cost and latency, plus Langfuse traces. Eval datasets and the 3-day eval job. Reply drafts saved straight into Gmail, written in my voice. Meeting prep that pulls from email, meetings, Linear and the calendar. Cleared tasks stopped coming back.
May 12 to 18, 2026
First version: the /today list on Supabase, Gmail extraction, short briefs for each task, a work-only filter, Google Calendar and Linear, and a connections page.
Built and written by Subash Rajaseelan, who leads product for EverTutor at SigIQ.ai and builds taskbash on the side. Numbers on this page come from taskbash's production database, read on October 16, 2026. More at subashrajaseelan.com.
| Back to profile