PROGRESS.md gains the ecosystem-hardening session log: entity-aware fact resolution, the typed Praxis lifecycle client, the durable delivery outbox, fail-closed IPC handling, correlation IDs, and the fake-ecosystem test harness. 20-07-2026-BACKLOG.md marks item 2 (morning routine engine) as core-engine done, with the wiring and the read-only /morning page described. REVIEW-30-07-2026.md is the review the preceding commits act on. Note two of its findings were wrong on the details and are corrected in the commits rather than in the document: the covdata failure was upstream Go tool-shipping behaviour, not a truncated cache, and the resident-model contradiction ran the opposite way — deploy/mavend.json pointed at a file that existed while the docs carried the stale claim, because /mnt/hdd1/llms is bind-mounted over the repo's models/llm/. One caveat, since the review itself argues against dated markdown accumulating at the root: this file should go the same way as the SESSION-*.md logs once its findings are closed. Two remain open — the kuma key rotation and the LLM router evaluation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X5JApcrCRVGmqrxnhynSik
11 KiB
beyond the model and tts work, the useful additions are mostly around reliability, context, and reach, not more intelligence.
highest-value additions
1. unified event intake
maven should receive normalized events from:
- praxis
- calendar
- telegram
- local notifications
- system/service health
- manual checklists
- eventually email bridges
one internal envelope:
type Event struct {
Source string
Kind string
EntityIDs []string
Title string
Body string
Priority string
OccurredAt time.Time
Payload json.RawMessage
}
this gives digestion one stable input instead of source-specific logic.
2. explicit morning routine engine — core engine done (2026-07-20)
internal/morning — pure checklist engine, mirrors internal/loop/
internal/routine's no-I/O contract. Evaluate(routine, facts, now) answers
"what's still missing" any time (order-independent — checks facts, not
sequence); Due(routines, facts, last, now) fires the once-per-day nag only
at NudgeAt (defaults to window end) and only when something's unevidenced,
with a last-map dedupe identical in shape to routine.Due's cold-start/
last-fire tracking. Evidence is just a fact timestamped inside today's
window — manual (voice-tapped) and inferred (another daemon writing the same
key) are indistinguishable, satisfying the manual/inferred requirement for
free. Weekday/weekend variants are two Routines with different Weekdays
sets under different names. Wired into config.MorningRoutineConfig +
cmd/mavend/tick.go's fireMorningRoutines (reads only the fact keys the
configured items reference, dispatches through the normal severity/presence
routing table, body is literal joined item labels — not LLM-phrased, same
no-hallucination rationale as cron routines). 13 unit tests in
internal/morning/morning_test.go.
Added since (2026-07-20, same day): a read-only /morning page in mavweb —
ipc.CoreAPI.MorningStatus (new wire method, mirrors TickTrace's
daemon-cache-only shape: the store adapter errors, daemonAPI serves it from
a tickLoop.morningStatus closure) returns each routine's active/window/
per-item done state, server-rendered same as /trace (no live-update loop —
checklist state moves on minutes, not seconds).
Not yet done: no config wired in deploy/mavend.json (no morning routines
configured on homesrv yet — add items there when the medicine/water/pets
fact keys the phone/desktop write are settled), no voice query path for
"what did I miss this morning" (Evaluate supports it; nothing calls it yet),
no way to create/edit routines from the web UI — construction still means
hand-editing config, deliberately deferred: routines are operator-declared
config (like cron routines), and a CRUD editor would mean moving them to a
DB table + hot-reload, a bigger change than this pass.
not ordinary reminders.
support:
- required morning items
- order-independent completion
- soft time windows
- skipped-step detection
- one nudge, not repeated spam
- manual and inferred completion evidence
- weekend/weekday variants
example:
08:00–11:00
- medicine
- water
- pets
- check praxis attention
maven should know what is still missing, not merely fire four timers.
3. cross-device presence
status (2026-07-20): the hysteresis engine and 3 of the listed signals are
already built and wired live: internal/store/presence.go (noisy-OR combiner
- Schmitt-trigger bucket resolve), fed by
desk_active(workstation, viascripts/desk-active.shposting to/api/signal),page_heartbeat(mavweb tab,app.js), andwg_handshake(mavpollpollingwg show) — threaded into the tick loop viainternal/loop/gather.go. Not done: phone-reachable, homesrv-available, audio-output, and active-maven-client signals from the list below are still missing.
a small presence daemon on each trusted device:
- workstation active/idle
- phone reachable
- homesrv available
- last keyboard/mouse activity
- wireguard presence
- current audio output
- active maven client
mavend receives only compact state, not raw activity logs.
useful for:
- choosing delivery channel
- suppressing voice while away
- surfacing reminders when you return
- knowing whether an agent result should be spoken or sent as text
4. interruption policy — done (2026-07-20), turned out to already be built
audited the existing code before writing anything new: internal/loop.Gate
already answers deliver_now vs. drop (quiet-hours/cooldown/snooze/presence/
calendar-busy), and cmd/mavend/tick.go's digestQ + config.DigestConfig
already implement queue/digest (low-severity nudges batch into one
notification, flushed on window elapsed or max-items reached). The four
outcomes below were already covered by these two mechanisms; nothing new to
build for the core policy.
Gap that was real: deploy/mavend.json had no digest block, so batching
was disabled in prod despite being fully implemented. Fixed — see the config
change alongside this note.
before delivering anything, evaluate:
urgency
current activity
quiet hours
recent nudges
available channels
whether already surfaced
result:
deliver_now
queue
digest
drop
this prevents maven from becoming annoying once praxis and other sources start producing more data.
5. entity-aware memory — done (2026-07-20)
03fa52d/9876187 (Vikunja #279): facts gain Subject/EntityID/
ResolutionState; an async enrichment worker resolves free-text subjects to
canonical Nexus entity_ids (mirrors Praxis's enrichment pattern). Ambiguous
or unreachable Nexus never guesses — the fact stays pending or terminal
ambiguous. Voice-tapped facts (IntentFact) now flow into the enrichment
queue automatically via an optional Subject field on WriteFactReq (old
callers unaffected).
Landed alongside this in the same session (not originally on this list, but
closes the plumbing gaps the last brief flagged for Nexus/Praxis maturity):
a typed Praxis lifecycle client (398997f — surface/acknowledge/resolve/
ignore/pin; fixes the surfaced≠acknowledged gap where reading an item aloud
left no trace), correlation-ID/version headers on the Nexus/Praxis clients
(b743860), entity-scoped Praxis attention queries (0579ef9), a durable
delivery outbox with begin-before-send/complete-after semantics
(29f23e3+9ff726e — closes a duplicate-send-on-crash bug), fail-closed
handling on ambiguous IPC mutation outcomes and Nexus/Hexis dependency
errors (838fde1+d9fa4d6), and a reusable fake-ecosystem test harness
with fault injection (c932cd8).
connect maven memory to nexus ids.
instead of:
key = "кошачий фонтан"
store:
entity_id = ent_pet_water_fountain
predicate = refilled_at
value = 2026-07-19T...
benefits:
- stable russian/english aliases
- fewer duplicate facts
- better “when did i last…” queries
- easier routine detection
- cleaner praxis correlation
6. bounded follow-up state
for short continuations:
- “yes”
- “tomorrow”
- “the second one”
- “not that project”
- “do it later”
store explicit pending state instead of relying on chat history:
type PendingInteraction struct {
Kind string
Candidates []string
Args json.RawMessage
ExpiresAt time.Time
}
this matters a lot for a 1.7b model.
7. evaluation lab — skipped for now (2026-07-20)
runs on a different machine (GPU box), and CPT is currently in progress there — deprioritized until the training pipeline has a checkpoint to gate. Not abandoned, just off the immediate list.
before every new checkpoint or lora deploy:
- routing accuracy
- slot accuracy
- malformed json rate
- russian/english mixed input
- ambiguous entity handling
- reminder vs note vs fact
- direct answer vs tool call
- confirmation safety
- phrasing quality
- latency and ram
also replay real anonymized traces against old and new checkpoints.
this should be a hard deployment gate.
8. replayable full-system simulator
fake:
- clock
- presence
- caldav
- telegram
- praxis
- nexus
- hexis
- stt
- tts
- llama-server
scenario:
08:30 user appears
08:35 medicine not completed
08:40 correx agent waits
08:45 calendar sync stale
08:50 user says “what did i miss?”
assert:
- what tools were called
- what was surfaced
- what stayed unresolved
- what maven said
- what was not executed
this will save more time than another feature daemon.
useful second-wave additions
voice session quality
- barge-in
- interrupt tts on wake word
- partial stt display
- confidence-aware clarification
- retry only failed stt segment
- per-room microphone profiles
- noise-floor calibration
- short response mode when speaking
notification bridge framework
small adapters for:
- ntfy
- telegram
- matrix
- web push
- android notification forwarding
- local dbus notifications
normalize into maven/praxis events instead of treating each as a separate feature.
local knowledge ingestion
- markdown/docs ingestion
- git repo summaries
- project decision records
- conversation exports
- provenance and source links
- incremental reindexing
keep this read-only and separate from personal fact memory.
service self-diagnostics
maven doctor:
- socket reachability
- model health
- stt/tts readiness
- embedder availability
- caldav freshness
- telegram poll state
- praxis/nexus/hexis reachability
- db integrity
- disk usage
- recent failures
config and secret management
- schema-validated config
- config migration
- secret references instead of inline values
- dry-run validation
- redacted config dump
- per-daemon health config
- startup dependency report
things i would not build yet
- autonomous multi-step planning
- large external reasoner
- generic workflow engine
- self-editing memory
- automatic hexis actions from praxis
- emotion simulation beyond phrasing
- full home-assistant replacement
- more model layers before routing is stable
recommended order
status as of 2026-07-20:
evaluation lab— skipped, GPU-box work, deprioritized while CPT is in progressentity-aware memory— done (03fa52d/9876187, plus adjacent Nexus/Praxis plumbing hardening — see item 5 above)morning routine engine— core engine done (internal/morning+cmd/mavendwiring — see item 2 above; not yet configured on homesrv, no voice query, no web UI)- interruption/delivery policy
- presence agents
- unified event intake
- full-system simulator
- notification bridges
- knowledge ingestion
- voice-session polish
the main goal should be: maven reliably knows what is happening, knows what you meant, and chooses the least annoying correct response. everything else can wait.