03d725ea3e
A user asked Fable to schedule "this Friday at 8am" on Wednesday 4/29
2026. The model picked 4/30 (Thursday) and confidently labeled it
"Friday." The TZ pipeline did everything correctly given the model's
date — the bug was upstream: the model was guessing weekdays from ISO
dates without an anchor, and the calendar tools had no way to verify.
Three layered fixes:
1. **System prompts now name the weekday alongside the ISO date.**
Both the journal-conversation prompt and the general chat prompt
used to say "Today is 2026-04-29 (America/New_York)." They now say
"Today is Wednesday, 2026-04-29 (...)." LLMs are unreliable at
deriving weekday names from ISO dates; supplying the name removes
the guess.
2. **`expected_weekday` parameter on create_event / update_event.**
When the model passes `expected_weekday="friday"`, the backend
computes the resolved start_date's weekday in the user's local
timezone and rejects mismatches with a self-correcting error
("Date 2026-04-30 falls on Thursday, not Friday. Recompute..."),
without creating the event. The check is local-aware: a Friday
23:00 event in Tokyo crosses midnight UTC but the local view
stays Friday, and the validator respects that.
3. **Tool descriptions instruct echo-and-confirm.** create_event and
update_event descriptions now tell the model: when the user names
a weekday, state the resolved date in the reply BEFORE calling
the tool, and pass `expected_weekday`. Costs nothing in code,
reinforces the validator.
6 new tests — match success, mismatch rejection (with create/update
not invoked), omitted-param backcompat, invalid weekday name, local-
not-UTC weekday computation, and the update_event variant. All 18
calendar-tool tests + 33 event-related tests pass; ruff clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>