Files
kandev/docs/plans/plugins/task-03-state-store.md
2026-08-24 11:09:03 +00:00

2.0 KiB

id, title, status, wave, depends_on, plan
id title status wave depends_on plan
task-03 plugin_state SQLite store done 1
docs/plans/plugins/plan.md

plugin_state SQLite store

Title

SQLite-backed plugin-scoped KV state store following the per-package initSchema() convention.

Inputs

  • Spec docs/specs/plugins/requirements/plugins.md → "plugin_state (SQLite)" and "Plugin state API". Table:
    CREATE TABLE plugin_state (
      id TEXT PRIMARY KEY, plugin_id TEXT NOT NULL,
      scope TEXT NOT NULL DEFAULT 'instance', scope_id TEXT,
      state_key TEXT NOT NULL, value_json TEXT NOT NULL, updated_at TEXT NOT NULL,
      UNIQUE (plugin_id, scope, scope_id, state_key));
    
  • Scopes: instance | workspace | task | agent. Plugins cannot read others' state (enforced by always filtering on plugin_id — the API layer passes it, task-09).
  • Pattern reference: internal/task/repository/sqlite/base_schema.go (initSchema with CREATE TABLE IF NOT EXISTS) and how repos take a *sql.DB/db handle. Use the same db handle type the other stores use (db.Pool writer/reader or *sql.DB — match sibling stores; inspect internal/sentry/store.go).

Acceptance

  1. StateStore with initSchema() creating plugin_state (idempotent).
  2. Methods: Get(ctx, pluginID, scope, scopeID, key) (json.RawMessage, bool, error), Set(ctx, pluginID, scope, scopeID, key, value) (upsert on the UNIQUE key), Delete(ctx, pluginID, scope, scopeID, key), List(ctx, pluginID, scope, scopeID) ([]StateEntry, error).
  3. updated_at set to RFC3339 UTC on write. NULL scope_id handled for instance scope.

Files

  • apps/backend/internal/plugins/state/store.go
  • apps/backend/internal/plugins/state/store_test.go (in-memory or temp-file sqlite)

Verification

  • go test ./internal/plugins/state/... from apps/backend
  • make -C apps/backend lint

Output contract

Report: db handle type chosen (match siblings), upsert approach, scope_id NULL handling. Stay within internal/plugins/state/.

Dependencies

None.