Files
Maven/20-07-2026-BACKLOG.md
kami 56c87b9e79 Record the 2026-07-20 session and the 2026-07-30 senior review
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
2026-07-30 23:49:44 +04:00

11 KiB
Raw Permalink Blame History

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:0011: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, via scripts/desk-active.sh posting to /api/signal), page_heartbeat (mavweb tab, app.js), and wg_handshake (mavpoll polling wg show) — threaded into the tick loop via internal/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

status as of 2026-07-20:

  1. evaluation labskipped, GPU-box work, deprioritized while CPT is in progress
  2. entity-aware memorydone (03fa52d/9876187, plus adjacent Nexus/Praxis plumbing hardening — see item 5 above)
  3. morning routine enginecore engine done (internal/morning + cmd/mavend wiring — see item 2 above; not yet configured on homesrv, no voice query, no web UI)
  4. interruption/delivery policy
  5. presence agents
  6. unified event intake
  7. full-system simulator
  8. notification bridges
  9. knowledge ingestion
  10. 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.