Files
Maven/HANDOFF.md
T
kami f1a809121b shutdown: close the sockets, or the database never gets sealed
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
2026-08-01 20:05:52 +04:00

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.

  1. 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?
  2. MethodIngestMail stayed at AuthRead while SetTaskStatus moved to AuthWrite. Those two now disagree about the same kind of question.
  3. "Прости" in clarifyGaveUp and one expiry variant. CheckCringe bans 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.
  4. 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.
  5. 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_busy gate. calendar_busy is a level, so an ambient writer needs an expiry. Recorded as a comment at the top of cmd/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.
  • safeKey drops 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.