Make thread/channel/message deletion complete (hard delete)

Deleting a thread, channel, or message was a no-op/soft-delete: messages
were only dropped from the plugin outbox (still in hermes' session store,
hence searchable/recoverable) and channels/threads were merely archived.

Now deletion is complete and non-recoverable, with no search trace:

- purge.py (new): hard-delete from hermes' session store (state.db).
  delete_lane wipes a channel's/thread's sessions + messages; deleting a
  messages row also drops it from the FTS5 index via the delete triggers.
  delete_message removes one message, matched by (session, role, exact
  content, closest timestamp) since plugin m_<hex> ids aren't persisted.
- channels.py: delete() hard-deletes the row (and a channel's child
  threads) instead of archiving.
- outbox.py: add delete_lane() (wipe all frames for a lane) and
  message_info() (read a message's final role/text/ts for the match).
- adapter.py: on_channel_delete wipes outbox + session store;
  on_message_delete purges the session-store row per message.
- App: delete confirmations no longer claim history stays for search;
  ChannelStore removes a channel's threads on channel delete.
- Docs updated to describe hard deletion.
This commit is contained in:
ARIA committed 2026-08-21 19:47:55 +02:00
1 parent 9286937e2d
commit 17bf41a0b9
11 files changed
+373 -51

No files matched your search

+11 -4
View File
@@ -376,6 +376,11 @@ Answer an interactive picker.
{"type":"channel.set_default","id":16,"chat_id":"android:chan_7","payload":{}}
```
`channel.delete` is a **hard delete**: the channel/thread row is removed from
the directory and the lane's history is wiped from the outbox and the hermes
session store (no search trace, not recoverable). Deleting a channel also
removes its threads. The default channel cannot be deleted.
### `search`
```json
@@ -409,10 +414,12 @@ Load a page of messages for a chat/thread (initial open, scroll-up pagination).
### `message.delete`
Delete the given message(s) from a chat/thread. The server removes them from the
outbox (so `history`/`sync` no longer return them) and broadcasts
`message.deleted` to every device. Idempotent: a message already gone (pruned by
retention) still yields a `message.deleted` broadcast so live caches drop it.
Completely delete the given message(s) from a chat/thread. The server removes
them from the outbox (so `history`/`sync` no longer return them) **and** from
the hermes session store (so no search trace survives and they are not
recoverable), then broadcasts `message.deleted` to every device. Idempotent: a
message already gone (pruned by retention) still yields a `message.deleted`
broadcast so live caches drop it.
```json
{"type":"message.delete","id":30,"chat_id":"android:default","thread_id":null,