Files
claude 5cae33a517 Split honesty into three milestones, defer five capabilities (V-719)
Owner's call. M1 is the turn path, M2 is memory he cannot correct, M3 is
step-up. They were one milestone and are three jobs: M1 and M2 touch
different code and owe different docs, and step-up is configuration, not
honesty. Nine milestones now.

Speaker recognition, smart home, bluetooth, model swap and self-update
move past v1. Bluetooth was on the v1 list and comes off it: no bluez on
the box. Their spec entries keep their DoD.

--no-verify: committing on master by the owner's call this session.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 18:40:45 +04:00

11 KiB

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.

Honesty, in three milestones

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.

That is one theme and three separate jobs. M1 is the turn path. M2 is the memory he cannot correct. M3 is a configuration job that is not honesty at all. They are split because each is one session, and because M1 and M2 touch different code with different docs owed.

None of the three touches voice. A dishonest turn spoken aloud is still dishonest.

M1: The turn does not lie

Every item is on the path from utterance to reply, and each is a false statement rather than a missing one.

Lands: Route an utterance. Speak as herself. Answer from the world.

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.
  • A world answer that would invent content is refused instead of phrased. The audit's "почему небо голубое?" answer is the failing case.

Docs this milestone owes: none new. docs/routing.md, docs/language.md and docs/world.md all exist and are corrected in place.

M2: Memory he can correct

The store is the other place she claims something untrue, and the only place he cannot fix it himself. It is separate from M1 because it is store and surface work, and because it owes the largest doc in the spec.

Lands: Facts. Notes.

Gate:

  • No confirmation claims a write that did not happen. The audit's "я записала информацию о тебе" wrote nothing.
  • A note can be deleted by voice and from the web UI (V-494).
  • A question is not stored as a statement.
  • A superseding fact retires the old value and both are readable.

Docs this milestone owes: the memory doc covering facts, notes, the supersede rule and the digestion worker's consolidation pass. It is the largest gap in the spec, and it is why this is its own milestone.

M3: Step-up is not fail-open

One bounded configuration-and-code job. It is not honesty and it does not belong inside M1. It is the audit's only high-severity item and it gates the act path, so it lands before anything reaches Hexis.

Lands: Passkey and step-up.

Gate:

  • WebAuthn is configured and no step-up gate is fail-open, including POST /api/chat (V-683).
  • Enrollment requires an existing credential once the first one exists. Anyone past the proxy can enroll today.
  • Step-up is per-request, not process-global.

M4: 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.

M5: 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.

M6: 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.

M7: 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).

M8: 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 M7.

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.

M9: 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 M6 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 M6 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.

Deferred past v1

Owner's call, 2026-08-15. Four are audit rows the v1 list did not name. Bluetooth control was on that list and comes off it. No bluez exists on the box and the radio has no owner. Their spec entries stay, so the DoD is already written when one comes back.

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.