Add conversation history persistence backend #2

Closed
opened 2026-08-01 19:58:44 -04:00 by lyssieth · 0 comments
Owner

Implement the conversation-history persistence backend declared in crates/sermones-runtime/src/lib.rs and docs/glossary.md:

Persist on disk and config load are planned but not yet implemented.

Neither module currently exists. The error kinds ErrorKind::HistoryCorrupt and ErrorKind::HistoryUnwritable already exist in crates/sermones-core/src/error.rs waiting to be produced.

Checklist

  • Add crates/sermones-runtime/src/persistence/ (or equivalent): load + save Conversation (from sermones-core) to the OS-conventional user-state location
  • Storage format: anything Facet-derived can round-trip through facet-format + facet-json — pick a shape (one file per conversation vs. single history file) and document it in docs/components/runtime.md
  • ConfigInvalid / HistoryCorrupt / HistoryUnwritable site constructions so errors carry the failing path in context (From<io::Error> for SermonError already exists)
  • Wire the load/save surface into the IPC bridge (engine exposes load_history / save_message slots; the UI calls them)
  • Tests against a tempdir; no live filesystem state

Refs:

  • docs/architecture/errors.md — canonical error shape + propagation
  • docs/components/error.md — how SermonError is constructed and carries source + context
  • docs/components/runtime.md — current state of the runtime crate's surface
  • crates/sermones-runtime/src/lib.rs — module docstring declares this as the runtime's job
  • docs/glossary.md — explicitly calls out "Persist on disk and config load are planned"

Resolution

Landed in 2112dbc (main): HistoryStore in crates/sermones-runtime/src/persistence/, one JSON file per Conversation at conversations/<id>.json (atomic tmp+rename, .corrupt quarantine, id-ordered load). HistoryCorrupt / HistoryUnwritable carry the failing path in context["path"]; ConfigInvalid stays unproduced until the config loader lands (no config file exists yet). Bridge: load_history / save_conversation slots + history_loaded / error_raised signals; typed helpers in frontend/src/lib/bridge.ts. 12 new tempdir tests; 452/452 workspace tests passing, lint clean.

Deviations: the slot is save_conversation, not save_message — there is no engine-side live Conversation to append messages to. Rendering saved history in App.svelte is out of scope here; it comes with the UI push.

Implement the conversation-history persistence backend declared in `crates/sermones-runtime/src/lib.rs` and `docs/glossary.md`: > Persist on disk and config load are planned but not yet implemented. Neither module currently exists. The error kinds `ErrorKind::HistoryCorrupt` and `ErrorKind::HistoryUnwritable` already exist in `crates/sermones-core/src/error.rs` waiting to be produced. ## Checklist - [x] Add `crates/sermones-runtime/src/persistence/` (or equivalent): load + save `Conversation` (from `sermones-core`) to the OS-conventional user-state location - [x] Storage format: anything `Facet`-derived can round-trip through `facet-format` + `facet-json` — pick a shape (one file per conversation vs. single history file) and document it in `docs/components/runtime.md` - [x] `ConfigInvalid` / `HistoryCorrupt` / `HistoryUnwritable` site constructions so errors carry the failing path in `context` (`From<io::Error> for SermonError` already exists) - [x] Wire the load/save surface into the IPC bridge (engine exposes `load_history` / `save_message` slots; the UI calls them) - [x] Tests against a tempdir; no live filesystem state Refs: - `docs/architecture/errors.md` — canonical error shape + propagation - `docs/components/error.md` — how `SermonError` is constructed and carries `source` + `context` - `docs/components/runtime.md` — current state of the runtime crate's surface - `crates/sermones-runtime/src/lib.rs` — module docstring declares this as the runtime's job - `docs/glossary.md` — explicitly calls out "Persist on disk and config load are planned" ## Resolution Landed in `2112dbc` (main): `HistoryStore` in `crates/sermones-runtime/src/persistence/`, one JSON file per `Conversation` at `conversations/<id>.json` (atomic tmp+rename, `.corrupt` quarantine, id-ordered load). `HistoryCorrupt` / `HistoryUnwritable` carry the failing path in `context["path"]`; `ConfigInvalid` stays unproduced until the config loader lands (no config file exists yet). Bridge: `load_history` / `save_conversation` slots + `history_loaded` / `error_raised` signals; typed helpers in `frontend/src/lib/bridge.ts`. 12 new tempdir tests; 452/452 workspace tests passing, lint clean. Deviations: the slot is `save_conversation`, not `save_message` — there is no engine-side live `Conversation` to append messages to. Rendering saved history in `App.svelte` is out of scope here; it comes with the UI push.
lyssieth added this to the v1 milestone 2026-08-01 19:59:00 -04:00
lyssieth removed their assignment 2026-08-01 19:59:14 -04:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
Reference
lyssieth/sermones#2
No description provided.