@tuturuuu/ai/memory boundary. Product routes must not call the
sidecar from the browser and must not create product-specific memory stores.
Scope
Memory scope is alwaysuser + workspace. The shared helper builds a stable
container tag from those two identifiers and stores product, surface, route,
locale, timezone, conversation, and workspace metadata on each write.
Default recall is cross-product within that user + workspace container. Use
metadata filters only when a route needs a narrower product or surface view.
Runtime
UsewithAiMemory for AI SDK calls when the route has a user and workspace.
Use ingestAiMemoryEvent, buildAiMemoryContext, and the Mira-compatible tool
executors for explicit memory reads and writes.
Reads fail open by default, and writes are best effort. Every embedding used for
memory add/search is generated through the metered @tuturuuu/ai embedding
helper before the sidecar is called. If credits, pricing, token counting, or
billable attribution cannot be verified, the memory operation skips before
calling Google. Structural metering failures disable memory for the user scope.
Keep SUPERMEMORY_FAIL_OPEN=true unless a product explicitly requires strict
persistence.
Required server-side env:
DOCKER_SUPERMEMORY_API_KEY, DOCKER_SUPERMEMORY_POSTGRES_PASSWORD,
DOCKER_SUPERMEMORY_DATABASE_URL, or DOCKER_SUPERMEMORY_ENABLED=false only
when an operator needs to override that generated runtime. An explicit false
value also removes the sidecar from Docker blue/green support builds and health
gates.
SUPERMEMORY_API_KEY is internal infrastructure configuration. Never expose it
through browser-visible env vars or client responses.
User Controls
Workspace settings live behind:Migration
Legacymira_memories rows are imported with the admin-only backfill endpoint:
customId values. Rows without a legacy
workspace are imported into the user’s default or personal workspace and tagged
with legacy_mira metadata.
Self-Hosting
The Docker fleet runs the first-party memory sidecar as an internal support service namedsupermemory for compatibility with existing base URL, API key,
watcher, and Compose wiring. The sidecar stores 3072-dimensional
gemini-embedding-2 vectors in extensions.halfvec(3072) with HNSW cosine
indexes, plus GIN indexes for metadata and full-text hybrid search. The
supermemory-db-migrate service applies apps/supermemory/db schema changes
before the runtime starts.
The watcher and cron recovery path use the same generated Docker env, so
recreating web-blue-green-watcher does not require manually exporting memory
service secrets. There is no SUPERMEMORY_IMAGE enterprise-image contract.
Connectors such as Google Drive, OneDrive, and Notion are disabled for the first
rollout. Product ingestion should persist concise summaries only; do not ingest
raw files or binaries unless the source is user-owned, enabled, and explicitly
appropriate for memory.
Mobile Assistant Settings
The mobile Assistant settings hub separates personal assistant identity from workspace memory. Name, tone, personality, and boundaries update the current user’s existing Mira soul. Memory controls address that user’s current workspace and list Mira memories only. Opening settings never changes consent. The global memory toggle preserves all existing product overrides; an existing disabled Mira override remains visible rather than implying that the global toggle enables Mira. An unavailable consent read is shown as unavailable, with retry, rather than inventing an enabled or disabled state. Memory viewing, confirmed deletion, and explicit export use the existing internal API. A row disappears only after the server confirms deletion. Export is shared only after the request completes within the same authorized settings scope. These controls create no offline privacy replay or separate memory store. Meet’s separate opt-in memory remains independent. Central Settings and the Assistant settings action open the same settings hub. Personality opens a dedicated page listing Assistant name, Tone, Response length, Personality, and Boundaries. Each row opens its own settings editor; saving updates that field against the latest confirmed personal soul and returns to Personality. Failed saves retain the draft for an explicit retry. Existing custom tone and response-detail values remain selectable. These pages and individual memory editors share the hub’s single title and floating back action, with scrollable content and the frame kept above the keyboard. System back and dock back return one level without submitting an edit. Opening a memory row reads its canonical content and revision through the existing Mira memory API. Saving uses that revision; a conflict retains the draft and requires reviewing the latest version before explicitly saving again. A confirmed receipt updates the list. An audit warning keeps the editor open, says the change is saved, and disables resubmitting the same content. Editors cancel on account or workspace transitions, including switching away and back during a pending read, review, or save. They never approximate editing by deleting and recreating a memory, and do not change collection consent. Settings retain prior confirmed values when a write fails and expose a localized retryable error. Account or workspace changes invalidate delayed reads, writes, and exports. Returning from settings refreshes the assistant soul from the server; request generations and the page’s actor epoch prevent older responses and account/workspace ABA transitions from replacing the current assistant identity. Regression coverage lives inassistant_personal_settings_repository_test.dart,
assistant_personal_settings_cubit_test.dart,
assistant_personal_settings_section_test.dart,
assistant_routed_editors_test.dart, assistant_personality_route_scope_test.dart,
assistant_memory_editor_section_test.dart, assistant_memory_editor_scope_test.dart,
settings_assistant_entrypoint_checks.dart, and assistant_soul_refresh_test.dart. These tests cover API receipts, product
preservation, delayed scope changes, English/Vietnamese controls, and large text
with a visible keyboard; they do not establish native-device or deployed runtime
proof.
Consolidating Mira memories
Themerge_memories tool preserves source memories until the sidecar confirms
that the replacement has persisted (done with a memory ID). Skipped, queued,
missing, or failed replacement receipts never authorize original deletion.
A successful replacement does not imply that every deletion succeeded: the
result includes its replacement ID/key, confirmed deleted keys, and retained
keys. Retry only retained keys; never claim the whole merge completed when
any deletion remains unconfirmed. Duplicate source keys are processed once,
and the replacement key is never deleted.
This rule applies to Mira’s existing user/workspace memory tool. It does not
admit background consolidation or combine Meet’s separately opted-in private
Live memory with workspace memory. Regression coverage lives in
packages/ai/src/tools/executors/memory.test.ts.
Settings lookup failures
Consent-checked memory operations deny admission when the current user/workspace/product settings RPC reports an error or throws. No metered embedding or sidecar read/write starts from that failed lookup. Existing separately authorized memory-management routes that explicitly bypass collection settings retain their current permissions; the repair does not change that management exception. A successful lookup with no settings row retains the existing enabled defaults; explicit disabled global or product settings still deny admission. This distinction changes outage behavior, not the existing missing-row consent policy. It does not introduce consent for background dreaming or merge Meet’s separately opted-in memory. The failure path returns a skipped memory operation so an optional memory outage does not make the surrounding chat depend on embedding or storage availability. Regression coverage inpackages/ai/src/memory/operations-consent.test.ts uses the
real settings/admission flow with synthetic RPC error and exception boundaries,
asserting no embedding or sidecar access. Positive missing-row and disabled/product
cases distinguish this rule from a blanket change to successful lookups.
In-place edit foundation
The private first-party sidecar exposes scoped read and revision-CAS update primitives for existing active memories. The service must have an API key configured for these new surfaces. Every read/update matches the memory ID, container, metadata user, workspace, product, anddone status. This foundation
alone does not expose a web/mobile editing API or a new assistant tool.
The opaque revision is computed in PostgreSQL from the full-precision timestamp
and stored content/metadata plus the PostgreSQL tuple version, before JavaScript
can round timestamp precision. The tuple component fences same-content updates
within one transaction. PostgreSQL documents that the
tuple version changes on update or VACUUM FULL;
table maintenance can require a fresh scoped read even
when content is unchanged; it does not change the logical memory ID.
It is a concurrency token, not an authorization token. Updates replace text and
its fresh 3072-dimensional vector atomically, clear the old derived summary, and
preserve the ID, original custom ID, creation time and provenance metadata.
Forgotten memories are never revived. A stale update receives a conflict instead
of overwriting the winner.
The service operation preflights ownership and revision before metered embedding.
Default operation admission still honors memory collection settings; the existing
explicit management exception must be passed deliberately by an authorized
future API. A stale preflight starts no embedding. Another edit or deletion can
win while embedding is underway: that CAS conflict may occur after credits were
used. Retrying the same stale revision is rejected before another embedding,
but there is no persistent idempotency key or guarantee of idempotent charging.
Do not retry using a newly loaded revision without reviewing the current content.
Regression coverage uses the actual sidecar route and emitted parameterized SQL
with a synthetic database boundary, plus operation/client tests with synthetic
network and embedding boundaries. This is source evidence, not live PostgreSQL,
provider, deployment or device proof. Proper edit-audit recording and the public
API/mobile editor remain dependent packets; no existing audit action is relabeled
and no background dreaming is dispatched.
Authenticated in-place editing
The live workspace memory item route providesGET/HEAD for an uncached
id, content, and opaque revision projection, and PATCH for a strict
value/revision body with the product in the query. Bearer and cookie sessions
both resolve the current actor, normalized workspace, and MEMBER admission before
private memory access. Another actor’s memory is unavailable; unknown products
are rejected rather than silently mapped to a different product.
Explicit owner editing remains available when automatic memory collection is
disabled, matching manual creation/deletion. This exception does not authorize
background consolidation or automatic dreaming. A stale revision returns 409;
callers preserve unsaved text and reread the current revision before retrying.
Embedding may already be metered when a concurrent edit wins the final CAS.
Confirmed edits record the distinct edit audit action with revision-only
metadata, never memory content or private provenance. If audit recording fails
after the durable edit, the response remains updated: true with
auditRecorded: false and warning: "audit_failed"; callers must not treat it as
a rolled-back edit or repeat the mutation. A missing audit receipt also counts as
an audit failure. GET responses do not expose source metadata or custom IDs.
Regression coverage: the item route and internal API client tests cover admission,
validation, conflicts, safe projections, and partial audit receipts. The
ai-memory-edit-audit.sql pgTAP fixture exercises the actual audit RPC and CHECK,
prior actions, membership and service-only access; the existing Programming
database contract workflow runs it after complete schema replay. Local wiring
checks are not PostgreSQL execution proof. Exact-head CI schema replay, typegen,
and web build remain required; the mobile editor is a separate dependent packet.