Index plans and evaluations by lifecycle (V-674)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user