parseDT stamped a zoned or floating DTSTART as UTC while every window
around it is built in local time, so the two sides of every comparison
were in different frames. On a +03 box a 22:00 local event parsed as
22:00Z, past the end of the local day, and the whole evening dropped out
of the busy gate and the day plan. A 13:00 Moscow meeting read on a +04
box was recited at 17:00 next to its own printed 13:00.
DTSTART now resolves three ways: a Z suffix is UTC, a TZID is loaded from
the zone database, and a floating value is read in the caller's location.
tzdata is embedded because the deploy image carries none, and a silent
fallback to the box offset is the bug being fixed. FactKey and FactValue
stamp the owner's clock, so the key date the store range-scans is the
same day the plan asks for. FactSummary drops the time tail for callers
that print the hour themselves.
Found in review of #56 and #58.
five fixes spotted during routing investigation:
- gitignore: replace blanket models/ ignore with per-dir exceptions
(/models/embedder/, /models/stt/, /models/tts/) so the seed text
files under models/seeds/ are tracked in version control
- query.txt: fix merged line — 'сколько стоит свет в этом месяце' and
'найди заметку про сервер' were fused with no separator
- reminder.txt: add 11 pure-verb reminder seeds without time expressions
to shift centroid toward the reminding intent rather than time-lexicon
- StubDateTimeParser: add Russian 'через <N> <unit>'/'через час'/'через
полчаса', 'сегодня'/'завтра'/'послезавтра' with optional clock, and
'в <clock>' scan. Add Russian word numbers (один-десять) and unit
inflections (час/часа/часов, минута/минуты/минут, день/дня/дней,
неделя/недели/недель). Also adds missing English day/week units.
- replySystem: guard time branch against duration queries ('сколько
времени прошло') reaching it via the classifier path after the
stage-0 grammar's build filter rejects them. Mirrors stage0.go
duration keywords.
three bugs causing time queries to land on reminder or fact intent:
- seed collision: query.txt and system.txt shared identical time/date
seeds (который час, сколько времени), making system intent
indistinguishable from query intent in centroid space
- threshold (0.35) too low for ONNX embedder — cosine similarities
cluster 0.5-0.7 for related intents, so Clarify never fired
- reminder centroid contaminated by time-lexicon (every seed has a time
expression), pulling any time-word utterance toward reminder intent
fixes:
- remove 3 duplicate time/date seeds from query.txt (keep in system.txt)
- DefaultRouterThreshold 0.35 -> 0.55
- stage-0 grammar for напомни/remind me -> IntentReminder, bypasses
classifier (fixes 'напомни через час' being misrouted to fact)
- stage-0 grammars for time/date system queries (сколько времени,
который час, какой сегодня день) -> IntentSystem, with Build filter
to exclude elapsed/duration queries (сколько времени прошло)
- time parser fallback in applyAction for stage-0 reminder matches
(extractor doesn't run on stage-0 decisions)