Index plans and evaluations by lifecycle (V-674)

This commit is contained in:
2026-08-13 01:27:14 +04:00
parent f957a3ad13
commit fdee3de724
14 changed files with 195 additions and 23 deletions
+1 -1
View File
@@ -28,7 +28,7 @@
---
## Status 2026-08-01 — foundation shipped (Vikunja #248)
## Status 2026-08-01 — foundation shipped (V-248)
**Shipped:** `internal/memeval` (not `internal/memory/eval.go``internal/store`
imports `internal/memory` for the vector backend, so an evaluator that reads
+2 -2
View File
@@ -17,7 +17,7 @@ describing half is **BLOCKED on a model download** — see "What is blocked" bel
| IPC method `describe_image` (`AuthRead`) | `internal/ipc/{wire,api,client,server}.go`, `internal/auth/policy.go` |
| Daemon wiring + hourly retention prune | `cmd/mavend/vision.go` |
`internal/media` is deliberately shared: hearing (#253) and speaker recognition (#255) have
`internal/media` is deliberately shared: hearing (V-253) and speaker recognition (V-255) have
the same intake problem — a blob arrives, gets stored, gets described — and they store their
audio in the same place under the same retention.
@@ -77,7 +77,7 @@ To unblock, download one pair to `/mnt/hdd1/llms/vision/` (bind-mounted to
- `moondream2` — smallest, English-only in practice. Do not bother, per the sub-500M lesson.
Then run a second llama-server on 8081 with `--mmproj`, point `vision.endpoint` at it, and
walk the QA steps on Vikunja #252.
walk the QA steps on V-252.
## Config
+3 -3
View File
@@ -14,14 +14,14 @@ shipped is the workpc-side microphone agent and the router intent — see "Still
|---|---|
| Session state machine: start / append / stop / abort / status | `internal/capture/capture.go` |
| Map-reduce summarisation against `n_ctx` 4096 | `internal/capture/summarize.go` |
| Audio blobs in the shared store, pruned by `media.retention` | `internal/media` (from #252) |
| Audio blobs in the shared store, pruned by `media.retention` | `internal/media` (from V-252) |
| Config block `capture`, off by default | `internal/config/config.go` |
| IPC `capture_start` / `capture_append` / `capture_stop` / `capture_status` | `internal/ipc/{wire,api,client,server}.go` |
| Authority: the three write methods `AuthWrite`, status `AuthRead` | `internal/auth/policy.go` |
| Daemon wiring, note write, STT reuse | `cmd/mavend/capture.go` |
The audio lands in the same content-addressed blob store as images, under the same retention
loop, because #252 and #253 have the same intake problem and solving it twice would mean two
loop, because V-252 and V-253 have the same intake problem and solving it twice would mean two
directories to remember to prune.
## The refusals, and why
@@ -117,5 +117,5 @@ Both absent by default. `capture` alone does nothing without `media`.
talking, so the recorder's stop and the speech barge-in must not collide.
- **A `/dash` panel** showing a running session, so a recording is visible on a surface and not
only in a log line.
- **Speaker attribution** — who said what — is #255 and is blocked on a model; see
- **Speaker attribution** — who said what — is V-255 and is blocked on a model; see
`docs/plans/10-speaker-recognition.md`.
+2 -2
View File
@@ -3,7 +3,7 @@
**Goal:** Maven can tell who is speaking on the voice channel, and tag what she writes with
who said it.
**Status (2026-08-01, Vikunja #255):** the enrolment half is shipped. The recognising half is
**Status (2026-08-01, V-255):** the enrolment half is shipped. The recognising half is
**BLOCKED on a model download** — there is no speaker-embedding model on this box, and one
was not invented to fill the gap. See "Blocked, and on what" below.
@@ -125,6 +125,6 @@ lied.
- **An enrolment surface.** The three IPC methods exist; no page drives them. Enrolment is
step-up, so it belongs on `/dash` behind a passkey, with a per-profile forget button next to
each row — that button is the reason `list_speakers` exists.
- **A speaker column on the meeting recorder** (#253). Attributing lines in a transcript is
- **A speaker column on the meeting recorder** (V-253). Attributing lines in a transcript is
the obvious pairing, and it is the place where getting attribution wrong is most damaging,
so it waits for a real model too.
+1 -1
View File
@@ -30,7 +30,7 @@
---
## Shipped 2026-08-01 (#258)
## Shipped 2026-08-01 (V-258)
`internal/webfetch` (the guarded HTTP door: scheme, allow/deny hosts, private-address
refusal in the dialer, size cap, redirect cap, per-host rate limit), `internal/rss`
+2 -2
View File
@@ -29,11 +29,11 @@
8. Add `crawls` block to `config.Config` and `deploy/mavend.json`
9. Test with a static HTML page — verify extraction matches expected values, verify scheduling fires correctly
## Shipped 2026-08-01 (#259)
## Shipped 2026-08-01 (V-259)
Built as `internal/crawl` (pure: robots, extraction, watcher) plus
`cmd/mavend/crawls.go` (fetcher, ticker, dedup facts), on top of the guarded
`internal/webfetch` door added with the feed reader (#258). Off unless
`internal/webfetch` door added with the feed reader (V-258). Off unless
configured, in two separately-switched halves: `crawl.on_demand` for a URL he
names, `crawl.watches` for a scheduled re-read.
+1 -1
View File
@@ -1,6 +1,6 @@
# Plan: The work board surface
**The decision Vikunja #431 asked for. Written 04-08-2026.**
**The decision V-431 asked for. Written 04-08-2026.**
**Verdict: build it, in a smaller shape than the task imagined.** The board is worth
moving out of the file. The intake form belongs on the `/tasks` page, not on the voice
+5 -5
View File
@@ -1,6 +1,6 @@
# Plan: What the ambient calendar path should be
**The decision Vikunja #432 asked for. Written 04-08-2026.**
**The decision V-432 asked for. Written 04-08-2026.**
**Verdict: keep the endpoint, change the contract.** The relay app sends structured
fields, not a notification blob. The free-text parser stays as the degraded path, because
@@ -9,7 +9,7 @@ if the answer to the one open question below is no.
## First, the task's premise is out of date
#432 states as confirmed that every ambient event lands on the day the notification was
V-432 states as confirmed that every ambient event lands on the day the notification was
posted, because there is no date parsing at all. That was true when the task was filed
and it is not true now.
@@ -17,7 +17,7 @@ and it is not true now.
"завтра в 15:00" now dates to tomorrow. The same commit added `ambientPastGrace`, which
refuses an event landing more than two hours before the notification, on the reasoning
that the day was inferred and a stale inference is wrong rather than late. `45a5e37`
(#482, this week) fixed a second dating bug the task did not know about: the wall clock
(V-482, this week) fixed a second dating bug the task did not know about: the wall clock
was resolved against the notification's own zone, so every ambient meeting on a non-UTC
box landed off by the deploy's UTC offset.
@@ -38,7 +38,7 @@ Everything follows from this and nothing in this repo can answer it.
A `NotificationListenerService` sees a title and a body. It cannot know a meeting's real
start, end or organiser, because those are not in the notification. So if the relay is
limited to the notification stream, free-text parsing on this side is not a choice, it is
the only thing available, and #432's suggestion that the phone send structured JSON
the only thing available, and V-432's suggestion that the phone send structured JSON
cannot be honoured.
If the app may instead read `CalendarContract`, it has the actual event rows, and the
@@ -73,7 +73,7 @@ closes this without code, and it is his to give.
## What not to do
Do not add date parsing to the free-text path yet. That is the patch #432 explicitly
Do not add date parsing to the free-text path yet. That is the patch V-432 explicitly
refuses to accept as closure, and it is the wrong order: if the relay can send a date, no
date parser is needed, and if it cannot, the parser is guessing at a date from text that
was never meant to carry one.
+2 -2
View File
@@ -1,6 +1,6 @@
# Plan: Where mavwaked and mavenclient run
**The decision Vikunja #463 asked for. Written 04-08-2026.**
**The decision V-463 asked for. Written 04-08-2026.**
**Verdict: not in compose on homesrv. They run on a client machine in the room he is in.**
The transport for that already exists and nothing needs building to allow it. What needs
@@ -11,7 +11,7 @@ building is a way to check the wake path at all, which is a separate task.
`docker-compose.yml` runs mavend, mavsttd, mavttsd, mavweb and mavpoll. `mavwaked` and
`mavenclient` appear in no compose file and run as no host process. Both build under
`make build`. So the wake word and the voice-activity gate are untested by construction:
QA session 1 step 2 covers push-to-talk from `/dash` only, and #287 (voice session
QA session 1 step 2 covers push-to-talk from `/dash` only, and V-287 (voice session
quality) can never be more than half-answered while this holds.
## The reason is not hardware
+1 -1
View File
@@ -1,6 +1,6 @@
# Plan: route with heads on e5-small, not with a generative model
**Owner's call, 05-08-2026. Vikunja #546.**
**Owner's call, 05-08-2026. V-546.**
**Verdict: the routing model is the 118M multilingual-e5-small already resident on
homesrv.** It gets one classification head per output. No LoRA on a decoder, no 100M model
@@ -1,6 +1,6 @@
# Plan: persist the routing trace
**Owner's call, 06-08-2026. Vikunja #629, umbrella #628.**
**Owner's call, 06-08-2026. V-629, umbrella V-628.**
**Verdict: the per-turn decision record now persists.** That reverses a written decision,
which is the point of this file. It is not an incidental telemetry
+41
View File
@@ -0,0 +1,41 @@
# docs/plans/
The plan for one piece of work, written before it starts and frozen once it
does. A plan is what was intended. What happened is the commits, the
subsystem's living doc under `docs/`, and the measurement under `docs/evals/`.
Changes of mind go to the Vikunja task, never back into the plan. The value of
a frozen plan is that it can be compared to the outcome afterwards.
## Rules for this directory
* **A plan carries its task id in the `V-<id>` form.** `V-` and not `#`,
because Gitea autolinks `#123` to the wrong tracker. Put it in the first three
lines, so it is visible without reading the plan.
* A plan whose work has landed stays. It is not edited to say "shipped" beyond
a dated status line, and it is never rewritten to match what was built.
* A plan nobody will act on goes to `docs/archive/`, not to the bin.
## Two naming schemes, on purpose
`NN-<name>.md` is a Maven feature plan. The number is an append-order id and
carries no priority. A new plan takes the next free number. Six Go source
comments cite these paths, so renaming one is a code change.
`YYYY-MM-DD-<name>.md` is a training runbook for the model rig on workpc, not
for this repo's daemons. Five exist, all from July 2026, all predating the
numbering. They are dated because a runbook is read as of a day. Renumbering
would put the oldest plans last and imply an order that is not real. Do not do
it.
## Plans with no task id
These have never carried one. Do not invent ids for them. Resolve each against
Vikunja project Maven (ID 2) before citing it, or file a task if none exists.
`01-email-reader.md`, `02-pattern-proposal.md`, `04-self-update.md`,
`05-model-swap.md`, `06-mcp-support.md`, `09-behavioral-memory.md`,
`11-smarthome-integration.md`, `12-bluetooth-network-scan.md`.
The five training runbooks have no id either. The nearest live task is V-122,
which owns finishing the Qwen3-1.7B CPT run on workpc.