Record the recall measurement and the two subsystem contracts (V-719)

docs/evals/2026-08-15-locative-answerability-verifier.md rules the
resident model out as a recall answerability verifier. Its constrained
output was syntactically reliable and neither semantically reliable nor
isolated from instructions inside stored memory: five false accepts out of
32 held-out cases, two of them prompt injections carried in the memory
text, all five identical across three fixed-seed repeats.

design.md carries the reminder row as it now is, one-shot or recurring,
with the outbox and the cancellation invariants. routing.md carries the
new stage 0 frames and the cancellation rung. deployment.md carries the
/reminders contract. The assistant_workday scenario exercises the turn
sequence end to end.

--no-verify: master is the working branch this session by the owner's call.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-15 17:19:38 +04:00
parent 1b5d35ad37
commit db50c34c23
5 changed files with 249 additions and 7 deletions
+38 -6
View File
@@ -53,9 +53,9 @@ Inside boundary — the ones that actually constrain the build:
- **Reactive** — converse (voice in → STT → router → LLM → TTS, and text);
act (function calls into the homelab).
- **Proactive** — health nudges (hydration, meals, breaks, shower, sleep,
cleanup); user reminders (stated future intent, fires once); deliver (voice
when near, ntfy/telegram when away); restrain (quiet hours, per-rule
cooldowns, snooze-memory, self-quieting).
cleanup); user reminders (stated future intent, one-shot or recurring);
deliver (voice when near, ntfy/telegram when away); restrain (quiet hours,
per-rule cooldowns, snooze-memory, self-quieting).
- **Capture** — throw facts/notes/tasks at it mid-flow.
- **State** — self (timestamped facts about you), presence (inferred, decaying
confidence, never one signal), activity, environment (homelab health,
@@ -141,12 +141,35 @@ facts (
-- index (key, ts desc)
```
**reminders** — user intent, fires once:
**reminders** — user intent, one-shot or recurring:
```sql
reminders ( id, created_ts, fire_ts, payload, status ) -- pending|fired|cancelled
reminders (
id, created_ts, fire_ts, next_fire_ts, payload,
status, -- pending | fired | cancelled
cron, -- empty for one-shot
delivery_group, phrase_body, phrase_summary, phrase_mood,
delivery_attempts, next_attempt_ts,
delivery_blocked_ts, delivery_blocked_error
)
```
Reminder payload is immutable, but its delivery lifecycle is deliberately not.
The only ordinary transitions are `pending -> fired` after a definite send and
`pending -> cancelled` through `CancelReminder`. A recurring success advances
`next_fire_ts` and clears the occurrence-scoped presentation instead of making
the row terminal. `MarkReminder` cannot cancel; that keeps every cancellation
behind the delivery-race checks rather than leaving a legacy write bypass.
`delivery_attempts` is the durable outbox. An occurrence or collapsed catch-up
bundle owns one non-empty `delivery_group`; its cached phrase and outbox row use
that same identity. Once an attempt is `pending`, `sent`, or `unknown`, Maven
refuses to claim that cancellation succeeded because the presentation may
already be outside the process. Cancelling first clears the group atomically,
so a sender cannot begin against the cancelled occurrence. Cancelling one row
in a collapsed group also invalidates the cached presentation on every pending
sibling before a later retry can repeat the old count.
**nudges** — every proactive send + outcome. This table IS the restraint
memory:
@@ -190,7 +213,16 @@ INTO the gate as an env predicate, not the LLM's job.
- Relative → absolute **at capture** ("in 4h" → store `now+4h`, never the
string).
- Reuses the loop, not a second scheduler — just a predicate:
`fire_ts <= now AND pending`.
`next_fire_ts <= now AND pending`, excluding retry waits, blocked delivery,
and occurrences with an ambiguous live outbox result.
- A one-shot success moves the row to `fired`. A recurring success advances the
same row to the next cron occurrence and gives that occurrence a fresh
delivery identity.
- Cancellation is an identity operation, not a relevance ranking. A direct
command must resolve one pending row by subject and/or time; multiple matches
are bound to the exact list Maven speaks and require an ordinal follow-up.
Questions, reports, prohibitions, stale ordinals, and unread times mutate
nothing.
- **Bypasses the restraint gate** — "wake me 7" fires in quiet hours; that's
the point. Snooze still applies. Two delivery paths.