• Joined on 2026-07-30
claude created pull request kami/Maven#88 2026-08-02 07:35:56 +02:00
dialogue.Slots and router.Slots are hand-kept copies that already drifted
claude created pull request kami/Maven#87 2026-08-02 07:11:22 +02:00
Retire PROGRESS.md, the backlog and the feature ranking
claude created pull request kami/Maven#86 2026-08-02 01:28:56 +02:00
Doc reorg: tier the tree, retire the three planning files
claude created pull request kami/Maven#85 2026-08-02 01:22:55 +02:00
Session workflow: pickup and wrap around the task flow
claude pushed to master at kami/Maven 2026-08-01 14:50:29 +02:00
6915e6a714 Land the 35-PR overnight stack (PRs 50-84)
0db31d21b9 hexis: re-vendor the client so a configured token is actually sent
df3220d039 auth: put mail ingestion on the same rung as resolving a task
76a251a20d Merge branch 'fix/g08' into fix/integrated
724e90759e llm: keep the priority gate and the swap drain apart
Compare 136 commits »
claude merged pull request kami/Maven#84 2026-08-01 14:50:26 +02:00
Version, authenticate and fully trace ecosystem calls
claude commented on pull request kami/Maven#69 2026-08-01 11:41:03 +02:00
Deploy a new build with verification and automatic rollback

The refusals in the package comment are the best part of this PR, and they are enforced rather than described. No timer, no IPC method, no web route, no fetch of code from anywhere. Snapshotting before the build, with the reason spelled out, is the non-obvious ordering and it is the correct one. The preflight health check is right, and for the reason given. Without a baseline, a failed update and an already broken box are the same picture. context.WithoutCancel around the rollback is the detail that makes a Ctrl-C during the health wait safe. Copies rather than hardlinks or a git stash, re-hashed on the way back out. A restore is checked, not hoped for.

claude commented on pull request kami/Maven#73 2026-08-01 11:40:00 +02:00
Meeting capture with an explicit start and stop (#253)

The refusals are the best part of this PR and they are refusals in code, not in

claude commented on pull request kami/Maven#77 2026-08-01 11:38:43 +02:00
Derive the cold-start unlock key from the passkey PRF, not the public key (#14)

The core change is right and the reasoning in the keywrap.go header is the clearest statement of the old bug I have read. Three details earn their keep. secretLen = 32 as a structural refusal, so a 77-byte COSE public key cannot be passed here again by accident. The magic authenticated as GCM additional data, so a v2 blob cannot be stripped and re-read as v1. Replacing the hand-rolled HKDF that keyed expand with the salt instead of the PRK. The daemonLock.st handoff is a separate real bug caught in passing. A cold-started daemon never called store.Close. Every write of that session was lost on the next boot, silently.

claude commented on pull request kami/Maven#81 2026-08-01 11:38:07 +02:00
Scan the LAN, bounded to configured subnets (#257)

Scan(ctx) taking no target is the correct API, and it is what makes the rest of the bounds hold. There is no exported path from an utterance to a range, so the prompt-injection story is closed by shape rather than by validation. Rejecting a non-private prefix and anything wider than a /22 at config load, in netscan.Validate, means the daemon cannot be talked into a scan it would not have done at boot. TCP-connect plus an ARP-table read, with no raw sockets and no root, is the right cost for the answer. The Russian count inflection in hostWord is correct including the teens.

claude commented on pull request kami/Maven#61 2026-08-01 11:37:15 +02:00
Rank captured tasks by what he actually said (#129)

One renderer for the voice reply and the page is the right structure. The reason string is what makes the ranking auditable instead of a black box. Refusing to ask the model which task matters, on the same grounds as the counted behaviour profile, is consistent and correct. Blanking a candidate's reason so her reading of a mail is never shown as his priority is a good detail. dayDelta in whole days rather than hours is right.

claude commented on pull request kami/Maven#80 2026-08-01 11:36:03 +02:00
Read and control the house through Home Assistant (#256)

Encoding a device as an allowlist row with cmd = ["smarthome", "<entity_id>", "<service>"] is the right move. It reuses the enable gate, the confirm turn and tool.Matcher without touching any of them, exactly as MCP did. Dropping the spoken args in the Exec branch is the load-bearing detail. The router picks a row and never composes a target. A misheard number cannot become a different lamp. Leaving set_temperature and set_brightness out of the controllable table for the same reason is consistent. The block ships "enabled": false.

claude commented on pull request kami/Maven#76 2026-08-01 11:35:51 +02:00
Half-duplex capture and barge-in in mavwaked (#287)

Half-duplex is the right fix and the reasoning holds. With no echo canceller, muting capture is the only honest option. Barge-in has to be off by default because the threshold is a property of the room. Putting aplay behind a player interface makes both halves testable. The gen counter in aplayPlayer closes a real race, where a finishing playback clears the flag of the one that replaced it. TestSessionEchoLevelAudioNeverBargesIn is the test that matters most and it is there.

claude commented on pull request kami/Maven#72 2026-08-01 11:35:38 +02:00
Vision: store and describe images through a shared media intake (#252)

The shape of internal/media is the good part. Sidecars instead of another

claude commented on pull request kami/Maven#65 2026-08-01 11:35:17 +02:00
Add mavmaild, the read-only IMAP poller that feeds mail intake (#246)

The credential split holds end to end. The password is read from a file, trimmed and checked for empty. It is never logged, and never put on a struct that outlives the call. mailIngester is a one-method interface, so the daemon's whole reach into core is visibly IngestMail and nothing else. The seen-state being an optimisation rather than a correctness requirement, with CaptureTask dedupe as the real guard, is the right way round. Atomic rename at 0600 for a file of message ids is the correct paranoia level.

claude commented on pull request kami/Maven#60 2026-08-01 11:35:15 +02:00
Capture tasks, with one intake seam mail can call later (#130)

Adding no eighth intent is the right call. Tying it to the prompt-parity contract in the header comment is the argument that makes it stick. The candidate status earns its keep. A derived task is named as unconfirmed in the spoken list and in the page. Mail can never quietly become work he owns. The partial unique index over live rows only is the correct shape for a recurring errand. NormalizeTaskText refusing to stem is the right kind of shallow.

claude commented on pull request kami/Maven#84 2026-08-01 11:34:53 +02:00
Version, authenticate and fully trace ecosystem calls

Reviewing 927e46b only. The extra commit on this branch is 7f42cc7. It answers your comments on 50, 52, 53, 54, 59 and 61. Not part of this PR.

claude commented on pull request kami/Maven#68 2026-08-01 11:34:44 +02:00
Swap the resident model without restarting mavend

Kill-then-load rather than blue/green is the right call for this box, and the file comment argues it instead of asserting it. One 1.7B fully offloaded to a Vega iGPU leaves no room for a second copy. The "keep the old one warm" design would OOM the laptop. The new server is probed for its own model identity before it is published, and that identity is reported instead of an echo of the request. A mislabelled gguf shows up on the page, not in a week of bad replies. launch staying nil in NewLLMPhraserAt so Swap refuses a server it did not start is the detail that keeps the eval harness safe. The allowlist is exact paths a human typed. cfg.Phraser.ModelPath is always included, so the way back never depends on remembering to list it.

claude commented on pull request kami/Maven#64 2026-08-01 11:33:39 +02:00
Turn a mail into task candidates, and into nothing else (#246)

The bound is real and it is structural, not a promise in a comment. Extractor holds no store and no writer, so it cannot persist anything. mailIntake.ingest hardcodes store.TaskCandidate and calls only CaptureTask, so no fact, reminder or nudge is reachable from a parsed mail. The double gate is the right shape too: no email block or no LLMPhraser leaves IngestMailFn nil, and MethodIngestMail then answers ErrUnknownMethod rather than succeeding quietly.

claude commented on pull request kami/Maven#75 2026-08-01 11:33:37 +02:00
Golden-audio STT tests against real whisper.cpp (#288)

Synthesising the fixtures instead of recording them is the right trade. Nothing of his voice is committed. The WAVs are regenerable from the script plus a voice model. The nginx note in gen-stt-fixtures.sh shows the artefact was hit and worked around, not guessed at. TestGoldenFixturesAreCanonical running the fixtures through gateReason before the model test uses them is the check that stops a silent-fixture false pass.