f1a809121b
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
121 lines
5.6 KiB
Markdown
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.
|