@prmichaelsen/remember-mcp 2.3.1 → 2.3.4
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/AGENT.md +20 -2
- package/CHANGELOG.md +27 -0
- package/agent/commands/acp.commit.md +511 -0
- package/agent/design/comment-memory-type.md +556 -0
- package/agent/design/unified-public-collection.md +545 -0
- package/agent/progress.yaml +26 -0
- package/agent/scripts/install.sh +25 -1
- package/agent/scripts/update.sh +37 -0
- package/dist/server-factory.js +6 -6
- package/dist/server.js +6 -6
- package/package.json +1 -1
- package/src/tools/confirm.ts +8 -6
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
# Unified Public Collection Architecture
|
|
2
|
+
|
|
3
|
+
**Concept**: Single `Memory_public` collection for all public spaces with multi-space support
|
|
4
|
+
**Created**: 2026-02-16
|
|
5
|
+
**Status**: Design Proposal
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
This design proposes replacing per-space collections (`Memory_the_void`, `Memory_dogs`, etc.) with a unified `Memory_public` collection where memories can belong to multiple spaces simultaneously. This enables multi-space search, eliminates duplication, and provides a more flexible and scalable architecture.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Problem Statement
|
|
16
|
+
|
|
17
|
+
### Current Architecture Limitations
|
|
18
|
+
|
|
19
|
+
**Per-Space Collections** (Current):
|
|
20
|
+
```
|
|
21
|
+
Memory_the_void → Only "The Void" memories
|
|
22
|
+
Memory_dogs → Only "Dogs" space memories
|
|
23
|
+
Memory_cats → Only "Cats" space memories
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Problems**:
|
|
27
|
+
1. **No Multi-Space Search**: Users can't search across multiple spaces in one query
|
|
28
|
+
- "Search the void and dogs for cute dog pictures" requires two separate queries
|
|
29
|
+
- Results must be merged manually
|
|
30
|
+
- Poor user experience
|
|
31
|
+
|
|
32
|
+
2. **Memory Duplication**: Publishing to multiple spaces creates copies
|
|
33
|
+
- Same memory stored multiple times
|
|
34
|
+
- Wastes storage
|
|
35
|
+
- Updates must be synchronized across copies
|
|
36
|
+
- Inconsistency risk
|
|
37
|
+
|
|
38
|
+
3. **Collection Proliferation**: Each new space requires a new collection
|
|
39
|
+
- Hundreds of collections for popular spaces
|
|
40
|
+
- Management overhead
|
|
41
|
+
- Weaviate resource usage
|
|
42
|
+
|
|
43
|
+
4. **Inflexible**: Can't easily add/remove spaces from a memory
|
|
44
|
+
- Must delete and recreate
|
|
45
|
+
- Loses discovery metrics
|
|
46
|
+
- Complex workflow
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Solution: Unified Public Collection
|
|
51
|
+
|
|
52
|
+
### Architecture
|
|
53
|
+
|
|
54
|
+
**Single Public Collection**:
|
|
55
|
+
```
|
|
56
|
+
Memory_public → ALL public space memories
|
|
57
|
+
Properties:
|
|
58
|
+
- spaces: ["the_void"] ← Single space
|
|
59
|
+
- spaces: ["dogs", "cats"] ← Multiple spaces
|
|
60
|
+
- spaces: ["the_void", "dogs"] ← Cross-space
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Key Changes**:
|
|
64
|
+
1. `space_id: string` → `spaces: string[]` (array of space IDs)
|
|
65
|
+
2. Single collection `Memory_public` instead of per-space collections
|
|
66
|
+
3. Filter by spaces array for targeted search
|
|
67
|
+
4. Publish to multiple spaces in one operation
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Benefits
|
|
72
|
+
|
|
73
|
+
### 1. Multi-Space Search
|
|
74
|
+
|
|
75
|
+
**User Request**: "Search the void and dogs for cute dog pictures"
|
|
76
|
+
|
|
77
|
+
**Current** (Requires 2 queries):
|
|
78
|
+
```typescript
|
|
79
|
+
// Query 1
|
|
80
|
+
remember_search_space({ space: "the_void", query: "cute dog pictures" })
|
|
81
|
+
// Query 2
|
|
82
|
+
remember_search_space({ space: "dogs", query: "cute dog pictures" })
|
|
83
|
+
// Merge results manually
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Proposed** (Single query):
|
|
87
|
+
```typescript
|
|
88
|
+
remember_search_space({
|
|
89
|
+
spaces: ["the_void", "dogs"], // ✅ Multiple spaces!
|
|
90
|
+
query: "cute dog pictures"
|
|
91
|
+
})
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 2. No Duplication
|
|
95
|
+
|
|
96
|
+
**Current**: Publish to 3 spaces = 3 copies
|
|
97
|
+
```
|
|
98
|
+
Memory_the_void/abc123 ← Copy 1
|
|
99
|
+
Memory_dogs/abc123 ← Copy 2
|
|
100
|
+
Memory_cats/abc123 ← Copy 3
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Proposed**: Publish to 3 spaces = 1 memory
|
|
104
|
+
```
|
|
105
|
+
Memory_public/abc123
|
|
106
|
+
spaces: ["the_void", "dogs", "cats"] ← One memory, three spaces!
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 3. Efficient Storage
|
|
110
|
+
|
|
111
|
+
- **Current**: N spaces × M memories = N×M documents
|
|
112
|
+
- **Proposed**: M memories (regardless of spaces)
|
|
113
|
+
- **Savings**: Up to N× reduction in storage
|
|
114
|
+
|
|
115
|
+
### 4. Flexible Space Management
|
|
116
|
+
|
|
117
|
+
**Add Space**:
|
|
118
|
+
```typescript
|
|
119
|
+
// Just update the spaces array
|
|
120
|
+
updateMemory({
|
|
121
|
+
id: "abc123",
|
|
122
|
+
spaces: [...existingSpaces, "new_space"]
|
|
123
|
+
})
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Remove Space**:
|
|
127
|
+
```typescript
|
|
128
|
+
// Just filter the spaces array
|
|
129
|
+
updateMemory({
|
|
130
|
+
id: "abc123",
|
|
131
|
+
spaces: existingSpaces.filter(s => s !== "old_space")
|
|
132
|
+
})
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 5. Simpler Architecture
|
|
136
|
+
|
|
137
|
+
- **Current**: Manage N collections
|
|
138
|
+
- **Proposed**: Manage 1 collection
|
|
139
|
+
- **Benefit**: Simpler code, easier maintenance
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Implementation
|
|
144
|
+
|
|
145
|
+
### Type Changes
|
|
146
|
+
|
|
147
|
+
**Before** (`src/types/space-memory.ts`):
|
|
148
|
+
```typescript
|
|
149
|
+
export interface SpaceMemory extends Omit<Memory, 'user_id' | 'doc_type'> {
|
|
150
|
+
space_id: string; // ❌ Single space
|
|
151
|
+
author_id: string;
|
|
152
|
+
// ...
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**After**:
|
|
157
|
+
```typescript
|
|
158
|
+
export interface SpaceMemory extends Omit<Memory, 'user_id' | 'doc_type'> {
|
|
159
|
+
spaces: string[]; // ✅ Multiple spaces!
|
|
160
|
+
author_id: string;
|
|
161
|
+
// ...
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Schema Changes
|
|
166
|
+
|
|
167
|
+
**Before** (`src/weaviate/space-schema.ts`):
|
|
168
|
+
```typescript
|
|
169
|
+
// Create separate collection for each space
|
|
170
|
+
export function getSpaceCollectionName(spaceId: string): string {
|
|
171
|
+
return `Memory_${spaceId}`; // Memory_the_void, Memory_dogs, etc.
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**After**:
|
|
176
|
+
```typescript
|
|
177
|
+
// Single public collection
|
|
178
|
+
export const PUBLIC_COLLECTION_NAME = 'Memory_public';
|
|
179
|
+
|
|
180
|
+
export function ensurePublicCollection(client: WeaviateClient): Promise<Collection> {
|
|
181
|
+
return ensureCollection(client, PUBLIC_COLLECTION_NAME);
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Schema Properties**:
|
|
186
|
+
```typescript
|
|
187
|
+
{
|
|
188
|
+
name: 'spaces',
|
|
189
|
+
dataType: 'text[]' as any, // ✅ Array of space IDs
|
|
190
|
+
description: 'Spaces this memory is published to (e.g., ["the_void", "dogs"])',
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Tool Changes
|
|
195
|
+
|
|
196
|
+
#### remember_publish
|
|
197
|
+
|
|
198
|
+
**Before**:
|
|
199
|
+
```typescript
|
|
200
|
+
{
|
|
201
|
+
target: {
|
|
202
|
+
type: 'string',
|
|
203
|
+
enum: ['the_void'], // Single space
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**After**:
|
|
209
|
+
```typescript
|
|
210
|
+
{
|
|
211
|
+
spaces: {
|
|
212
|
+
type: 'array',
|
|
213
|
+
items: {
|
|
214
|
+
type: 'string',
|
|
215
|
+
enum: SUPPORTED_SPACES // Multiple spaces!
|
|
216
|
+
},
|
|
217
|
+
description: 'Spaces to publish to (e.g., ["the_void", "dogs"])',
|
|
218
|
+
minItems: 1,
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
#### remember_search_space
|
|
224
|
+
|
|
225
|
+
**Before**:
|
|
226
|
+
```typescript
|
|
227
|
+
{
|
|
228
|
+
space: {
|
|
229
|
+
type: 'string',
|
|
230
|
+
enum: ['the_void'], // Single space
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**After**:
|
|
236
|
+
```typescript
|
|
237
|
+
{
|
|
238
|
+
spaces: {
|
|
239
|
+
type: 'array',
|
|
240
|
+
items: {
|
|
241
|
+
type: 'string',
|
|
242
|
+
enum: SUPPORTED_SPACES
|
|
243
|
+
},
|
|
244
|
+
description: 'Spaces to search (e.g., ["the_void", "dogs"])',
|
|
245
|
+
minItems: 1,
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Filter Logic**:
|
|
251
|
+
```typescript
|
|
252
|
+
// Weaviate filter: memory.spaces contains ANY of the requested spaces
|
|
253
|
+
collection.filter
|
|
254
|
+
.byProperty('spaces')
|
|
255
|
+
.containsAny(requestedSpaces)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### remember_query_space
|
|
259
|
+
|
|
260
|
+
Same changes as `remember_search_space`.
|
|
261
|
+
|
|
262
|
+
### Confirmation Flow Changes
|
|
263
|
+
|
|
264
|
+
**Before** (`src/tools/confirm.ts`):
|
|
265
|
+
```typescript
|
|
266
|
+
const targetCollection = await ensureSpaceCollection(
|
|
267
|
+
weaviateClient,
|
|
268
|
+
request.target_collection || 'the_void'
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
const publishedMemory = {
|
|
272
|
+
...originalMemory.properties,
|
|
273
|
+
space_id: request.target_collection || 'the_void',
|
|
274
|
+
// ...
|
|
275
|
+
};
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**After**:
|
|
279
|
+
```typescript
|
|
280
|
+
const publicCollection = await ensurePublicCollection(weaviateClient);
|
|
281
|
+
|
|
282
|
+
const publishedMemory = {
|
|
283
|
+
...originalMemory.properties,
|
|
284
|
+
spaces: request.spaces || ['the_void'], // ✅ Array!
|
|
285
|
+
// ...
|
|
286
|
+
};
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Migration Strategy
|
|
292
|
+
|
|
293
|
+
### Phase 1: Add Support (Backward Compatible)
|
|
294
|
+
|
|
295
|
+
1. **Add `spaces` field** to SpaceMemory type (keep `space_id` for now)
|
|
296
|
+
2. **Support both** `space` and `spaces` parameters in tools
|
|
297
|
+
3. **Create `Memory_public`** collection alongside existing collections
|
|
298
|
+
4. **Dual-write**: Publish to both old and new collections
|
|
299
|
+
|
|
300
|
+
### Phase 2: Migrate Data
|
|
301
|
+
|
|
302
|
+
1. **Copy existing memories** from per-space collections to `Memory_public`
|
|
303
|
+
2. **Set `spaces` array** based on source collection
|
|
304
|
+
3. **Verify data integrity**
|
|
305
|
+
|
|
306
|
+
### Phase 3: Deprecate Old Collections
|
|
307
|
+
|
|
308
|
+
1. **Update tools** to use only `spaces` parameter
|
|
309
|
+
2. **Remove `space_id` field** from types
|
|
310
|
+
3. **Delete old collections**: `Memory_the_void`, etc.
|
|
311
|
+
4. **Update documentation**
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Trade-offs
|
|
316
|
+
|
|
317
|
+
### Pros
|
|
318
|
+
|
|
319
|
+
✅ **Multi-space search**: Single query across multiple spaces
|
|
320
|
+
✅ **No duplication**: One memory, multiple spaces
|
|
321
|
+
✅ **Efficient storage**: N× reduction in documents
|
|
322
|
+
✅ **Flexible**: Easy to add/remove spaces
|
|
323
|
+
✅ **Simpler**: One collection vs. many
|
|
324
|
+
✅ **Scalable**: Handles thousands of spaces
|
|
325
|
+
✅ **Better UX**: Natural multi-space queries
|
|
326
|
+
|
|
327
|
+
### Cons
|
|
328
|
+
|
|
329
|
+
❌ **Migration complexity**: Must migrate existing data
|
|
330
|
+
❌ **Breaking change**: API changes required
|
|
331
|
+
❌ **Lost isolation**: All public spaces share collection
|
|
332
|
+
❌ **Security considerations**: Can't have per-space access control at collection level
|
|
333
|
+
❌ **Schema constraints**: All spaces must use same schema
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Security Considerations
|
|
338
|
+
|
|
339
|
+
### Access Control
|
|
340
|
+
|
|
341
|
+
**Current**: Per-space collections enable collection-level access control
|
|
342
|
+
```
|
|
343
|
+
Memory_the_void → Public read access
|
|
344
|
+
Memory_private → Restricted access
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**Proposed**: Document-level access control via `spaces` field
|
|
348
|
+
```
|
|
349
|
+
Memory_public
|
|
350
|
+
- spaces: ["the_void"] → Public
|
|
351
|
+
- spaces: ["private_123"] → Restricted (filter by user)
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**Solution**: Separate collections for different access levels
|
|
355
|
+
```
|
|
356
|
+
Memory_public → Public spaces (the_void, dogs, cats)
|
|
357
|
+
Memory_shared → User-shared spaces (family, work)
|
|
358
|
+
Memory_private → Private spaces (personal)
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Space Validation
|
|
362
|
+
|
|
363
|
+
**Prevent unauthorized space access**:
|
|
364
|
+
```typescript
|
|
365
|
+
// Validate user can publish to requested spaces
|
|
366
|
+
const allowedSpaces = await getAuthorizedSpaces(userId);
|
|
367
|
+
const requestedSpaces = args.spaces;
|
|
368
|
+
|
|
369
|
+
if (!requestedSpaces.every(s => allowedSpaces.includes(s))) {
|
|
370
|
+
throw new Error('Unauthorized space access');
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## Examples
|
|
377
|
+
|
|
378
|
+
### Example 1: Publish to Multiple Spaces
|
|
379
|
+
|
|
380
|
+
**Request**:
|
|
381
|
+
```typescript
|
|
382
|
+
remember_publish({
|
|
383
|
+
memory_id: "abc123",
|
|
384
|
+
spaces: ["the_void", "dogs", "cute_animals"]
|
|
385
|
+
})
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Result**:
|
|
389
|
+
```json
|
|
390
|
+
{
|
|
391
|
+
"success": true,
|
|
392
|
+
"token": "xyz789"
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**After Confirmation**:
|
|
397
|
+
```typescript
|
|
398
|
+
// Memory in Memory_public collection
|
|
399
|
+
{
|
|
400
|
+
"id": "new-id",
|
|
401
|
+
"spaces": ["the_void", "dogs", "cute_animals"],
|
|
402
|
+
"author_id": "user123",
|
|
403
|
+
"content": "My dog is so cute!",
|
|
404
|
+
"doc_type": "space_memory"
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Example 2: Multi-Space Search
|
|
409
|
+
|
|
410
|
+
**Request**:
|
|
411
|
+
```typescript
|
|
412
|
+
remember_search_space({
|
|
413
|
+
spaces: ["the_void", "dogs"],
|
|
414
|
+
query: "cute dog pictures",
|
|
415
|
+
limit: 10
|
|
416
|
+
})
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
**Weaviate Query**:
|
|
420
|
+
```typescript
|
|
421
|
+
collection
|
|
422
|
+
.query
|
|
423
|
+
.hybrid(query, { alpha: 0.5 })
|
|
424
|
+
.filter(
|
|
425
|
+
Filters.or(
|
|
426
|
+
collection.filter.byProperty('spaces').containsAny(['the_void', 'dogs'])
|
|
427
|
+
)
|
|
428
|
+
)
|
|
429
|
+
.limit(10)
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Result**: Memories from both "The Void" and "Dogs" spaces
|
|
433
|
+
|
|
434
|
+
### Example 3: Add Space to Existing Memory
|
|
435
|
+
|
|
436
|
+
**Request**:
|
|
437
|
+
```typescript
|
|
438
|
+
remember_update_memory({
|
|
439
|
+
memory_id: "abc123",
|
|
440
|
+
spaces: [...existingSpaces, "new_space"]
|
|
441
|
+
})
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
**Result**: Memory now appears in additional space
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Alternatives Considered
|
|
449
|
+
|
|
450
|
+
### Alternative 1: Keep Per-Space Collections
|
|
451
|
+
|
|
452
|
+
**Pros**: Isolation, per-space schemas
|
|
453
|
+
**Cons**: All the problems listed above
|
|
454
|
+
**Verdict**: ❌ Doesn't solve multi-space search
|
|
455
|
+
|
|
456
|
+
### Alternative 2: Hybrid Approach
|
|
457
|
+
|
|
458
|
+
**Architecture**:
|
|
459
|
+
```
|
|
460
|
+
Memory_public → General public spaces
|
|
461
|
+
Memory_private_123 → User's private spaces
|
|
462
|
+
Memory_the_void → Special "The Void" space (isolated)
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
**Pros**: Flexibility, isolation where needed
|
|
466
|
+
**Cons**: Complexity, inconsistent architecture
|
|
467
|
+
**Verdict**: ⚠️ Consider if security requires it
|
|
468
|
+
|
|
469
|
+
### Alternative 3: Space as Tag
|
|
470
|
+
|
|
471
|
+
**Architecture**: Use `tags` array instead of dedicated `spaces` field
|
|
472
|
+
|
|
473
|
+
**Pros**: Reuses existing field
|
|
474
|
+
**Cons**: Conflates spaces with tags, less clear semantics
|
|
475
|
+
**Verdict**: ❌ Spaces are not tags
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## Recommendations
|
|
480
|
+
|
|
481
|
+
### Immediate Actions
|
|
482
|
+
|
|
483
|
+
1. ✅ **Approve this design** before implementing
|
|
484
|
+
2. ✅ **Create migration plan** for existing data
|
|
485
|
+
3. ✅ **Update M10 tasks** to reflect new architecture
|
|
486
|
+
4. ✅ **Document breaking changes** in CHANGELOG
|
|
487
|
+
|
|
488
|
+
### Implementation Order
|
|
489
|
+
|
|
490
|
+
1. **Phase 1**: Update types and schema (backward compatible)
|
|
491
|
+
2. **Phase 2**: Update tools to support `spaces` array
|
|
492
|
+
3. **Phase 3**: Create `Memory_public` collection
|
|
493
|
+
4. **Phase 4**: Migrate existing data
|
|
494
|
+
5. **Phase 5**: Deprecate old collections
|
|
495
|
+
6. **Phase 6**: Update documentation
|
|
496
|
+
|
|
497
|
+
### Version Planning
|
|
498
|
+
|
|
499
|
+
- **v2.4.0**: Add `spaces` support (backward compatible)
|
|
500
|
+
- **v2.5.0**: Migrate to `Memory_public` (deprecate old)
|
|
501
|
+
- **v3.0.0**: Remove per-space collections (breaking change)
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
## Open Questions
|
|
506
|
+
|
|
507
|
+
1. **Should we support both `space` and `spaces` parameters during migration?**
|
|
508
|
+
- Recommendation: Yes, for backward compatibility
|
|
509
|
+
|
|
510
|
+
2. **How do we handle private vs. public spaces?**
|
|
511
|
+
- Recommendation: Separate collections (`Memory_public`, `Memory_shared`)
|
|
512
|
+
|
|
513
|
+
3. **Should spaces be ordered or unordered?**
|
|
514
|
+
- Recommendation: Unordered (set semantics)
|
|
515
|
+
|
|
516
|
+
4. **Maximum number of spaces per memory?**
|
|
517
|
+
- Recommendation: 10 spaces (prevent abuse)
|
|
518
|
+
|
|
519
|
+
5. **Can users create custom spaces?**
|
|
520
|
+
- Recommendation: Yes, but with validation
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## Success Criteria
|
|
525
|
+
|
|
526
|
+
- [ ] Multi-space search works in single query
|
|
527
|
+
- [ ] No memory duplication across spaces
|
|
528
|
+
- [ ] Storage reduced by N× (where N = avg spaces per memory)
|
|
529
|
+
- [ ] Add/remove spaces without recreating memory
|
|
530
|
+
- [ ] All existing functionality preserved
|
|
531
|
+
- [ ] Migration completes without data loss
|
|
532
|
+
- [ ] Performance equal or better than current
|
|
533
|
+
- [ ] Documentation updated
|
|
534
|
+
- [ ] Tests passing
|
|
535
|
+
|
|
536
|
+
---
|
|
537
|
+
|
|
538
|
+
**Status**: Design Proposal - Awaiting Approval
|
|
539
|
+
**Recommendation**: Implement in v2.4.0 with backward compatibility, full migration in v3.0.0
|
|
540
|
+
|
|
541
|
+
**Next Steps**:
|
|
542
|
+
1. Review and approve design
|
|
543
|
+
2. Update M10 milestone with new architecture
|
|
544
|
+
3. Create migration tasks
|
|
545
|
+
4. Begin implementation
|
package/agent/progress.yaml
CHANGED
|
@@ -391,6 +391,32 @@ progress:
|
|
|
391
391
|
overall: 50%
|
|
392
392
|
|
|
393
393
|
recent_work:
|
|
394
|
+
- date: 2026-02-16
|
|
395
|
+
description: ACP Initialization Complete - Project Status Verified
|
|
396
|
+
items:
|
|
397
|
+
- ✅ ACP initialization workflow executed via @acp.init command
|
|
398
|
+
- ⚠️ ACP updates available (v1.2.1 with new command format)
|
|
399
|
+
- ✅ All agent documentation reviewed (23 design docs, 10 milestones, 33 tasks, 5 patterns)
|
|
400
|
+
- ✅ Project status verified: M1-M4 complete (100%), M10 in progress
|
|
401
|
+
- ✅ Version 2.3.1 confirmed (latest patch release)
|
|
402
|
+
- ✅ 53 unit tests passing (1 skipped integration test)
|
|
403
|
+
- ✅ Test coverage: 29.76% overall
|
|
404
|
+
- ✅ TypeScript compiles without errors
|
|
405
|
+
- ✅ Build successful (dual export: server + factory)
|
|
406
|
+
- ✅ All 17 MCP tools implemented and working
|
|
407
|
+
- ✅ M10 Shared Spaces: 5 tools implemented (publish, confirm, deny, search_space, query_space)
|
|
408
|
+
- ✅ Token-based confirmation system operational
|
|
409
|
+
- ✅ Space collections: Memory_the_void with snake_case naming
|
|
410
|
+
- ✅ Confirmation token service with 5-minute expiry
|
|
411
|
+
- ✅ Space memory types and schema complete
|
|
412
|
+
- ✅ Multi-tenant architecture with per-user isolation
|
|
413
|
+
- ✅ Vector search with Weaviate + metadata with Firestore
|
|
414
|
+
- ✅ 45 content types with dynamic descriptions
|
|
415
|
+
- ✅ N-way relationships with bidirectional tracking
|
|
416
|
+
- ✅ User preferences system (6 categories)
|
|
417
|
+
- 📋 M10 implementation appears complete - needs verification
|
|
418
|
+
- 📋 Ready to verify M10 completion and update documentation
|
|
419
|
+
|
|
394
420
|
- date: 2026-02-16
|
|
395
421
|
description: Created Milestone 10 and Tasks for Shared Spaces
|
|
396
422
|
items:
|
package/agent/scripts/install.sh
CHANGED
|
@@ -55,6 +55,7 @@ mkdir -p "$TARGET_DIR/agent/patterns"
|
|
|
55
55
|
mkdir -p "$TARGET_DIR/agent/tasks"
|
|
56
56
|
mkdir -p "$TARGET_DIR/agent/commands"
|
|
57
57
|
mkdir -p "$TARGET_DIR/agent/scripts"
|
|
58
|
+
mkdir -p "$TARGET_DIR/agent/reports"
|
|
58
59
|
|
|
59
60
|
# Create .gitkeep files
|
|
60
61
|
touch "$TARGET_DIR/agent/design/.gitkeep"
|
|
@@ -62,6 +63,15 @@ touch "$TARGET_DIR/agent/milestones/.gitkeep"
|
|
|
62
63
|
touch "$TARGET_DIR/agent/patterns/.gitkeep"
|
|
63
64
|
touch "$TARGET_DIR/agent/tasks/.gitkeep"
|
|
64
65
|
|
|
66
|
+
# Create agent/.gitignore to exclude reports from version control
|
|
67
|
+
cat > "$TARGET_DIR/agent/.gitignore" << 'EOF'
|
|
68
|
+
# Agent Context Protocol - Local Files
|
|
69
|
+
# These files are generated locally and should not be committed
|
|
70
|
+
|
|
71
|
+
# Reports directory - generated by @acp.report command
|
|
72
|
+
reports/
|
|
73
|
+
EOF
|
|
74
|
+
|
|
65
75
|
echo -e "${GREEN}✓${NC} Directory structure created"
|
|
66
76
|
echo ""
|
|
67
77
|
|
|
@@ -113,6 +123,20 @@ echo " cp agent/progress.template.yaml agent/progress.yaml"
|
|
|
113
123
|
echo ""
|
|
114
124
|
echo "4. Read AGENT.md for complete documentation"
|
|
115
125
|
echo ""
|
|
126
|
+
echo -e "${BLUE}ACP Commands Available:${NC}"
|
|
127
|
+
echo ""
|
|
128
|
+
echo " ${GREEN}@acp.init${NC} - Initialize agent context (start here!)"
|
|
129
|
+
echo " ${GREEN}@acp.proceed${NC} - Continue with next task"
|
|
130
|
+
echo " ${GREEN}@acp.status${NC} - Display project status"
|
|
131
|
+
echo " ${GREEN}@acp.update${NC} - Update progress tracking"
|
|
132
|
+
echo " ${GREEN}@acp.sync${NC} - Sync documentation with code"
|
|
133
|
+
echo " ${GREEN}@acp.validate${NC} - Validate ACP documents"
|
|
134
|
+
echo " ${GREEN}@acp.report${NC} - Generate project report"
|
|
135
|
+
echo " ${GREEN}@acp.version-check${NC} - Show current ACP version"
|
|
136
|
+
echo " ${GREEN}@acp.version-check-for-updates${NC} - Check for ACP updates"
|
|
137
|
+
echo " ${GREEN}@acp.version-update${NC} - Update ACP to latest version"
|
|
138
|
+
echo " ${GREEN}@acp.package-install${NC} - Install third-party command packages"
|
|
139
|
+
echo ""
|
|
116
140
|
echo -e "${BLUE}For AI agents:${NC}"
|
|
117
|
-
echo "Type '
|
|
141
|
+
echo "Type '${GREEN}@acp.init${NC}' to get started."
|
|
118
142
|
echo ""
|
package/agent/scripts/update.sh
CHANGED
|
@@ -41,6 +41,20 @@ fi
|
|
|
41
41
|
echo -e "${GREEN}✓${NC} Latest files fetched"
|
|
42
42
|
echo ""
|
|
43
43
|
|
|
44
|
+
# Ensure reports directory exists and is ignored
|
|
45
|
+
mkdir -p "agent/reports"
|
|
46
|
+
if [ ! -f "agent/.gitignore" ]; then
|
|
47
|
+
echo "Creating agent/.gitignore..."
|
|
48
|
+
cat > "agent/.gitignore" << 'EOF'
|
|
49
|
+
# Agent Context Protocol - Local Files
|
|
50
|
+
# These files are generated locally and should not be committed
|
|
51
|
+
|
|
52
|
+
# Reports directory - generated by @acp.report command
|
|
53
|
+
reports/
|
|
54
|
+
EOF
|
|
55
|
+
echo -e "${GREEN}✓${NC} Created agent/.gitignore"
|
|
56
|
+
fi
|
|
57
|
+
|
|
44
58
|
echo "Updating ACP files..."
|
|
45
59
|
|
|
46
60
|
# Update template files (only .template.md files from these directories)
|
|
@@ -77,6 +91,12 @@ echo -e "${GREEN}✓${NC} All files updated"
|
|
|
77
91
|
echo ""
|
|
78
92
|
echo -e "${GREEN}Update complete!${NC}"
|
|
79
93
|
echo ""
|
|
94
|
+
echo -e "${BLUE}What was updated:${NC}"
|
|
95
|
+
echo " ✓ AGENT.md (methodology documentation)"
|
|
96
|
+
echo " ✓ Template files (design, milestone, task, pattern)"
|
|
97
|
+
echo " ✓ Command files (all ACP commands)"
|
|
98
|
+
echo " ✓ Utility scripts (update, check-for-updates, version, etc.)"
|
|
99
|
+
echo ""
|
|
80
100
|
echo -e "${BLUE}Next steps:${NC}"
|
|
81
101
|
echo "1. Review changes: git diff"
|
|
82
102
|
echo "2. See what changed: git status"
|
|
@@ -85,3 +105,20 @@ echo ""
|
|
|
85
105
|
echo "For detailed changelog:"
|
|
86
106
|
echo " https://github.com/prmichaelsen/agent-context-protocol/blob/mainline/CHANGELOG.md"
|
|
87
107
|
echo ""
|
|
108
|
+
echo -e "${BLUE}ACP Commands Available:${NC}"
|
|
109
|
+
echo ""
|
|
110
|
+
echo " ${GREEN}@acp.init${NC} - Initialize agent context (run after update!)"
|
|
111
|
+
echo " ${GREEN}@acp.proceed${NC} - Continue with next task"
|
|
112
|
+
echo " ${GREEN}@acp.status${NC} - Display project status"
|
|
113
|
+
echo " ${GREEN}@acp.update${NC} - Update progress tracking"
|
|
114
|
+
echo " ${GREEN}@acp.sync${NC} - Sync documentation with code"
|
|
115
|
+
echo " ${GREEN}@acp.validate${NC} - Validate ACP documents"
|
|
116
|
+
echo " ${GREEN}@acp.report${NC} - Generate project report"
|
|
117
|
+
echo " ${GREEN}@acp.version-check${NC} - Show current ACP version"
|
|
118
|
+
echo " ${GREEN}@acp.version-check-for-updates${NC} - Check for ACP updates"
|
|
119
|
+
echo " ${GREEN}@acp.version-update${NC} - Update ACP to latest version"
|
|
120
|
+
echo " ${GREEN}@acp.package-install${NC} - Install third-party command packages"
|
|
121
|
+
echo ""
|
|
122
|
+
echo -e "${BLUE}For AI agents:${NC}"
|
|
123
|
+
echo "Type '${GREEN}@acp.init${NC}' to reload context with updated files."
|
|
124
|
+
echo ""
|
package/dist/server-factory.js
CHANGED
|
@@ -3826,10 +3826,10 @@ async function executePublishMemory(request, userId) {
|
|
|
3826
3826
|
const additionalTags = Array.isArray(request.payload.additional_tags) ? request.payload.additional_tags : [];
|
|
3827
3827
|
const publishedMemory = {
|
|
3828
3828
|
...originalMemory.properties,
|
|
3829
|
-
//
|
|
3829
|
+
// Add space-specific fields
|
|
3830
3830
|
space_id: request.target_collection || "the_void",
|
|
3831
3831
|
author_id: userId,
|
|
3832
|
-
//
|
|
3832
|
+
// Track original author
|
|
3833
3833
|
published_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3834
3834
|
discovery_count: 0,
|
|
3835
3835
|
doc_type: "space_memory",
|
|
@@ -3844,11 +3844,11 @@ async function executePublishMemory(request, userId) {
|
|
|
3844
3844
|
console.log("[executePublishMemory] Inserting into space collection:", {
|
|
3845
3845
|
spaceId: request.target_collection || "the_void",
|
|
3846
3846
|
memoryId: request.payload.memory_id,
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
properties: publishedMemory
|
|
3847
|
+
hasUserId: !!publishedMemory.user_id,
|
|
3848
|
+
hasAuthorId: !!publishedMemory.author_id,
|
|
3849
|
+
hasSpaceId: !!publishedMemory.space_id
|
|
3851
3850
|
});
|
|
3851
|
+
const result = await targetCollection.data.insert(publishedMemory);
|
|
3852
3852
|
console.log("[executePublishMemory] Insert result:", {
|
|
3853
3853
|
success: !!result,
|
|
3854
3854
|
spaceMemoryId: result
|