I still remember the email that came in on a Tuesday morning. The agent had booked a call with a woman whose husband had died six weeks earlier. The model saw a recent gift, a clean CRM field, and an open slot on the calendar. It did exactly what we asked it to do.
She wrote back asking how we had known to reach her right then, and whether someone on staff had been watching the obituary pages. I had no good answer for her. The prompt never told the model to pause for a death in the family.
That was the week I stopped trusting volume as a proxy for care, and the week we started designing the agent roster rule that eventually stopped it from happening again.
The agent that booked the wrong donor call three times
The first run pulled a retired pastor who had served on the denomination’s finance committee years earlier. The model saw the title, the past gift size, and the open calendar slot. It booked the call for Tuesday at 10 a.m. The executive assistant who received the invite replied that her boss had passed away the year before.
The second run found a current major donor whose assistant had already asked multiple times that year to route all requests through the foundation office. The agent ignored the note in the CRM because the note sat in a free-text field the model treated as secondary. The call was booked anyway. The donor’s office canceled and asked to be removed from future outreach.
The third run surfaced a board member’s spouse who had served on the development committee until a quiet conflict over grant priorities. The model had no signal for that conflict. The invite went out, the board member called the CEO directly, and the project paused for two weeks while leadership decided whether the agent should continue at all.
Each failure looked like a data-quality problem on the surface. It was not. It was a refusal problem.
Why the agent roster rule had to live in the prompt and the calendar
We built the roster as a single shared document the agent had to check before any calendar action. The document contained three columns: name, explicit refusal reason, and the human owner who last confirmed the refusal. The agent prompt required it to query that document first and surface any match before generating an invite.
The calendar itself carried the same rule. Every proposed meeting block carried a hidden tag that the agent could not override. If the tag matched a roster entry, the block stayed blocked even if the model found an opening. The human owner received a daily digest of attempted bookings that hit the roster, not a list of successful bookings.
The rule moved from a nice-to-have note in the brief to a hard gate because the first three runs showed that volume incentives always outrun soft instructions. Once the roster lived in both the prompt and the calendar system, the agent stopped treating every open slot as an opportunity.
The measurable drop in wasted follow-up hours once the roster rule was explicit
After the roster rule went live, the booked calls that later required apology or removal dropped from a weekly occurrence to essentially none across a six-week test. The agent still surfaced the same volume of potential names, but it now routed the roster matches to a human queue instead of sending invites.
The follow-up work shifted from reactive damage control to proactive list maintenance. One PM had spent several hours a week cleaning up after bad bookings before the rule. After the rule, that time dropped to a short weekly pass on roster updates. The saved hours went into tightening the criteria the human owner applied, which in turn improved the quality of the names the agent was allowed to touch.
The same pattern appeared when we applied the roster approach to volunteer recruitment for a children’s ministry resource platform. The agent stopped inviting people who had already declined multiple times, and the volunteer completion rate for the first session rose because the remaining contacts had not been burned by repeated outreach.
Your Turn: Apply This Today
- Export the last thirty days of agent-proposed outreach and mark every name that produced a refusal or complaint; turn that list into the first version of your roster document.
- Add a single required query step in the agent prompt that checks the roster before any calendar action and surfaces matches to a human instead of booking.
- Tag every calendar block the agent can use with a hidden refusal flag that the model cannot override without human approval.
- Set a daily digest that shows only the roster hits, not the successful bookings, so the human owner sees refusal patterns before they compound.
- Run the next agent test with a hard stop after ten proposed actions; require the human owner to review roster matches before the agent continues.
- Measure the hours spent on post-booking cleanup this week and again after the roster lives in both prompt and calendar; treat the difference as the real retention metric for the agent.
The same refusal logic shows up when an evaluation layer has to decide what an agent is allowed to touch at all, which is why the post on shipping an agent and then needing that layer is worth reading next. The custom work we had to do after off-the-shelf tools hit ministry data limits also traces back to the same roster problem.
I consult with product leaders shipping autonomous agents in ministry contexts on refusal criteria, evaluation layers, and roster design. Let’s talk.
Discover more from Dr. Joshua Read
Subscribe to get the latest posts sent to your email.

