How to Make Your AI Agent Keep Its Promises
AI agents say 'I'll handle it' dozens of times a day, and most memory systems store that promise the same way they store a weather observation. Here is how to give commitments a due date, a lifecycle, and progress that only advances when the work actually gets done, so a promise survives the context reset that would otherwise erase it.
By Clinton Stark • series, explainer, commitments, agent-reliability
I have been running AI agents in production for about a year now, and the thing that breaks first is never the model. The LLM is fine. What breaks is the agent’s relationship with its own promises.
Here is how it goes. Your agent is in a conversation, and someone asks it to follow up on something tomorrow. The agent says “I’ll handle it.” The context window rolls over, the session resets, and tomorrow arrives. No follow-up. The agent has no idea it ever made a commitment, because the memory system treated “I’ll handle it tomorrow” the same way it treats “the user likes cold brew.” Both are facts. Neither has a deadline. Neither knows whether it was fulfilled.
When we started building Meaning Memory, the commitment gap was the one that frustrated me most in practice. We had STARE 5D scoring for significance. We had cross-channel working memory so agents could see what happened in other sessions. We had scope groups for multi-agent access control. What we did not have was a memory type that knew it was a promise.
So we built one. It is live in the current release, and it changes how agents operate in a way I did not fully appreciate until I watched it working.
Why a promise is not a fact
The core insight is straightforward: a promise is structurally different from a fact. “I told Sarah the migration plan would be ready by Friday” is not the same kind of memory as “Sarah uses Salesforce.” The first carries an obligation, a deadline, and a consequence for someone else if it is missed. The second is a preference.
Most memory systems store both as text with an embedding vector. Neither carries a due date. Neither has a lifecycle. When the context window resets, both are equally gone, and the agent has no way to distinguish “I observed this about the world” from “I owe someone something by Friday.”
Meaning Memory introduces commitment as a fourth memory type, alongside semantic, episodic, and procedural. A commitment usually has a due date (the exception is the unscheduled holding state described below). It has a status. It has a lifecycle the engine tracks from creation to resolution. And it persists in the ledger independent of any conversation, so it survives context resets the same way every other memory does.
How the commitment lifecycle works
A one-shot commitment moves through a small set of states, and the engine enforces the transitions:
- Pending. The commitment exists, the due date is known, and it is awaiting action. This is the default starting state.
- Acknowledged. The obligor has confirmed receipt. Useful when a commitment is created by one actor but needs to be picked up by another.
- Completed. The work was done. Terminal.
- Failed. The deadline passed without completion. Terminal, and recorded as such rather than quietly forgotten.
- Cancelled. The obligation was deliberately retired before the deadline. Terminal. The system knows the difference between “done” and “decided not to.”
There is also a holding state, pending (unscheduled), for commitments recovered from conversation where the promise was clear but the date was not. Those wait for a due date before they enter the normal flow.
Every transition is recorded as an audit event with a timestamp, an actor, and a reason. You can trace the full history of a commitment from creation to resolution. For anyone running agents where accountability matters, this is the part that makes the feature real rather than theoretical.
How to keep recurring commitments honest
Recurring commitments are where this gets interesting, because they solve a problem that has annoyed me for months.
You have an agent that is supposed to do something every Monday; for example, I ask our OpenClaw agent Molty to check on the status of our Reachy Mini order, and make sure the engineering work to bring our new lab robot online is on track. In most systems, this means someone manually rolls a due date forward each week. The agent either does the work or does not, and there is no systematic way to tell which happened. The duty either fires every cycle regardless, producing duplicate work, or relies on a human to re-arm it, producing gaps.
In Meaning Memory, a recurring commitment carries a recurrence rule (something like FREQ=DAILY or FREQ=WEEKLY;BYDAY=MO) and a bookmark that marks the next due occurrence (the engine calls it the cursor). The bookmark only moves when an agent explicitly closes the current occurrence, and there are exactly two ways to do that:
Satisfy. The agent does the work and calls mm_satisfy_commitment. The bookmark advances to the next occurrence, the status re-arms to pending, and a commitment_satisfied event lands in the audit trail.
Waive. The agent decides to skip this cycle, maybe because there was nothing new to report. It calls mm_waive_commitment. The bookmark still advances, but the close is recorded as commitment_waived. The audit trail later shows that this occurrence was skipped, not done. That distinction matters if you are tracking reliability.
Nobody rolls a date. Nobody re-arms anything. And if nobody touches the bookmark at all, the commitment stays due. It surfaces in the due list every cycle, flagged overdue, until someone acts on it. A missed duty cannot quietly disappear. That is the behavior we wanted.
Two details make this safe to run on a fleet:
The bookmark is compare-and-set guarded. The agent passes the occurrence it believes it is closing (expected_due_at), and the engine checks it against the live bookmark. A match advances. A match against the previously closed occurrence is treated as a harmless retry and does nothing. Anything else is a stale view and the call is rejected. This prevents double-advancement when cycles overlap, which sounds like an edge case until you run agents on a 30-minute heartbeat and realize it happens whenever a cycle runs long.
Catch-up is explicit. If three weekly occurrences went by untouched, closing the live one jumps the bookmark to the upcoming occurrence rather than making the agent close each missed week individually, and the skipped occurrences are recorded in a separate audit event. Nothing is lost; it is just not silently absorbed either.
One more guard: the normal close operation refuses to terminate a recurring commitment, because that would strand the bookmark with no supported way to restart the cadence. Retiring a recurring duty for good is a deliberate, separately flagged action.
What this fixes in production
If you are deploying agents in production, the commitment lifecycle addresses three gaps that most memory systems do not cover:
Promises that survive context resets. An agent that says “I’ll do X by Friday” needs to remember that on Friday. Not in the same conversation, not in the same session. In whatever session happens to be running on Friday. Commitments persist in the ledger, and the agent queries them fresh each cycle. The promise survives the person who heard it, the session it was made in, and the model that generated the response.
A due list, not a recall list. When an agent starts a new cycle, it should not have to search its entire memory for things it might owe. It should get a sorted list of what is due right now. That is what mm_due_commitments returns: overdue items first, then due soon, then scheduled, then anything still waiting for a date. This is a different kind of query from semantic search, and it is the one that matters for reliability.
An audit trail for missed obligations. When an occurrence is satisfied or waived, or a one-shot commitment is completed, failed, or cancelled, the transition is recorded with a timestamp, an actor, and a reason. You can trace why a recurring duty was skipped, who retired a one-shot commitment, and when the bookmark last moved. If you have ever tried to debug why an agent stopped doing its weekly task and found no evidence anywhere, you know why this matters.
How it fits with STARE 5D
Commitments do not exist in isolation. They participate in the same STARE 5D scoring system as every other memory, and they arrive with strong priors on two dimensions: Significance, because a promise is rarely trivial, and Temporal, because a commitment is inherently time-bound. The Asymmetry dimension is where the stakes of a promise live: someone else is depending on it and cannot verify on their own that it will happen.
What keeps an open commitment in front of the agent is not a scoring trick. It is the lifecycle. An overdue recurring commitment keeps surfacing in the due list because nothing can advance its bookmark except a deliberate satisfy or waive. A one-shot commitment that was completed six months ago fades the way any settled obligation should, through the same consolidation and decay every other memory goes through.
This is what I mean by memory with consequences. A database stores facts. A memory system understands what those facts mean, what they obligate, and when they stop mattering. The commitment lifecycle is the mechanism that makes promises consequential.
How to create your first commitment
If you are building agents with Meaning Memory, commitments are available through the MCP tool surface. Create one with mm_remember using memory_type="commitment", a due_at timestamp, and a commitment_status. For recurring duties, add a recurrence rule. Query what is due with mm_due_commitments. Close recurring occurrences with mm_satisfy_commitment or mm_waive_commitment, and retire one-shot commitments with mm_close_commitment.
The shift is simple but it took me a while to internalize: when your agent makes a promise, do not store it as a fact. Store it as a commitment. Give it a deadline. Give it a lifecycle. Let the memory system track it, surface it, and record what happened.
Your agent said “I’ll handle it.” Now something does.
Common questions
What is a commitment in Meaning Memory?
A commitment is a memory type that carries an expectation of action and a due date. Unlike a semantic fact (“the user likes coffee”), a commitment tracks a promise (“send the weekly report by Friday”) through a lifecycle: pending, acknowledged, and then a terminal state of completed, failed, or cancelled.
How are recurring commitments different from one-shot commitments?
A one-shot commitment ends in a terminal state: completed, failed, or cancelled. A recurring commitment carries a cadence rule (daily, weekly) and a bookmark pointing at the next due occurrence. Each occurrence is closed by satisfying it or waiving it, and only those two actions move the bookmark forward. The duty re-arms for the next cycle.
What happens when an agent says “I’ll do it” but the context window gets pruned?
In most systems, the promise is lost. In Meaning Memory, the commitment persists in the ledger independent of the conversation context. The agent queries its due commitments on the next cycle and picks up where it left off.
Can commitments be shared across multiple agents?
Yes. Commitments live in the memory ledger with scope groups, so team-shared commitments can be visible to agents that need to coordinate. Private commitments stay scoped to the agent that created them.
How does this compare to a task queue or todo list?
Task queues manage external work items. Commitments live inside the agent’s own memory, which means they survive context resets, carry significance scores, and participate in the same retrieval and consolidation system as every other memory. The agent does not query a separate system. It remembers what it owes.
Related reading: Your Agent Treats Every Memory the Same. That’s the Problem., From Context Window to Memory Layer: A CTO’s Guide, and Introducing Throughline: Cross-Channel Working Memory.