@oyasmi/pipiclaw 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -5
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +156 -57
- package/dist/agent.js.map +1 -1
- package/dist/context.d.ts +18 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +26 -0
- package/dist/context.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/llm-json.d.ts +7 -0
- package/dist/llm-json.d.ts.map +1 -0
- package/dist/llm-json.js +77 -0
- package/dist/llm-json.js.map +1 -0
- package/dist/markdown-sections.d.ts +6 -0
- package/dist/markdown-sections.d.ts.map +1 -0
- package/dist/markdown-sections.js +34 -0
- package/dist/markdown-sections.js.map +1 -0
- package/dist/memory-candidates.d.ts +21 -0
- package/dist/memory-candidates.d.ts.map +1 -0
- package/dist/memory-candidates.js +126 -0
- package/dist/memory-candidates.js.map +1 -0
- package/dist/memory-consolidation.d.ts.map +1 -1
- package/dist/memory-consolidation.js +28 -49
- package/dist/memory-consolidation.js.map +1 -1
- package/dist/memory-files.d.ts +3 -0
- package/dist/memory-files.d.ts.map +1 -1
- package/dist/memory-files.js +51 -0
- package/dist/memory-files.js.map +1 -1
- package/dist/memory-lifecycle.d.ts +9 -0
- package/dist/memory-lifecycle.d.ts.map +1 -1
- package/dist/memory-lifecycle.js +66 -0
- package/dist/memory-lifecycle.js.map +1 -1
- package/dist/memory-recall.d.ts +29 -0
- package/dist/memory-recall.d.ts.map +1 -0
- package/dist/memory-recall.js +218 -0
- package/dist/memory-recall.js.map +1 -0
- package/dist/prompt-builder.d.ts.map +1 -1
- package/dist/prompt-builder.js +7 -2
- package/dist/prompt-builder.js.map +1 -1
- package/dist/session-memory-files.d.ts +2 -0
- package/dist/session-memory-files.d.ts.map +1 -0
- package/dist/session-memory-files.js +2 -0
- package/dist/session-memory-files.js.map +1 -0
- package/dist/session-memory.d.ts +22 -0
- package/dist/session-memory.d.ts.map +1 -0
- package/dist/session-memory.js +274 -0
- package/dist/session-memory.js.map +1 -0
- package/dist/sidecar-worker.d.ts +27 -0
- package/dist/sidecar-worker.d.ts.map +1 -0
- package/dist/sidecar-worker.js +105 -0
- package/dist/sidecar-worker.js.map +1 -0
- package/dist/sub-agents.d.ts +10 -0
- package/dist/sub-agents.d.ts.map +1 -1
- package/dist/sub-agents.js +90 -0
- package/dist/sub-agents.js.map +1 -1
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/subagent.d.ts +6 -0
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +127 -12
- package/dist/tools/subagent.js.map +1 -1
- package/docs/improve-memory/design.md +537 -0
- package/docs/improve-memory/interfaces-and-tests.md +473 -0
- package/docs/improve-memory/spec.md +357 -0
- package/docs/memory-rfc.md +7 -1
- package/docs/proj-review.md +188 -0
- package/docs/test-supplementation-plan.md +553 -0
- package/package.json +3 -1
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
# Pipiclaw Context Upgrade Interfaces And Test Plan
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
This document turns the context-upgrade design into an implementation map:
|
|
6
|
+
|
|
7
|
+
1. interfaces
|
|
8
|
+
2. directory and file layout
|
|
9
|
+
3. phased rollout plan
|
|
10
|
+
4. test checklist
|
|
11
|
+
|
|
12
|
+
## Proposed Files
|
|
13
|
+
|
|
14
|
+
### New Files
|
|
15
|
+
|
|
16
|
+
- `src/memory-candidates.ts`
|
|
17
|
+
- `src/memory-recall.ts`
|
|
18
|
+
- `src/session-memory-files.ts`
|
|
19
|
+
- `src/session-memory.ts`
|
|
20
|
+
- `src/sidecar-worker.ts`
|
|
21
|
+
- `src/skill-hooks.ts`
|
|
22
|
+
|
|
23
|
+
### Existing Files To Modify
|
|
24
|
+
|
|
25
|
+
- [src/agent.ts](/Users/oyasmi/projects/pipiclaw/src/agent.ts)
|
|
26
|
+
- [src/context.ts](/Users/oyasmi/projects/pipiclaw/src/context.ts)
|
|
27
|
+
- [src/prompt-builder.ts](/Users/oyasmi/projects/pipiclaw/src/prompt-builder.ts)
|
|
28
|
+
- [src/memory-files.ts](/Users/oyasmi/projects/pipiclaw/src/memory-files.ts)
|
|
29
|
+
- [src/memory-consolidation.ts](/Users/oyasmi/projects/pipiclaw/src/memory-consolidation.ts)
|
|
30
|
+
- [src/memory-lifecycle.ts](/Users/oyasmi/projects/pipiclaw/src/memory-lifecycle.ts)
|
|
31
|
+
- [src/sub-agents.ts](/Users/oyasmi/projects/pipiclaw/src/sub-agents.ts)
|
|
32
|
+
- [src/tools/subagent.ts](/Users/oyasmi/projects/pipiclaw/src/tools/subagent.ts)
|
|
33
|
+
- [src/config-loader.ts](/Users/oyasmi/projects/pipiclaw/src/config-loader.ts)
|
|
34
|
+
- [src/command-extension.ts](/Users/oyasmi/projects/pipiclaw/src/command-extension.ts)
|
|
35
|
+
- [src/main.ts](/Users/oyasmi/projects/pipiclaw/src/main.ts)
|
|
36
|
+
|
|
37
|
+
## Directory Layout
|
|
38
|
+
|
|
39
|
+
### Channel Workspace
|
|
40
|
+
|
|
41
|
+
Target layout:
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
<channel>/
|
|
45
|
+
├── MEMORY.md
|
|
46
|
+
├── SESSION.md
|
|
47
|
+
├── HISTORY.md
|
|
48
|
+
├── log.jsonl
|
|
49
|
+
├── context.jsonl
|
|
50
|
+
├── scratch/
|
|
51
|
+
└── skills/
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Workspace Root
|
|
55
|
+
|
|
56
|
+
Unchanged plus richer semantics:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
workspace/
|
|
60
|
+
├── SOUL.md
|
|
61
|
+
├── AGENTS.md
|
|
62
|
+
├── MEMORY.md
|
|
63
|
+
├── sub-agents/
|
|
64
|
+
├── skills/
|
|
65
|
+
└── events/
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Interface Sketches
|
|
69
|
+
|
|
70
|
+
### 1. Memory Candidates
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
export interface MemoryCandidate {
|
|
74
|
+
id: string;
|
|
75
|
+
source: "workspace-memory" | "channel-memory" | "channel-session" | "channel-history";
|
|
76
|
+
path: string;
|
|
77
|
+
title: string;
|
|
78
|
+
content: string;
|
|
79
|
+
timestamp?: string;
|
|
80
|
+
sectionKind?: string;
|
|
81
|
+
priority: number;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface BuildMemoryCandidatesOptions {
|
|
85
|
+
workspaceDir: string;
|
|
86
|
+
channelDir: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function buildMemoryCandidates(
|
|
90
|
+
options: BuildMemoryCandidatesOptions,
|
|
91
|
+
): Promise<MemoryCandidate[]>;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Responsibilities:
|
|
95
|
+
|
|
96
|
+
1. read the relevant files
|
|
97
|
+
2. split them into sections/blocks
|
|
98
|
+
3. normalize titles and timestamps
|
|
99
|
+
4. assign coarse priority hints
|
|
100
|
+
|
|
101
|
+
### 2. Memory Recall
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
export interface RecallRequest {
|
|
105
|
+
query: string;
|
|
106
|
+
workspaceDir: string;
|
|
107
|
+
channelDir: string;
|
|
108
|
+
maxCandidates: number;
|
|
109
|
+
maxInjected: number;
|
|
110
|
+
maxChars: number;
|
|
111
|
+
rerankWithModel: boolean;
|
|
112
|
+
model: Model<Api>;
|
|
113
|
+
resolveApiKey: (model: Model<Api>) => Promise<string>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface RecalledMemory {
|
|
117
|
+
source: MemoryCandidate["source"];
|
|
118
|
+
path: string;
|
|
119
|
+
title: string;
|
|
120
|
+
content: string;
|
|
121
|
+
score: number;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface RecallResult {
|
|
125
|
+
items: RecalledMemory[];
|
|
126
|
+
renderedText: string;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export async function recallRelevantMemory(
|
|
130
|
+
request: RecallRequest,
|
|
131
|
+
): Promise<RecallResult>;
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Responsibilities:
|
|
135
|
+
|
|
136
|
+
1. score candidates locally
|
|
137
|
+
2. optionally rerank
|
|
138
|
+
3. apply caps
|
|
139
|
+
4. return rendered prompt block
|
|
140
|
+
|
|
141
|
+
### 3. SESSION.md File Helpers
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
export function getChannelSessionPath(channelDir: string): string;
|
|
145
|
+
export async function ensureChannelSessionFile(channelDir: string): Promise<void>;
|
|
146
|
+
export function ensureChannelSessionFileSync(channelDir: string): void;
|
|
147
|
+
export async function readChannelSession(channelDir: string): Promise<string>;
|
|
148
|
+
export async function rewriteChannelSession(channelDir: string, content: string): Promise<void>;
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
These should mirror existing `memory-files.ts` conventions.
|
|
152
|
+
|
|
153
|
+
### 4. Session Memory Structure
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
export interface SessionMemoryState {
|
|
157
|
+
title: string;
|
|
158
|
+
currentState: string[];
|
|
159
|
+
userIntent: string[];
|
|
160
|
+
activeFiles: string[];
|
|
161
|
+
decisions: string[];
|
|
162
|
+
constraints: string[];
|
|
163
|
+
errorsAndCorrections: string[];
|
|
164
|
+
nextSteps: string[];
|
|
165
|
+
worklog: string[];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface SessionMemoryUpdateOptions {
|
|
169
|
+
channelDir: string;
|
|
170
|
+
messages: AgentMessage[];
|
|
171
|
+
model: Model<Api>;
|
|
172
|
+
resolveApiKey: (model: Model<Api>) => Promise<string>;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export async function updateChannelSessionMemory(
|
|
176
|
+
options: SessionMemoryUpdateOptions,
|
|
177
|
+
): Promise<SessionMemoryState>;
|
|
178
|
+
|
|
179
|
+
export function renderSessionMemory(state: SessionMemoryState): string;
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 5. Sidecar Worker
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
export interface SidecarTask<T> {
|
|
186
|
+
name: string;
|
|
187
|
+
model: Model<Api>;
|
|
188
|
+
resolveApiKey: (model: Model<Api>) => Promise<string>;
|
|
189
|
+
systemPrompt: string;
|
|
190
|
+
prompt: string;
|
|
191
|
+
parse: (text: string) => T;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface SidecarResult<T> {
|
|
195
|
+
output: T;
|
|
196
|
+
rawText: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export async function runSidecarTask<T>(task: SidecarTask<T>): Promise<SidecarResult<T>>;
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### 6. Settings
|
|
203
|
+
|
|
204
|
+
Extend [src/context.ts](/Users/oyasmi/projects/pipiclaw/src/context.ts) settings:
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
export interface PipiclawMemoryRecallSettings {
|
|
208
|
+
enabled: boolean;
|
|
209
|
+
maxCandidates: number;
|
|
210
|
+
maxInjected: number;
|
|
211
|
+
maxChars: number;
|
|
212
|
+
rerankWithModel: boolean;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export interface PipiclawSessionMemorySettings {
|
|
216
|
+
enabled: boolean;
|
|
217
|
+
minTurnsBetweenUpdate: number;
|
|
218
|
+
minToolCallsBetweenUpdate: number;
|
|
219
|
+
forceRefreshBeforeCompact: boolean;
|
|
220
|
+
forceRefreshBeforeNewSession: boolean;
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### 7. Sub-Agent Frontmatter Extensions
|
|
225
|
+
|
|
226
|
+
Extend [src/sub-agents.ts](/Users/oyasmi/projects/pipiclaw/src/sub-agents.ts):
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
export interface SubAgentConfig {
|
|
230
|
+
// existing fields...
|
|
231
|
+
contextMode?: "isolated" | "contextual";
|
|
232
|
+
memory?: "none" | "relevant" | "session" | "channel";
|
|
233
|
+
paths?: string[];
|
|
234
|
+
thinkingLevel?: "off" | "minimal" | "low" | "medium" | "high";
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Behavior:
|
|
239
|
+
|
|
240
|
+
1. preserve current behavior when omitted
|
|
241
|
+
2. only enrich context when explicitly configured
|
|
242
|
+
|
|
243
|
+
### 8. Skill Frontmatter Extensions
|
|
244
|
+
|
|
245
|
+
Introduce parsing support for:
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
export interface PipiclawSkillMeta {
|
|
249
|
+
name?: string;
|
|
250
|
+
description?: string;
|
|
251
|
+
whenToUse?: string;
|
|
252
|
+
allowedTools?: string[];
|
|
253
|
+
paths?: string[];
|
|
254
|
+
hooks?: {
|
|
255
|
+
before_prompt?: string[];
|
|
256
|
+
after_response?: string[];
|
|
257
|
+
before_compact?: string[];
|
|
258
|
+
after_subagent?: string[];
|
|
259
|
+
};
|
|
260
|
+
memoryScope?: "none" | "relevant" | "session";
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Integration Map
|
|
265
|
+
|
|
266
|
+
### ChannelRunner
|
|
267
|
+
|
|
268
|
+
Update [src/agent.ts](/Users/oyasmi/projects/pipiclaw/src/agent.ts):
|
|
269
|
+
|
|
270
|
+
1. before `session.prompt()`, call `recallRelevantMemory()`
|
|
271
|
+
2. inject `renderedText` into the prompt if non-empty
|
|
272
|
+
3. after final turn, queue `SESSION.md` maintenance when thresholds are met
|
|
273
|
+
4. before session resource reload or switches, ensure session-memory hooks are respected
|
|
274
|
+
|
|
275
|
+
### MemoryLifecycle
|
|
276
|
+
|
|
277
|
+
Update [src/memory-lifecycle.ts](/Users/oyasmi/projects/pipiclaw/src/memory-lifecycle.ts):
|
|
278
|
+
|
|
279
|
+
1. before compact, refresh `SESSION.md`, then durable consolidation
|
|
280
|
+
2. before new-session switch, refresh `SESSION.md`, then durable consolidation
|
|
281
|
+
3. background maintenance expands to:
|
|
282
|
+
- cleanup `MEMORY.md`
|
|
283
|
+
- fold `HISTORY.md`
|
|
284
|
+
- optionally trim stale `SESSION.md` sections
|
|
285
|
+
|
|
286
|
+
### Memory Consolidation
|
|
287
|
+
|
|
288
|
+
Update [src/memory-consolidation.ts](/Users/oyasmi/projects/pipiclaw/src/memory-consolidation.ts):
|
|
289
|
+
|
|
290
|
+
1. read current `SESSION.md` as an additional input
|
|
291
|
+
2. use it when deciding what belongs in durable memory versus active session state
|
|
292
|
+
3. keep append-first behavior for `MEMORY.md`, but allow cleanup to remove transient state
|
|
293
|
+
|
|
294
|
+
### Memory File Bootstrap
|
|
295
|
+
|
|
296
|
+
Update [src/memory-files.ts](/Users/oyasmi/projects/pipiclaw/src/memory-files.ts) and [src/main.ts](/Users/oyasmi/projects/pipiclaw/src/main.ts):
|
|
297
|
+
|
|
298
|
+
1. ensure `SESSION.md` exists wherever channel memory files are created
|
|
299
|
+
2. document it in the bootstrap-generated workspace model
|
|
300
|
+
3. preserve compatibility for channel dirs created before this upgrade
|
|
301
|
+
|
|
302
|
+
### Prompt Builder
|
|
303
|
+
|
|
304
|
+
Update [src/prompt-builder.ts](/Users/oyasmi/projects/pipiclaw/src/prompt-builder.ts):
|
|
305
|
+
|
|
306
|
+
1. include `SESSION.md` in workspace layout and memory rules
|
|
307
|
+
2. explain that memory files are not preloaded wholesale
|
|
308
|
+
3. explain that runtime may inject relevant memory snippets automatically
|
|
309
|
+
|
|
310
|
+
## Phased Rollout
|
|
311
|
+
|
|
312
|
+
### Phase 0: Relevant Memory Recall
|
|
313
|
+
|
|
314
|
+
Deliverables:
|
|
315
|
+
|
|
316
|
+
1. candidate builder
|
|
317
|
+
2. recall scoring
|
|
318
|
+
3. injected runtime context block
|
|
319
|
+
4. settings toggles
|
|
320
|
+
|
|
321
|
+
Success criteria:
|
|
322
|
+
|
|
323
|
+
1. turns involving prior channel context use the right memory more often
|
|
324
|
+
2. no noticeable latency spike for common turns
|
|
325
|
+
3. no huge prompt bloat
|
|
326
|
+
|
|
327
|
+
### Phase 1: SESSION.md
|
|
328
|
+
|
|
329
|
+
Deliverables:
|
|
330
|
+
|
|
331
|
+
1. `SESSION.md` file lifecycle
|
|
332
|
+
2. session updater
|
|
333
|
+
3. background thresholds
|
|
334
|
+
4. prompt-builder documentation
|
|
335
|
+
|
|
336
|
+
Success criteria:
|
|
337
|
+
|
|
338
|
+
1. current work state survives `/new`
|
|
339
|
+
2. current work state survives compaction better
|
|
340
|
+
3. `MEMORY.md` stops absorbing excessive transient detail
|
|
341
|
+
|
|
342
|
+
### Phase 1.5: Compaction Bridge
|
|
343
|
+
|
|
344
|
+
Deliverables:
|
|
345
|
+
|
|
346
|
+
1. pre-compaction session refresh
|
|
347
|
+
2. durable consolidation informed by `SESSION.md`
|
|
348
|
+
3. fallback semantics
|
|
349
|
+
|
|
350
|
+
Success criteria:
|
|
351
|
+
|
|
352
|
+
1. fewer "forgot what we were doing" failures after compaction
|
|
353
|
+
2. no brittle dependency on background maintenance
|
|
354
|
+
|
|
355
|
+
### Phase 2: Contextual Sub-Agents
|
|
356
|
+
|
|
357
|
+
Deliverables:
|
|
358
|
+
|
|
359
|
+
1. `contextMode`
|
|
360
|
+
2. `memory` scope
|
|
361
|
+
3. recall-aware task preamble for sub-agents
|
|
362
|
+
|
|
363
|
+
Success criteria:
|
|
364
|
+
|
|
365
|
+
1. sub-agents require less hand-written context
|
|
366
|
+
2. review and research agents produce better results on long-running channels
|
|
367
|
+
|
|
368
|
+
### Phase 3: Skill Metadata And Hooks
|
|
369
|
+
|
|
370
|
+
Deliverables:
|
|
371
|
+
|
|
372
|
+
1. richer frontmatter
|
|
373
|
+
2. lightweight lifecycle hooks
|
|
374
|
+
3. optional memory scope shaping
|
|
375
|
+
|
|
376
|
+
Success criteria:
|
|
377
|
+
|
|
378
|
+
1. skills become better aligned with channel context
|
|
379
|
+
2. skill-triggered behavior remains understandable and debuggable
|
|
380
|
+
|
|
381
|
+
## Test Plan
|
|
382
|
+
|
|
383
|
+
### Phase 0 Unit Tests
|
|
384
|
+
|
|
385
|
+
1. splits `MEMORY.md`, `SESSION.md`, and `HISTORY.md` into stable candidates
|
|
386
|
+
2. ranks session-current-state above old history for matching queries
|
|
387
|
+
3. respects max item and max char budgets
|
|
388
|
+
4. produces empty injection when nothing is relevant
|
|
389
|
+
5. handles malformed or missing files gracefully
|
|
390
|
+
|
|
391
|
+
### Phase 0 Integration Tests
|
|
392
|
+
|
|
393
|
+
1. injected memory block appears before the user message in debug prompt output
|
|
394
|
+
2. unrelated turns do not receive noisy memory injection
|
|
395
|
+
3. recall remains stable when channel files are empty
|
|
396
|
+
|
|
397
|
+
### Phase 1 Unit Tests
|
|
398
|
+
|
|
399
|
+
1. `ensureChannelSessionFile*()` creates the default template
|
|
400
|
+
2. `renderSessionMemory()` is deterministic
|
|
401
|
+
3. updater preserves section boundaries
|
|
402
|
+
4. updater truncates oversized sections
|
|
403
|
+
5. updater can render an effectively empty but valid session file
|
|
404
|
+
|
|
405
|
+
### Phase 1 Integration Tests
|
|
406
|
+
|
|
407
|
+
1. a normal coding turn updates `SESSION.md`
|
|
408
|
+
2. a steer/follow-up updates `SESSION.md`
|
|
409
|
+
3. `/new` keeps `SESSION.md` intact for the channel
|
|
410
|
+
4. existing `MEMORY.md` / `HISTORY.md` behavior continues to work
|
|
411
|
+
5. an old channel directory without `SESSION.md` is repaired automatically
|
|
412
|
+
|
|
413
|
+
### Phase 1.5 Unit Tests
|
|
414
|
+
|
|
415
|
+
1. pre-compaction refresh is invoked before durable consolidation
|
|
416
|
+
2. durable consolidation receives `SESSION.md` as input
|
|
417
|
+
3. fallback uses last persisted `SESSION.md` when refresh fails
|
|
418
|
+
4. cleanup can remove transient content from `MEMORY.md`
|
|
419
|
+
|
|
420
|
+
### Phase 1.5 Integration Tests
|
|
421
|
+
|
|
422
|
+
1. compaction followed by another turn still remembers current work
|
|
423
|
+
2. new session after compaction still recovers current state
|
|
424
|
+
3. failure in the updater does not crash the run loop
|
|
425
|
+
4. fallback works when `SESSION.md` was missing before the first compaction
|
|
426
|
+
|
|
427
|
+
### Phase 2 Unit Tests
|
|
428
|
+
|
|
429
|
+
1. sub-agent config parses `contextMode` and `memory`
|
|
430
|
+
2. isolated sub-agents retain current behavior
|
|
431
|
+
3. contextual sub-agents receive bounded relevant memory preamble
|
|
432
|
+
|
|
433
|
+
### Phase 2 Integration Tests
|
|
434
|
+
|
|
435
|
+
1. reviewer sub-agent sees the right open loop without the parent hand-copying it
|
|
436
|
+
2. simple sub-agents do not get unnecessary memory noise
|
|
437
|
+
|
|
438
|
+
### Phase 3 Unit Tests
|
|
439
|
+
|
|
440
|
+
1. skill frontmatter parsing handles new fields
|
|
441
|
+
2. invalid hook declarations are rejected cleanly
|
|
442
|
+
3. hook registration stays session-scoped
|
|
443
|
+
|
|
444
|
+
### Phase 3 Integration Tests
|
|
445
|
+
|
|
446
|
+
1. a skill with `before_compact` hook runs in the expected lifecycle
|
|
447
|
+
2. a skill with `memoryScope=relevant` shapes prompt preparation predictably
|
|
448
|
+
|
|
449
|
+
## Manual Validation Checklist
|
|
450
|
+
|
|
451
|
+
1. Start a fresh channel and confirm `SESSION.md` is created.
|
|
452
|
+
2. Run a multi-step coding task and confirm `SESSION.md` tracks active files and next steps.
|
|
453
|
+
3. Trigger `/compact` and confirm current work state survives.
|
|
454
|
+
4. Trigger `/new` and confirm channel working state survives but raw session history resets as expected.
|
|
455
|
+
5. Use a contextual sub-agent and verify it inherits relevant channel state without seeing the full parent transcript.
|
|
456
|
+
6. Confirm `MEMORY.md` remains concise and durable after repeated work cycles.
|
|
457
|
+
7. Confirm `HISTORY.md` remains chronological and non-transcript-like.
|
|
458
|
+
8. Restart the process mid-task and confirm the next turn recovers state primarily from `SESSION.md`.
|
|
459
|
+
9. Test an older pre-upgrade channel directory and confirm migration is silent and non-destructive.
|
|
460
|
+
|
|
461
|
+
## Open Questions To Resolve During Implementation
|
|
462
|
+
|
|
463
|
+
1. Should `SESSION.md` keep blank stable sections, or omit empty sections for brevity?
|
|
464
|
+
2. Should recall injection be visible in `last_prompt.json` as a separate field for debugging?
|
|
465
|
+
3. Should `SESSION.md` cleanup run only during background maintenance, or also during forced refresh?
|
|
466
|
+
4. At what point should `MEMORY.md` cleanup become allowed to remove historical transient content aggressively?
|
|
467
|
+
|
|
468
|
+
The recommended default is:
|
|
469
|
+
|
|
470
|
+
1. deterministic rendering
|
|
471
|
+
2. visible debug output
|
|
472
|
+
3. cleanup in background plus light normalization in forced refresh
|
|
473
|
+
4. conservative cleanup first, then more aggressive pruning only after observing real channels
|