Skip to content

Agent state store: SQLite reminders/countdowns/watches + leashed url-watch#9

Merged
hartsock merged 1 commit into
pr6/release-path-newt-parityfrom
pr7/agent-state-store
Jun 6, 2026
Merged

Agent state store: SQLite reminders/countdowns/watches + leashed url-watch#9
hartsock merged 1 commit into
pr6/release-path-newt-parityfrom
pr7/agent-state-store

Conversation

@hartsock

@hartsock hartsock commented Jun 5, 2026

Copy link
Copy Markdown
Owner

Summary

Issue #7, phases A+B. Stacked on #6 — retarget after it merges.

Agents register state through modulex instead of editing config:

  • Store (~/.modulex/store.db, rusqlite bundled): reminders / countdowns / watches, generation-stamped (counters, never clocks); ical_feeds/mcp_servers schema reserved for phases C/D. Plain-JSON store export/import keeps content sovereign.
  • Cross-restart monotonic generations: the engine seeds its counter from the store and persists after each run — report identity now survives process restarts.
  • MCP tools (9 new): reminder_add/list/done, countdown_add/retire, watch_add/list/remove, store_export. Mutations stamp "registered after run N".
  • Steps: reminders (overdue → today → upcoming → undated, recurrence tags); countdown-calc merges config + store; url-watch fetches via agent-bridle-tool-web — first use of the net Caveats axis (host allowlist, SSRF screen, per-redirect re-check, DNS-rebind pin) — BLAKE3 change detection against the last seen generation. Behind default-on web feature.
  • CLI: modulex remind add "text" [--due DATE] [--recur daily] / list / done, modulex store export/import.

Test plan

  • just check green: 118 tests, clippy -D warnings all-features, fmt clean
  • Store unit tests (lifecycles, export/import round-trip, reopen persistence); reminders/url-watch handler tests over mock fetcher incl. real-BridleFetcher deny-all-net leash test (no network I/O — denied before connect)
  • MCP lifecycle test: routine_runreminder_add (stamped gen 1) → appears in next run's reminders step → reminder_done → double-done errors
  • Live smoke across processes: registered via CLI, surfaced in run morning (gen 1), done, re-ran (gen 2 — generation persisted across separate invocations)

Fixes #7 (phases A+B; C=iCal, D=mcp-query proxy follow)

…ssue #7 A+B)

WHAT: (1) modulex-core/store.rs — rusqlite (bundled) store at
$MODULEX_STORE → [store] path → ~/.modulex/store.db; schema v1
(reminders, countdowns, watches + reserved ical_feeds/mcp_servers;
PRAGMA user_version); generation-stamped rows (created_gen/done_gen/
retired_gen/last_seen_gen — counters, never clocks); plain-JSON
export/import (sovereignty: no SQLite lock-in). (2) Engine grows an
optional store: seeds its generation counter from meta.last_generation
and persists it after each run, so generations are MONOTONIC ACROSS
RESTARTS; RunContext carries the store. (3) Steps: new 'reminders'
(overdue → due-today → upcoming → undated, recurrence tags);
countdown-calc now merges config + store entries; new 'url-watch'
(feature web, default on) fetching through agent-bridle-tool-web —
net-axis Caveats + SSRF screen + redirect re-check + DNS-rebind pin —
BLAKE3-hashing extracted content and reporting changed/unchanged since
the last seen generation. ExecGate exposes read-only tool_context() for
in-proc leashed tools. (4) MCP tools: reminder_add/list/done,
countdown_add/retire, watch_add/list/remove, store_export — mutation
stamps use the engine's current generation ('registered after run N').
(5) CLI: modulex remind add/list/done + modulex store export/import;
doctor reports store health.

WHY: issue #7 phases A+B — agents say 'remind me of X' through modulex
tools instead of hand-editing config; URL tracking lands behind the
same deterministic surface. 118 tests; live smoke proved the full loop
including cross-process generation persistence.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hartsock hartsock added the risk:low Scoped, tested, no CI/build changes label Jun 5, 2026
@hartsock hartsock merged commit 6443194 into pr6/release-path-newt-parity Jun 6, 2026
1 check passed
hartsock added a commit that referenced this pull request Jun 6, 2026
Integrate stranded merges: agent state store (#9) and FOUNDATION.md (#33)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:low Scoped, tested, no CI/build changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant