Memory that comes back to you: reminders in Empirical

Memory only answers when you ask it something, which is fine until a note has a date on it. Any Empirical memory can now carry a due date. When it comes up you get a calendar alarm, an email, and a heads-up inside whatever AI agent you happen to be working in.

Generated editorial hero image for "Memory that comes back to you: reminders in Empirical

Memory is pull-based. You ask, it answers. That's what makes it trustworthy, and it's also why it's kind of useless for the one type of note that needs to move on its own, the one with a date on it.

Found this out on September 15. I wrote a todo into Empirical, put the due date in the note itself, and had an agent read it back the next day. It saw the deadline, said nothing, moved on. Which, fair. A memory that says "due Tuesday" is just text unless something goes looking for it on Tuesday.

So this week any memory can have a real due date, and there's a delivery path behind it. Set a reminder from whatever tool you're in, and when it's due it comes to you. Below is what that looks like from each side, screenshots are from my own account, plus the handful of things I had to get right for it to actually be trustworthy.

What changed

How it works

Flow diagram: a due date on a memory produces a confirmation email with a calendar entry at set time; an hourly scanner claims it when due and creates an alert; the alert reaches each agent once through MCP results and CLI banners, the portal shows it, and a due email goes out; acknowledging from any surface closes it everywhere.

Four steps. Each one has a rule attached and I'll explain why.

1. Set. The due date is stored as a real indexed field on the memory, not inside its free-form data. I know that sounds like an implementation detail but it's most of the feature. A date inside the note's text is something search might rank highly, or might not. A field is something the system can filter on exactly and fire on exactly. Early in the build I planted a memory due that same day and asked a normal question about the project. It didn't come up. Being due isn't a semantic property, so ranking was never going to catch it reliably.

2. Confirm, with the alarm attached. The second you set a reminder you get an email with a calendar entry in it. The .ics is published rather than sent as a meeting request, so your calendar doesn't try to RSVP to your own reminder. Its UID is the memory id, which means re-dating a reminder updates the existing calendar entry instead of adding another one. And it has a VALARM on it, which honestly is the part that matters, cuz that notification fires on your phone whether or not you're anywhere near an AI that day.

The calendar entry only makes sense at set time. An earlier version had the .ics riding on the due-time email instead, and it took maybe a minute of looking at that to realize it was pointless. The alarm would arrive at the exact moment it was supposed to have already gone off.

3. Claim once, then deliver. A scanner on Empirical's worker host runs on a schedule and picks up every reminder whose time has passed. Before delivering anything it marks the reminder as fired, one conditional write that only succeeds if the reminder is still pending. Then it delivers. The order matters. If the process dies between those two steps, one reminder gets missed once. Reverse the order and a crash would repeat the same reminder every cycle for as long as the crash lasted. A month ago an unrelated queue bug in this system re-enqueued events forever and produced 42,030 rows before anyone noticed, so I'm a little sensitive about this. Reminders are built so that particular failure can't happen.

4. Reach each agent once. Delivery to your AI tools rides on the responses they're already getting. Empirical attaches a notice to the next MCP tool result or CLI response, so the reminder shows up inside whatever conversation you're actually having. No polling, no background process on your machine. The notice is the first block of the result, worded as an instruction the model can act on, and it goes out once per agent. Claude Code open in two projects and ChatGPT on your phone? Each tells you once, none of them keep bringing it up.

The walkthrough

Everything below is my real account today. The three reminders are actual things I need to do this month.

The Reminders page lists what's coming, how far away it is, and how many of your plan's slots are in use.

The Empirical Reminders page showing four active reminders, the next due in two days, and three scheduled cards for checking Reddit campaign attribution, sending the September newsletter, and resetting a scanner interval.

New reminder is a sentence and a time. The calendar email shows up right away.

The New reminder dialog with a text box reading Renew the domain for gauzza.com before it lapses, a date and time picker, and a note that you will get an email with a calendar entry now and a nudge when it is due.

Each card's menu does the four things you'd ever need: change the date, mark it done, cancel it, or drop the due date and keep the note.

The action sheet on a reminder card with Change date, Mark done, Cancel reminder, and Remove due date.

Home got a fifth card. When a plan is full it names the plan that raises the cap instead of just saying "upgrade".

The Home dashboard with a Reminders card reading 4, Next Sep 19, and a Manage link beside the memory, connection, workspace, and plan-usage cards.

The two emails

The confirmation arrives when you set the reminder. The date is really the only thing you need to read, so it's the only big thing on the page. The calendar buttons work in any mail client, the attached .ics is for the ones that render it.

The Reminder set email: Empirical will remind you on Wednesday, October 14, 2026 at 9:00 AM EDT, the reminder text in a box, an explanation that the attached calendar entry carries an alarm, and Add to Google Calendar and Add to Outlook buttons.

Here's the calendar entry that rides along. No organizer, no attendees, one alarm at the due time.

text
BEGIN:VCALENDAR
METHOD:PUBLISH
BEGIN:VEVENT
UID:6aab36a2062bc7e6b860368f@reminders.empirical.gauzza.com
DTSTART:20261014T130000Z
DTEND:20261014T133000Z
SUMMARY:Reminder: Renew the Atlas TLS certificate before it expires on October 14
URL:https://empirical.gauzza.com/app/memories/6aab36a2062bc7e6b860368f
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER:-PT0M
END:VALARM
END:VEVENT
END:VCALENDAR

The due-time email is plain. It's there for when you ignored the attachment, which I do too.

The Reminder email sent at the due time: You asked to be reminded Wednesday, October 14 at 9:00 AM EDT, the reminder text, a line saying it has fired once and will not repeat, and an Open the memory button.

The agent side

This is the part that failed on September 15, so it's the part I spent the most time on.

When a reminder is due, the next response an agent gets from Empirical leads with it. Here's a CLI session. The banner text and the acknowledge output are what the 1.0.30 CLI actually prints, the query rows are placeholders.

A terminal running empirical memory query. Above the results a banner reads REMINDER DUE - tell the user now: Send the September newsletter, five at a time, after the Resend daily cap resets, with the due time, an Open memory link, and the acknowledge command. Below, empirical memory acknowledge returns remindState acknowledged and Reminder marked done. Its slot is free.

In an MCP client like Claude Code or ChatGPT, the notice is the first block of the tool result and it tells the model what to do with it: tell the user in its own words, before the actual task, and ask whether to mark it done. The reminder text, the memory id, and both ways to close it are all in the notice so the model doesn't have to go looking.

A mockup of a Claude Code conversation. A record_graph_memory tool result opens with the REMINDER DUE notice, the assistant relays the reminder and asks whether to mark it done, the user says done, and an acknowledge_reminder tool result confirms it.

That's the mockup. Here's roughly how the first live run went in my own Claude Code session this afternoon, and it's the reason the notice is worded the way it is now.

You

Save a note that we are moving the marketing sends to Resend's Pro plan next month.

Assistant

Saved. Also, a reminder you set is due: send the September newsletter, five at a time, after the Resend daily cap resets. It came due at 9:00 this morning. Want me to mark it done?

You

Done, mark it.

Assistant

Marked done. That frees one of your reminder slots.

acknowledge_reminder closed the reminder and cleared the alert on every surface

The first version of the notice was a trailing text block that said "relay this to the user". An agent got it and just... didn't. Moving it to the front and writing it as an instruction with a specific question to ask is what fixed it.

Try it

From a connected assistant, say "remind me on Friday to renew the domain" and it'll call record_graph_memory with a dueAt. From the terminal:

text
empirical memory record --category project --summary "Renew the domain before it lapses" --due 2026-09-25T13:00:00Z
empirical memory query --match "what is due" --due-before 2026-09-26T00:00:00Z --remind-state pending
empirical memory acknowledge --memory-id <id>

The portal page is at /app/reminders. The tool reference is in the MCP tools docs. The CLI needs 1.0.30 or later, npm install -g @empirical-gauzza/cli gets you there.

If a deadline you gave your AI two weeks ago shows up on the right day without you asking, on your phone and in whatever conversation you're in, then this is working. If it ever nags you twice, tell me. That's the one thing it's not supposed to do.

Reminders are on every plan

Give your AI a deadline it will keep.

Set a due date on any memory from ChatGPT, Claude, the CLI, or the portal. You get the calendar entry now, and the reminder reaches your agents, your inbox, and your phone when it is due.

All Empirical blog posts