Agent state store: SQLite reminders/countdowns/watches + leashed url-watch#9
Merged
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Issue #7, phases A+B. Stacked on #6 — retarget after it merges.
Agents register state through modulex instead of editing config:
~/.modulex/store.db, rusqlite bundled): reminders / countdowns / watches, generation-stamped (counters, never clocks);ical_feeds/mcp_serversschema reserved for phases C/D. Plain-JSONstore export/importkeeps content sovereign.reminder_add/list/done,countdown_add/retire,watch_add/list/remove,store_export. Mutations stamp "registered after run N".reminders(overdue → today → upcoming → undated, recurrence tags);countdown-calcmerges config + store;url-watchfetches 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-onwebfeature.modulex remind add "text" [--due DATE] [--recur daily]/list/done,modulex store export/import.Test plan
just checkgreen: 118 tests, clippy-D warningsall-features, fmt cleanroutine_run→reminder_add(stamped gen 1) → appears in next run'sremindersstep →reminder_done→ double-done errorsrun 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)