docs(FN-2097): clarify layered memory layout and legacy fallback semantics

- Update memory architecture and contributing docs to describe .fusion/memory/ as the canonical layered workspace
- Reframe .fusion/memory.md references as a deprecated legacy fallback used only for migration/alias compatibility
- Expand the memory plugin contract with explicit layered layout, migration behavior, and invariant language
- Align settings reference memory-insight file descriptions with the canonical long-term memory model
This commit is contained in:
Fusion
2026-04-19 02:15:01 -07:00
committed by gsxdsm
parent d7943e87b2
commit 91abafc11c
4 changed files with 37 additions and 14 deletions

View File

@@ -480,7 +480,7 @@ SQLite schema is initialized in `packages/core/src/db.ts` and uses:
- `.fusion/memory/MEMORY.md` - `.fusion/memory/MEMORY.md`
- `.fusion/memory/YYYY-MM-DD.md` - `.fusion/memory/YYYY-MM-DD.md`
- `.fusion/memory/DREAMS.md` - `.fusion/memory/DREAMS.md`
- Legacy `.fusion/memory.md` is compatibility-only (migration seed + mirrored alias path) and is not canonical storage. - Legacy `.fusion/memory.md` is a deprecated legacy fallback (migration seed/alias path) and is not canonical storage.
### File-based side stores ### File-based side stores
Some data remains intentionally filesystem-based: Some data remains intentionally filesystem-based:

View File

@@ -109,7 +109,7 @@ When enabled, Fusion uses OpenClaw-style memory files:
- `.fusion/memory/MEMORY.md` — long-term project memory - `.fusion/memory/MEMORY.md` — long-term project memory
- `.fusion/memory/YYYY-MM-DD.md` — daily running notes - `.fusion/memory/YYYY-MM-DD.md` — daily running notes
- `.fusion/memory/DREAMS.md` — dream-processing memory file - `.fusion/memory/DREAMS.md` — dream-processing memory file
- Legacy `.fusion/memory.md` is compatibility-only (migration seed + mirrored alias) and should not be treated as canonical - Legacy `.fusion/memory.md` is a deprecated legacy fallback (migration seed/alias) and should not be treated as canonical
Use project memory for reusable patterns, constraints, and pitfalls that should persist across tasks. Use project memory for reusable patterns, constraints, and pitfalls that should persist across tasks.
@@ -117,7 +117,7 @@ Use project memory for reusable patterns, constraints, and pitfalls that should
Fusion can automatically extract insights from memory and prune transient content. Enable via `insightExtractionEnabled` setting: Fusion can automatically extract insights from memory and prune transient content. Enable via `insightExtractionEnabled` setting:
- `.fusion/memory/MEMORY.md` — Canonical long-term working memory file (inside the layered `.fusion/memory/` workspace) compacted/pruned by extraction jobs - `.fusion/memory/MEMORY.md` — Canonical long-term memory source (inside the layered `.fusion/memory/` workspace) compacted/pruned by extraction jobs
- `.fusion/memory-insights.md` — Distilled insights output - `.fusion/memory-insights.md` — Distilled insights output
- `.fusion/memory-audit.md` — Audit report after each extraction (includes pruning outcome) - `.fusion/memory-audit.md` — Audit report after each extraction (includes pruning outcome)

View File

@@ -115,7 +115,7 @@ Prompt wording is selected by `resolveMemoryInstructionContext(settings?)`:
| `/api/memory` | GET | Returns `{ content: string }` from project memory (empty string if absent) | | `/api/memory` | GET | Returns `{ content: string }` from project memory (empty string if absent) |
| `/api/memory` | PUT | Body `{ content: string }`; writes memory content | | `/api/memory` | PUT | Body `{ content: string }`; writes memory content |
Route handlers are still file-service based, but operate on OpenClaw-style canonical long-term memory path (`.fusion/memory/MEMORY.md`) and remain compatible with backend-aware bootstrap/prompt behavior. Route handlers are still file-service based, but operate on OpenClaw-style canonical long-term memory path (`.fusion/memory/MEMORY.md`) with migration compatibility for legacy `.fusion/memory.md` seeding/alias handling.
### 1.6 Dashboard Settings UI ### 1.6 Dashboard Settings UI
@@ -130,7 +130,7 @@ Route handlers are still file-service based, but operate on OpenClaw-style canon
| Test File | Coverage | | Test File | Coverage |
|-----------|----------| |-----------|----------|
| `packages/core/src/memory-backend.test.ts` | Backend interface behavior, built-in backends, registry helpers, `DEFAULT_MEMORY_BACKEND = "qmd"`, backend resolution/fallback | | `packages/core/src/memory-backend.test.ts` | Backend interface behavior, built-in backends, registry helpers, layered path helpers/bootstrap (`ensureOpenClawMemoryFiles`), `DEFAULT_MEMORY_BACKEND = "qmd"`, backend resolution/fallback |
| `packages/core/src/project-memory.test.ts` | `MEMORY_FILE_PATH`, bootstrap behavior, backend-aware instruction context and prompt content | | `packages/core/src/project-memory.test.ts` | `MEMORY_FILE_PATH`, bootstrap behavior, backend-aware instruction context and prompt content |
| `packages/core/src/store.test.ts` | Init/toggle bootstrap behavior for enabled/disabled memory states | | `packages/core/src/store.test.ts` | Init/toggle bootstrap behavior for enabled/disabled memory states |
| `packages/engine/src/triage.test.ts` | `memoryEnabled` and `memoryBackendType` influence on triage prompt injection | | `packages/engine/src/triage.test.ts` | `memoryEnabled` and `memoryBackendType` influence on triage prompt injection |
@@ -140,7 +140,7 @@ Route handlers are still file-service based, but operate on OpenClaw-style canon
### 1.8 Summary of Non-Negotiable Behaviors ### 1.8 Summary of Non-Negotiable Behaviors
1. **Canonical layout**: OpenClaw-style memory workspace is canonical (`.fusion/memory/` with `MEMORY.md`, daily files, and `DREAMS.md`). 1. **Canonical layout**: OpenClaw-style memory workspace is canonical (`.fusion/memory/` with `MEMORY.md`, daily files, and `DREAMS.md`).
2. **Legacy compatibility**: Legacy `.fusion/memory.md` remains compatibility-only (migration seed / accepted legacy alias), not canonical storage. 2. **Legacy compatibility**: Legacy `.fusion/memory.md` is a **deprecated legacy fallback** (migration seed / accepted alias), not canonical storage.
3. **Backend default**: Memory backend default is `qmd`. 3. **Backend default**: Memory backend default is `qmd`.
4. **Backend selector key**: `memoryBackendType` controls backend selection. 4. **Backend selector key**: `memoryBackendType` controls backend selection.
5. **Toggle gate**: `memoryEnabled: false` disables memory prompt injection regardless of backend type. 5. **Toggle gate**: `memoryEnabled: false` disables memory prompt injection regardless of backend type.
@@ -152,6 +152,12 @@ Route handlers are still file-service based, but operate on OpenClaw-style canon
## 2. OpenClaw Research Findings ## 2. OpenClaw Research Findings
> **Provenance:** OpenClaw / pi-style memory patterns were used as design input. This section documents what Fusion adopted versus what remained conceptual. > **Provenance:** OpenClaw / pi-style memory patterns were used as design input. This section documents what Fusion adopted versus what remained conceptual.
>
> **Update (2026-04-19):** Fusion now uses a layered OpenClaw-style workspace as canonical storage:
> - `.fusion/memory/MEMORY.md` — curated long-term memory
> - `.fusion/memory/YYYY-MM-DD.md` — append-only daily notes
> - `.fusion/memory/DREAMS.md` — synthesized patterns
> - `.fusion/memory.md` — deprecated legacy fallback (migration compatibility only)
### 2.1 OpenClaw Memory Concepts ### 2.1 OpenClaw Memory Concepts
@@ -163,7 +169,7 @@ OpenClaw-style memory emphasizes a layered workspace rather than a single flat f
- Daily notes: `.fusion/memory/YYYY-MM-DD.md` - Daily notes: `.fusion/memory/YYYY-MM-DD.md`
- Dream synthesis: `.fusion/memory/DREAMS.md` - Dream synthesis: `.fusion/memory/DREAMS.md`
Legacy `.fusion/memory.md` is retained only for compatibility/migration paths. Legacy `.fusion/memory.md` is retained only as a deprecated legacy fallback for migration compatibility.
#### 2.1.2 Pluggable backend abstraction #### 2.1.2 Pluggable backend abstraction
@@ -194,7 +200,7 @@ OpenClaw literature often discusses flush-style semantics; Fusion currently uses
| OpenClaw Concept | Fusion Current State | Contract Implication | | OpenClaw Concept | Fusion Current State | Contract Implication |
|-----------------|---------------------|----------------------| |-----------------|---------------------|----------------------|
| Layered memory files | Implemented (`MEMORY.md`, daily files, `DREAMS.md`) | Canonical path model is `.fusion/memory/` workspace, not a single flat file | | Layered memory files | Implemented (`MEMORY.md`, daily files, `DREAMS.md`) | Canonical path model is `.fusion/memory/` workspace, not a single flat file |
| Legacy compatibility | Retained only for migration/alias handling | Keep `.fusion/memory.md` references compatibility-scoped, not canonical | | Legacy compatibility | Retained only as a deprecated migration fallback/alias | Keep `.fusion/memory.md` references compatibility-scoped, not canonical |
| Pluggable backends | Implemented (registry + built-ins) | Contract must document real runtime API (`type`, `capabilities`, `read/write/get/search/exists`) | | Pluggable backends | Implemented (registry + built-ins) | Contract must document real runtime API (`type`, `capabilities`, `read/write/get/search/exists`) |
| QMD backend | Implemented and default | Document `qmd` as default backend and describe qmd→local fallback behavior | | QMD backend | Implemented and default | Document `qmd` as default backend and describe qmd→local fallback behavior |
| Search capability | Implemented (`file` + `qmd`) | Contract search section must match real `search(rootDir, options)` signature and result shape | | Search capability | Implemented (`file` + `qmd`) | Contract search section must match real `search(rootDir, options)` signature and result shape |
@@ -338,7 +344,7 @@ Built-ins are registered at module load:
- Supports: `read`, `write`, `exists`, `get`, `search` - Supports: `read`, `write`, `exists`, `get`, `search`
Legacy compatibility behavior tied to file backend ecosystem: Legacy compatibility behavior tied to file backend ecosystem:
- Legacy `.fusion/memory.md` is retained as a compatibility constant (`LEGACY_MEMORY_FILE_PATH`) - Legacy `.fusion/memory.md` is retained as a deprecated compatibility constant (`LEGACY_MEMORY_FILE_PATH`)
- OpenClaw bootstrap (`ensureOpenClawMemoryFiles`) can seed `MEMORY.md` from legacy file on first migration - OpenClaw bootstrap (`ensureOpenClawMemoryFiles`) can seed `MEMORY.md` from legacy file on first migration
- `get` path normalization recognizes legacy alias paths, but canonical writes remain under `.fusion/memory/` - `get` path normalization recognizes legacy alias paths, but canonical writes remain under `.fusion/memory/`
@@ -403,7 +409,7 @@ Notes:
- Canonical long-term memory path: `.fusion/memory/MEMORY.md` - Canonical long-term memory path: `.fusion/memory/MEMORY.md`
- Canonical workspace root: `.fusion/memory/` - Canonical workspace root: `.fusion/memory/`
- Legacy `.fusion/memory.md` is compatibility-only (migration/alias context) - Legacy `.fusion/memory.md` is a deprecated legacy fallback (migration/alias context)
- There is no persistent dual-write mirror contract in the current runtime API; migration compatibility is handled via bootstrap seeding and legacy path alias handling. - There is no persistent dual-write mirror contract in the current runtime API; migration compatibility is handled via bootstrap seeding and legacy path alias handling.
#### 3.8.2 Return-shape compatibility #### 3.8.2 Return-shape compatibility
@@ -443,11 +449,27 @@ Insights storage remains file-based today:
#### 3.8.6 Must-not-break invariants #### 3.8.6 Must-not-break invariants
1. Memory remains accessible through OpenClaw canonical long-term path (`.fusion/memory/MEMORY.md`) in file-backed flows, and the built-in `file` backend remains available for explicit fallback/use. 1. Memory remains accessible through OpenClaw canonical long-term path (`.fusion/memory/MEMORY.md`) in file-backed flows, and the built-in `file` backend remains available for explicit fallback/use.
2. Legacy `.fusion/memory.md` remains compatibility-only and is not reintroduced as canonical storage. 2. Legacy `.fusion/memory.md` remains a deprecated legacy fallback and is not reintroduced as canonical storage.
3. Instruction behavior is backend-dependent; file backend can include path hints, qmd/readonly do not require one. 3. Instruction behavior is backend-dependent; file backend can include path hints, qmd/readonly do not require one.
4. `memoryEnabled: false` suppresses memory prompt injection regardless of backend type. 4. `memoryEnabled: false` suppresses memory prompt injection regardless of backend type.
5. Read semantics remain stable (`""` for missing working memory, `null` for missing insights memory). 5. Read semantics remain stable (`""` for missing working memory, `null` for missing insights memory).
#### 3.8.7 OpenClaw Layered Memory Layout
Canonical project memory uses a directory-based layout under `.fusion/memory/`:
| File | Purpose | Layer |
|------|---------|-------|
| `.fusion/memory/MEMORY.md` | Curated long-term memory (durable decisions, conventions, pitfalls) | long-term |
| `.fusion/memory/YYYY-MM-DD.md` | Append-only daily notes (running observations, open loops) | daily |
| `.fusion/memory/DREAMS.md` | Synthesized patterns/themes from daily notes | dreams |
| `.fusion/memory.md` | **Deprecated** legacy fallback (migration compatibility only) | legacy |
Migration behavior (`ensureOpenClawMemoryFiles()`):
- When `.fusion/memory/MEMORY.md` does not exist but `.fusion/memory.md` does, legacy content is seeded into the new canonical file
- Once `.fusion/memory/MEMORY.md` exists, canonical writes stay in `.fusion/memory/` (no legacy re-canonicalization)
- Legacy paths may still appear as accepted aliases during transition, but are not canonical storage
--- ---
## 4. Migration Strategy + Compatibility Guardrails ## 4. Migration Strategy + Compatibility Guardrails
@@ -482,7 +504,7 @@ The migration work has already progressed beyond the original FN-1418/FN-1419/FN
| `.fusion/memory/MEMORY.md` | Canonical long-term working memory | Canonical | | `.fusion/memory/MEMORY.md` | Canonical long-term working memory | Canonical |
| `.fusion/memory/YYYY-MM-DD.md` | Daily memory | Canonical layered layout | | `.fusion/memory/YYYY-MM-DD.md` | Daily memory | Canonical layered layout |
| `.fusion/memory/DREAMS.md` | Dream/synthesis memory | Canonical layered layout | | `.fusion/memory/DREAMS.md` | Dream/synthesis memory | Canonical layered layout |
| `.fusion/memory.md` | Legacy compatibility path | Compatibility-only (migration/alias), not canonical | | `.fusion/memory.md` | Deprecated legacy fallback path | Compatibility-only (migration/alias), not canonical |
| `.fusion/memory-insights.md` | Insight extraction output | Preserved | | `.fusion/memory-insights.md` | Insight extraction output | Preserved |
| `.fusion/memory-audit.md` | Extraction audit output | Preserved | | `.fusion/memory-audit.md` | Extraction audit output | Preserved |
@@ -498,7 +520,7 @@ The migration work has already progressed beyond the original FN-1418/FN-1419/FN
### 4.3 Must-Not-Break Invariants ### 4.3 Must-Not-Break Invariants
1. **Canonical layout invariant:** OpenClaw layered memory workspace (`.fusion/memory/`) remains canonical. 1. **Canonical layout invariant:** OpenClaw layered memory workspace (`.fusion/memory/`) remains canonical.
2. **Legacy-path invariant:** `.fusion/memory.md` remains compatibility-only; it must not be reintroduced as primary storage. 2. **Legacy-path invariant:** `.fusion/memory.md` remains a deprecated legacy fallback; it must not be reintroduced as primary storage.
3. **Backend-selection invariant:** Runtime selection uses `memoryBackendType`, with default `qmd`. 3. **Backend-selection invariant:** Runtime selection uses `memoryBackendType`, with default `qmd`.
4. **Prompt-context invariant:** Memory instructions vary by backend type; only `file` backend emits an explicit file path hint. 4. **Prompt-context invariant:** Memory instructions vary by backend type; only `file` backend emits an explicit file path hint.
5. **Read-shape invariant:** Missing working memory resolves to `""`; missing insights memory resolves to `null`. 5. **Read-shape invariant:** Missing working memory resolves to `""`; missing insights memory resolves to `null`.

View File

@@ -410,7 +410,8 @@ Fusion can automatically extract insights from project memory and prune transien
| File | Description | | File | Description |
|------|-------------| |------|-------------|
| `.fusion/memory/MEMORY.md` | Working memory (updated when pruning is applied and validated) | | `.fusion/memory/MEMORY.md` | Long-term memory (updated when pruning is applied and validated) |
| `.fusion/memory.md` | Deprecated legacy fallback (migration compatibility only; not canonical storage) |
| `.fusion/memory-insights.md` | Long-term insights distilled from working memory | | `.fusion/memory-insights.md` | Long-term insights distilled from working memory |
| `.fusion/memory-audit.md` | Human-readable audit report after each extraction | | `.fusion/memory-audit.md` | Human-readable audit report after each extraction |