molecule-core/docs/memory-plugins/CHANGELOG.md
devops-engineer 55689e0b10
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 16s
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 22s
CI / Detect changes (pull_request) Successful in 24s
E2E API Smoke Test / detect-changes (pull_request) Successful in 20s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 21s
pr-guards / disable-auto-merge-on-push (pull_request) Failing after 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 44s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 38s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 35s
Harness Replays / detect-changes (pull_request) Successful in 44s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 27s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 56s
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Failing after 2m1s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Failing after 2m34s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Failing after 2m34s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 23s
Harness Replays / Harness Replays (pull_request) Failing after 1m12s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 2m51s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Failing after 5m37s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6m15s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 6m34s
CI / Python Lint & Test (pull_request) Successful in 8m20s
CI / Canvas (Next.js) (pull_request) Successful in 9m46s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Failing after 13m23s
fix(post-suspension): migrate github.com/Molecule-AI refs to git.moleculesai.app (Class G #168)
The GitHub org Molecule-AI was suspended on 2026-05-06; canonical SCM
is now Gitea at https://git.moleculesai.app/molecule-ai/. Stale
github.com/Molecule-AI/... URLs return 404 and break tooling that
clones / pip-installs / curls them.

This bundles all non-Go-module URL fixes for this repo into a single PR.
Go module path references (in *.go, go.mod, go.sum) are out of scope
here -- tracked separately under Task #140.

Token-auth clone URLs also flip ${GITHUB_TOKEN} -> ${GITEA_TOKEN} since
the GitHub token does not auth against Gitea.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 13:08:15 -07:00

114 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Memory Plugin Contract — Changelog
Every breaking or operationally-relevant change to the v1 plugin
contract or the workspace-server-side wiring lands here. Plugin
authors should subscribe to PRs touching this file.
## [Unreleased] — fixup wave 1 (post-RFC-#2728 self-review)
A self-review of the initial 11-PR rollout (PRs #2729-#2742) flagged
two correctness bugs and three operational hazards. This wave fixes
all of them. Order matches operator-impact severity.
### Critical: backfill idempotency via `MemoryWrite.id` (#2744)
**The bug.** The backfill CLI claimed idempotent on re-run, but
`gen_random_uuid()` in the plugin's INSERT meant every retry created
a fresh row. Operators retrying a failed `-apply` would silently
double their memory count.
**The fix.** Optional `id` field on `MemoryWrite`. When supplied,
plugins MUST upsert. The backfill now forwards `agent_memories.id`
to `MemoryWrite.id`, so retries update in place.
**Plugin author action.** If your plugin uses
`INSERT INTO ... DEFAULT gen_random_uuid()`, switch to
`INSERT ... ON CONFLICT (id) DO UPDATE` when `id` is set. The wire
contract is forward-compatible — plugins that ignore the field still
work for production agent commits (which leave `id` empty), but they
will silently corrupt backfill retries.
### Critical: `memory-backfill -verify` mode (#2747)
**The miss.** The original PR-7 task spec called for a parity-check
mode but it never landed. Operators had no way to confirm a
migration succeeded short of "no errors logged."
**The fix.** New `-verify` flag samples N workspaces, queries
`agent_memories` direct, runs an equivalent plugin search via the
namespace resolver, multiset-compares contents. Reports mismatches
to stdout and exits non-zero so CI can gate the cutover.
```bash
memory-backfill -verify # default sample 50
memory-backfill -verify -verify-sample=200 # bigger
memory-backfill -verify -workspace=<uuid> # one workspace
```
### Important: `expires_at` validation (#2746)
**The bug.** `commit_memory_v2` silently dropped malformed
`expires_at` strings. Agent passes `expires_at: "tomorrow"`, gets a
200, memory has no TTL — agent thinks it set a TTL, didn't.
**The fix.** Returns
`fmt.Errorf("invalid expires_at: must be RFC3339")` on parse
failure. Plugin is not called in this case.
**Plugin author action.** None — this is a workspace-server-side
fix. But: if your plugin advertises the `ttl` capability, make sure
you actually evict expired rows on read (not just on a janitor cron
that runs once a day). The harness in `testing-your-plugin.md` has
a TTL-eviction test you should run.
### Important: audit log JSON via `json.Marshal` (#2746)
**The bug.** `auditOrgWrite` built `activity_logs.metadata` via
`fmt.Sprintf` with `%q`. For ASCII (today's UUID + hex digest) this
coincidentally produces valid JSON; for unicode or control bytes it
silently produces non-JSON.
**The fix.** Replaced with `json.Marshal(map[string]string{...})`.
Same wire shape today, won't regress when metadata grows.
**Plugin author action.** None — workspace-server-internal.
### Operator action: staging verification (#292)
**Status.** Tracked as task #292. PR-merged ≠ verified. Operator
must:
1. Provision a staging tenant, set `MEMORY_PLUGIN_URL`
2. Run real `commit_memory_v2` from a workspace
3. `memory-backfill -dry-run` against staging data
4. `memory-backfill -apply`, then `-verify`
5. Set `MEMORY_V2_CUTOVER=true`, verify admin export still works
6. Run a legacy `commit_memory` from a workspace, verify it lands
in plugin storage via the PR-6 shim
### Other follow-ups still open
- **#289**: admin export O(workspaces) → O(namespaces) — N+1 pattern
in `exportViaPlugin` (1000-workspace tenants run 1000× resolver
CTEs + 1000× plugin searches today).
- **#291**: workspace deletion must call `DELETE
/v1/namespaces/{name}` — orphans accumulate today.
- **#293**: real-subprocess boot E2E — current PR-11 is integration
(httptest + sqlmock), not E2E.
These are tracked but deferred; they're operationally annoying, not
incident-shaped.
## [v1.0.0] — initial release (RFC #2728, PRs #2729-#2742)
Initial plugin contract + 11-PR rollout. See
[issue #2728](https://git.moleculesai.app/molecule-ai/molecule-core/issues/2728)
for the full RFC.
Endpoints: `/v1/health`, `/v1/namespaces/{name}` (PUT/PATCH/DELETE),
`/v1/namespaces/{name}/memories` (POST), `/v1/search` (POST),
`/v1/memories/{id}` (DELETE).
Capabilities: `embedding`, `fts`, `ttl`, `pin`, `propagation`.
Operator runbook: see [README.md § Replacing the built-in plugin](README.md#replacing-the-built-in-plugin).