Direction
Conversation First
Notifications leave Mallory's remit entirely; the interrupt budget they release is reinvested in conversation and linked memory.
Situation
Mallory is strongest as a conversation and weakest as a notifier, and the estate's own instruments have said so for a month: 0 of 142 ball-in-court items were ever nudged, the board logged 7 acted events against 41 views, proactive_nudge has been deliberately muted since 15 August, and web push has no subscription at all.
The demand board line was retired on 23 August on exactly that evidence. What the decision did not do was retire the board it was meant to replace — slaEnrich still sweeps every fifteen minutes, runBoardCompose still runs three times a day, and /waiting still ships as its measured rival. The measurement concluded and changed nothing.
Meanwhile the thing that is actually broken is not a surface. Two consecutive weeks of miss-log data land on the briefing's promotion and Schedule steps — W34's misses were items Mallory already held and failed to escalate; W35 dropped a confirmed calendar event for the second week running. Capture works; triage does not.
Key decisions
Notifications leave
Remove, don't redesign. Inbox interrupts go back to Slack and Gmail's own tuning — Mallory is a lagging replica of a system Alex sits inside all day, and structurally cannot beat it.
Split the budget by who it's for
Reminders stay (the only interrupt Alex authored himself) and estate alerts stay (rare, operational, and nothing else can see them). Everything else goes. Rolling them together is what made the choice all-or-nothing for months.
Three zones survive, as a glance
Coming up (genuinely fed — calendar-sync.sh:288 calls post_calendar), Remember, and the editor's note at ~2p/month. They fold into the briefing rather than justifying a standing surface.
The briefing becomes a turn
It arrives in the feed as something Alex can argue with, routed by the conversational-feedback spec's gate. The only proposal here that gives the promotion bug a correction path running daily rather than fortnightly.
Memory gains a graph
A typed memory_links edge table plus superseded_by and first-class entities — so "Bruno" is a node, not a substring, and memory acquires a present tense.
Retrieval is the point
The About block stops being *the ten most recent pinned facts* and becomes *the pinned core plus facts linked to this turn's entities*. A link graph nothing retrieves against is a schema, not a memory.
Pebble stands down
Recommendation reversed by this brief: with notifications gone the timeline fan-out has a handful of items a week to carry. Leave the code inert and gated; mark mallory-pebble archived, not pending.
Architecture
Mostly subtraction. The additions are one migration and one changed assembly step in runTurn — no new surface, no new cron, no new secret.
triage defaults to 'off' and was never switched on in prod KV, so no live behaviour is lost — only a sweep and a classify tier that would have cost ~£70/mo had it run.SituationBoard's court fold, boardActions, handleSlaAction, WaitingView, WaitingCard. Two surfaces over one dataset; the measurement between them is over.slack-mentions.sh, mk-inbox.sh, slack-email-monitor.sh stop feeding channel_pending.TODO(after-the-holiday).about · supersedes · contradicts · evidence · co_occurred) joining a memory to a message, vault note, loop item, calendar event or another memory.classification.type === 'recall' gate is now the thing hiding past conversation from turns that need it.Risks & guardrails
The cut removes the only net
~12 of 142 items aged without a reply and nothing else would have caught them. Recorded as a real loss, with the counter already accepted on 23 August: a net that has never fired across 142 items is not a net.
The estate's stall shape
Voices stalled 72 days and the Pebble stub 44 days, both on an action Alex takes off-keyboard with no deadline. Rule adopted: an increment ends in a merged PR, or it names its manual step as a dated, owned task.
Linking multiplies an undrained queue
memoryExtract proposals need a tap in the Memory view. More links means more proposals; extraction must earn the feedback spec's spoken confirm, or the graph inherits a queue nobody drains.
Stop condition on the cut
If the miss log shows more misses in the four weeks after than the four before, the cut was wrong and the interrupt path returns. A night with no daily note counts as a GAP, not a zero.
Stop condition on the graph
If retrieval ships and recall answers do not visibly change, the links were decoration — stop before anything is built on them.
Delivery
1 · The cut
Remove the SLA machinery, the court zone, /waiting, the post_pending producers and Hunstanton. Nothing new ships.
2 · Recall gate retired
One conditional in chat.ts, plus eval cases before and after.
3 · Memory foundations
memory_links, entities, superseded_by. Additive migration — nothing reads it yet.
4 · Retrieval uses the links
buildAboutBlock becomes relevance-ordered within the same budget. The increment that pays, and the one the stop condition judges.
5 · Rolling summary
New table, one injection point in runTurn's context parts.
6 · Briefing-as-a-turn
Depends on the conversational-feedback spec being approved; carries its own retire-itself stop condition at fewer than one correction a fortnight.
7 · Voices
Two ElevenLabs IDs pasted back and set as secrets. A manual step, so: dated and owned, per the rule above.
Out of scope
docs/superpowers/specs/2026-08-31-conversation-first-design.md