diff --git a/CLAUDE.md b/CLAUDE.md index 1cf2a82..d19415a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -15,6 +15,8 @@ under `docs/`. Read that doc before changing the subsystem. | `docs/world.md` | touching search, Kiwix or the world chain | | `docs/language.md` | changing a prompt contract or a Russian word list | | `docs/ecosystem.md` | touching Nexus, Praxis or Hexis | +| `docs/spec.md` | asking what a capability is for, or whether it is done | +| `docs/roadmap.md` | picking what to work on next | | `docs/rearchitecture.md`, `docs/design.md` | changing the shape of anything | | `docs/workflow.md` | the five stores, the doc tiers, the guards | | `docs/caveats/` | a known limit, its task id and its revisit trigger | diff --git a/docs/roadmap.md b/docs/roadmap.md new file mode 100644 index 0000000..64095ff --- /dev/null +++ b/docs/roadmap.md @@ -0,0 +1,215 @@ +# Roadmap: the order the spec gets built in + +*Last verified: 2026-08-15 @ 231248a* + +`docs/spec.md` says what every capability is for and what done means. +This file says which order they land in, and why that order and not another. +`CLAUDE.md` carries the rules. + +## The ordering rule + +The audit ruled out a roadmap ordered by code work +(`docs/evals/2026-08-13-capability-audit.md`). None of the four broken +capabilities is a code defect. Weather has no configuration block. Nexus has no +data. The voice reach has no listener. Step-up has no WebAuthn credential. + +So the order is by what would make her untrustworthy if it shipped later. A +capability she does badly costs more than one she does not have. From the outside +he cannot tell the difference. Honesty comes before reach, and reach comes before +breadth. + +Two rules bind every milestone. + +**A milestone closes its own documentation gaps.** The spec found seventeen +capabilities with no living doc. Those are not a milestone of their own. A +capability does not ship out of a milestone until the doc its spec entry points +at exists. + +**A milestone writes its own scenarios.** Only five scenario files exist and 46 +spec entries name one to write. The scenarios a milestone's DoD items cite are +part of that milestone. + +## M1: Honesty in the turn + +She currently claims things that are not true. That is worse than a gap, because +a gap is visible and a false claim is not. Nothing else is worth building on top +of a turn that lies. + +V-683 rides alongside this milestone as one bounded configuration-and-code job. +It is not honesty and it is not a milestone of its own. Every step-up gate is +fail-open today, including `POST /api/chat`, which reaches the act path. Anyone +past the proxy can enroll a passkey. + +Lands: Route an utterance. Speak as herself. Facts. Notes. Answer from the world. +Passkey and step-up. + +Gate: + +- A question about what Maven remembers routes to query. Both audit probes pass. +- No masculine self-reference reaches the wire, checked on the outbound path and + not only in the eval. +- No confirmation claims a write that did not happen. +- A note can be deleted by voice and from the web UI (V-494). +- A world answer that would invent content is refused instead of phrased. +- WebAuthn is configured and no step-up gate is fail-open (V-683). + +Docs this milestone owes: the memory doc covering facts, notes and the supersede +rule. It is the largest gap in the spec. + +Not here: anything about voice. A dishonest turn spoken aloud is still dishonest. + +## M2: The four broken, none of them code + +Cheap, and it unblocks two later milestones. Nexus with entities is what makes +the act path real. Weather is the capability he asked about first on the audit +day. + +Lands: Weather. Nexus. Hexis. The deployed stack. + +Gate: + +- A `weather` block names a provider and a home city. The follow-up city parks + as a clarify instead of dying with "Я тебя не разобрала". +- Nexus has entities, so free text resolves to a canonical entity id. +- One act runs through Hexis against a real target, with confirmation binding + capability id, target, arguments, requester and expiry. +- All five compose services run the current build. Three were four days stale + during the audit. + +Not here: smart home and bluetooth. Both are blocked on the host, not on Nexus. + +## M3: Voice is the spine + +v1 is a voice assistant. Until a proactive message can reach him by speech, she +is a web app he can talk at. He reaches her by speaking, which is a pull. She has +no push. + +Lands: Voice reach. Wake word to session. Hearing. Text to speech. Speech to text. + +Gate: + +- A proactive message reaches him by speech without him speaking first. Every + proactive message during the audit fell through with "no live voice session". +- Waking her opens a session the proactive path can push into (V-515). +- A capture client runs on workpc and streams end to end from microphone to + reply (V-514). +- `internal/ttsnorm` expands times and dates into `Europe/Samara` phrasing. +- The `mavsttd` floor arm is exercised on its own, not only behind the workstation. + +The voice port stays on homesrv loopback and reaches workpc over ssh. This +milestone does not LAN-bind it. + +Docs this milestone owes: what holds a live voice session open. `docs/protocol.md` +documents the wire and nothing documents the listener. + +## M4: Proactive that arrives + +Everything in this milestone exists and fails at the last step. The morning +routine builds a plan and drops it. Reminders fire and one reach failure loops. +Recurring is storage and delivery with no caller. + +Lands: Reminders, including recurring. Morning routine. Interruption policy. +Digest of held nudges. Tasks. RSS and news. + +Gate: + +- A recurring reminder is set by voice and states its schedule back: meetings, + pills, the dog, the vet, the kibble. `store.Reminder` carries `Cron` and no + caller in `cmd/mavend` passes one. +- The morning plan reaches him inside its 08:00-11:00 window `Europe/Samara`, and + falls back to the non-voice reaches when no voice session exists (V-280). +- The four presence-and-severity outcomes are written down before any of them + changes (V-281). +- A failed delivery retries into another reach rather than once a minute until 03:05. +- One suppressed nudge is watched surfacing in a later digest, on the box (V-687). + +Docs this milestone owes: the reminder lifecycle. Parking, firing, delivery, +retry and cancellation span three packages with no written contract. + +## M5: Breadth she can already almost do + +These have code and no path from an utterance. Each is one wiring job, not a +design job. They come after the spine because none of them changes whether she is +trustworthy or reachable. + +Lands: Read an encyclopedia. Recall. See an image. Network scans. MCPs. Routine +proposals. Memory evaluation. + +Gate: + +- A Russian question lands on the Russian book, an English one on the English book. +- `TestONNXPersonalBoundary` is green and a recall miss says she does not remember. +- An image sent through Telegram gets a Russian description, and the vision call + falls back silently when the workstation is down (V-667). +- A scan of the configured subnets is read back as prose. +- A configured MCP server's tools are callable through the act path, and only + through the allowlist. +- The routine proposer's hand-written Russian verb list is replaced by + `internal/lexicon` or the embedder (V-606). +- One memory evaluation run is observed and its notes read back (V-248). + +## M6: The product decision, then the deploy + +Email and calendar are built and neither is in `docker-compose.yml`. +`internal/email` with `mavmaild`, `internal/calendar` with `mavcaldav`. Deploying +either before deciding what she does with his mail writes the decision by +accident. That is why they sit behind a milestone boundary rather than inside M5. + +Lands: Email triage. Calendar management. + +Gate: + +- The owner has decided what triage means: read-only summary, task extraction, or + reply drafting. +- Mail-derived candidates stay candidates until he accepts one (V-130). +- An event is created by voice with the slot asked for rather than guessed, times + in `Europe/Samara`. +- Both daemons are in compose, or their absence is deliberate and recorded. + +## M7: Design pass, then the undesigned seven + +Seven v1 capabilities have no design. They keep a DoD in the spec so the gap +stays visible, and each needs a design pass before any code. Every one of them +assumes a turn that is honest, reachable and proactive. Each gets cheaper once M1 +through M4 have landed, which is why they come last. + +Lands: Web crawling. Summaries. Webhooks. Cron jobs. Desk notifications, outbound +half. Learning the style. Learning from mistakes. Command chaining. + +Two decisions this milestone opens with: + +- **Cron jobs against routines against recurring reminders.** Three schedulers + must not exist. `internal/routine` already carries a `Cron`, and M4 gives + reminders one. What "cron jobs" adds beyond those two is undecided. +- **Which direction webhooks means.** The only webhook in the tree is Telegram's + own inbound intake. Inbound as an event source and outbound as a fourth reach + are different capabilities. + +Learning means behavioral, not weights. Stored outcomes: dismissed nudges, +corrected phrasings, repaired routes. No adapter, no training set. Everything +learned is readable on a page and deletable. + +## Proposed for after v1 + +These are audit rows the owner's v1 list did not name. The list below is a +proposal, not a decision. + +| capability | why deferred | +| --- | --- | +| Speaker recognition | Nothing depends on it until someone other than him speaks to her (V-255). | +| Smart home | Blocked on the host, not on code (V-256). | +| Bluetooth control | No bluez on the box (V-257). | +| Model swap | The resident model being whatever the config says is an acceptable answer (V-250). | +| Self-update | `mavupdate` cannot reach the containerized socket, and a manual deploy works (V-477). | + +## What is not filed + +Vikunja returned 503 across two sessions, so the following have no task id. +Filing them is the first thing to do when it comes back. + +- The capability audit itself. It is headed "unfiled". +- The remember-versus-query misroute. Two of seven audit probes. +- The masculine reply on the wire, caught live while the eval passed. +- Recurring reminders having no caller. +- The seventeen capabilities with no living doc. +- The 46 scenario files the spec names and does not have.