Implement SermonErrorStore + ErrorsPanel UI surface #4

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

Implement the SermonErrorStore + ErrorsPanel UI surface described in docs/architecture/errors.md and specified behaviourally in docs/invariants/error-visibility.md.

The Rust side already exists (crates/sermones-core/src/error.rs: SermonError, ErrorKind round-trips through facet-json; codegen emits the matching TypeScript type in frontend/src/generated/). The Svelte frontend dependency has landed (ce4774e); today's bootstrap surfaces errors ad hoc as inline message bubbles, not via the store — this issue covers the real subsystem layered on top.

Checklist

  • frontend/src/lib/errorStore.svelte.ts — single persistent Svelte store of SermonErrors. Errors are added but never auto-removed; dismissal is the user's gesture via an X on each entry
  • frontend/src/lib/ErrorsPanel.svelte — the UI surface: tier-coloured (critical/operational/informational), keyed on kind, dismissible per-entry, collapsible context details, copy-to-clipboard on Critical
  • Tier mapping per the table in docs/invariants/error-visibility.md (Critical: IpcDrift, PanicCaught, CodegenFailure, ProviderAuth; Operational: ProviderUnavailable, StreamBackpressureTimeout, HistoryCorrupt, …; Unknown treated as Operational)
  • IPC: error_raised signal from the bridge pushes a SermonError into the store; stream errors via stream_ended{reason=ProviderError} and slot-rejection paths both funnel into the store, never console.error
  • TypeBox-validate any inbound SermonError before adding to the store (per docs/architecture/errors.md's runtime validator section)
  • Persistence across reloads and (for Critical) restarts: written to XDG_STATE_HOME/sermones/errors.json on each add, rehydrated on startup, stale-schema errors dropped — implementation documented in the component doc

Landed in b13f503 (+ 7a95c31 for the oxlint no-console enforcement, which mechanically lints the console.error anti-pattern). CI green. Component doc: docs/components/error-store.md.

Refs:

  • docs/architecture/errors.md — full spec for the store, propagation across IPC, tier table
  • docs/components/error.md — Rust SermonError surface + builder methods
  • docs/invariants/error-visibility.md — the behavioural contract this issue implements
  • docs/invariants/ipc-schema-hash.md — the IpcDrift kind reaches the store via the validator
> Implement the `SermonErrorStore` + `ErrorsPanel` UI surface described in `docs/architecture/errors.md` and specified behaviourally in `docs/invariants/error-visibility.md`. > > The Rust side already exists (`crates/sermones-core/src/error.rs`: `SermonError`, `ErrorKind` round-trips through `facet-json`; codegen emits the matching TypeScript type in `frontend/src/generated/`). The Svelte frontend dependency has landed (`ce4774e`); today's bootstrap surfaces errors ad hoc as inline message bubbles, not via the store — this issue covers the real subsystem layered on top. ## Checklist - [x] `frontend/src/lib/errorStore.svelte.ts` — single persistent Svelte store of `SermonError`s. Errors are *added* but never auto-*removed*; dismissal is the user's gesture via an X on each entry - [x] `frontend/src/lib/ErrorsPanel.svelte` — the UI surface: tier-coloured (critical/operational/informational), keyed on `kind`, dismissible per-entry, collapsible `context` details, copy-to-clipboard on Critical - [x] Tier mapping per the table in `docs/invariants/error-visibility.md` (Critical: `IpcDrift`, `PanicCaught`, `CodegenFailure`, `ProviderAuth`; Operational: `ProviderUnavailable`, `StreamBackpressureTimeout`, `HistoryCorrupt`, …; `Unknown` treated as Operational) - [x] IPC: `error_raised` signal from the bridge pushes a `SermonError` into the store; stream errors via `stream_ended{reason=ProviderError}` and slot-rejection paths both funnel into the store, never `console.error` - [x] TypeBox-validate any inbound `SermonError` before adding to the store (per `docs/architecture/errors.md`'s runtime validator section) - [x] Persistence across reloads and (for Critical) restarts: written to `XDG_STATE_HOME/sermones/errors.json` on each add, rehydrated on startup, stale-schema errors dropped — implementation documented in the component doc Landed in `b13f503` (+ `7a95c31` for the oxlint `no-console` enforcement, which mechanically lints the `console.error` anti-pattern). CI green. Component doc: `docs/components/error-store.md`. Refs: - `docs/architecture/errors.md` — full spec for the store, propagation across IPC, tier table - `docs/components/error.md` — Rust `SermonError` surface + builder methods - `docs/invariants/error-visibility.md` — the behavioural contract this issue implements - `docs/invariants/ipc-schema-hash.md` — the `IpcDrift` kind reaches the store via the validator
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.

Reference
lyssieth/sermones#4
No description provided.