The renewal money guard — what it is, where it went wrong, and the fix spec

Handoff — Decision 6 ruled (Option A) · 2026-08-18

Requested by Fede after the Mallory parking replay (r08). This is the deep dive on the safety net that blocked a correct, manager-taught answer and replaced it with a hand-off promise nobody was behind.

What the guard is

Clara has a last-line safety check that runs on every reply in a conversation with an open renewal (and on tour conversations), right before the message is sent. It exists because renewals are legal contracts: if Clara names a wrong number and the resident signs, we own the discrepancy. It does three things:

1. Numbers check — every dollar figure and every "X-month" phrase in the reply must match the resident's own prepared renewal offer (or their current rent). Anything else blocks the whole reply.
2. Action-claim check — "I've locked in your renewal" must be backed by the real action having happened this turn.
3. Tour-time check — a confirmed tour time must match what's actually on the calendar.

When it blocks, the resident instead gets: "Thanks — I'm looping in your property manager to make sure we get this exactly right. They'll follow up shortly." The blocked draft is preserved internally for audit.

Track record: the guard has caught real incidents (a made-up month-to-month total in May, a silently dropped tour reschedule in July). It is a good net with two real holes — both about what it refuses to trust and what happens after it blocks.

Mistake 1 — the guard and Clara's own instructions disagree about what counts as "backed up"

Clara's instructions say a dollar figure is legitimate if she can point to it in the property's knowledge (including answers the team taught her) or in a tool result from this conversation. The guard was built narrower: it trusts only the renewal offer and the current rent. It never looks at property knowledge at all.

Mallory (replay r08): the manager taught Clara "one lot spot at $75/month, garage has a waitlist" minutes earlier. Mallory asked "any parking spot available?" on her renewal thread. Clara drafted exactly the taught answer — $75/mo, garage waitlist. The guard saw a dollar figure that isn't in her renewal offer and threw the whole reply away. The correct, taught answer was blocked by our own net.

Related scope problem: because the guard arms on "this conversation has an open renewal," it applies renewal-offer math to every topic on the thread — parking, fees, anything. A resident mid-renewal asking about anything with a price gets the strictest filter we have, keyed to the wrong data.

Mistake 2 — the promise after a block wasn't always backed by a real hand-off

The replacement text promises "they'll follow up shortly." Behind that promise, the system auto-files a renewal escalation — but only when the block happened on a resident with a renewal in scope, and the escalation email only actually sends if the property has an escalation address configured. In Mallory's case: no tracked question was opened, no email went out, nobody was looped in — the resident got a promise with nothing behind it. (This "promised follow-up that never came" pattern is the same class as the bed-bug and parking-spot incidents that produced the team-inbox quiet rule.)

History worth knowing: an earlier version of this guard also over-blocked on harmless phrases ("all set", "good to go") — at one point ~79% of production blocks were that false-positive class before it was narrowed. Lesson: when this guard's list of what-to-trust drifts from how Clara actually writes and learns, it fails loud and wrong.

The ruling (Decision 6, Option A — Fede, 2026-08-18) and the fix spec

1. Taught knowledge counts as grounded. The guard's trusted set expands from "renewal offer + current rent" to also include the property's knowledge — the same sources Clara's own instructions already name, including answers the team taught her. A figure she can point to is never blocked.

2. Every block opens a real tracked question. Whatever the topic, if the guard withholds a reply, the fallback files a tracked question to the property's escalation owner — the promise in the safe message is always backed by an actual hand-off with reminders (three, per Decision 3).

3. Harness graduates. The replay case r08 and the disaster cases move from tolerated expected-failures to hard passes before this ships.

Engineering pointers: guard logic in agents/clara/lib/agent/guards/hallucination-guard.ts (trusted set built in validateOfferReferences); block-and-replace + auto-escalation wiring in agents/clara/lib/agent/conversation-manager.ts around the "safety:hallucination-guard" step; taught-knowledge source is the property-knowledge block the prompt already receives; tracked-question primitive is openMatterAndAsk (activates per property via its escalation owner). Interacts with Decision 1C (redrive-with-policy) and Decision 7 (one-off vs. policy layer).

PropFlow Docs