-
v0.9.2
Stablereleased this
2026-08-10 21:07:03 -05:00 | 88 commits to main since this releaseThe answers-short-without-erroring group, which is the defect class this project keeps
finding: three of the four live defects found so far were in it. Also the OAuth regression
coverage that had been outstanding since before 0.9.0. Phase 2 ofdocs/audit.md.Added
-
truncatedandevents_foundin the read envelopes.MAX_EVENTS(default 500)
truncates in two places — per calendar during expansion, and again across the merged
list. Both logged a warning; neither reached the caller. Solist_eventsover a busy
month returnedcount: 500and a clean envelope, and the model reported that as the
user's whole month. A request that failed, reporting success.FetchResultnow carries whether anything was dropped and how many there were, counted
before the limit rather than inferred from the length that came back — which cannot tell
a window holding exactly the limit from one holding ten times it.The
find_free_timewording is deliberately harder thanlist_events', because the
consequence inverts. Dropping events from a listing shortens the answer. Dropping them
from an availability search removes busy time, so the tool invents free slots and
offers to book over meetings that exist — the same argument
_reject_unknown_calendarsalready makes about unknown calendar names. Both tools log
truncated_fromtoo, so a shortcounthas one more explanation on the same line. -
The browser half of the sign-in flow is regression-tested. Dynamic registration,
/authorize, the consent screen and the hand-off to Forgejo now run in the suite
against the real ASGI stack. It pins the things that fail silently: the upstream
redirect URI is this server's/auth/callbackrather than Claude's (the
redirect_uri_mismatchin the operations table), PKCE is forwarded under a second
challenge of the proxy's own, declining consent never reaches Forgejo, a registered
client survives a restart, tokens are checked by introspection with no required scope,
and the signing key is derived from configuration rather than generated per process —
the last of which presents only as everyone being signed out for no visible reason.Forgejo's own answer and the token exchange still need a network. Neither has ever been
where this broke.
Fixed
-
Two calendars sharing a display name shared a cache entry.
fetch_eventskeys its
results by index, with a comment saying why: two collections on one account can share a
name, and collapsing them would drop a calendar's events while reporting success. The
resource cache key, seven lines later, was the name. First request, both missed and both
searched — correct, by luck. Any request insideEVENT_CACHE_TTL, both indices hit
whichever was written second: one calendar's events returned twice, the other's gone,
nothing inunavailable. A follow-up question about the same week is exactly the
traffic the cache exists to serve. Keyed by collection URL now, which is unique, stable,
and stays out of the log line because it carries the account DSID. -
A basic-format end date silently excluded its own day.
parse_whendecided a value
was date-only withlen(text) == 10, which is true of2026-08-07and false of
20260807— a spellingdatetime.fromisoformataccepts perfectly happily on 3.11+. So
end="20260807"parsed clean to midnight, skipped the end-of-day widening, and dropped
everything on the 7th with no error. The tool description asks forYYYY-MM-DD, but it
also accepts "a full ISO 8601 datetime", and basic format is ISO 8601. Decided from the
parse now, which cannot drift from what was actually parsed.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-