← Sam Zoloth
Spark
Mac and iPhone · built for my own life

Every open loop in my life, one decision at a time

A few times a day Claude reads my mail, messages, calendar and meeting notes and lists the replies, bills and promises I owe. Spark shows them one card at a time. Agents can do the prep, and nothing sends until I confirm the exact words.

Decide3

Spark is on it

Agents working0
Later0
Done today0
Maya, Jordan and Priya are Spark’s sample people.
How the list gets made

Claude sorts. Plain code checks its work.

The check runs at 7, 10, 1, 4 and 7, or when I press Check now. Claude gets the current list and what’s new since, with no tools, so all it can do is return text. Nothing it writes reaches the list until the check passes it.

Read

Every source is read, never written to. A source that can’t be read shows in amber instead of quietly missing.

GmailiMessageLinkedInSlackCalendarGranolaThings

Sort

Claude decides which threads are open loops, whose move each one is, what’s due and a next step, marked as a guess.

Check

The answer has to pass the list’s schema. If it fails, the old list stays and Spark shows the reason.

Compare

Plain code compares the old list with the new one and marks what changed, so a reworded next step doesn’t count as news.

1 new · 2 changed · 9:41
The Desk

One card, and every option says what it will do

The whole Mac window is there to show what needs me next. Each card’s bar shows its first option and at most two others, and each option says in one line what it will do.

  • ↩Decide holds one card in ranked order: an agent waiting on me first, then anything due by tomorrow, then work that’s already prepared.
  • LLater holds the card until tomorrow, next week or someday, with its evidence, draft and conversation intact. U undoes it for eight seconds.
  • ZEverything zooms out to every open ask, grouped by space, with the next decision ringed.
Spark's Everything view with sample data: Job search holds Maya Chen's and Priya Raman's asks, with Maya's ringed as the next decision, and a recruiter at Harbor Labs everyone is waiting on; Network holds Jordan Ellis's ask and Theo Brooks's coffee intro.Spark's Everything view in dark mode with sample data, grouped into Job search and Network, with Maya Chen's ask ringed as the next decision.
Hand off

Agents work on the card and ask before they act

Any card can go to Claude or Codex. Reading mail, the calendar, meeting notes or the web happens on its own. Anything else waits on the card for me to allow or deny, and the agent waits with it.

“Always allow” covers a kind of command from then on. It can’t cover sending, submitting, paying, posting or deleting, which ask every time. Return can never grant an approval, so a keystroke meant for another card can’t either.

Claude wants to write a file: case-study-notes.md

Jordan Ellis · Former teammate · LinkedInOverdue

Read the onboarding case study and say whether the metrics section lands.

Sending

A message counts as sent once it’s in the thread

Spark sends email through Gmail and chats through Beeper. Before anything goes, the card’s bar turns into one line naming the recipient and the channel, over the exact text. Afterward Spark looks for the new message in the thread, and every send leaves a receipt.

If a send may have gone out but can’t be confirmed, Spark holds every later send on that channel until I check.

Sent, and read back from GmailThe new message is in the thread. The ask closes, and Reopen undoes that.
May have sent. Not read back from Gmail yetSends on this channel wait until I check again or say it didn’t go.
Not sentThe send expired before it posted, so nothing went and the card stays open.
Find and capture

Ask a question in the bar, and the list answers without an agent

A question like “what did Jordan send me about the case study?” finds the ask by plain word matching and shows the sources and the words that matched. Ask Claude is one press further. Anything that isn’t a question goes to the tray, and Send to Spark puts a selection from any app there too.

Spark's find view with sample data. The bar asks what Jordan sent about the case study; the best match is one LinkedIn message from Oct 28, with the ask it belongs to outlined and unrelated asks dimmed. A captured job posting from Safari waits in the tray with Make it an ask.
On the iPhone

The same list in my pocket, with names kept off the lock screen

The iPhone syncs with the Mac through iCloud, and sends still run on the Mac. Widgets and a Live Activity count what needs me and when the first thing is due. Lock Screen widgets never show a name or a message, and nothing in a widget can send.

Medium widget: 2 asks need you, both replies ready, first due 5:00 PM, Maya Chen is first.Medium widget in dark mode: 2 asks need you, both replies ready, first due 5:00 PM.
Small widget: 2 asks need you, first due 5:00 PM.Small widget in dark mode: 2 asks need you, first due 5:00 PM.
Lock Screen Live Activity: Spark today, first due 5:00 PM, 2 asks need you, both have replies ready, with one bar per ask.Live Activity in dark mode: 2 asks need you, both have replies ready.
Lock Screen widget: An ask is due today, 2 replies ready, with no names.
What leaves my Mac

Nothing goes out in my name unless I send it

  • Claude reads, on my subscriptionNew messages go to Claude to be sorted, with no tools in that call. Agents run through the Claude and Codex command-line tools on the subscriptions I already have.
  • Nothing sends on its ownNot the check, not an agent, not Siri. The command-line tool agents use has no send action at all, only a way to propose one for me to confirm.
  • Client work stays outSpark covers my own life. Work for clients and employers is left out of every source.
  • Mine to take outEverything lives in one folder on my Mac. Settings exports all of it as a zip, or deletes every file Spark made and names each one.