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

121 lines
5.6 KiB
Markdown

# 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.