Skip to content

Persist UX insights weekly gate across restarts - #39

Open
silas-dsc wants to merge 1 commit into
mainfrom
claude/ux-report-weekly-monday-ra2uk9
Open

Persist UX insights weekly gate across restarts#39
silas-dsc wants to merge 1 commit into
mainfrom
claude/ux-report-weekly-monday-ra2uk9

Conversation

@silas-dsc

Copy link
Copy Markdown
Owner

Summary

Follow-up to #38. That PR anchored the UX insights report to a weekday (Monday), which stopped it re-posting on Tue–Sun restarts — but the weekly-gate clock (nextRunAt) was still in-memory only, so a restart reset it to 0. On a restart that happened on the report day (Monday), both gates were open and the report re-posted. It could re-post on every Monday restart.

This closes that gap by persisting the clock across restarts.

Change

  • New injectable UxStateStore (load() / save()) on UxInsightsWatcher, defaulting to a disk-backed FileUxStateStore that reads/writes .symphony-ux-insights-state.json — mirroring the orchestrator's existing .symphony-slack-queue.json persistence pattern.
  • The watcher restores nextRunAt on construction and rewrites it after each successful run.
  • Both load and save are best-effort: a missing, corrupt, or unwritable file logs a warning and degrades to the previous in-memory behaviour rather than crashing the watcher.
  • The day-of-week anchor from Limit UX insights report to run once weekly on Monday #38 stays as the secondary guarantee that the run always lands on the configured weekday.

Net effect: the report goes out at most once per run_interval_ms even across repeated restarts, and always on the configured weekday.

The symphony-ux-insights CLI / --dry-run path is unchanged — it still bypasses the gate and doesn't touch the state store.

Files

  • src/ux-insights.tsUxSchedulerState / UxStateStore types, load-on-construct + save-on-advance, FileUxStateStore.
  • src/orchestrator.ts — wire a FileUxStateStore (under symphonyRoot) into the watcher.
  • .gitignore — ignore .symphony-ux-insights-state.json.
  • WORKFLOW.md — updated the scheduling note to reflect persistence.
  • src/__tests__/ux-insights.test.ts — tests for persist-on-success, no-persist-on-failure, restore-blocks-restart, and FileUxStateStore round-trip / missing / corrupt / bad-value handling.

Testing

  • pnpm build — clean.
  • pnpm test — 260 passed (16 files), including 7 new tests for the persistence behaviour.

🤖 Generated with Claude Code

https://claude.ai/code/session_014aJhv8L2YPc8TaJE6SXeXM


Generated by Claude Code

The weekly gate's nextRunAt clock was in-memory only, so a restart reset
it to 0. Combined with the day-of-week anchor, that still let the report
re-post on any restart that happened on the report day (e.g. Monday).

Persist nextRunAt to .symphony-ux-insights-state.json (mirroring the
orchestrator's existing Slack-queue persistence) via a new injectable
UxStateStore, defaulting to a disk-backed FileUxStateStore. The watcher
restores the clock on construction and rewrites it after each successful
run. Both load and save are best-effort: a missing, corrupt, or unwritable
file degrades to the previous in-memory behaviour instead of crashing.

The report now goes out at most once per run_interval_ms even across
repeated restarts, and always on the configured weekday.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aJhv8L2YPc8TaJE6SXeXM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants