mavend seals its encrypted database in `defer st.Close()` when run() returns. It had not returned since 2026-07-21. Every restart since then decrypted the same eleven-day-old ciphertext and rolled back everything written in between: the Telegram nudge that kept firing was a fact being un-written on each boot. The goroutine dump named it. main → srv.Close() → ipc.(*Server).Close → wg.Wait(), waiting on per-connection goroutines parked in readFrame. Close shut the listener and nothing else, so the idle persistent sockets held by mavweb, mavpoll, mavcaldav and mavmaild blocked shutdown forever. `docker compose stop -t 60` spent the whole sixty seconds and then took a SIGKILL. So: track the accepted conns and close them, in ipc and in voice, which had the identical defect. Bound all three waits — the two per-server ones and the worker wait in main — because the seal matters more than any single in-flight call. A dropped RPC costs one reply; a missed seal costs a session. The regression test leaves a client connected and idle, which is the case the old tests avoided by closing the client first. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TrVSBKe3RFDF4fGYKWYQnX
5.6 KiB
Handoff
Uncommitted scratch file. Delete it once the work below is finished.
Written 2026-08-01. Kami is away for about an hour and will start a new session.
Where things stand
The 35-PR stack (50 to 84 on gitea, one linear chain) has been reviewed and the findings have been fixed. Two things are done and one is not.
Done: reviews. One review posted on every PR from 50 to 84, as the claude
login. Review ids 58 to 92.
Done: fixes. Eleven agents fixed the findings in parallel git worktrees.
All eleven branches are merged onto fix/integrated, which is 68 commits
ahead of the tip. make test and make build both pass on it.
Not done: landing them. overnight/eco-versioned-traces (the stack tip) has
NOT been moved. Kami chose to land the fixes as commits on that tip. The final
step is a fast-forward, once he has answered the open questions below.
git checkout overnight/eco-versioned-traces
git merge --ff-only fix/integrated
Do not push. He merges the stack himself.
Ask him these first
He asked for the list and then left, so none of it is answered. Nothing below is a blocker for the fast-forward, but all of it is easier to change before the tip moves than after.
- Hexis refuses to wire when a token is configured. It used to log once and then call unauthenticated forever. Fail closed, or warn and continue?
MethodIngestMailstayed atAuthReadwhileSetTaskStatusmoved toAuthWrite. Those two now disagree about the same kind of question.- "Прости" in
clarifyGaveUpand one expiry variant.CheckCringebans apologies. The fix scoped the ban to nudges and kept his wording, with the reasoning in a test skip. Absolute ban is the other reading. - Memory evaluation timeout is 60s. Two agents disagreed here. The merge kept the short budget plus the gate that yields the slot to voice turns. Five minutes is safe again now that the gate exists.
- Cold-start v1 recovery is narrow. It fires only when an assertion carries
a PRF secret and that unlock fails. A pre-existing box whose only
authenticator lacks PRF still needs
MAVEN_DB_KEY.
Two things to know before deploy
The update block. The self-update fix refuses at startup any
build-from-source deployment that cannot say how to undo the source.
deploy/mavend.json has no update block today, so nothing breaks. Adding one
for the docker layout without source_rollback will stop the daemon booting.
That is intended. It should not be a surprise.
Three migrations became four numbers. Three agents each wrote a migration 15. Tasks kept 15, ecosystem traces became 16, MCP tool fingerprints became 17. Any box already carrying an unreleased 15 from a worktree build needs its schema version checked by hand.
Merge decisions already made
Two agents independently added llm.Gate. One is priority between a voice turn
and background work. The other is admission control while the resident model is
swapped. Both were kept. The swap one is now SwapGate with SetSwapGate.
Complete takes priority first and the drain second, so a background request
waiting on priority cannot stall a swap.
Still open in the code, on purpose
- Ambient calendar events never reach the
calendar_busygate.calendar_busyis a level, so an ambient writer needs an expiry. Recorded as a comment at the top ofcmd/mavweb/ambient.go. - Hands-free has no session-scoped voice assertion. Noted in the mavweb route table.
- The Hexis capabilities call sends no correlation id. The vendored client has no header hook, so closing it means re-vendoring.
- Re-running a stored audio blob by id does not exist. The comments that claimed the wire offered it were corrected.
- Simulator persona checks read a Go constant on one step, because chat there
goes through
phraser.NewStub()rather than the replier. - The PRF value is client-supplied and unbound to the assertion signature. This
is inherent to PRF key wrapping, which needs a fixed salt. Documented in
cmd/mavweb/webauthn.go. Do not try to bind it. safeKeydrops Cyrillic, so Russian calendar events on one day collide. Filed as Vikunja #443 with three fix options. It is a migration, not a patch.
The one task left
Audit what the agents filed in Vikunja. They created QA tasks on their own initiative, which nobody asked them to do. Kami saw them and said some are new bugs worth a later sweep. Dedupe against existing tasks, and separate genuine new bugs from restatements of findings the commits already fixed. That produces the second sweep list without re-reading 35 PRs.
Recipes
Gitea is https://gitea.kvmx.ru, repo kami/Maven. Tokens are in
~/.config/tea/config.yml: the homesrv login reads, the claude login posts.
tea cannot list review comments, so use the REST API.
Read the reviews for one PR:
curl -s -H "Authorization: token <homesrv-token>" \
"https://gitea.kvmx.ru/api/v1/repos/kami/Maven/pulls/<n>/reviews"
Do not fetch /issues/comments without a since filter. It returns 50 stale
comments from a superseded stack.
The scratchpad from this session holds RECIPE.md (how the reviews were done),
FIXBRIEF.md (how the fixes were done) and postreview.sh. Worktrees are under
scratchpad/wt/g01 to g11 and can be removed with git worktree remove once
the tip has moved.
Constraints that do not change
Read CLAUDE.md. Maven is feminine and calls him "ты". The eval enforces both.
Not a nag, not autonomous. No telemetry, no cloud model, no third-party account.
His notes and facts are never search input. Use make, never bare go build on
a CGO daemon.