feat: an hour-precision clock that says so, and a cron tool that names the real timezone
Nightly Build / build (push) Successful in 7m30s
Nightly Build / build (push) Successful in 7m30s
The datetime block claimed second precision it never had. It is built once per request and a turn can run for minutes, so `17:54:31` is a lie by the time the model reads it — and the model, having no way to know, wrote cron expressions from it. Rounding was already there but configurable (`round_minutes`, shipped at 60) and justified by the prompt cache. That justification was false: the block is the LAST system message, after the whole conversation, so the cached prefix is identical from turn to turn whatever the timestamp says. Rounding buys nothing for caching today. So the knob goes and the granularity becomes part of the contract: always truncated to the hour, stated in words, with a pointer to `date` for the cases that need the minute. `DatetimeConfig` keeps only `enabled`. - truncation happens in the DISPLAYED zone, not on the UTC epoch: +05:30 zones would otherwise render 20:30 — an hour off and not on an hour boundary, which reads as precise again. - the weekday is spelled out. "next Tuesday" is a far more common ask than the minute, and weekday-from-date is exactly the arithmetic models get wrong. Also fixes a real bug found on the way: `execute_task` told the model, twice, that cron expressions are evaluated in Europe/London — hardcoded, while TaskManager uses the configured timezone. On a non-UK box every scheduled job was written against the wrong clock. The description now names the zone the scheduler actually uses (`TaskManager::timezone_name`), and the assistant's AGENT.md stops repeating the literal. CLAUDE.md: record that the instance is in production. The greenfield licence has expired — schema changes need a versioning mechanism, and per-user SQLCipher files mean it cannot be a boot-time sweep.
This commit is contained in:
@@ -58,7 +58,7 @@ Rules of thumb:
|
||||
|
||||
- **`mode=async`** — **the default for anything non-trivial.** It launches without blocking you, so you keep talking to the user while it runs. When it finishes, the system injects the result as a synthetic `task_completed` tool call — react to it and relay the outcome. After launching, tell the user it is running, then **do not poll** — the result arrives on its own.
|
||||
- **`mode=sync`** — run now and block for the answer. Only for **short** sub-tasks whose result you need immediately to finish composing your current reply.
|
||||
- **`mode=cron`** — schedule a recurring or one-shot task (7-field cron expression, `Europe/London`). The result arrives as a notification.
|
||||
- **`mode=cron`** — schedule a recurring or one-shot task (7-field cron expression; the tool description names the timezone it is evaluated in). The result arrives as a notification.
|
||||
|
||||
## Notifications
|
||||
|
||||
|
||||
Reference in New Issue
Block a user