From a38e7335145f97d6dc257a1df935937f67804a04 Mon Sep 17 00:00:00 2001 From: kami Date: Sat, 4 Jul 2026 00:13:13 +0400 Subject: [PATCH] fix: local timezone for replies + quiet-hours; guard presence "ago" overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Timezone: the container ran in UTC, so mavend answered clock/date queries (voice.go replySystem) and evaluated quiet-hours (gather.go) in UTC. Fixed at the root — process TZ — rather than per-call: TZ=Europe/Samara in compose + tzdata in the image (debian-slim strips it, without which Go ignores TZ and stays UTC). One knob fixes replies and quiet-hours for every daemon; change the zone in compose. Overflow: the dash "ago" helper ran time.Since on a zero timestamp (no presence yet / fresh db), saturating to ~292y and rendering "2562047h47m…". Guard zero → "never". Co-Authored-By: Claude Opus 4.8 --- Dockerfile | 5 ++++- cmd/mavweb/main.go | 9 ++++++++- docker-compose.yml | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 844e3d2..0e4ab58 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,8 +47,11 @@ RUN go build -o /out/mavend ./cmd/mavend && \ go build -o /out/mavcaldav ./cmd/mavcaldav FROM debian:trixie-slim AS runtime +# tzdata so the TZ env (set in compose) resolves — otherwise Go can't load the +# zone and time.Now() stays UTC, and mavend answers clock/date queries and +# evaluates quiet-hours in UTC. RUN apt-get update && apt-get install -y --no-install-recommends \ - ca-certificates libvulkan1 mesa-vulkan-drivers libgomp1 && \ + ca-certificates libvulkan1 mesa-vulkan-drivers libgomp1 tzdata && \ rm -rf /var/lib/apt/lists/* # runtime native libs: whisper/ggml (incl. vulkan) are real files in deps/lib. diff --git a/cmd/mavweb/main.go b/cmd/mavweb/main.go index 81bdba9..9ea66d7 100644 --- a/cmd/mavweb/main.go +++ b/cmd/mavweb/main.go @@ -50,7 +50,14 @@ var dashHTML string // text in facts/nudges. Read-only: browses the append-only store via CoreAPI, // never writes — the store IS the audit trail, this just shows it. var dashTmpl = template.Must(template.New("dash").Funcs(template.FuncMap{ - "ago": func(t time.Time) string { return time.Since(t).Round(time.Second).String() + " ago" }, + "ago": func(t time.Time) string { + // A zero timestamp (no presence signal yet, fresh DB) would make + // time.Since saturate to ~292y (MaxInt64) and render as garbage. + if t.IsZero() { + return "never" + } + return time.Since(t).Round(time.Second).String() + " ago" + }, }).Parse(dashHTML)) func noCache(h http.Handler) http.Handler { diff --git a/docker-compose.yml b/docker-compose.yml index aa9e21e..041de96 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,6 +15,10 @@ x-image: &image build: . pull_policy: never # only ever the locally-built image restart: unless-stopped + # local time for clock/date replies AND quiet-hours evaluation. Change to + # your zone; needs tzdata in the image (installed in the Dockerfile). + environment: + - TZ=Europe/Samara services: mavend: