Owner: backend on-call
Scope: the universal canonical writer, dual-format reader, historical compatibility adapter, and Short-term maintenance job.
There is no product UID enrollment, dogfood activation, or general account backfill. The drain's dev-only operational allowlist is a safety fence, not product enrollment. Every authenticated user follows one memory/task authority. Existing historical documents are read in place and materialized only when that item is mutated.
| Control | Owner | Meaning |
|---|---|---|
MEMORY_MODE |
backend + maintenance manifests | Global readiness/incident declaration. Never a user selector. |
MEMORY_V3_GET_ENABLED |
backend manifests | Deprecated, non-authoritative declaration pending manifest cleanup. Never a user selector. |
MEMORY_CANONICAL_MAINTENANCE_ENABLED |
memory-maintenance-job only |
Enables scheduled Short-term normalization, TTL audit, consolidation, and outbox drain. |
MEMORY_CANONICAL_CONSOLIDATION_ENABLED |
maintenance job | Global L2 cost/incident switch. Required processing, TTL audit, and outbox ownership remain independent. |
| consolidation batch/candidate caps | maintenance job | Bound one L2 call and one pass. |
KNOWLEDGE_LEDGER_DRAIN_ENABLED |
knowledge-ledger-drain-job |
Explicit operational gate; development and production manifests default off. A one-shot development execution may override the gate only after read-only preflight and direct-user ledger-write proof. |
KNOWLEDGE_LEDGER_DRAIN_UID_ALLOWLIST |
knowledge-ledger-drain-job |
Development retains one named QA owner for an explicit override; production is empty. It is a safety fence, not product enrollment, and the gate-off default prevents scheduled mutation. |
| shared JIT admission + kill switch | knowledge-ledger-drain-job |
Re-authorizes every account and row before migration; unavailable authority fails closed. |
| ledger drain page cap/cursor | knowledge-ledger-drain-job |
Global rollout scans at most 20 apply-control documents per hourly run and advances only after every account in the page completes without an error; the dev allowlist reads only its named controls and has no global cursor side effects. |
| cursor secret/version/TTL | backend | Unused by the live route; removal requires confirming no separate consumer owns the binding. |
MEMORY_ENABLED_USERS and code-owned product UID lists are retired. Runtime
validation rejects a reintroduced per-user memory inventory.
- Run the hermetic memory pipeline, universal service/mutation, task no-drop/no-duplicate, privacy/export, runtime-env, and OpenAPI compatibility contracts for the exact SHA.
- In a non-production project, deploy that SHA with two or more synthetic authenticated users: historical-only, canonical-only, and mixed rows.
- Verify identical logical IDs, ordering, lifecycle/device/visibility policy, duplicate suppression, and cross-UID isolation across REST, chat, MCP, tools, and developer surfaces.
- Verify the dedicated maintenance job and Scheduler identity/cadence. The job must advance the bounded, content-free account-registry cursor without scanning the users collection or repeating one fixed page.
- Verify
knowledge-ledger-drain-jobandknowledge-ledger-drain-hourlyare independent of maintenance and the scheduler principal hasrun.invokeron the job, then confirm its content-free counters show bounded cursor progress and compatibility-to-ledger cutovers. - Exercise the global stop and restore path. Record revision, image digest, project/database identity, Scheduler/job result, and content-free counters.
- Deploy the same universal reader before enabling canonical intake or maintenance in production. Do not add a canary UID or enrollment document.
Record counts only: canonical rows returned, historical rows returned, canonical-over-historical suppressions, override/tombstone suppressions, malformed historical rows, cursor failures, pending/terminal maintenance rows, outbox lag/dead letters, and historical cleanup failures. Do not log memory content, embeddings, or provider payloads.
The universal repository exports these low-cardinality Prometheus counters:
memory_universal_read_origin_total{origin="canonical|historical"};memory_historical_suppression_total{reason="canonical_identity|canonical_state"};memory_historical_materialization_total{outcome="not_needed|committed"}.
Maintenance receipts additionally report retryable outbox failures, dead letters, acknowledgement failures, processed accounts, and cursor progress. Alerting must aggregate those fields without UID, memory ID, or content labels.
- Keep the universal dual-format reader deployed. Rolling back to a legacy-only reader can hide newly canonical data and is forbidden.
- Stop L2 cost or bad consolidation with
MEMORY_CANONICAL_CONSOLIDATION_ENABLED=false. - Stop scheduled mutation with
MEMORY_CANONICAL_MAINTENANCE_ENABLED=false; continue authoritative reads. - If new intake itself is unsafe, use the global memory incident mode owned by the deployment. Never route selected UIDs to a legacy writer.
- Preserve canonical items, historical rows, overrides, tombstones, journals, and outbox state. Physical deletion requires separate approval.
- After repair, restore globally, run one bounded maintenance execution with
--wait, then confirm a later Scheduler execution and provider lag recovery.
The rehearsal must show that stopping new canonical processing does not hide historical or canonical data, does not resume a legacy writer, and does not make task intelligence unavailable. Cross-origin deletes remain suppressed by canonical tombstones/overrides while providers drain.