Skip to content

Commit 9b78935

Browse files
xinhuaguclaude
andauthored
docs: define session/workspace/global memory ownership model (#348)
Audit all memory stores, learning write paths, and persistent state. Classify by scope (session-local, workspace-scoped, global). Document concurrency guarantees, promotion paths, and file layout. Identify follow-up code tasks for CandidateStore partitioning, SkillMetricsStore race, and legacy migration. Closes #347 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d66c927 commit 9b78935

2 files changed

Lines changed: 176 additions & 17 deletions

File tree

docs/memory-ownership.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# Memory Ownership Model
2+
3+
This document defines the memory ownership model for multi-session AceClaw. It classifies every persistent store by scope, documents concurrency guarantees, and identifies follow-up work.
4+
5+
See also: [Multi-Session Model](multi-session.md) for the session/workspace architecture.
6+
7+
## Scope Definitions
8+
9+
| Scope | Lifetime | Shared By | Location |
10+
|-------|----------|-----------|----------|
11+
| **Session-local** | One TUI session | Nothing — fully isolated | `~/.aceclaw/history/{sessionId}.*`, `~/.aceclaw/sessions/`, `~/.aceclaw/checkpoints/` |
12+
| **Workspace-scoped** | Project lifetime | All sessions targeting the same project directory | `~/.aceclaw/workspaces/{hash}/`, `{projectRoot}/.aceclaw/` |
13+
| **Global/user-scoped** | User lifetime | All sessions across all workspaces | `~/.aceclaw/memory/`, `~/.aceclaw/index/`, `~/.aceclaw/skills/` |
14+
15+
## Store Classification
16+
17+
### Session-Local Stores
18+
19+
These stores are fully isolated per session. No multi-session concerns.
20+
21+
| Store | Module | Persistence | Notes |
22+
|-------|--------|-------------|-------|
23+
| `SessionHistoryStore` | daemon | `~/.aceclaw/history/{sessionId}.jsonl` | Conversation messages + snapshot |
24+
| `FilePlanCheckpointStore` | daemon | `~/.aceclaw/checkpoints/{planId}.checkpoint.json` | Plan resume state |
25+
| `ResumeCheckpointStore` | cli | `~/.aceclaw/sessions/{sessionId}-{taskId}.checkpoint.json` | Task resume state |
26+
| `AgentSession` (in-memory) | daemon | Not persisted | Conversation messages, active flag |
27+
| `ErrorDetector` | daemon | Via HistoricalLogIndex | Analyzes current session errors |
28+
| `PatternDetector` | daemon | Via HistoricalLogIndex | Detects patterns in current session |
29+
| `SessionEndExtractor` | daemon | Feeds → AutoMemoryStore | Heuristic extraction at session end |
30+
31+
### Workspace-Scoped Stores
32+
33+
These stores are shared by all sessions targeting the same workspace. Concurrent access is serialized.
34+
35+
| Store | Module | Persistence | Concurrency |
36+
|-------|--------|-------------|-------------|
37+
| `MarkdownMemoryStore` | memory | `~/.aceclaw/workspaces/{hash}/memory/MEMORY.md` + topic files | `ReentrantLock` |
38+
| `DailyJournal` | memory | `~/.aceclaw/workspaces/{hash}/memory/journal/YYYY-MM-DD.md` | `ReentrantLock` |
39+
| `CorrectionRulePromoter` | memory | Writes to workspace `ACECLAW.md` | Via MarkdownMemoryStore lock |
40+
| `LearningExplanationStore` | daemon | `{projectRoot}/.aceclaw/metrics/learning-explanations.jsonl` | `FileChannel.lock()` |
41+
| `LearningValidationStore` | daemon | `{projectRoot}/.aceclaw/metrics/learning-validations.jsonl` | `FileChannel.lock()` |
42+
| `LearningSignalReviewStore` | daemon | `{projectRoot}/.aceclaw/metrics/learning-signal-reviews.jsonl` | `ReentrantLock` + `FileChannel.lock()` |
43+
| `SkillDraftGenerator` | daemon | `{projectRoot}/.aceclaw/skills-drafts/{name}/SKILL.md` | Atomic write (tmp→rename) |
44+
| `SessionSkillPacker` | daemon | `{projectRoot}/.aceclaw/skills-drafts/{name}/SKILL.md` | Atomic write (tmp→rename) |
45+
46+
**Workspace path resolution**: `WorkspacePaths` computes a deterministic hash (`SHA-256`, truncated to 12 hex chars) of the canonical workspace path. All sessions in the same project directory share the same workspace directory.
47+
48+
### Global/User-Scoped Stores
49+
50+
These stores are shared across all workspaces. Most use file-level locking for safety.
51+
52+
| Store | Module | Persistence | Concurrency |
53+
|-------|--------|-------------|-------------|
54+
| `AutoMemoryStore` | memory | `~/.aceclaw/memory/global.jsonl` + per-project files | `ReentrantLock` |
55+
| `CandidateStore` | memory | `~/.aceclaw/memory/candidates.jsonl` | `ReentrantLock`, full rewrite |
56+
| `HistoricalLogIndex` | memory | `~/.aceclaw/index/*.jsonl` | `FileChannel.lock()` on append |
57+
| `SkillMetricsStore` | daemon | `~/.aceclaw/skills/{name}/metrics.json` | Atomic write |
58+
| `SkillRefinementEngine` | daemon | `~/.aceclaw/skills/{name}/` | Atomic write |
59+
60+
## Promotion Paths
61+
62+
Data flows from session-local to durable scopes through defined pipelines:
63+
64+
```
65+
Session-Local Workspace-Scoped Global
66+
───────────── ──────────────── ──────
67+
AgentSession messages
68+
→ SessionEndExtractor ──────→ AutoMemoryStore (project)
69+
→ ErrorDetector ─────────────────────────────────────────→ HistoricalLogIndex
70+
→ PatternDetector ───────────────────────────────────────→ HistoricalLogIndex
71+
72+
AutoMemoryStore (project)
73+
→ MemoryConsolidator ────→ (dedup/prune in place)
74+
→ CrossSessionPatternMiner → AutoMemoryStore
75+
→ StrategyRefiner ───────→ AutoMemoryStore
76+
→ TrendDetector ─────────→ AutoMemoryStore
77+
→ CorrectionRulePromoter → MarkdownMemoryStore
78+
79+
CandidateStore ────────────→ (global candidates)
80+
→ SkillDraftGenerator ──→ workspace skill drafts
81+
→ SkillRefinementEngine → workspace/user skills
82+
```
83+
84+
**Key rule**: Session-local insights become durable memory only through the `SelfImprovementEngine` pipeline, which runs after session close. This avoids mid-conversation writes to shared stores from concurrent sessions.
85+
86+
## Concurrency Guarantees
87+
88+
All stores are safe for multi-session concurrent access:
89+
90+
- **Session-local**: Fully isolated by session ID — no contention possible.
91+
- **Workspace-scoped**: Serialized by `ReentrantLock` or `FileChannel.lock()`. Multiple sessions in the same workspace can safely write concurrently.
92+
- **Global**: Serialized by `ReentrantLock` or `FileChannel.lock()`. The learning pipeline runs after session close, reducing contention.
93+
94+
### Known Limitation: CandidateStore Full-File Rewrite
95+
96+
`CandidateStore` rewrites the entire `candidates.jsonl` file on state transitions. If two sessions transition candidates simultaneously, one write may be lost. This is mitigated by:
97+
- The `ReentrantLock` serializing in-process writes
98+
- State transitions being infrequent (triggered by learning maintenance, not on every turn)
99+
- The candidate state machine being idempotent (re-applying a transition is safe)
100+
101+
**Follow-up**: Consider per-workspace candidate partitioning or CAS-based updates if contention becomes an issue.
102+
103+
## File System Layout
104+
105+
```
106+
~/.aceclaw/
107+
├── memory/ [GLOBAL]
108+
│ ├── memory.key HMAC signing key
109+
│ ├── global.jsonl Cross-project memories
110+
│ ├── candidates.jsonl Learning candidates
111+
│ ├── candidate-transitions.jsonl State transition audit
112+
│ └── archived.jsonl Pruned entries
113+
114+
├── index/ [GLOBAL]
115+
│ ├── tool_invocations.jsonl Tool usage aggregates
116+
│ ├── errors.jsonl Error occurrences
117+
│ └── patterns.jsonl Recurring patterns
118+
119+
├── workspaces/{hash}/ [WORKSPACE]
120+
│ ├── workspace-path.txt Human reference
121+
│ └── memory/
122+
│ ├── MEMORY.md Main workspace memory
123+
│ ├── ACECLAW.md Promoted rules
124+
│ ├── {topic}.md Topic files
125+
│ └── journal/YYYY-MM-DD.md Daily activity
126+
127+
├── history/ [SESSION]
128+
│ ├── {sessionId}.jsonl Conversation history
129+
│ └── {sessionId}.snapshot.json Learning snapshot
130+
131+
├── sessions/ [SESSION]
132+
│ └── {sessionId}-{taskId}.checkpoint.json
133+
134+
├── checkpoints/ [SESSION]
135+
│ └── {planId}.checkpoint.json
136+
137+
├── skills/{name}/ [GLOBAL — user skills]
138+
│ ├── SKILL.md
139+
│ ├── metrics.json
140+
│ └── versions/{v}.SKILL.md
141+
142+
{projectRoot}/.aceclaw/
143+
├── metrics/ [WORKSPACE]
144+
│ ├── learning-explanations.jsonl
145+
│ ├── learning-validations.jsonl
146+
│ └── learning-signal-reviews.jsonl
147+
├── skills/{name}/ [WORKSPACE — project skills]
148+
└── skills-drafts/{name}/SKILL.md [WORKSPACE — drafts]
149+
```
150+
151+
## Follow-Up Code Tasks
152+
153+
1. **CandidateStore partitioning** — Consider per-workspace candidate files to eliminate global rewrite contention (#347-1)
154+
2. **SkillMetricsStore race** — Concurrent sessions updating the same skill's `metrics.json` may race. Consider load-once-per-session with async persist (#347-2)
155+
3. **AutoMemoryStore project file migration** — Legacy `project-{hashCode}.jsonl` format still co-exists with `WorkspacePaths`-based routing. Complete migration to workspace-scoped paths (#347-3)

docs/multi-session.md

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,33 +43,37 @@ Each workspace (project directory) can have at most **one active TUI session** a
4343

4444
## State Model
4545

46+
For a complete classification of every memory store, concurrency guarantees, and promotion paths, see [Memory Ownership Model](memory-ownership.md).
47+
4648
### Session-Local State
4749

4850
Each TUI session owns:
4951

50-
- Conversation messages (chat history)
51-
- Context window contents
52-
- Active tasks and their status
53-
- Resume checkpoints
52+
- Conversation messages (chat history)`SessionHistoryStore`
53+
- Context window contents — in-memory only
54+
- Active tasks and their status`ResumeCheckpointStore`, `FilePlanCheckpointStore`
55+
- Error/pattern detection for current session
5456

55-
### Daemon-Shared State
57+
### Workspace-Shared State
5658

57-
The daemon manages state shared across all sessions:
59+
All sessions targeting the same project directory share:
5860

59-
- Memory stores (auto-memory, markdown memory, candidate state)
60-
- Learning engines (self-improvement, pattern detection, correction rules)
61-
- Cron scheduler and deferred actions
62-
- MCP client connections
63-
- Tool registry and permission manager
64-
- System prompt and model configuration
61+
- Workspace memory — `MarkdownMemoryStore` (MEMORY.md, topic files)
62+
- Daily journal — `DailyJournal`
63+
- Learning metrics — `LearningExplanationStore`, `LearningValidationStore`
64+
- Skill drafts — `SkillDraftGenerator`, `SessionSkillPacker`
65+
- Promoted rules — `CorrectionRulePromoter` → ACECLAW.md
6566

66-
### Workspace-Shared State
67+
### Global/Daemon-Shared State
6768

68-
Some state is shared by all sessions targeting the same workspace:
69+
The daemon manages state shared across all sessions and workspaces:
6970

70-
- Workspace-level memory and skill drafts
71-
- Historical session snapshots
72-
- Resume checkpoint routing (sessions can resume within the same workspace)
71+
- Global memory — `AutoMemoryStore` (global.jsonl)
72+
- Learning candidates — `CandidateStore`
73+
- Historical index — `HistoricalLogIndex`
74+
- User-scoped skills — `SkillMetricsStore`, `SkillRefinementEngine`
75+
- Cron scheduler, deferred actions, MCP clients
76+
- Tool registry, permission manager, system prompt
7377

7478
## Session Identity
7579

0 commit comments

Comments
 (0)