Additional
Workspace Memory Flow
Synced from github.com/CoWork-OS/CoWork-OS/docs
This document describes how CoWork OS stores, curates, retrieves, and injects workspace memory after the layered-memory upgrade.
The foundation is still the hybrid memory system, but the runtime now makes it explicit as a four-layer wake-up model built on top of those storage lanes:
- Curated hot memory: small, prompt-visible, explicitly edited or promoted
- Recall archive: larger searchable memory/history, not injected by default
- Structured observations: inspectable sidecar metadata for archive memories
- Session recall: recent transcript/checkpoint history for “what happened in that run?”
- Topic packs: focused
.cowork/memory/topics/*.mdfiles loaded explicitly for topical work
An optional external provider lane can also sit beside that local stack. Today that provider is Supermemory, and it is additive rather than authoritative.
Those lanes map into runtime layers as:
- L0 Identity: curated user/workspace memory +
USER.mdessentials - L1 Essential Story: durable decisions, weekly/daily synthesis, active commitments
- L2 Topic Packs: focused topic files loaded on demand
- L3 Deep Recall: unified recall and verbatim quote search across tasks/messages/files/memory/KG
Chronicle fits this model as a screen-context evidence source, not as a fifth memory lane. Raw passive frames stay ephemeral in app-local storage. Only task-used Chronicle observations are promoted into workspace state and become searchable through unified recall as screen_context. When enabled, those promoted observations can also create linked screen_context memory entries through the normal memory service instead of bypassing it.
Overview
User messages / task events / accepted distill candidates
│
├─→ CuratedMemoryService
│ ├─→ curated_memory_entries (SQLite)
│ ├─→ .cowork/USER.md (auto block)
│ └─→ .cowork/MEMORY.md (auto block)
│
├─→ MemoryService
│ ├─→ memories + embeddings + summaries (archive lane)
│ └─→ MemoryObservationService
│ └─→ memory_observation_metadata + FTS sidecar
│
├─→ SupermemoryService (optional)
│ ├─→ prompt-time profile/search context
│ └─→ mirrored non-private memory captures
│
├─→ TranscriptStore
│ └─→ .cowork/memory/transcripts/*
│
└─→ DailyLogService / DailyLogSummarizer
└─→ .cowork/memory/daily + summaries
MemorySynthesizer.synthesize()
│
├─→ L0 Identity
│ ├─→ workspace kit essentials
│ └─→ hot curated memory
└─→ L1 Essential Story
└─→ playbook / KG / daily summaries
Explicit recall tools
├─→ memory_search_index
├─→ memory_timeline
├─→ memory_details
├─→ search_memories
├─→ search_sessions
├─→ search_quotes
├─→ memory_topics_load
├─→ memory_curate
├─→ memory_curated_read
├─→ supermemory_profile
├─→ supermemory_search
├─→ supermemory_remember
└─→ supermemory_forget
Chronicle promoted observations
├─→ .cowork/chronicle/observations + assets
└─→ ChronicleMemoryService → MemoryService (`screen_context`)
Lane 1 — Curated Hot Memory
Service: src/electron/memory/CuratedMemoryService.ts
Storage: curated_memory_entries table
Mirrors: .cowork/USER.md, .cowork/MEMORY.md
This lane is for the small set of durable facts that should stay front-and-center in prompts:
- user preferences
- identity facts
- durable constraints
- workflow rules
- project facts
- active commitments
How entries arrive
- explicit agent/user actions through
memory_curate - accepted stable promotions from
CoreMemoryDistiller - future human edits that are synced back through governed workflows
Guardrails
- curated content is normalized before storage
- stored curated content is capped at 320 characters
matchstrings used for replace/remove are capped at 120 characters- writes mirror into auto-managed blocks inside
.cowork/USER.mdand.cowork/MEMORY.md - file sync is serialized per workspace to reduce last-writer-wins races
- replace/remove prefers stable
idvalues frommemory_curated_readfor deterministic updates
Prompt behavior
Curated hot memory is injected by default through <cowork_hot_memory>.
Lane 2 — Recall Archive
Service: src/electron/memory/MemoryService.ts
Storage: memories, memory_embeddings, memory_summaries
Structured sidecar: src/electron/memory/MemoryObservationService.ts, memory_observation_metadata
This is the broad searchable archive:
- observations
- decisions
- errors
- insights
- imported ChatGPT history
- compressed summaries
Chronicle-promoted observations remain provenance-rich screen_context records so unified recall can surface them separately from ordinary memory text. When background Chronicle memory generation is enabled, the runtime can also create linked screen_context memory rows derived from those observations. Those derived rows are summaries with provenance warnings, not raw frame dumps.
This lane still uses hybrid lexical + local semantic retrieval, but it is not injected by default. The feature flag defaultArchiveInjectionEnabled now defaults to false.
Structured observations
Every archive memory can have a structured observation sidecar keyed by memory_id. The sidecar stores title, subtitle, narrative, facts, concepts, file/tool provenance, source event IDs, content hash, capture reason, privacy state, generation source, and migration status.
This gives CoWork a compact index for retrieval and a user-inspectable control plane without rewriting the original memories table. The original archive row remains authoritative for full content.
Backfill is deterministic and local. It derives metadata from existing content and summaries without per-row LLM calls. It does not run as a synchronous startup write path; Memory Hub shows status and can trigger rebuild explicitly.
Destructive inspector actions are workspace-scoped. Delete is implemented as confirmed soft-delete: the observation becomes suppressed, the underlying memory is marked private, and the row is excluded from default search and prompt recall instead of being hard-deleted directly.
Retrieval path
search_memoriessearches archive memory plus indexed.cowork/markdownmemory_search_indexreturns compact structured observation matches firstmemory_timelinereturns compact neighboring observations around an anchor ID or querymemory_detailsexpands only selected observation IDs and is scoped to the active workspace- archive recall can still be injected when explicitly enabled for a workspace/runtime
MemoryTierServicestill tracks reference counts and promotes/evicts archive entries over time
Privacy path
<no-memory>disables automatic capture for the relevant task content<private>...</private>redacts that segment from captured memory and marks affected derived entries private when needed- private, redacted, and suppressed observations are excluded from Supermemory mirroring
- redacted and suppressed observations are excluded from both search-based prompt recall and recent-memory prompt recall
Screen Context Evidence — Chronicle Promotions
Services: src/electron/chronicle/ChronicleCaptureService.ts, src/electron/chronicle/ChronicleObservationRepository.ts, src/electron/chronicle/ChronicleMemoryService.ts
Workspace storage: .cowork/chronicle/observations/*.json, .cowork/chronicle/assets/*
Chronicle keeps a local recent-screen buffer in app user-data storage, but only writes into the workspace when a task actually used a screen observation.
Promoted Chronicle records contain:
- the original query
- capture timestamp
- app name and window title
- OCR-derived local text snippet
- confidence
- provenance (
untrusted_screen_text) - source reference when frontmost URL/file/app metadata can be resolved
- destination hints when the task implied a workflow target such as
google_docorslack_dm - linked
memoryId/memoryGeneratedAtfields when background Chronicle memory generation produced a relatedscreen_contextmemory row
Durable promotion is also gated by Chronicle's respectWorkspaceMemory setting:
- when it is
true, Chronicle only persists promoted observations if workspace memory is enabled, auto-capture is enabled, and memory privacy mode is not disabled - when it is
false, Chronicle can still persist observations even if workspace memory capture is otherwise restricted
Retrieval path
- unified recall can surface promoted Chronicle observations as
screen_context - Mission Control learning/evidence cards can attach Chronicle-backed evidence refs and a dedicated
Chronicle screen context usedlearning step - linked
screen_contextmemory rows can participate in normal memory search and retention logic - raw passive frames are not indexed or injected by default
Optional External Lane — Supermemory
Service: src/electron/memory/SupermemoryService.ts
Surface: Settings → Memory Hub → Supermemory
Supermemory is an optional external memory provider that runs alongside CoWork's local memory system.
What it adds:
- scoped profile fetches for prompt construction
- explicit external recall and write tools
- optional mirroring of non-private local memory captures
- workspace-scoped container tags derived from a template such as
cowork:{workspaceId}
What it does not replace:
- curated hot memory
- archive memory
- transcript/session recall
- workspace kit files
- knowledge graph state
Retrieval and write path
supermemory_profilefetches a scoped profile plus relevant external contextsupermemory_searchperforms explicit search against the resolved or overriddencontainerTagsupermemory_remembercreates a durable external memory directly in Supermemorysupermemory_forgetremoves an external memory by ID or exact content
Prompt behavior
If prompt injection is enabled in Memory Hub, CoWork appends a Supermemory profile block during chat, execution, and follow-up prompt construction. This block is treated as soft context and should lose to fresher or conflicting user instructions in the active conversation.
Mirroring behavior
If mirroring is enabled in Memory Hub, MemoryService.capture(...) best-effort mirrors non-private memory entries into Supermemory with workspace/task metadata.
Current boundary:
- private or strict-mode entries are not mirrored
- workspace kit files remain local
- full conversation turn-by-turn sync is not implemented yet
Failure handling
Supermemory requests are guarded with timeouts, best-effort behavior, and a temporary circuit breaker after repeated failures. When the provider is unavailable, CoWork continues with local memory only.
Lane 3 — Session Recall
Service: src/electron/memory/SessionRecallService.ts
Backing store: src/electron/memory/TranscriptStore.ts
Recent task/session history is now a first-class recall lane rather than something folded into archive recall.
Stored artifacts include:
- transcript spans under
.cowork/memory/transcripts/spans/*.jsonl - lightweight checkpoints under
.cowork/memory/transcripts/checkpoints/*.json
Each checkpoint can now carry two complementary artifacts:
structuredSummary: compact durable synthesis used by existing memory/prompt flowsevidencePacket: exact transcript/message spans with provenance and a dedupe hash
Checkpoint capture triggers
- Pre-compaction: always, before messages are dropped
- Periodic long-run capture: every 12 meaningful user/assistant exchanges, deduped by span hash
- Task completion: only when the task produced a non-trivial result or decision
Retrieval path
search_sessionssearches transcript spans- optional checkpoint search can widen recall to summary/checkpoint payloads
- this is intended for “what happened in that run?” rather than “what should the system remember forever?”
Verbatim recall lane
search_quotes is the low-loss recall lane for exact wording. It searches:
- transcript spans
- task messages
- imported/archive memories
- indexed workspace markdown
Results return exact excerpts plus provenance such as sourceType, objectId, taskId, timestamp, optional path, and ranking reason. Transcript/message hits outrank synthesized-memory hits when both match.
Topic Packs
Service: src/electron/memory/LayeredMemoryIndexService.ts
Files: .cowork/memory/MEMORY.md, .cowork/memory/topics/*.md
Topic packs are query-scoped, focused memory slices generated from:
- relevant archive recall
- relevant indexed markdown
- curated hot memory summary lines
- recent daily summaries
Retrieval path
memory_topics_loadcan rebuild topic files for a querymemory_topics_load(refresh: false)now performs a true read-only lookup over existing topic files- topic snippets are intentionally capped so packs stay compact
Topic packs are for topical work such as “bring me the onboarding context for billing migrations,” not for always-on prompt injection.
Daily Logs and Summaries
Operational Daily Log
Service: src/electron/memory/DailyLogService.ts
Location: .cowork/memory/daily/<YYYY-MM-DD>.md
When another runtime path or automation writes entries through DailyLogService, the files act as raw operational journals for:
- user feedback events
- task completions
- notable decisions
- high-value observations or corrections
Raw daily logs are never injected into prompts.
Daily Summaries
Service: src/electron/memory/DailyLogSummarizer.ts
Location: .cowork/memory/summaries/<YYYY-MM-DD>.md
Daily summaries remain part of the structured memory lane. They are ranked below curated/user relationship facts and above raw archive snippets when archive injection is enabled.
Prompt Synthesis
Service: src/electron/memory/MemorySynthesizer.ts
Prompt synthesis now builds separate sections instead of one monolithic synthesized-memory block:
<cowork_hot_memory>—L0 Identity: curated hot memory + user/profile + active relationship items<cowork_structured_memory>—L1 Essential Story: playbook, daily summaries, active commitments, and current KG context- optional Supermemory profile block — external profile/search context appended only when enabled
L2 Topic Packs and L3 Deep Recall are not injected into the live prompt by default. They stay explicit and tool-driven.
Workspace kit context is still injected separately and placed before the memory sections.
Budgeting
- total memory synthesis budget defaults to
2800estimated tokens - workspace kit keeps roughly
35%of the budget - remaining budget is split between hot memory and structured memory
- fragment selection happens before rendering, so truncation does not cut markup blocks mid-stream
Default injection behavior
L0 Identity: onL1 Essential Story: on- archive memory: off by default
- Supermemory profile injection: optional
L2 Topic Packs: tool-drivenL3 Deep Recall(memory_search_index,memory_timeline,memory_details,search_quotes,search_sessions,search_memories): tool-driven
Workspace Kit Context
Service: src/electron/memory/WorkspaceKitContext.ts
Location: .cowork/*.md
The workspace kit remains a governed durable context layer with its own contracts, freshness windows, and prompt budgets. USER.md and MEMORY.md now contain auto-managed curated-memory blocks in addition to human-authored content.
From Settings → Memory Hub → Per Workspace, the "Open USER.md" and "Open MEMORY.md" buttons open (or create if missing) these files directly in the system editor via kit:openFile IPC.
Memory Hub also shows a preview of the current L0/L1 payload plus the L2/L3 layers excluded from default injection, including fragment counts dropped by budget.
Message Feedback → Memory
User feedback still flows into memory/personalization systems:
User clicks 👍 or 👎 (+ optional reason)
│
▼
kit:submitMessageFeedback IPC
│
▼
UserProfileService.ingestUserFeedback()
│
├─→ RelationshipMemoryService
└─→ AdaptiveStyleEngine.observeFeedback() [if enabled]
Feedback reason values: incorrect, too_verbose, ignored_instructions, wrong_tone, unsafe.