@prmichaelsen/remember-mcp 2.6.2 → 2.6.3

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/CHANGELOG.md CHANGED
@@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.6.3] - 2026-02-16
9
+
10
+ ### 🐛 Fixed
11
+
12
+ - **CRITICAL: Fixed Empty Published Memories Bug**
13
+ - Published memories were empty shells with no content, title, or properties
14
+ - Root cause: `fetchObjectById()` calls missing `returnProperties` parameter
15
+ - Fixed in `remember_publish` and `remember_confirm` (executePublishMemory)
16
+ - All published memories now include complete property data
17
+
18
+ ### ✨ Added
19
+
20
+ - **New Utility Function**: `fetchMemoryWithAllProperties()`
21
+ - Centralized helper in `src/weaviate/client.ts`
22
+ - Ensures all memory properties are fetched consistently
23
+ - Prevents future bugs from missing properties
24
+ - Includes `ALL_MEMORY_PROPERTIES` constant (20+ properties)
25
+
26
+ ### 🔧 Improved
27
+
28
+ - Enhanced debug logging in publish flow
29
+ - Added property count verification
30
+ - Added hasTitle and hasContent checks
31
+ - Better diagnostics for troubleshooting
32
+
33
+ ### 🎯 Impact
34
+
35
+ - **Fixes**: All published memories since v2.4.0 were empty
36
+ - **Search**: Published memories now searchable (have content)
37
+ - **Discovery**: Space functionality now works as designed
38
+ - **Note**: Existing empty memories need to be re-published
39
+
40
+ ---
41
+
8
42
  ## [2.6.2] - 2026-02-16
9
43
 
10
44
  ### 🔒 Security
@@ -2,10 +2,10 @@
2
2
 
3
3
  project:
4
4
  name: remember-mcp
5
- version: 2.5.1
5
+ version: 2.6.3
6
6
  started: 2026-02-11
7
7
  status: in_progress
8
- current_milestone: M11
8
+ current_milestone: M12
9
9
  last_updated: 2026-02-16
10
10
 
11
11
  milestones:
@@ -162,7 +162,26 @@ milestones:
162
162
  ✅ No memory duplication across spaces
163
163
  ✅ All tests passing with multi-space support
164
164
  ✅ Documentation updated with multi-space examples
165
-
165
+
166
+ - id: M12
167
+ name: Comment System (Phase 1)
168
+ status: in_progress
169
+ progress: 60%
170
+ started: 2026-02-16
171
+ completed: null
172
+ estimated_weeks: 1
173
+ tasks_completed: 3
174
+ tasks_total: 5
175
+ notes: |
176
+ ✅ Task 55: Added 3 comment fields to schema (parent_id, thread_root_id, moderation_flags)
177
+ ✅ Task 56: Updated remember_search_space with include_comments parameter
178
+ ✅ Task 57: Updated remember_query_space with include_comments parameter
179
+ 📋 Task 58: Add Comment Unit Tests (pending)
180
+ 📋 Task 59: Update Documentation for Comments (pending)
181
+ ✅ Zero new tools required - reuses existing infrastructure
182
+ ✅ Backward compatible - comments excluded by default
183
+ ✅ Released v2.6.0 with comment system foundation
184
+
166
185
  - id: M7
167
186
  name: Trust & Permissions
168
187
  status: not_started
@@ -406,11 +425,97 @@ tasks:
406
425
  ✅ Context inclusion toggle
407
426
  ✅ Integrated into server.ts and server-factory.ts
408
427
 
428
+ milestone_12:
429
+ - id: task-55
430
+ name: Add Comment Fields to Weaviate Schema
431
+ status: completed
432
+ file: agent/tasks/task-55-add-comment-fields-to-schema.md
433
+ estimated_hours: 2
434
+ completed_date: 2026-02-16
435
+ notes: |
436
+ ✅ Added 3 fields to Memory schema: parent_id, thread_root_id, moderation_flags
437
+ ✅ Added same fields to Memory_public collection
438
+ ✅ Enables infinite comment nesting
439
+ ✅ Per-space moderation support
440
+ ✅ Released in v2.6.0
441
+
442
+ - id: task-56
443
+ name: Update remember_search_space for Comments
444
+ status: completed
445
+ file: agent/tasks/task-56-update-search-space-for-comments.md
446
+ estimated_hours: 2
447
+ completed_date: 2026-02-16
448
+ notes: |
449
+ ✅ Added include_comments parameter (default: false)
450
+ ✅ Comments excluded from search by default
451
+ ✅ Opt-in via include_comments: true
452
+ ✅ Backward compatible
453
+ ✅ Released in v2.6.0
454
+
455
+ - id: task-57
456
+ name: Update remember_query_space for Comments
457
+ status: completed
458
+ file: agent/tasks/task-57-update-query-space-for-comments.md
459
+ estimated_hours: 1
460
+ completed_date: 2026-02-16
461
+ notes: |
462
+ ✅ Added include_comments parameter (default: false)
463
+ ✅ Same filtering logic as search_space
464
+ ✅ Backward compatible
465
+ ✅ Released in v2.6.0
466
+
467
+ - id: task-58
468
+ name: Add Comment Unit Tests
469
+ status: not_started
470
+ file: agent/tasks/task-58-add-comment-unit-tests.md
471
+ estimated_hours: 3
472
+ notes: |
473
+ 📋 Pending: Schema tests, filtering tests, edge cases
474
+ 📋 Test infinite nesting support
475
+ 📋 Test moderation flags
476
+
477
+ - id: task-59
478
+ name: Update Documentation for Comments
479
+ status: not_started
480
+ file: agent/tasks/task-59-update-documentation-for-comments.md
481
+ estimated_hours: 2
482
+ notes: |
483
+ 📋 Pending: README updates, CHANGELOG entry, examples
484
+ 📋 Document comment creation workflow
485
+ 📋 Add threading examples
486
+
487
+ - id: task-60
488
+ name: Standardize Structured Logging
489
+ status: completed
490
+ file: agent/tasks/task-60-standardize-structured-logging.md
491
+ estimated_hours: 3
492
+ completed_date: 2026-02-16
493
+ notes: |
494
+ ✅ Replaced 54 console.log/error/warn calls with structured logger
495
+ ✅ Updated 8 files: confirmation-token.service, publish, confirm, deny, weaviate client/schema/space-schema, firestore init, config
496
+ ✅ All logs include context objects (service, module, tool names)
497
+ ✅ Fixed circular dependency in config.ts with dynamic import
498
+ ✅ Released in v2.6.1
499
+
500
+ - id: task-61
501
+ name: Enhance Confirmation Tool Safety Guidelines
502
+ status: completed
503
+ file: agent/tasks/task-61-enhance-confirmation-tool-descriptions.md
504
+ estimated_hours: 1
505
+ completed_date: 2026-02-16
506
+ notes: |
507
+ ✅ Enhanced remember_confirm tool description with 5 critical safety requirements
508
+ ✅ Enhanced remember_deny tool description with same safety guidelines
509
+ ✅ Added JSDoc comments explaining proper workflow
510
+ ✅ Prevents agents from bypassing user consent
511
+ ✅ Visual indicators (⚠️) for critical requirements
512
+ ✅ Released in v2.6.2
513
+
409
514
  documentation:
410
515
  design_documents: 23
411
- milestone_documents: 10
516
+ milestone_documents: 11
412
517
  pattern_documents: 5
413
- task_documents: 33
518
+ task_documents: 61
414
519
 
415
520
  progress:
416
521
  planning: 100%
@@ -418,6 +523,33 @@ progress:
418
523
  overall: 50%
419
524
 
420
525
  recent_work:
526
+ - date: 2026-02-16
527
+ description: Comment System, Structured Logging, and Safety Guidelines (v2.6.0-v2.6.2)
528
+ items:
529
+ - 🎉 M12 STARTED: Comment System (Phase 1) - 60% complete (3/5 tasks)
530
+ - ✅ Task 55: Added 3 comment fields to Weaviate schema
531
+ - ✅ parent_id, thread_root_id, moderation_flags fields added
532
+ - ✅ Enables infinite comment nesting with no depth limit
533
+ - ✅ Per-space moderation flags support
534
+ - ✅ Task 56: Updated remember_search_space with include_comments parameter
535
+ - ✅ Comments excluded by default for clean discovery
536
+ - ✅ Opt-in via include_comments: true
537
+ - ✅ Task 57: Updated remember_query_space with include_comments parameter
538
+ - ✅ Same filtering logic as search_space
539
+ - ✅ Released v2.6.0 with comment system foundation
540
+ - ✅ Task 60: Standardized structured logging across 8 files
541
+ - ✅ Replaced 54 console.log/error/warn calls with logger.info/error/warn/debug
542
+ - ✅ All logs include context objects (service, module, tool names)
543
+ - ✅ Fixed circular dependency in config.ts with dynamic import
544
+ - ✅ Released v2.6.1 with structured logging
545
+ - ✅ Task 61: Enhanced confirmation tool safety guidelines
546
+ - ✅ Added 5 critical safety requirements to remember_confirm and remember_deny
547
+ - ✅ Prevents agents from chaining confirmations without user consent
548
+ - ✅ Visual indicators (⚠️) and JSDoc comments added
549
+ - ✅ Released v2.6.2 with safety enhancements
550
+ - 📋 Next: Complete M12 with Tasks 58-59 (tests + documentation)
551
+ - 📋 6 commits ready to push to origin
552
+
421
553
  - date: 2026-02-16
422
554
  description: ACP Initialization Complete - Multi-Space Architecture Verified (v2.5.1)
423
555
  items:
@@ -743,18 +875,21 @@ recent_work:
743
875
  - ✅ Build successful
744
876
 
745
877
  next_steps:
746
- - Deploy v2.5.1 to Cloud Run and verify multi-space functionality
747
- - Test multi-space publishing workflow end-to-end
748
- - Test multi-space search across multiple spaces
749
- - Verify Firestore request creation with enhanced error handling
750
- - Check Cloud Run logs for diagnostic output from ConfirmationTokenService
751
- - Consider implementing comment system (v2.6.0) - 3 schema fields only!
878
+ - Complete Task 58: Add Comment Unit Tests (3 hours)
879
+ - Complete Task 59: Update Documentation for Comments (2 hours)
880
+ - Push 6 commits to origin (v2.6.0, v2.6.1, v2.6.2)
881
+ - Deploy v2.6.2 to Cloud Run
882
+ - Test comment system end-to-end (create, search, thread fetching)
883
+ - Test structured logging in Cloud Run logs
884
+ - Verify confirmation tool safety guidelines in production
885
+ - Complete M12: Comment System (Phase 1)
752
886
  - Start M5: Template System (15 default templates + auto-suggestion)
753
887
  - Optional: Create integration tests (Task 6)
754
888
  - Optional: Add development documentation (Task 7)
755
889
  - Consider M6: Auth & Multi-Tenancy
756
890
 
757
891
  notes:
892
+ - 🚀 Milestone 12 (Comment System Phase 1) IN PROGRESS - 60% complete!
758
893
  - 🎉 Milestone 11 (Unified Public Collection) COMPLETED!
759
894
  - 🎉 Milestone 10 (Shared Spaces & Confirmation Flow) COMPLETED!
760
895
  - 🎉 Milestone 4 (User Preferences) COMPLETED!
@@ -769,6 +904,10 @@ notes:
769
904
  - ✅ M4: 2/2 preference tools complete (100% progress)
770
905
  - ✅ M10: 10/10 shared space tools complete (100% progress)
771
906
  - ✅ M11: 9/9 multi-space architecture tasks complete (100% progress)
907
+ - 🚀 M12: 3/5 comment system tasks complete (60% progress)
908
+ - ✅ Comment system foundation implemented (v2.6.0)
909
+ - ✅ Structured logging standardized (v2.6.1)
910
+ - ✅ Confirmation tool safety enhanced (v2.6.2)
772
911
  - ✅ Complete memory CRUD operations (create, read, update, delete)
773
912
  - ✅ Complete relationship CRUD operations (create, read, update, delete)
774
913
  - ✅ Advanced search capabilities (hybrid, similarity, RAG queries)
@@ -833,8 +972,10 @@ build_status:
833
972
  - ✅ Source maps generated
834
973
  - ✅ Type definitions generated (.d.ts files)
835
974
  - ✅ Package exports configured for both entry points
836
- - ✅ Version 2.0.1 published (patch release - error logging)
837
- - ✅ 30 TypeScript source files (added error-handler.ts)
975
+ - ✅ Version 2.6.2 published (patch release - safety guidelines)
976
+ - ✅ Version 2.6.1 published (patch release - structured logging)
977
+ - ✅ Version 2.6.0 published (minor release - comment system)
978
+ - ✅ 30 TypeScript source files
838
979
  - ✅ All 12 tools implemented
839
980
  - ✅ Weaviate v3 filter API implemented
840
981
  - ✅ Or/And operator validation implemented
@@ -857,6 +998,12 @@ tools_status:
857
998
  preference_tools:
858
999
  - ✅ remember_set_preference (src/tools/set-preference.ts)
859
1000
  - ✅ remember_get_preferences (src/tools/get-preferences.ts)
1001
+ space_tools:
1002
+ - ✅ remember_publish (src/tools/publish.ts) - Multi-space support
1003
+ - ✅ remember_confirm (src/tools/confirm.ts) - Enhanced safety guidelines
1004
+ - ✅ remember_deny (src/tools/deny.ts) - Enhanced safety guidelines
1005
+ - ✅ remember_search_space (src/tools/search-space.ts) - Comment filtering
1006
+ - ✅ remember_query_space (src/tools/query-space.ts) - Comment filtering
860
1007
 
861
1008
  implementation_notes:
862
1009
  - All 12 core tools implemented and integrated
@@ -899,3 +1046,6 @@ task_20_completion:
899
1046
  releases:
900
1047
  - v1.0.0: Major release with breaking change (async createServer)
901
1048
  - v1.0.1: Patch release with Or operator bug fix
1049
+ - v2.6.0: Minor release with comment system foundation
1050
+ - v2.6.1: Patch release with structured logging
1051
+ - v2.6.2: Patch release with confirmation tool safety guidelines
@@ -0,0 +1,323 @@
1
+ # Task 62: Fix Confirmation Response Storage
2
+
3
+ **Milestone**: M12 (Comment System / Bug Fixes)
4
+ **Estimated Time**: 2 hours
5
+ **Dependencies**: None
6
+ **Status**: Not Started
7
+ **Priority**: High
8
+
9
+ ---
10
+
11
+ ## Objective
12
+
13
+ Fix bug where `remember_confirm` executes actions successfully but doesn't store the response data in the Firestore confirmation record. This prevents agents and users from verifying action results and breaks the audit trail.
14
+
15
+ ---
16
+
17
+ ## Context
18
+
19
+ **Current Behavior:**
20
+ 1. `remember_confirm` validates token and marks request as "confirmed"
21
+ 2. Action executes successfully (e.g., `executePublishMemory`)
22
+ 3. Response data (space_memory_id, etc.) is returned to agent
23
+ 4. **BUG**: Response data is NOT saved to Firestore
24
+ 5. Database record shows `status: confirmed` but no response/result data
25
+
26
+ **Impact:**
27
+ - ⚠️ Agents cannot verify publication success
28
+ - ⚠️ No space_memory_id available for reference
29
+ - ⚠️ Audit trail incomplete
30
+ - ⚠️ Cannot track what happened after confirmation
31
+
32
+ **Root Cause:**
33
+ - `ConfirmationRequest` interface lacks `response` field
34
+ - `confirmRequest()` method only updates status, not response
35
+ - `executePublishMemory()` returns data but doesn't persist it
36
+
37
+ ---
38
+
39
+ ## Steps
40
+
41
+ ### 1. Update ConfirmationRequest Interface
42
+
43
+ Add response field to store action results:
44
+
45
+ ```typescript
46
+ // src/services/confirmation-token.service.ts
47
+
48
+ export interface ConfirmationRequest {
49
+ user_id: string;
50
+ token: string;
51
+ action: string;
52
+ target_collection?: string;
53
+ payload: any;
54
+ created_at: string;
55
+ expires_at: string;
56
+ status: 'pending' | 'confirmed' | 'denied' | 'expired' | 'retracted';
57
+ confirmed_at?: string;
58
+ response?: any; // ✅ ADD THIS - Stores action execution result
59
+ }
60
+ ```
61
+
62
+ ### 2. Add storeResponse Method
63
+
64
+ Create method to store response data after action execution:
65
+
66
+ ```typescript
67
+ // src/services/confirmation-token.service.ts
68
+
69
+ /**
70
+ * Store response data for a confirmed request
71
+ *
72
+ * @param userId - User ID
73
+ * @param requestId - Request ID
74
+ * @param response - Response data from action execution
75
+ */
76
+ async storeResponse(
77
+ userId: string,
78
+ requestId: string,
79
+ response: any
80
+ ): Promise<void> {
81
+ logger.info('Storing confirmation response', {
82
+ service: 'ConfirmationTokenService',
83
+ userId,
84
+ requestId,
85
+ hasResponse: !!response,
86
+ });
87
+
88
+ const docPath = `users/${userId}/requests/${requestId}`;
89
+
90
+ await updateDocument(docPath, {
91
+ response,
92
+ updated_at: new Date().toISOString(),
93
+ });
94
+
95
+ logger.info('Response stored successfully', {
96
+ service: 'ConfirmationTokenService',
97
+ requestId,
98
+ });
99
+ }
100
+ ```
101
+
102
+ ### 3. Update handleConfirm to Store Response
103
+
104
+ Modify `remember_confirm` to persist response data:
105
+
106
+ ```typescript
107
+ // src/tools/confirm.ts
108
+
109
+ export async function handleConfirm(
110
+ args: ConfirmArgs,
111
+ userId: string
112
+ ): Promise<string> {
113
+ try {
114
+ logger.info('Starting confirmation', {
115
+ tool: 'remember_confirm',
116
+ userId,
117
+ token: args.token,
118
+ });
119
+
120
+ // Validate and confirm token
121
+ const request = await confirmationTokenService.confirmRequest(userId, args.token);
122
+
123
+ if (!request) {
124
+ logger.info('Token invalid or expired', {
125
+ tool: 'remember_confirm',
126
+ userId,
127
+ });
128
+ return JSON.stringify({
129
+ success: false,
130
+ error: 'Invalid or expired token',
131
+ message: 'The confirmation token is invalid, expired, or has already been used.',
132
+ }, null, 2);
133
+ }
134
+
135
+ logger.info('Executing confirmed action', {
136
+ tool: 'remember_confirm',
137
+ action: request.action,
138
+ userId,
139
+ });
140
+
141
+ // Execute action based on type
142
+ let responseJson: string;
143
+ if (request.action === 'publish_memory') {
144
+ responseJson = await executePublishMemory(request, userId);
145
+ } else {
146
+ throw new Error(`Unknown action type: ${request.action}`);
147
+ }
148
+
149
+ // ✅ NEW: Parse and store response data
150
+ try {
151
+ const responseData = JSON.parse(responseJson);
152
+
153
+ logger.info('Storing action response', {
154
+ tool: 'remember_confirm',
155
+ requestId: request.request_id,
156
+ success: responseData.success,
157
+ });
158
+
159
+ await confirmationTokenService.storeResponse(
160
+ userId,
161
+ request.request_id,
162
+ responseData
163
+ );
164
+
165
+ logger.info('Response stored successfully', {
166
+ tool: 'remember_confirm',
167
+ requestId: request.request_id,
168
+ });
169
+ } catch (parseError) {
170
+ logger.warn('Failed to parse/store response', {
171
+ tool: 'remember_confirm',
172
+ error: parseError instanceof Error ? parseError.message : String(parseError),
173
+ });
174
+ // Don't fail the whole operation if storage fails
175
+ }
176
+
177
+ // Return response to agent
178
+ return responseJson;
179
+ } catch (error) {
180
+ handleToolError(error, {
181
+ toolName: 'remember_confirm',
182
+ userId,
183
+ operation: 'confirm action',
184
+ token: args.token,
185
+ });
186
+ }
187
+ }
188
+ ```
189
+
190
+ ### 4. Update Tests
191
+
192
+ Add tests for response storage:
193
+
194
+ ```typescript
195
+ // tests/unit/confirmation-token.service.test.ts
196
+
197
+ describe('ConfirmationTokenService', () => {
198
+ describe('storeResponse', () => {
199
+ it('should store response data for confirmed request', async () => {
200
+ const service = new ConfirmationTokenService();
201
+ const userId = 'test-user';
202
+ const requestId = 'test-request';
203
+ const response = {
204
+ success: true,
205
+ space_memory_id: 'space-123',
206
+ spaces: ['the_void'],
207
+ };
208
+
209
+ await service.storeResponse(userId, requestId, response);
210
+
211
+ // Verify response was stored
212
+ const request = await getDocument(`users/${userId}/requests/${requestId}`);
213
+ expect(request.response).toEqual(response);
214
+ expect(request.updated_at).toBeDefined();
215
+ });
216
+ });
217
+ });
218
+ ```
219
+
220
+ ### 5. Update Documentation
221
+
222
+ Document the response field in design docs:
223
+
224
+ ```markdown
225
+ # agent/design/publish-tools-confirmation-flow.md
226
+
227
+ ## Confirmation Record Structure
228
+
229
+ After confirmation, the record includes:
230
+ - `status`: 'confirmed'
231
+ - `confirmed_at`: ISO timestamp
232
+ - `response`: Action execution result (NEW)
233
+ - For publish_memory: { success, space_memory_id, spaces }
234
+ - For other actions: Action-specific response data
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Verification
240
+
241
+ - [ ] ConfirmationRequest interface has `response?: any` field
242
+ - [ ] `storeResponse()` method exists in ConfirmationTokenService
243
+ - [ ] `handleConfirm` calls `storeResponse()` after action execution
244
+ - [ ] Response data is persisted to Firestore
245
+ - [ ] Agent receives response data in tool output
246
+ - [ ] Database record contains response field after confirmation
247
+ - [ ] Tests pass for response storage
248
+ - [ ] TypeScript compiles without errors
249
+ - [ ] Build successful
250
+ - [ ] Manual test: Publish memory and verify response in Firestore
251
+
252
+ ---
253
+
254
+ ## Expected Output
255
+
256
+ **Before Fix:**
257
+ ```json
258
+ {
259
+ "status": "confirmed",
260
+ "confirmed_at": "2026-02-16T21:44:39.154Z",
261
+ "action": "publish_memory",
262
+ "payload": { "memory_id": "...", "spaces": ["the_void"] }
263
+ // ❌ No response field
264
+ }
265
+ ```
266
+
267
+ **After Fix:**
268
+ ```json
269
+ {
270
+ "status": "confirmed",
271
+ "confirmed_at": "2026-02-16T21:44:39.154Z",
272
+ "action": "publish_memory",
273
+ "payload": { "memory_id": "...", "spaces": ["the_void"] },
274
+ "response": {
275
+ "success": true,
276
+ "space_memory_id": "9b536938-1188-4e69-b3cd-4362d84fff1c",
277
+ "spaces": ["the_void"]
278
+ }
279
+ }
280
+ ```
281
+
282
+ ---
283
+
284
+ ## Common Issues and Solutions
285
+
286
+ ### Issue 1: Response not storing
287
+
288
+ **Cause**: Parse error or Firestore write failure
289
+ **Solution**: Check logs for errors, verify Firestore permissions
290
+
291
+ ### Issue 2: Response field undefined
292
+
293
+ **Cause**: Old records don't have response field
294
+ **Solution**: This is expected - only new confirmations will have response
295
+
296
+ ### Issue 3: Response too large for Firestore
297
+
298
+ **Cause**: Response data exceeds Firestore document size limit (1MB)
299
+ **Solution**: Store only essential fields (space_memory_id, success, spaces)
300
+
301
+ ---
302
+
303
+ ## Resources
304
+
305
+ - [Firestore Document Limits](https://firebase.google.com/docs/firestore/quotas)
306
+ - [ConfirmationTokenService](../src/services/confirmation-token.service.ts)
307
+ - [remember_confirm Tool](../src/tools/confirm.ts)
308
+ - [Confirmation Flow Design](../design/publish-tools-confirmation-flow.md)
309
+
310
+ ---
311
+
312
+ ## Notes
313
+
314
+ - This is a backward-compatible change - old records without response field will continue to work
315
+ - Response storage is best-effort - if it fails, the action still succeeds
316
+ - Response data is primarily for audit trail and debugging
317
+ - Agents receive response data regardless of storage success
318
+ - Consider adding response field to remember_deny as well (for consistency)
319
+
320
+ ---
321
+
322
+ **Status**: Not Started
323
+ **Recommendation**: Implement this fix before completing M12 to ensure proper audit trail
@@ -0,0 +1,397 @@
1
+ # Task 63: Fix fetchObjectById Missing Properties in Publish Flow
2
+
3
+ **Milestone**: M12 (Bug Fixes)
4
+ **Estimated Time**: 1 hour
5
+ **Dependencies**: None
6
+ **Status**: Not Started
7
+ **Priority**: CRITICAL 🚨
8
+
9
+ ---
10
+
11
+ ## Objective
12
+
13
+ Fix critical bug where `remember_publish` and `remember_confirm` (executePublishMemory) fail to fetch all memory properties because they don't specify `returnProperties` parameter in `fetchObjectById()` calls. This causes published memories to be empty shells with only metadata and vectors.
14
+
15
+ ---
16
+
17
+ ## Context
18
+
19
+ **Critical Bug Discovered**: Published memories in `Memory_public` have no content!
20
+
21
+ **Symptom**:
22
+ - Space memory created with ID ✅
23
+ - Vector embedding generated ✅
24
+ - Metadata exists ✅
25
+ - **All properties missing** ❌ (no title, content, tags, etc.)
26
+
27
+ **Root Cause**:
28
+ Weaviate v3 API `fetchObjectById()` requires explicit `returnProperties` parameter. Without it, only metadata is returned, not the actual property values.
29
+
30
+ **Affected Code**:
31
+ 1. [`src/tools/publish.ts:125`](src/tools/publish.ts) - `remember_publish` tool
32
+ 2. [`src/tools/confirm.ts:154`](src/tools/confirm.ts) - `executePublishMemory` function
33
+
34
+ **Evidence**:
35
+ All other tools correctly specify `returnProperties`:
36
+ - `update-relationship.ts:100` ✅ Specifies properties
37
+ - `create-relationship.ts:119` ✅ Specifies properties
38
+ - `find-similar.ts:120` ✅ Specifies properties
39
+ - `update-memory.ts:119` ✅ Specifies properties
40
+ - `delete-relationship.ts:66` ✅ Specifies properties
41
+ - `delete-memory.ts:72` ✅ Specifies properties
42
+ - **`publish.ts:125`** ❌ Missing returnProperties
43
+ - **`confirm.ts:154`** ❌ Missing returnProperties
44
+
45
+ ---
46
+
47
+ ## Steps
48
+
49
+ ### 1. Create Utility Function for Consistent Property Fetching
50
+
51
+ Create a helper function to ensure all memory properties are always fetched:
52
+
53
+ ```typescript
54
+ // src/weaviate/client.ts (add after existing functions)
55
+
56
+ /**
57
+ * List of all memory properties to fetch
58
+ * Centralized to ensure consistency across all tools
59
+ */
60
+ export const ALL_MEMORY_PROPERTIES = [
61
+ 'user_id',
62
+ 'doc_type',
63
+ 'type',
64
+ 'title',
65
+ 'content',
66
+ 'tags',
67
+ 'weight',
68
+ 'base_weight',
69
+ 'trust_level',
70
+ 'context',
71
+ 'location',
72
+ 'relationships',
73
+ 'created_at',
74
+ 'updated_at',
75
+ 'version',
76
+ 'attribution',
77
+ 'source_url',
78
+ 'author',
79
+ 'parent_id',
80
+ 'thread_root_id',
81
+ 'moderation_flags',
82
+ ] as const;
83
+
84
+ /**
85
+ * Fetch a memory object by ID with all properties
86
+ *
87
+ * @param collection - Weaviate collection
88
+ * @param memoryId - Memory ID to fetch
89
+ * @returns Memory object with all properties
90
+ */
91
+ export async function fetchMemoryWithAllProperties(
92
+ collection: any,
93
+ memoryId: string
94
+ ) {
95
+ return await collection.query.fetchObjectById(memoryId, {
96
+ returnProperties: ALL_MEMORY_PROPERTIES,
97
+ });
98
+ }
99
+ ```
100
+
101
+ ### 2. Fix remember_publish Tool
102
+
103
+ Update `fetchObjectById` call to return all properties:
104
+
105
+ ```typescript
106
+ // src/tools/publish.ts (around line 125)
107
+
108
+ // BEFORE (BROKEN):
109
+ const memory = await userCollection.query.fetchObjectById(args.memory_id);
110
+
111
+ // AFTER (FIXED):
112
+ const memory = await userCollection.query.fetchObjectById(args.memory_id, {
113
+ returnProperties: [
114
+ 'user_id',
115
+ 'doc_type',
116
+ 'type',
117
+ 'title',
118
+ 'content',
119
+ 'tags',
120
+ 'weight',
121
+ 'base_weight',
122
+ 'trust_level',
123
+ 'context',
124
+ 'location',
125
+ 'relationships',
126
+ 'created_at',
127
+ 'updated_at',
128
+ 'version',
129
+ 'attribution',
130
+ 'source_url',
131
+ 'author',
132
+ 'parent_id',
133
+ 'thread_root_id',
134
+ 'moderation_flags',
135
+ ],
136
+ });
137
+ ```
138
+
139
+ ### 2. Fix executePublishMemory in remember_confirm
140
+
141
+ Update `fetchObjectById` call in confirm tool:
142
+
143
+ ```typescript
144
+ // src/tools/confirm.ts (around line 154)
145
+
146
+ // BEFORE (BROKEN):
147
+ const originalMemory = await userCollection.query.fetchObjectById(
148
+ request.payload.memory_id
149
+ );
150
+
151
+ // AFTER (FIXED):
152
+ const originalMemory = await userCollection.query.fetchObjectById(
153
+ request.payload.memory_id,
154
+ {
155
+ returnProperties: [
156
+ 'user_id',
157
+ 'doc_type',
158
+ 'type',
159
+ 'title',
160
+ 'content',
161
+ 'tags',
162
+ 'weight',
163
+ 'base_weight',
164
+ 'trust_level',
165
+ 'context',
166
+ 'location',
167
+ 'relationships',
168
+ 'created_at',
169
+ 'updated_at',
170
+ 'version',
171
+ 'attribution',
172
+ 'source_url',
173
+ 'author',
174
+ 'parent_id',
175
+ 'thread_root_id',
176
+ 'moderation_flags',
177
+ ],
178
+ }
179
+ );
180
+ ```
181
+
182
+ ### 3. Add Logging to Verify Properties
183
+
184
+ Add debug logging to confirm properties are fetched:
185
+
186
+ ```typescript
187
+ // src/tools/confirm.ts (after fetch)
188
+
189
+ logger.debug('Original memory fetch result', {
190
+ function: 'executePublishMemory',
191
+ found: !!originalMemory,
192
+ memoryId: request.payload.memory_id,
193
+ hasProperties: !!originalMemory?.properties,
194
+ propertyCount: originalMemory?.properties ? Object.keys(originalMemory.properties).length : 0,
195
+ hasTitle: !!originalMemory?.properties?.title,
196
+ hasContent: !!originalMemory?.properties?.content,
197
+ });
198
+ ```
199
+
200
+ ### 4. Test the Fix
201
+
202
+ Manual test to verify properties are copied:
203
+
204
+ ```bash
205
+ # 1. Create a test memory
206
+ remember_create_memory({
207
+ type: "note",
208
+ title: "Test Memory",
209
+ content: "This is test content",
210
+ tags: ["test"]
211
+ })
212
+
213
+ # 2. Publish it
214
+ remember_publish({
215
+ memory_id: "<memory_id>",
216
+ spaces: ["the_void"]
217
+ })
218
+
219
+ # 3. Confirm publication
220
+ remember_confirm({
221
+ token: "<token>"
222
+ })
223
+
224
+ # 4. Search for it
225
+ remember_search_space({
226
+ spaces: ["the_void"],
227
+ query: "test content",
228
+ include_comments: false
229
+ })
230
+
231
+ # 5. Verify result has title, content, tags
232
+ ```
233
+
234
+ ### 5. Update Tests
235
+
236
+ Add test case for property copying:
237
+
238
+ ```typescript
239
+ // tests/unit/publish.test.ts
240
+
241
+ describe('remember_publish', () => {
242
+ it('should fetch all memory properties', async () => {
243
+ const mockMemory = {
244
+ properties: {
245
+ user_id: 'test-user',
246
+ title: 'Test Title',
247
+ content: 'Test Content',
248
+ tags: ['tag1', 'tag2'],
249
+ // ... all properties
250
+ },
251
+ };
252
+
253
+ mockCollection.query.fetchObjectById.mockResolvedValue(mockMemory);
254
+
255
+ await handlePublish({ memory_id: 'test-id', spaces: ['the_void'] }, 'test-user');
256
+
257
+ expect(mockCollection.query.fetchObjectById).toHaveBeenCalledWith(
258
+ 'test-id',
259
+ expect.objectContaining({
260
+ returnProperties: expect.arrayContaining([
261
+ 'title',
262
+ 'content',
263
+ 'tags',
264
+ 'user_id',
265
+ 'doc_type',
266
+ ]),
267
+ })
268
+ );
269
+ });
270
+ });
271
+ ```
272
+
273
+ ---
274
+
275
+ ## Verification
276
+
277
+ - [ ] Created `fetchMemoryWithAllProperties` utility function in `src/weaviate/client.ts`
278
+ - [ ] Created `ALL_MEMORY_PROPERTIES` constant with all 20+ properties
279
+ - [ ] `remember_publish` uses `fetchMemoryWithAllProperties`
280
+ - [ ] `executePublishMemory` uses `fetchMemoryWithAllProperties`
281
+ - [ ] Utility function exported from client module
282
+ - [ ] Debug logging shows property count > 0
283
+ - [ ] Debug logging shows `hasTitle: true` and `hasContent: true`
284
+ - [ ] Manual test: Published memory has title, content, tags
285
+ - [ ] Search returns published memory with full content
286
+ - [ ] TypeScript compiles without errors
287
+ - [ ] Build successful
288
+ - [ ] All tests passing
289
+
290
+ ---
291
+
292
+ ## Expected Output
293
+
294
+ **Before Fix** (Current - BROKEN):
295
+ ```json
296
+ {
297
+ "id": "9b536938-1188-4e69-b3cd-4362d84fff1c",
298
+ "vector": [...],
299
+ // ❌ NO PROPERTIES - Empty shell
300
+ }
301
+ ```
302
+
303
+ **After Fix**:
304
+ ```json
305
+ {
306
+ "id": "9b536938-1188-4e69-b3cd-4362d84fff1c",
307
+ "vector": [...],
308
+ "properties": {
309
+ "title": "Breaking the Mold of Boredom",
310
+ "content": "i feel like i'm boring...",
311
+ "type": "note",
312
+ "tags": ["self-discovery", "societal norms", "breaking free"],
313
+ "author_id": "MnOyIarhz5b8n06TsTovM582NSG2",
314
+ "spaces": ["the_void"],
315
+ "published_at": "2026-02-16T21:44:39Z",
316
+ // ... all other properties
317
+ }
318
+ }
319
+ ```
320
+
321
+ ---
322
+
323
+ ## Impact Analysis
324
+
325
+ **Severity**: CRITICAL 🚨
326
+
327
+ **Affected Users**: ALL users who published memories since v2.4.0
328
+
329
+ **Data Loss**:
330
+ - All published memories are empty shells
331
+ - Content exists in user collections but not in public space
332
+ - Search returns no results (no content to match)
333
+ - Discovery completely broken
334
+
335
+ **Workaround**: None - memories must be re-published after fix
336
+
337
+ **Migration**:
338
+ - Option 1: Users re-publish memories manually
339
+ - Option 2: Create migration script to re-publish all memories
340
+ - Option 3: Backfill from user collections (requires tracking original IDs)
341
+
342
+ ---
343
+
344
+ ## Common Issues and Solutions
345
+
346
+ ### Issue 1: TypeScript error about returnProperties
347
+
348
+ **Cause**: Type definition might not include all properties
349
+ **Solution**: Use `as any` if needed or update type definition
350
+
351
+ ### Issue 2: Some properties still missing
352
+
353
+ **Cause**: Property list incomplete
354
+ **Solution**: Check schema.ts for all property names
355
+
356
+ ### Issue 3: Old memories still empty
357
+
358
+ **Cause**: This fix only affects new publications
359
+ **Solution**: Users must re-publish or run migration script
360
+
361
+ ---
362
+
363
+ ## Resources
364
+
365
+ - [Weaviate v3 Query API](https://weaviate.io/developers/weaviate/api/graphql/get)
366
+ - [Memory Schema](../src/weaviate/schema.ts)
367
+ - [Space Schema](../src/weaviate/space-schema.ts)
368
+ - [Other fetchObjectById Examples](../src/tools/)
369
+
370
+ ---
371
+
372
+ ## Notes
373
+
374
+ - **This is more critical than Task 62** (response storage)
375
+ - Task 62 affects audit trail, Task 63 affects core functionality
376
+ - Without this fix, the entire publish/space feature is broken
377
+ - This bug has been in production since shared spaces were released
378
+ - All published memories need to be re-published after fix
379
+ - Consider adding integration test to catch this in future
380
+ - ✅ Created `fetchMemoryWithAllProperties` helper function
381
+ - This prevents the bug from recurring in future code
382
+ - Consider migrating other tools to use the utility function
383
+ - Consider adding ESLint rule to prevent direct `fetchObjectById` usage
384
+
385
+ ---
386
+
387
+ ## Related Tasks
388
+
389
+ - **Task 62**: Fix confirmation response storage (audit trail)
390
+ - **Task 58**: Add comment unit tests
391
+ - **Task 59**: Update documentation
392
+
393
+ ---
394
+
395
+ **Status**: Not Started
396
+ **Recommendation**: FIX IMMEDIATELY - This breaks core functionality
397
+ **Priority**: CRITICAL - Must be fixed before any other M12 tasks
@@ -565,6 +565,34 @@ function sanitizeUserId(userId) {
565
565
  function getMemoryCollectionName(userId) {
566
566
  return `Memory_${sanitizeUserId(userId)}`;
567
567
  }
568
+ var ALL_MEMORY_PROPERTIES = [
569
+ "user_id",
570
+ "doc_type",
571
+ "type",
572
+ "title",
573
+ "content",
574
+ "tags",
575
+ "weight",
576
+ "base_weight",
577
+ "trust_level",
578
+ "context",
579
+ "location",
580
+ "relationships",
581
+ "created_at",
582
+ "updated_at",
583
+ "version",
584
+ "attribution",
585
+ "source_url",
586
+ "author",
587
+ "parent_id",
588
+ "thread_root_id",
589
+ "moderation_flags"
590
+ ];
591
+ async function fetchMemoryWithAllProperties(collection, memoryId) {
592
+ return await collection.query.fetchObjectById(memoryId, {
593
+ returnProperties: ALL_MEMORY_PROPERTIES
594
+ });
595
+ }
568
596
 
569
597
  // src/firestore/init.ts
570
598
  init_config();
@@ -3833,11 +3861,15 @@ async function handlePublish(args, userId) {
3833
3861
  memoryId: args.memory_id
3834
3862
  });
3835
3863
  const userCollection = weaviateClient.collections.get(collectionName);
3836
- const memory = await userCollection.query.fetchObjectById(args.memory_id);
3864
+ const memory = await fetchMemoryWithAllProperties(userCollection, args.memory_id);
3837
3865
  logger.debug("Memory fetch result", {
3838
3866
  tool: "remember_publish",
3839
3867
  found: !!memory,
3840
- memoryId: args.memory_id
3868
+ memoryId: args.memory_id,
3869
+ hasProperties: !!memory?.properties,
3870
+ propertyCount: memory?.properties ? Object.keys(memory.properties).length : 0,
3871
+ hasTitle: !!memory?.properties?.title,
3872
+ hasContent: !!memory?.properties?.content
3841
3873
  });
3842
3874
  if (!memory) {
3843
3875
  logger.info("Memory not found", {
@@ -4024,13 +4056,18 @@ async function executePublishMemory(request, userId) {
4024
4056
  collectionName: getMemoryCollectionName(userId),
4025
4057
  memoryId: request.payload.memory_id
4026
4058
  });
4027
- const originalMemory = await userCollection.query.fetchObjectById(
4059
+ const originalMemory = await fetchMemoryWithAllProperties(
4060
+ userCollection,
4028
4061
  request.payload.memory_id
4029
4062
  );
4030
4063
  logger.debug("Original memory fetch result", {
4031
4064
  function: "executePublishMemory",
4032
4065
  found: !!originalMemory,
4033
- memoryId: request.payload.memory_id
4066
+ memoryId: request.payload.memory_id,
4067
+ hasProperties: !!originalMemory?.properties,
4068
+ propertyCount: originalMemory?.properties ? Object.keys(originalMemory.properties).length : 0,
4069
+ hasTitle: !!originalMemory?.properties?.title,
4070
+ hasContent: !!originalMemory?.properties?.content
4034
4071
  });
4035
4072
  if (!originalMemory) {
4036
4073
  logger.info("Original memory not found", {
package/dist/server.js CHANGED
@@ -611,6 +611,34 @@ function sanitizeUserId(userId) {
611
611
  function getMemoryCollectionName(userId) {
612
612
  return `Memory_${sanitizeUserId(userId)}`;
613
613
  }
614
+ var ALL_MEMORY_PROPERTIES = [
615
+ "user_id",
616
+ "doc_type",
617
+ "type",
618
+ "title",
619
+ "content",
620
+ "tags",
621
+ "weight",
622
+ "base_weight",
623
+ "trust_level",
624
+ "context",
625
+ "location",
626
+ "relationships",
627
+ "created_at",
628
+ "updated_at",
629
+ "version",
630
+ "attribution",
631
+ "source_url",
632
+ "author",
633
+ "parent_id",
634
+ "thread_root_id",
635
+ "moderation_flags"
636
+ ];
637
+ async function fetchMemoryWithAllProperties(collection, memoryId) {
638
+ return await collection.query.fetchObjectById(memoryId, {
639
+ returnProperties: ALL_MEMORY_PROPERTIES
640
+ });
641
+ }
614
642
 
615
643
  // src/firestore/init.ts
616
644
  init_config();
@@ -3901,11 +3929,15 @@ async function handlePublish(args, userId) {
3901
3929
  memoryId: args.memory_id
3902
3930
  });
3903
3931
  const userCollection = weaviateClient.collections.get(collectionName);
3904
- const memory = await userCollection.query.fetchObjectById(args.memory_id);
3932
+ const memory = await fetchMemoryWithAllProperties(userCollection, args.memory_id);
3905
3933
  logger.debug("Memory fetch result", {
3906
3934
  tool: "remember_publish",
3907
3935
  found: !!memory,
3908
- memoryId: args.memory_id
3936
+ memoryId: args.memory_id,
3937
+ hasProperties: !!memory?.properties,
3938
+ propertyCount: memory?.properties ? Object.keys(memory.properties).length : 0,
3939
+ hasTitle: !!memory?.properties?.title,
3940
+ hasContent: !!memory?.properties?.content
3909
3941
  });
3910
3942
  if (!memory) {
3911
3943
  logger.info("Memory not found", {
@@ -4092,13 +4124,18 @@ async function executePublishMemory(request, userId) {
4092
4124
  collectionName: getMemoryCollectionName(userId),
4093
4125
  memoryId: request.payload.memory_id
4094
4126
  });
4095
- const originalMemory = await userCollection.query.fetchObjectById(
4127
+ const originalMemory = await fetchMemoryWithAllProperties(
4128
+ userCollection,
4096
4129
  request.payload.memory_id
4097
4130
  );
4098
4131
  logger.debug("Original memory fetch result", {
4099
4132
  function: "executePublishMemory",
4100
4133
  found: !!originalMemory,
4101
- memoryId: request.payload.memory_id
4134
+ memoryId: request.payload.memory_id,
4135
+ hasProperties: !!originalMemory?.properties,
4136
+ propertyCount: originalMemory?.properties ? Object.keys(originalMemory.properties).length : 0,
4137
+ hasTitle: !!originalMemory?.properties?.title,
4138
+ hasContent: !!originalMemory?.properties?.content
4102
4139
  });
4103
4140
  if (!originalMemory) {
4104
4141
  logger.info("Original memory not found", {
@@ -33,6 +33,22 @@ export declare function getTemplateCollectionName(userId: string): string;
33
33
  * Get collection name for user's audit logs
34
34
  */
35
35
  export declare function getAuditCollectionName(userId: string): string;
36
+ /**
37
+ * List of all memory properties to fetch
38
+ * Centralized to ensure consistency across all tools
39
+ */
40
+ export declare const ALL_MEMORY_PROPERTIES: readonly ["user_id", "doc_type", "type", "title", "content", "tags", "weight", "base_weight", "trust_level", "context", "location", "relationships", "created_at", "updated_at", "version", "attribution", "source_url", "author", "parent_id", "thread_root_id", "moderation_flags"];
41
+ /**
42
+ * Fetch a memory object by ID with all properties
43
+ *
44
+ * This utility ensures all memory properties are fetched consistently
45
+ * across all tools, preventing bugs where properties are missing.
46
+ *
47
+ * @param collection - Weaviate collection
48
+ * @param memoryId - Memory ID to fetch
49
+ * @returns Memory object with all properties
50
+ */
51
+ export declare function fetchMemoryWithAllProperties(collection: any, memoryId: string): Promise<any>;
36
52
  /**
37
53
  * Check if collection exists
38
54
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "2.6.2",
3
+ "version": "2.6.3",
4
4
  "description": "Multi-tenant memory system MCP server with vector search and relationships",
5
5
  "main": "dist/server.js",
6
6
  "type": "module",
@@ -7,7 +7,7 @@
7
7
 
8
8
  import type { Tool } from '@modelcontextprotocol/sdk/types.js';
9
9
  import { confirmationTokenService, type ConfirmationRequest } from '../services/confirmation-token.service.js';
10
- import { getWeaviateClient, getMemoryCollectionName } from '../weaviate/client.js';
10
+ import { getWeaviateClient, getMemoryCollectionName, fetchMemoryWithAllProperties } from '../weaviate/client.js';
11
11
  import { ensurePublicCollection } from '../weaviate/space-schema.js';
12
12
  import { handleToolError } from '../utils/error-handler.js';
13
13
  import { logger } from '../utils/logger.js';
@@ -151,7 +151,8 @@ async function executePublishMemory(
151
151
  memoryId: request.payload.memory_id,
152
152
  });
153
153
 
154
- const originalMemory = await userCollection.query.fetchObjectById(
154
+ const originalMemory = await fetchMemoryWithAllProperties(
155
+ userCollection,
155
156
  request.payload.memory_id
156
157
  );
157
158
 
@@ -159,6 +160,10 @@ async function executePublishMemory(
159
160
  function: 'executePublishMemory',
160
161
  found: !!originalMemory,
161
162
  memoryId: request.payload.memory_id,
163
+ hasProperties: !!originalMemory?.properties,
164
+ propertyCount: originalMemory?.properties ? Object.keys(originalMemory.properties).length : 0,
165
+ hasTitle: !!originalMemory?.properties?.title,
166
+ hasContent: !!originalMemory?.properties?.content,
162
167
  });
163
168
 
164
169
  if (!originalMemory) {
@@ -7,7 +7,7 @@
7
7
 
8
8
  import type { Tool } from '@modelcontextprotocol/sdk/types.js';
9
9
  import { confirmationTokenService } from '../services/confirmation-token.service.js';
10
- import { getWeaviateClient, getMemoryCollectionName } from '../weaviate/client.js';
10
+ import { getWeaviateClient, getMemoryCollectionName, fetchMemoryWithAllProperties } from '../weaviate/client.js';
11
11
  import { isValidSpaceId } from '../weaviate/space-schema.js';
12
12
  import { handleToolError } from '../utils/error-handler.js';
13
13
  import { SUPPORTED_SPACES } from '../types/space-memory.js';
@@ -122,12 +122,16 @@ export async function handlePublish(
122
122
 
123
123
  const userCollection = weaviateClient.collections.get(collectionName);
124
124
 
125
- const memory = await userCollection.query.fetchObjectById(args.memory_id);
125
+ const memory = await fetchMemoryWithAllProperties(userCollection, args.memory_id);
126
126
 
127
127
  logger.debug('Memory fetch result', {
128
128
  tool: 'remember_publish',
129
129
  found: !!memory,
130
130
  memoryId: args.memory_id,
131
+ hasProperties: !!memory?.properties,
132
+ propertyCount: memory?.properties ? Object.keys(memory.properties).length : 0,
133
+ hasTitle: !!memory?.properties?.title,
134
+ hasContent: !!memory?.properties?.content,
131
135
  });
132
136
 
133
137
  if (!memory) {
@@ -139,6 +139,53 @@ export function getAuditCollectionName(userId: string): string {
139
139
  return `Audit_${sanitizeUserId(userId)}`;
140
140
  }
141
141
 
142
+ /**
143
+ * List of all memory properties to fetch
144
+ * Centralized to ensure consistency across all tools
145
+ */
146
+ export const ALL_MEMORY_PROPERTIES = [
147
+ 'user_id',
148
+ 'doc_type',
149
+ 'type',
150
+ 'title',
151
+ 'content',
152
+ 'tags',
153
+ 'weight',
154
+ 'base_weight',
155
+ 'trust_level',
156
+ 'context',
157
+ 'location',
158
+ 'relationships',
159
+ 'created_at',
160
+ 'updated_at',
161
+ 'version',
162
+ 'attribution',
163
+ 'source_url',
164
+ 'author',
165
+ 'parent_id',
166
+ 'thread_root_id',
167
+ 'moderation_flags',
168
+ ] as const;
169
+
170
+ /**
171
+ * Fetch a memory object by ID with all properties
172
+ *
173
+ * This utility ensures all memory properties are fetched consistently
174
+ * across all tools, preventing bugs where properties are missing.
175
+ *
176
+ * @param collection - Weaviate collection
177
+ * @param memoryId - Memory ID to fetch
178
+ * @returns Memory object with all properties
179
+ */
180
+ export async function fetchMemoryWithAllProperties(
181
+ collection: any,
182
+ memoryId: string
183
+ ) {
184
+ return await collection.query.fetchObjectById(memoryId, {
185
+ returnProperties: ALL_MEMORY_PROPERTIES,
186
+ });
187
+ }
188
+
142
189
  /**
143
190
  * Check if collection exists
144
191
  */