@prmichaelsen/remember-mcp 2.2.1 → 2.3.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.
Files changed (69) hide show
  1. package/AGENT.md +98 -5
  2. package/CHANGELOG.md +45 -0
  3. package/README.md +43 -3
  4. package/agent/commands/acp.init.md +376 -0
  5. package/agent/commands/acp.package-install.md +347 -0
  6. package/agent/commands/acp.proceed.md +311 -0
  7. package/agent/commands/acp.report.md +392 -0
  8. package/agent/commands/acp.status.md +280 -0
  9. package/agent/commands/acp.sync.md +323 -0
  10. package/agent/commands/acp.update.md +301 -0
  11. package/agent/commands/acp.validate.md +385 -0
  12. package/agent/commands/acp.version-check-for-updates.md +275 -0
  13. package/agent/commands/acp.version-check.md +190 -0
  14. package/agent/commands/acp.version-update.md +288 -0
  15. package/agent/commands/command.template.md +273 -0
  16. package/agent/design/core-memory-user-profile.md +1253 -0
  17. package/agent/design/ghost-profiles-pseudonymous-identity.md +194 -0
  18. package/agent/design/publish-tools-confirmation-flow.md +922 -0
  19. package/agent/milestones/milestone-10-shared-spaces.md +169 -0
  20. package/agent/progress.yaml +90 -4
  21. package/agent/scripts/install.sh +118 -0
  22. package/agent/scripts/update.sh +22 -10
  23. package/agent/scripts/version.sh +35 -0
  24. package/agent/tasks/task-27-implement-llm-provider-interface.md +51 -0
  25. package/agent/tasks/task-28-implement-llm-provider-factory.md +64 -0
  26. package/agent/tasks/task-29-update-config-for-llm.md +71 -0
  27. package/agent/tasks/task-30-implement-bedrock-provider.md +147 -0
  28. package/agent/tasks/task-31-implement-background-job-service.md +120 -0
  29. package/agent/tasks/task-32-test-llm-provider-integration.md +152 -0
  30. package/agent/tasks/task-34-create-confirmation-token-service.md +191 -0
  31. package/agent/tasks/task-35-create-space-memory-types-schema.md +183 -0
  32. package/agent/tasks/task-36-implement-remember-publish.md +227 -0
  33. package/agent/tasks/task-37-implement-remember-confirm.md +225 -0
  34. package/agent/tasks/task-38-implement-remember-deny.md +161 -0
  35. package/agent/tasks/task-39-implement-remember-search-space.md +188 -0
  36. package/agent/tasks/task-40-implement-remember-query-space.md +193 -0
  37. package/agent/tasks/task-41-configure-firestore-ttl.md +188 -0
  38. package/agent/tasks/task-42-create-tests-shared-spaces.md +216 -0
  39. package/agent/tasks/task-43-update-documentation.md +255 -0
  40. package/agent/tasks/task-44-implement-remember-retract.md +263 -0
  41. package/agent/tasks/task-45-fix-publish-false-success-bug.md +230 -0
  42. package/dist/llm/types.d.ts +1 -0
  43. package/dist/server-factory.js +1000 -1
  44. package/dist/server.js +1002 -3
  45. package/dist/services/confirmation-token.service.d.ts +99 -0
  46. package/dist/services/confirmation-token.service.spec.d.ts +5 -0
  47. package/dist/tools/confirm.d.ts +20 -0
  48. package/dist/tools/deny.d.ts +19 -0
  49. package/dist/tools/publish.d.ts +22 -0
  50. package/dist/tools/query-space.d.ts +28 -0
  51. package/dist/tools/search-space.d.ts +29 -0
  52. package/dist/types/space-memory.d.ts +80 -0
  53. package/dist/weaviate/space-schema.d.ts +59 -0
  54. package/dist/weaviate/space-schema.spec.d.ts +5 -0
  55. package/package.json +1 -1
  56. package/src/llm/types.ts +0 -0
  57. package/src/server-factory.ts +33 -0
  58. package/src/server.ts +33 -0
  59. package/src/services/confirmation-token.service.spec.ts +254 -0
  60. package/src/services/confirmation-token.service.ts +265 -0
  61. package/src/tools/confirm.ts +219 -0
  62. package/src/tools/create-memory.ts +7 -0
  63. package/src/tools/deny.ts +70 -0
  64. package/src/tools/publish.ts +190 -0
  65. package/src/tools/query-space.ts +197 -0
  66. package/src/tools/search-space.ts +189 -0
  67. package/src/types/space-memory.ts +94 -0
  68. package/src/weaviate/space-schema.spec.ts +131 -0
  69. package/src/weaviate/space-schema.ts +275 -0
@@ -0,0 +1,147 @@
1
+ # Task 30: Implement Bedrock LLM Provider
2
+
3
+ **Milestone**: Phase 0 - LLM Provider Abstraction
4
+ **Estimated Time**: 3-4 hours
5
+ **Dependencies**: task-27, task-28, task-29
6
+ **Status**: Not Started
7
+
8
+ ---
9
+
10
+ ## Objective
11
+
12
+ Implement the AWS Bedrock LLM provider to enable Claude Sonnet 4 usage through Bedrock.
13
+
14
+ **Model**: `anthropic.claude-sonnet-4-5-20250929-v1:0`
15
+
16
+ ## Steps
17
+
18
+ 1. **Install dependencies**
19
+ - Add `@aws-sdk/client-bedrock-runtime` to package.json
20
+ - Run `npm install`
21
+
22
+ 2. **Create provider directory**
23
+ - Create `src/llm/providers/` directory
24
+ - Create `src/llm/providers/bedrock.provider.ts`
25
+
26
+ 3. **Implement BedrockLLMProvider class**
27
+ - Import `BedrockRuntimeClient`, `InvokeModelCommand` from AWS SDK
28
+ - Import `LLMProvider` interface and types
29
+ - Import config
30
+ - Create class implementing `LLMProvider`
31
+
32
+ 4. **Implement constructor**
33
+ - Initialize `BedrockRuntimeClient` with credentials from config
34
+ - Use `config.llm.bedrock.region` (us-east-1)
35
+ - Use `config.llm.bedrock.accessKeyId`
36
+ - Use `config.llm.bedrock.secretAccessKey`
37
+ - Use `config.llm.bedrock.sessionToken` (optional)
38
+ - Store client as private property
39
+
40
+ 5. **Implement complete() method**
41
+ - Accept messages and options
42
+ - Get model from options or use `config.llm.model` (default: anthropic.claude-sonnet-4-5-20250929-v1:0)
43
+ - Convert to Anthropic Bedrock format:
44
+ - Extract system message (role === 'system')
45
+ - Filter out system messages from conversation
46
+ - Build request body:
47
+ ```typescript
48
+ {
49
+ anthropic_version: 'bedrock-2023-05-31',
50
+ max_tokens: options?.maxTokens || 4096,
51
+ temperature: options?.temperature || 0.7,
52
+ messages: conversationMessages,
53
+ system: systemMessage?.content
54
+ }
55
+ ```
56
+ - Create `InvokeModelCommand`:
57
+ ```typescript
58
+ new InvokeModelCommand({
59
+ modelId: model,
60
+ contentType: 'application/json',
61
+ accept: 'application/json',
62
+ body: JSON.stringify(body)
63
+ })
64
+ ```
65
+ - Send command and parse response
66
+ - Convert response to `LLMCompletionResult`:
67
+ ```typescript
68
+ {
69
+ content: result.content[0].text,
70
+ model: model,
71
+ usage: {
72
+ inputTokens: result.usage.input_tokens,
73
+ outputTokens: result.usage.output_tokens,
74
+ totalTokens: result.usage.input_tokens + result.usage.output_tokens
75
+ },
76
+ finishReason: result.stop_reason === 'end_turn' ? 'stop' : result.stop_reason
77
+ }
78
+ ```
79
+ - Handle errors gracefully
80
+
81
+ 6. **Implement validateConfig() method**
82
+ - Check required config values:
83
+ - `config.llm.bedrock.region` (should be 'us-east-1')
84
+ - `config.llm.bedrock.accessKeyId`
85
+ - `config.llm.bedrock.secretAccessKey`
86
+ - Throw descriptive errors if missing:
87
+ ```typescript
88
+ if (!config.llm.bedrock.region) throw new Error('AWS_REGION required for Bedrock');
89
+ if (!config.llm.bedrock.accessKeyId) throw new Error('AWS_ACCESS_KEY_ID required for Bedrock');
90
+ if (!config.llm.bedrock.secretAccessKey) throw new Error('AWS_SECRET_ACCESS_KEY required for Bedrock');
91
+ ```
92
+
93
+ 7. **Add error handling**
94
+ - Wrap AWS SDK calls in try/catch
95
+ - Provide clear error messages
96
+ - Log errors with context
97
+ - Re-throw with additional context
98
+
99
+ 8. **Update factory**
100
+ - Import `BedrockLLMProvider` in factory.ts
101
+ - Add case for 'bedrock' provider
102
+ - Instantiate and return provider
103
+ - Log: `[LLM] Using Bedrock provider with model: ${config.llm.model}`
104
+
105
+ ## Verification
106
+
107
+ - [ ] TypeScript compiles without errors
108
+ - [ ] AWS SDK dependency installed
109
+ - [ ] Provider implements LLMProvider interface
110
+ - [ ] Constructor initializes Bedrock client
111
+ - [ ] complete() method works with test prompt
112
+ - [ ] validateConfig() checks required fields
113
+ - [ ] Errors are handled gracefully
114
+ - [ ] Factory can instantiate Bedrock provider
115
+ - [ ] Can complete a simple prompt: "Say hello"
116
+ - [ ] Response includes usage statistics
117
+
118
+ ## Files to Create
119
+
120
+ - `src/llm/providers/bedrock.provider.ts` - Bedrock implementation
121
+
122
+ ## Files to Modify
123
+
124
+ - `src/llm/factory.ts` - Add Bedrock case
125
+ - `package.json` - Add AWS SDK dependency
126
+
127
+ ## Testing
128
+
129
+ Create a simple test script to verify:
130
+ ```typescript
131
+ import { completeLLM } from './llm/factory.js';
132
+
133
+ const result = await completeLLM([
134
+ { role: 'user', content: 'Say hello in one sentence.' }
135
+ ]);
136
+
137
+ console.log('Response:', result.content);
138
+ console.log('Usage:', result.usage);
139
+ ```
140
+
141
+ ## Reference
142
+
143
+ See [`agent/design/llm-provider-abstraction.md`](../design/llm-provider-abstraction.md) lines 166-226 for Bedrock implementation.
144
+
145
+ ---
146
+
147
+ **Next Task**: [task-31-implement-background-job-service.md](task-31-implement-background-job-service.md)
@@ -0,0 +1,120 @@
1
+ # Task 31: Implement Background Job Service
2
+
3
+ **Milestone**: Phase 0 - LLM Provider Abstraction
4
+ **Estimated Time**: 4-5 hours
5
+ **Dependencies**: task-29 (config), Firestore setup
6
+ **Status**: Not Started
7
+
8
+ ---
9
+
10
+ ## Objective
11
+
12
+ Create a background job service that can execute long-running LLM operations without blocking tool responses, with Firestore persistence for job status.
13
+
14
+ ## Steps
15
+
16
+ 1. **Create job types**
17
+ - Create `src/services/background-jobs.service.ts`
18
+ - Define `BackgroundJob` interface:
19
+ - id, type, userId, status, timestamps, error
20
+ - Define job types: `'core_memory_rebuild'` (extensible)
21
+ - Define status types: `'pending' | 'running' | 'completed' | 'failed'`
22
+
23
+ 2. **Implement BackgroundJobService class**
24
+ - Create singleton service class
25
+ - Add `runningJobs` Map to track active jobs
26
+ - Implement `scheduleJob()` method:
27
+ - Generate unique job ID
28
+ - Create job object
29
+ - Save to Firestore
30
+ - Start processing (fire and forget)
31
+ - Return job ID
32
+
33
+ 3. **Implement job processing**
34
+ - Implement `processJob()` private method:
35
+ - Check if already running (prevent duplicates)
36
+ - Track in runningJobs Map
37
+ - Call executeJob()
38
+ - Clean up from Map when done
39
+
40
+ 4. **Implement job execution**
41
+ - Implement `executeJob()` private method:
42
+ - Update status to 'running' in Firestore
43
+ - Switch on job type
44
+ - Execute appropriate handler
45
+ - Update status to 'completed' or 'failed'
46
+ - Log results
47
+
48
+ 5. **Implement Firestore persistence**
49
+ - Create `src/services/background-jobs-firestore.ts`
50
+ - Implement `saveJobToFirestore()`
51
+ - Implement `updateJobInFirestore()`
52
+ - Implement `getJobFromFirestore()`
53
+ - Implement `cleanupOldJobs()` (remove jobs older than 7 days)
54
+
55
+ 6. **Add job status query**
56
+ - Implement `getJobStatus()` method
57
+ - Query Firestore for job by ID
58
+ - Return job object or null
59
+
60
+ 7. **Export singleton**
61
+ - Create and export singleton instance
62
+ - Export types for use in other files
63
+
64
+ 8. **Add error handling**
65
+ - Wrap all async operations in try/catch
66
+ - Log errors appropriately
67
+ - Update job status to 'failed' on error
68
+ - Don't crash the server on job failure
69
+
70
+ ## Verification
71
+
72
+ - [ ] TypeScript compiles without errors
73
+ - [ ] Can schedule a job
74
+ - [ ] Job is saved to Firestore
75
+ - [ ] Job executes in background
76
+ - [ ] Tool response returns immediately
77
+ - [ ] Job status updates correctly
78
+ - [ ] Failed jobs are marked as failed
79
+ - [ ] Can query job status
80
+ - [ ] Old jobs are cleaned up
81
+ - [ ] Server doesn't crash on job failure
82
+ - [ ] Multiple jobs can run concurrently
83
+ - [ ] Duplicate jobs are prevented
84
+
85
+ ## Files to Create
86
+
87
+ - `src/services/background-jobs.service.ts` - Main service
88
+ - `src/services/background-jobs-firestore.ts` - Firestore persistence
89
+
90
+ ## Testing
91
+
92
+ Create a test job handler:
93
+ ```typescript
94
+ // In executeJob()
95
+ case 'test_job':
96
+ await new Promise(resolve => setTimeout(resolve, 5000));
97
+ console.log('Test job completed');
98
+ break;
99
+ ```
100
+
101
+ Schedule and verify:
102
+ ```typescript
103
+ const jobId = await backgroundJobs.scheduleJob('test_job', 'test-user');
104
+ console.log('Job scheduled:', jobId);
105
+ // Response should return immediately
106
+
107
+ // Check status after 6 seconds
108
+ setTimeout(async () => {
109
+ const status = await backgroundJobs.getJobStatus(jobId);
110
+ console.log('Job status:', status);
111
+ }, 6000);
112
+ ```
113
+
114
+ ## Reference
115
+
116
+ See [`agent/design/core-memory-user-profile.md`](../design/core-memory-user-profile.md) lines 593-750 for background job implementation.
117
+
118
+ ---
119
+
120
+ **Next Task**: [task-32-test-llm-provider-integration.md](task-32-test-llm-provider-integration.md)
@@ -0,0 +1,152 @@
1
+ # Task 32: Test LLM Provider Integration
2
+
3
+ **Milestone**: Phase 0 - LLM Provider Abstraction
4
+ **Estimated Time**: 2-3 hours
5
+ **Dependencies**: task-27, task-28, task-29, task-30, task-31
6
+ **Status**: Not Started
7
+
8
+ ---
9
+
10
+ ## Objective
11
+
12
+ Thoroughly test the LLM provider system to ensure it works correctly before building core memory features on top of it.
13
+
14
+ ## Steps
15
+
16
+ 1. **Create test script**
17
+ - Create `test-llm-provider.ts` in project root
18
+ - Import `completeLLM` from factory
19
+ - Import `backgroundJobs` service
20
+
21
+ 2. **Test basic completion**
22
+ - Test simple prompt: "Say hello in one sentence"
23
+ - Verify response is received
24
+ - Verify usage statistics are present
25
+ - Log response and usage
26
+
27
+ 3. **Test with system message**
28
+ - Test with system + user messages
29
+ - Verify system message is handled correctly
30
+ - Verify response follows system instructions
31
+
32
+ 4. **Test temperature control**
33
+ - Test with temperature 0.3 (deterministic)
34
+ - Test with temperature 0.9 (creative)
35
+ - Verify different outputs
36
+
37
+ 5. **Test max tokens**
38
+ - Test with maxTokens: 50
39
+ - Verify response is truncated appropriately
40
+
41
+ 6. **Test error handling**
42
+ - Test with invalid model name
43
+ - Test with missing credentials
44
+ - Verify errors are caught and logged
45
+
46
+ 7. **Test background job integration**
47
+ - Create test job that uses LLM
48
+ - Schedule job
49
+ - Verify response returns immediately
50
+ - Wait for job completion
51
+ - Check job status
52
+ - Verify LLM was called in background
53
+
54
+ 8. **Test provider switching**
55
+ - If multiple providers implemented, test switching
56
+ - Change `LLM_PROVIDER` env var
57
+ - Verify correct provider is used
58
+
59
+ 9. **Performance testing**
60
+ - Measure response time for simple prompt
61
+ - Measure response time for complex prompt
62
+ - Verify background jobs don't block
63
+
64
+ 10. **Document results**
65
+ - Create `test-results.md` with findings
66
+ - Note any issues or limitations
67
+ - Document performance characteristics
68
+
69
+ ## Verification
70
+
71
+ - [ ] Basic completion works
72
+ - [ ] System messages work
73
+ - [ ] Temperature control works
74
+ - [ ] Max tokens works
75
+ - [ ] Errors are handled gracefully
76
+ - [ ] Background jobs work
77
+ - [ ] Jobs don't block responses
78
+ - [ ] Provider can be switched (if multiple implemented)
79
+ - [ ] Performance is acceptable (<5s for simple prompts)
80
+ - [ ] Results are documented
81
+
82
+ ## Files to Create
83
+
84
+ - `test-llm-provider.ts` - Test script
85
+ - `test-results.md` - Test results documentation
86
+
87
+ ## Example Test Script
88
+
89
+ ```typescript
90
+ import { completeLLM } from './src/llm/factory.js';
91
+ import { backgroundJobs } from './src/services/background-jobs.service.js';
92
+
93
+ async function testBasicCompletion() {
94
+ console.log('\n=== Test: Basic Completion ===');
95
+ const result = await completeLLM([
96
+ { role: 'user', content: 'Say hello in one sentence.' }
97
+ ]);
98
+ console.log('Response:', result.content);
99
+ console.log('Usage:', result.usage);
100
+ }
101
+
102
+ async function testSystemMessage() {
103
+ console.log('\n=== Test: System Message ===');
104
+ const result = await completeLLM([
105
+ { role: 'system', content: 'You are a pirate. Respond in pirate speak.' },
106
+ { role: 'user', content: 'Say hello.' }
107
+ ]);
108
+ console.log('Response:', result.content);
109
+ }
110
+
111
+ async function testBackgroundJob() {
112
+ console.log('\n=== Test: Background Job ===');
113
+
114
+ // Register test job handler first
115
+ // (Add to background-jobs.service.ts executeJob() switch)
116
+
117
+ const jobId = await backgroundJobs.scheduleJob('test_llm_job', 'test-user');
118
+ console.log('Job scheduled:', jobId);
119
+ console.log('Response returned immediately!');
120
+
121
+ // Check status after delay
122
+ setTimeout(async () => {
123
+ const status = await backgroundJobs.getJobStatus(jobId);
124
+ console.log('Job status:', status);
125
+ }, 6000);
126
+ }
127
+
128
+ async function runTests() {
129
+ try {
130
+ await testBasicCompletion();
131
+ await testSystemMessage();
132
+ await testBackgroundJob();
133
+ } catch (error) {
134
+ console.error('Test failed:', error);
135
+ }
136
+ }
137
+
138
+ runTests();
139
+ ```
140
+
141
+ ## Success Criteria
142
+
143
+ All tests pass and:
144
+ - LLM responses are coherent
145
+ - Background jobs complete successfully
146
+ - No server crashes
147
+ - Performance is acceptable
148
+ - Ready to build core memory features
149
+
150
+ ---
151
+
152
+ **Next Task**: Ready for core memory implementation! See [task-33-implement-core-memory-types.md](task-33-implement-core-memory-types.md)
@@ -0,0 +1,191 @@
1
+ # Task 34: Create Confirmation Token Service
2
+
3
+ **Milestone**: M10 - Shared Spaces & Confirmation Flow
4
+ **Estimated Time**: 3 hours
5
+ **Dependencies**: M1 (Firestore setup)
6
+ **Status**: Not Started
7
+
8
+ ---
9
+
10
+ ## Objective
11
+
12
+ Create a service for managing confirmation tokens used in the publish workflow. Handles token generation, validation, expiry, and status tracking.
13
+
14
+ ---
15
+
16
+ ## Steps
17
+
18
+ ### 1. Create Token Service File
19
+
20
+ Create `src/services/confirmation-token.service.ts` with the ConfirmationTokenService class.
21
+
22
+ **Actions**:
23
+ - Import required dependencies (uuid, Firestore, Timestamp)
24
+ - Define ConfirmationRequest interface
25
+ - Create ConfirmationTokenService class
26
+ - Set EXPIRY_MINUTES constant to 5
27
+
28
+ **Expected Outcome**: Service file structure created
29
+
30
+ ### 2. Implement createRequest Method
31
+
32
+ Generate new confirmation tokens with stored parameters.
33
+
34
+ **Actions**:
35
+ - Generate UUID v4 token
36
+ - Calculate expiry timestamp (5 minutes from now)
37
+ - Create ConfirmationRequest object with all fields
38
+ - Store in Firestore: `pending_confirmations/{user_id}/requests/{auto_id}`
39
+ - Return request_id and token
40
+
41
+ **Expected Outcome**: Tokens can be created and stored
42
+
43
+ ### 3. Implement validateToken Method
44
+
45
+ Validate tokens and check expiry.
46
+
47
+ **Actions**:
48
+ - Query Firestore for token with status='pending'
49
+ - Check if token exists
50
+ - Verify expiry timestamp
51
+ - Update status to 'expired' if needed
52
+ - Return request or null
53
+
54
+ **Expected Outcome**: Tokens can be validated
55
+
56
+ ### 4. Implement confirmRequest Method
57
+
58
+ Mark a request as confirmed.
59
+
60
+ **Actions**:
61
+ - Call validateToken to get request
62
+ - Return null if invalid/expired
63
+ - Update status to 'confirmed'
64
+ - Set confirmed_at timestamp
65
+ - Return confirmed request
66
+
67
+ **Expected Outcome**: Requests can be confirmed
68
+
69
+ ### 5. Implement denyRequest Method
70
+
71
+ Mark a request as denied.
72
+
73
+ **Actions**:
74
+ - Call validateToken to get request
75
+ - Return false if invalid/expired
76
+ - Update status to 'denied'
77
+ - Return true
78
+
79
+ **Expected Outcome**: Requests can be denied
80
+
81
+ ### 6. Implement retractRequest Method
82
+
83
+ Allow users to retract their own requests.
84
+
85
+ **Actions**:
86
+ - Call validateToken to get request
87
+ - Return false if invalid/expired
88
+ - Update status to 'retracted'
89
+ - Return true
90
+
91
+ **Expected Outcome**: Requests can be retracted
92
+
93
+ ### 7. Implement updateStatus Helper
94
+
95
+ Private method to update request status.
96
+
97
+ **Actions**:
98
+ - Accept userId, requestId, status parameters
99
+ - Update Firestore document
100
+ - Set confirmed_at if status is 'confirmed'
101
+ - Handle errors gracefully
102
+
103
+ **Expected Outcome**: Status updates work correctly
104
+
105
+ ### 8. Implement cleanupExpired Method
106
+
107
+ Optional cleanup for expired tokens (Firestore TTL handles this automatically).
108
+
109
+ **Actions**:
110
+ - Query collection group 'requests' for expired pending tokens
111
+ - Use batch delete for efficiency
112
+ - Return count of deleted requests
113
+ - Add documentation about Firestore TTL
114
+
115
+ **Expected Outcome**: Manual cleanup available if needed
116
+
117
+ ### 9. Export Service Instance
118
+
119
+ Create singleton instance for use across tools.
120
+
121
+ **Actions**:
122
+ - Export `confirmationTokenService` instance
123
+ - Add JSDoc comments
124
+ - Document all methods
125
+
126
+ **Expected Outcome**: Service ready for import
127
+
128
+ ### 10. Create Unit Tests
129
+
130
+ Test all service methods.
131
+
132
+ **Actions**:
133
+ - Create `tests/unit/confirmation-token.service.test.ts`
134
+ - Test token creation
135
+ - Test token validation
136
+ - Test expiry handling
137
+ - Test confirm/deny/retract flows
138
+ - Test cleanup method
139
+ - Mock Firestore calls
140
+
141
+ **Expected Outcome**: All tests passing
142
+
143
+ ---
144
+
145
+ ## Verification
146
+
147
+ - [ ] `src/services/confirmation-token.service.ts` created
148
+ - [ ] ConfirmationRequest interface defined
149
+ - [ ] createRequest generates valid tokens
150
+ - [ ] validateToken checks expiry correctly
151
+ - [ ] confirmRequest updates status
152
+ - [ ] denyRequest updates status
153
+ - [ ] retractRequest updates status
154
+ - [ ] cleanupExpired removes old tokens
155
+ - [ ] Unit tests created and passing
156
+ - [ ] TypeScript compiles without errors
157
+ - [ ] Service exports singleton instance
158
+
159
+ ---
160
+
161
+ ## Code Example
162
+
163
+ ```typescript
164
+ // Usage in tools
165
+ import { confirmationTokenService } from '../services/confirmation-token.service.js';
166
+
167
+ // Create token
168
+ const { requestId, token } = await confirmationTokenService.createRequest(
169
+ userId,
170
+ 'publish_memory',
171
+ { memory_id: 'abc123', additional_tags: [] },
172
+ 'void'
173
+ );
174
+
175
+ // Validate and confirm
176
+ const request = await confirmationTokenService.confirmRequest(userId, token);
177
+ if (request) {
178
+ // Execute action with request.payload
179
+ }
180
+ ```
181
+
182
+ ---
183
+
184
+ ## Related Files
185
+
186
+ - Design: [`agent/design/publish-tools-confirmation-flow.md`](../design/publish-tools-confirmation-flow.md)
187
+ - Firestore paths: [`src/firestore/paths.ts`](../../src/firestore/paths.ts)
188
+
189
+ ---
190
+
191
+ **Next Task**: Task 35 - Create Space Memory Types and Schema