What happened
Twice on 2026-09-15 the Mini's iak-mcp-daemon was restarted (config changes, launchctl kickstart -k). Each restart cleared the in-memory intent map. The confirmation cards for those intents stayed in the room with live Approve/Deny buttons, and Petrus tapped them: c675a9e8, e14e119b (afternoon) and 0c9c8152 (evening). The daemon logged unknown intent here, staying silent and the taps did nothing. In every case the command had already auto-allowed at the gate's timeout, so nothing was lost, but each wasted tap costs the owner trust in the buttons.
Why
src/confirmations.mjs keeps intents in a Map; nothing is persisted, and a restart neither settles the open cards nor reloads them.
Proposal (either is enough; both is best)
- Persist pending intents to a small state file (path under
poller.state_dir, like the seen-ids) and reload on start, so a restart keeps the cards answerable.
- Settle on shutdown/startup: on SIGTERM, and on startup for any card whose intent is not found, post a threaded reply "gate restarted, card inactive" and push
expired to the action-status API, the same path the timeout auto-allow already uses (expireIntent). Then a stale card shows as inactive instead of live.
Notes
🤖 Generated with Claude Code
What happened
Twice on 2026-09-15 the Mini's
iak-mcp-daemonwas restarted (config changes,launchctl kickstart -k). Each restart cleared the in-memory intent map. The confirmation cards for those intents stayed in the room with live Approve/Deny buttons, and Petrus tapped them: c675a9e8, e14e119b (afternoon) and 0c9c8152 (evening). The daemon loggedunknown intent here, staying silentand the taps did nothing. In every case the command had already auto-allowed at the gate's timeout, so nothing was lost, but each wasted tap costs the owner trust in the buttons.Why
src/confirmations.mjskeepsintentsin aMap; nothing is persisted, and a restart neither settles the open cards nor reloads them.Proposal (either is enough; both is best)
poller.state_dir, like the seen-ids) and reload on start, so a restart keeps the cards answerable.expiredto the action-status API, the same path the timeout auto-allow already uses (expireIntent). Then a stale card shows as inactive instead of live.Notes
@claudemmcurrently 422s (agent has no owner in GroupMind), so item 2's durable button state only works once that row is fixed; the threaded reply works regardless.🤖 Generated with Claude Code