@prmichaelsen/remember-mcp 3.15.4 → 3.15.6

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 (132) hide show
  1. package/AGENT.md +363 -5
  2. package/CHANGELOG.md +7 -0
  3. package/agent/commands/acp.clarification-capture.md +386 -0
  4. package/agent/commands/acp.clarification-create.md +50 -0
  5. package/agent/commands/acp.command-create.md +60 -0
  6. package/agent/commands/acp.design-create.md +62 -0
  7. package/agent/commands/acp.design-reference.md +355 -0
  8. package/agent/commands/acp.index.md +423 -0
  9. package/agent/commands/acp.init.md +48 -0
  10. package/agent/commands/acp.package-create.md +1 -0
  11. package/agent/commands/acp.package-info.md +1 -0
  12. package/agent/commands/acp.package-install.md +19 -0
  13. package/agent/commands/acp.package-list.md +1 -0
  14. package/agent/commands/acp.package-publish.md +1 -0
  15. package/agent/commands/acp.package-remove.md +1 -0
  16. package/agent/commands/acp.package-search.md +1 -0
  17. package/agent/commands/acp.package-update.md +1 -0
  18. package/agent/commands/acp.package-validate.md +1 -0
  19. package/agent/commands/acp.pattern-create.md +60 -0
  20. package/agent/commands/acp.plan.md +25 -0
  21. package/agent/commands/acp.proceed.md +621 -75
  22. package/agent/commands/acp.project-create.md +3 -0
  23. package/agent/commands/acp.project-info.md +3 -0
  24. package/agent/commands/acp.project-list.md +3 -1
  25. package/agent/commands/acp.project-set.md +1 -0
  26. package/agent/commands/acp.project-update.md +14 -3
  27. package/agent/commands/acp.projects-restore.md +228 -0
  28. package/agent/commands/acp.projects-sync.md +347 -0
  29. package/agent/commands/acp.report.md +13 -0
  30. package/agent/commands/acp.resume.md +3 -1
  31. package/agent/commands/acp.sessions.md +301 -0
  32. package/agent/commands/acp.status.md +13 -0
  33. package/agent/commands/acp.sync.md +1 -0
  34. package/agent/commands/acp.task-create.md +105 -3
  35. package/agent/commands/acp.update.md +1 -0
  36. package/agent/commands/acp.validate.md +32 -2
  37. package/agent/commands/acp.version-check-for-updates.md +1 -0
  38. package/agent/commands/acp.version-check.md +1 -0
  39. package/agent/commands/acp.version-update.md +1 -0
  40. package/agent/commands/command.template.md +23 -0
  41. package/agent/commands/git.commit.md +1 -0
  42. package/agent/commands/git.init.md +1 -0
  43. package/agent/design/complete-tool-set.md +157 -233
  44. package/agent/design/design.template.md +18 -0
  45. package/agent/design/user-preferences.md +11 -7
  46. package/agent/milestones/milestone-19-new-search-ghost-tools.md +46 -0
  47. package/agent/package.template.yaml +50 -0
  48. package/agent/patterns/pattern.template.md +18 -0
  49. package/agent/progress.yaml +162 -6
  50. package/agent/scripts/acp.common.sh +258 -15
  51. package/agent/scripts/acp.install.sh +91 -4
  52. package/agent/scripts/acp.package-create.sh +0 -1
  53. package/agent/scripts/acp.package-info.sh +19 -1
  54. package/agent/scripts/acp.package-install-optimized.sh +1 -1
  55. package/agent/scripts/acp.package-install.sh +388 -38
  56. package/agent/scripts/acp.package-list.sh +52 -4
  57. package/agent/scripts/acp.package-remove.sh +77 -1
  58. package/agent/scripts/acp.package-search.sh +2 -2
  59. package/agent/scripts/acp.package-update.sh +91 -12
  60. package/agent/scripts/acp.package-validate.sh +136 -1
  61. package/agent/scripts/acp.project-info.sh +34 -11
  62. package/agent/scripts/acp.project-list.sh +4 -0
  63. package/agent/scripts/acp.project-update.sh +66 -19
  64. package/agent/scripts/acp.projects-restore.sh +170 -0
  65. package/agent/scripts/acp.projects-sync.sh +155 -0
  66. package/agent/scripts/acp.sessions.sh +725 -0
  67. package/agent/scripts/acp.version-update.sh +21 -3
  68. package/agent/scripts/acp.yaml-parser.sh +20 -6
  69. package/agent/tasks/milestone-19-new-search-ghost-tools/task-203-create-search-by-tool.md +143 -0
  70. package/agent/tasks/milestone-19-new-search-ghost-tools/task-204-add-new-filters-existing-tools.md +77 -0
  71. package/agent/tasks/milestone-19-new-search-ghost-tools/task-205-add-feel-fields-create-update.md +137 -0
  72. package/agent/tasks/milestone-19-new-search-ghost-tools/task-206-add-byproperty-bysignificance-modes.md +135 -0
  73. package/agent/tasks/milestone-19-new-search-ghost-tools/task-207-add-emotional-composites-search-results.md +88 -0
  74. package/agent/tasks/milestone-19-new-search-ghost-tools/task-208-add-bybroad-byrandom-modes.md +115 -0
  75. package/agent/tasks/milestone-19-new-search-ghost-tools/task-209-create-ghost-memory-tools.md +192 -0
  76. package/agent/tasks/milestone-19-new-search-ghost-tools/task-210-create-get-core-tool.md +203 -0
  77. package/agent/tasks/milestone-19-new-search-ghost-tools/task-211-create-search-space-by-tool.md +182 -0
  78. package/agent/tasks/task-1-{title}.template.md +19 -0
  79. package/agent/tasks/unassigned/bug-report-remember-core-e2e-findings.md +99 -0
  80. package/dist/e2e-helpers.d.ts +26 -0
  81. package/dist/ghost-persona.e2e.d.ts +8 -0
  82. package/dist/memory-crud.e2e.d.ts +8 -0
  83. package/dist/preferences.e2e.d.ts +8 -0
  84. package/dist/relationships.e2e.d.ts +8 -0
  85. package/dist/search-modes.e2e.d.ts +8 -0
  86. package/dist/server-factory.js +1977 -100
  87. package/dist/server.js +1174 -51
  88. package/dist/shared-spaces.e2e.d.ts +8 -0
  89. package/dist/tools/create-ghost-memory.d.ts +70 -0
  90. package/dist/tools/create-memory.d.ts +175 -0
  91. package/dist/tools/get-core.d.ts +28 -0
  92. package/dist/tools/get-core.spec.d.ts +2 -0
  93. package/dist/tools/ghost-tools.spec.d.ts +2 -0
  94. package/dist/tools/query-ghost-memory.d.ts +34 -0
  95. package/dist/tools/query-memory.d.ts +4 -0
  96. package/dist/tools/search-by.d.ts +147 -0
  97. package/dist/tools/search-by.spec.d.ts +2 -0
  98. package/dist/tools/search-ghost-memory-by.d.ts +54 -0
  99. package/dist/tools/search-ghost-memory.d.ts +53 -0
  100. package/dist/tools/search-memory.d.ts +19 -0
  101. package/dist/tools/search-space-by.d.ts +78 -0
  102. package/dist/tools/search-space-by.spec.d.ts +2 -0
  103. package/dist/tools/search-space.d.ts +2 -0
  104. package/dist/tools/update-ghost-memory.d.ts +51 -0
  105. package/dist/tools/update-memory.d.ts +175 -0
  106. package/jest.e2e.config.js +11 -0
  107. package/package.json +2 -2
  108. package/src/e2e-helpers.ts +86 -0
  109. package/src/ghost-persona.e2e.ts +215 -0
  110. package/src/memory-crud.e2e.ts +203 -0
  111. package/src/preferences.e2e.ts +88 -0
  112. package/src/relationships.e2e.ts +156 -0
  113. package/src/search-modes.e2e.ts +184 -0
  114. package/src/server-factory.ts +56 -0
  115. package/src/shared-spaces.e2e.ts +204 -0
  116. package/src/tools/create-ghost-memory.ts +103 -0
  117. package/src/tools/create-memory.ts +45 -1
  118. package/src/tools/get-core.spec.ts +223 -0
  119. package/src/tools/get-core.ts +109 -0
  120. package/src/tools/ghost-tools.spec.ts +361 -0
  121. package/src/tools/query-ghost-memory.ts +63 -0
  122. package/src/tools/query-memory.ts +4 -0
  123. package/src/tools/search-by.spec.ts +325 -0
  124. package/src/tools/search-by.ts +298 -0
  125. package/src/tools/search-ghost-memory-by.ts +80 -0
  126. package/src/tools/search-ghost-memory.ts +73 -0
  127. package/src/tools/search-memory.ts +23 -0
  128. package/src/tools/search-space-by.spec.ts +289 -0
  129. package/src/tools/search-space-by.ts +173 -0
  130. package/src/tools/search-space.ts +20 -1
  131. package/src/tools/update-ghost-memory.ts +86 -0
  132. package/src/tools/update-memory.ts +45 -1
@@ -3,6 +3,20 @@
3
3
  # Agent Context Protocol (ACP) Update Script
4
4
  # This script updates AGENT.md, template files, and utility scripts from the repository
5
5
 
6
+ # Self-relocation guard: this script overwrites itself during the update
7
+ # (it copies the latest version from the repo to agent/scripts/). Bash reads
8
+ # files lazily by byte offset, so the overwrite garbles execution. Fix: re-exec
9
+ # from a temp copy so the file on disk can safely change.
10
+ if [ -z "$_ACP_UPDATE_RELOCATED" ]; then
11
+ _tmp_copy=$(mktemp)
12
+ cp "$0" "$_tmp_copy"
13
+ export _ACP_UPDATE_RELOCATED=1
14
+ bash "$_tmp_copy" "$@"
15
+ _rc=$?
16
+ rm -f "$_tmp_copy"
17
+ exit $_rc
18
+ fi
19
+
6
20
  set -e
7
21
 
8
22
  # Colors for output using tput (more reliable than ANSI codes)
@@ -61,6 +75,10 @@ if [ ! -f "agent/.gitignore" ]; then
61
75
 
62
76
  # Reports directory - generated by @acp.report command
63
77
  reports/
78
+ clarifications/
79
+ feedback/
80
+ drafts/
81
+ preferences/
64
82
  EOF
65
83
  echo "${GREEN}✓${NC} Created agent/.gitignore"
66
84
  fi
@@ -123,13 +141,13 @@ if [ -f "agent/manifest.yaml" ]; then
123
141
  UPDATE_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
124
142
 
125
143
  # Update acp-core version and timestamps
126
- sed -i "/^ acp-core:/,/^ [a-z]/ {
144
+ _sed_i "/^ acp-core:/,/^ [a-z]/ {
127
145
  s/package_version: .*/package_version: ${NEW_VERSION}/
128
146
  s/updated_at: .*/updated_at: ${UPDATE_DATE}/
129
147
  }" agent/manifest.yaml
130
-
148
+
131
149
  # Update manifest timestamp
132
- sed -i "s/^last_updated: .*/last_updated: ${UPDATE_DATE}/" agent/manifest.yaml
150
+ _sed_i "s/^last_updated: .*/last_updated: ${UPDATE_DATE}/" agent/manifest.yaml
133
151
 
134
152
  echo "${GREEN}✓${NC} Updated acp-core to v${NEW_VERSION} in manifest.yaml"
135
153
  echo ""
@@ -4,6 +4,20 @@
4
4
  # Version: 1.0.0
5
5
  # Created: 2026-02-21
6
6
 
7
+ # ============================================================================
8
+ # PORTABILITY HELPERS
9
+ # ============================================================================
10
+
11
+ # Portable in-place sed (works on both GNU and BSD/macOS sed)
12
+ # Usage: _yaml_sed_i "expression" "file"
13
+ _yaml_sed_i() {
14
+ if [ "$(uname)" = "Darwin" ]; then
15
+ sed -i '' "$@"
16
+ else
17
+ sed -i "$@"
18
+ fi
19
+ }
20
+
7
21
  # ============================================================================
8
22
  # GLOBAL STATE
9
23
  # ============================================================================
@@ -85,7 +99,7 @@ add_child() {
85
99
  fi
86
100
 
87
101
  local updated="$id|$type|$key|$value|$parent|$children"
88
- sed -i "$((parent_id + 1))s@.*@$updated@" "$AST_FILE"
102
+ _yaml_sed_i "$((parent_id + 1))s@.*@$updated@" "$AST_FILE"
89
103
  }
90
104
 
91
105
  update_node_type() {
@@ -103,7 +117,7 @@ update_node_type() {
103
117
  children=$(echo "$node" | cut -d'|' -f6)
104
118
 
105
119
  local updated="$id|$new_type|$key|$value|$parent|$children"
106
- sed -i "$((node_id + 1))s@.*@$updated@" "$AST_FILE"
120
+ _yaml_sed_i "$((node_id + 1))s@.*@$updated@" "$AST_FILE"
107
121
  }
108
122
 
109
123
  # ============================================================================
@@ -388,7 +402,7 @@ create_node_and_link() {
388
402
  # Update parent node with new children list
389
403
  local parent_prefix
390
404
  parent_prefix=$(echo "$parent_line" | cut -d'|' -f1-5)
391
- sed -i "$((parent_id + 1))s@.*@${parent_prefix}|${parent_children}@" "$AST_FILE"
405
+ _yaml_sed_i "$((parent_id + 1))s@.*@${parent_prefix}|${parent_children}@" "$AST_FILE"
392
406
  fi
393
407
 
394
408
  echo "$next_id"
@@ -496,11 +510,11 @@ yaml_set() {
496
510
  if [ "$new_value" = "[]" ]; then
497
511
  # Convert node to array type and clear children
498
512
  local updated="$id|array|$key||$parent|"
499
- sed -i "$((current_node + 1))s@.*@$updated@" "$AST_FILE"
513
+ _yaml_sed_i "$((current_node + 1))s@.*@$updated@" "$AST_FILE"
500
514
  else
501
515
  new_value=$(echo "$new_value" | sed 's/|/\\|/g')
502
516
  local updated="$id|$type|$key|$new_value|$parent|$children"
503
- sed -i "$((current_node + 1))s@.*@$updated@" "$AST_FILE"
517
+ _yaml_sed_i "$((current_node + 1))s@.*@$updated@" "$AST_FILE"
504
518
  fi
505
519
  }
506
520
 
@@ -838,7 +852,7 @@ yaml_delete() {
838
852
 
839
853
  # Update parent node
840
854
  local updated="$id|$type|$key|$value|$parent|$new_children"
841
- sed -i "$((current_node + 1))s@.*@$updated@" "$AST_FILE"
855
+ _yaml_sed_i "$((current_node + 1))s@.*@$updated@" "$AST_FILE"
842
856
 
843
857
  return 0
844
858
  }
@@ -0,0 +1,143 @@
1
+ # Task 203: Create `remember_search_by` Tool
2
+
3
+ **Milestone**: M19 — New Search Modes, Ghost Tools & Emotional Exposure
4
+ **Status**: Not Started
5
+ **Created**: 2026-03-07
6
+ **Estimated Hours**: 3-4
7
+ **Dependencies**: remember-core MemoryService.byTime/byDensity/byRating/byDiscovery methods
8
+
9
+ ---
10
+
11
+ ## Objective
12
+
13
+ Create the `remember_search_by` MCP tool with initial modes: byTime, byDensity, byRating, byDiscovery. This is the foundation tool that later tasks extend with additional modes (byProperty, bySignificance, byBroad, byRandom).
14
+
15
+ ## Context
16
+
17
+ remember-core already has `MemoryService.byTime()`, `byDensity()`, `byRating()`, `byDiscovery()`. This task creates the MCP tool definition and a thin handler that dispatches by mode.
18
+
19
+ ## Complete Tool Definition
20
+
21
+ ```typescript
22
+ {
23
+ name: 'remember_search_by',
24
+ description: `Search memories using specialized modes beyond hybrid search.
25
+
26
+ Modes:
27
+ - byTime: Chronological sort (newest/oldest first)
28
+ - byDensity: Sort by relationship count (most connected memories)
29
+ - byRating: Sort by Bayesian rating average (social ratings from spaces)
30
+ - byDiscovery: Interleaved rated + unrated content for exploration (4:1 ratio)
31
+
32
+ Use remember_search_memory for hybrid semantic+keyword search.
33
+ Use remember_find_similar for vector similarity.
34
+ Use this tool for structured browsing, sorting, and discovery.`,
35
+ inputSchema: {
36
+ type: 'object',
37
+ properties: {
38
+ mode: {
39
+ type: 'string',
40
+ enum: ['byTime', 'byDensity', 'byRating', 'byDiscovery'],
41
+ description: 'Search mode to use'
42
+ },
43
+ query: {
44
+ type: 'string',
45
+ description: 'Optional search query (used within mode for filtering)'
46
+ },
47
+ sort_order: {
48
+ type: 'string',
49
+ enum: ['asc', 'desc'],
50
+ description: 'Sort order (byTime, byDensity, byRating). Default: desc'
51
+ },
52
+ limit: { type: 'number', description: 'Max results. Default: 10' },
53
+ offset: { type: 'number', description: 'Pagination offset' },
54
+ filters: {
55
+ type: 'object',
56
+ description: 'Standard search filters',
57
+ properties: {
58
+ types: { type: 'array', items: { type: 'string' }, description: 'Include specific content types' },
59
+ exclude_types: { type: 'array', items: { type: 'string' }, description: 'Exclude specific content types' },
60
+ tags: { type: 'array', items: { type: 'string' } },
61
+ weight_min: { type: 'number' },
62
+ weight_max: { type: 'number' },
63
+ trust_min: { type: 'number' },
64
+ trust_max: { type: 'number' },
65
+ date_from: { type: 'string', description: 'ISO 8601' },
66
+ date_to: { type: 'string', description: 'ISO 8601' },
67
+ rating_min: { type: 'number', description: 'Minimum Bayesian rating' },
68
+ relationship_count_min: { type: 'number' },
69
+ relationship_count_max: { type: 'number' },
70
+ has_relationships: { type: 'boolean' }
71
+ }
72
+ },
73
+ deleted_filter: {
74
+ type: 'string',
75
+ enum: ['exclude', 'include', 'only'],
76
+ description: 'Default: exclude'
77
+ }
78
+ },
79
+ required: ['mode']
80
+ }
81
+ }
82
+ ```
83
+
84
+ ## Handler Logic
85
+
86
+ ```typescript
87
+ async function handleSearchBy(userId: string, args: SearchByArgs): Promise<ToolResult> {
88
+ const services = await createCoreServices(userId);
89
+ const { mode, query, sort_order, limit, offset, filters, deleted_filter } = args;
90
+
91
+ let results;
92
+ switch (mode) {
93
+ case 'byTime':
94
+ results = await services.memoryService.byTime({ query, sort_order, limit, offset, filters, deleted_filter });
95
+ break;
96
+ case 'byDensity':
97
+ results = await services.memoryService.byDensity({ query, sort_order, limit, offset, filters, deleted_filter });
98
+ break;
99
+ case 'byRating':
100
+ results = await services.memoryService.byRating({ query, sort_order, limit, offset, filters, deleted_filter });
101
+ break;
102
+ case 'byDiscovery':
103
+ // byDiscovery interleaves rated (4) + unrated (1) results
104
+ results = await services.memoryService.byDiscovery({ query, limit, offset, filters, deleted_filter });
105
+ break;
106
+ default:
107
+ return { content: [{ type: 'text', text: `Unknown mode: ${mode}` }], isError: true };
108
+ }
109
+
110
+ return { content: [{ type: 'text', text: JSON.stringify(results) }] };
111
+ }
112
+ ```
113
+
114
+ ## Key Decisions
115
+
116
+ - **Mode enum is extensible**: Later tasks (206, 208) add byProperty, bySignificance, byBroad, byRandom to the enum. Design the switch statement to be easily extendable.
117
+ - **Filters object matches core's SearchFilters**: Pass through directly — don't transform. The MCP schema mirrors core's interface.
118
+ - **byDiscovery interleaves**: 4:1 ratio of rated to unrated content. sort_order is not applicable for byDiscovery.
119
+ - **byRating uses Bayesian averaging**: `rating_bayesian` field, not raw `rating_sum`. Social rating from spaces.
120
+ - **Default limit**: 10 for all initial modes. byBroad (added later) defaults to 50.
121
+
122
+ ## Steps
123
+
124
+ 1. Create `src/tools/search-by.ts` with tool definition and handler per above
125
+ 2. Register in `src/server-factory.ts` (imports, ListTools, CallTool switch)
126
+ 3. Write unit tests in `src/tools/search-by.spec.ts`:
127
+ - Each mode dispatches to correct core method
128
+ - Invalid mode returns error
129
+ - Filters pass through to core
130
+ - sort_order parameter passed correctly
131
+ - Default limit/offset behavior
132
+ - byDiscovery ignores sort_order
133
+
134
+ ## Verification
135
+
136
+ - [ ] Tool definition exports `searchByTool` and `handleSearchBy`
137
+ - [ ] Modes byTime, byDensity, byRating, byDiscovery all dispatch correctly
138
+ - [ ] Full filter object passed through (types, exclude_types, tags, weight, trust, date, rating, relationship count)
139
+ - [ ] sort_order works for byTime, byDensity, byRating
140
+ - [ ] Tool registered in server-factory.ts
141
+ - [ ] Unit tests passing
142
+ - [ ] TypeScript clean
143
+ - [ ] Build passing
@@ -0,0 +1,77 @@
1
+ # Task 204: Add New Filters to Existing Tool Schemas
2
+
3
+ **Milestone**: M19 — New Search Modes, Ghost Tools & Emotional Exposure
4
+ **Status**: Not Started
5
+ **Created**: 2026-03-07
6
+ **Estimated Hours**: 2-3
7
+ **Dependencies**: None (filters already exist in remember-core)
8
+
9
+ ---
10
+
11
+ ## Objective
12
+
13
+ Update existing MCP tool input schemas to expose filters that already exist in remember-core but aren't in the MCP tool definitions.
14
+
15
+ ## Context
16
+
17
+ remember-core's `SearchFilters` interface has `rating_min`, `relationship_count_min`, `relationship_count_max`, and `exclude_types` — none are exposed in the current MCP tool schemas. These filters need to be added to the appropriate tools.
18
+
19
+ ## Filter-to-Tool Mapping
20
+
21
+ | Filter | Type | Description | Add To |
22
+ |--------|------|-------------|--------|
23
+ | `rating_min` | number | Minimum Bayesian rating average | search_memory, find_similar, query_memory, search_space |
24
+ | `relationship_count_min` | number | Minimum relationship count | search_memory, find_similar |
25
+ | `relationship_count_max` | number | Maximum relationship count | search_memory, find_similar |
26
+ | `exclude_types` | string[] | Exclude specific content types | search_memory, search_space |
27
+
28
+ ## Steps
29
+
30
+ ### 1. Update `src/tools/search-memory.ts`
31
+ Add to inputSchema.properties (inside filters object or at top level, matching existing pattern):
32
+ ```typescript
33
+ rating_min: { type: 'number', description: 'Minimum Bayesian rating average' },
34
+ relationship_count_min: { type: 'number', description: 'Minimum relationship count' },
35
+ relationship_count_max: { type: 'number', description: 'Maximum relationship count' },
36
+ exclude_types: { type: 'array', items: { type: 'string' }, description: 'Exclude specific content types' }
37
+ ```
38
+ Pass new filters through to core `memoryService.search()` call.
39
+
40
+ ### 2. Update `src/tools/find-similar.ts`
41
+ Add:
42
+ ```typescript
43
+ rating_min: { type: 'number' },
44
+ relationship_count_min: { type: 'number' },
45
+ relationship_count_max: { type: 'number' }
46
+ ```
47
+
48
+ ### 3. Update `src/tools/query-memory.ts`
49
+ Add:
50
+ ```typescript
51
+ rating_min: { type: 'number' }
52
+ ```
53
+
54
+ ### 4. Update `src/tools/search-space.ts`
55
+ Add:
56
+ ```typescript
57
+ rating_min: { type: 'number' },
58
+ exclude_types: { type: 'array', items: { type: 'string' } }
59
+ ```
60
+
61
+ ### 5. Update unit tests for each modified tool to verify new filters are passed through to core service calls
62
+
63
+ ## Key Decisions
64
+
65
+ - **rating_min uses Bayesian average**: The `rating_bayesian` field in core, not raw sum. This provides fairer comparison for items with different rating counts.
66
+ - **relationship_count filters are for personal search only**: Not applicable to space search (relationships are per-user, not per-space).
67
+ - **exclude_types complements existing types filter**: `types` is an include list, `exclude_types` is an exclude list. If both provided, `exclude_types` takes precedence (core behavior).
68
+
69
+ ## Verification
70
+
71
+ - [ ] `rating_min` available on search_memory, find_similar, query_memory, search_space
72
+ - [ ] `relationship_count_min/max` available on search_memory, find_similar
73
+ - [ ] `exclude_types` available on search_memory, search_space
74
+ - [ ] All new filters pass through to core service calls correctly
75
+ - [ ] Existing tests still pass (no regressions)
76
+ - [ ] New filter tests added for each tool
77
+ - [ ] TypeScript clean
@@ -0,0 +1,137 @@
1
+ # Task 205: Add `feel_*` Fields to create_memory and update_memory Schemas
2
+
3
+ **Milestone**: M19 — New Search Modes, Ghost Tools & Emotional Exposure
4
+ **Status**: Not Started
5
+ **Created**: 2026-03-07
6
+ **Estimated Hours**: 2-3
7
+ **Dependencies**: remember-core schema with 31 `feel_*` Weaviate properties
8
+
9
+ ---
10
+
11
+ ## Objective
12
+
13
+ Add all 31 optional `feel_*` emotional dimension fields to `remember_create_memory` and `remember_update_memory` input schemas. These are create-time hints that REM re-scores authoritatively during its consolidation cycle.
14
+
15
+ ## Context
16
+
17
+ remember-core's emotional weighting design adds 31 `feel_*` properties to the Memory Weaviate schema (21 discrete emotions + 10 functional signals). The creating LLM can provide sane defaults at creation time. All fields are optional floats (0-1, except `feel_valence` which is -1 to 1).
18
+
19
+ ## Complete Field List
20
+
21
+ ### Layer 1: Discrete Emotions (21 dimensions)
22
+
23
+ | Property | Range | Category | Description |
24
+ |----------|-------|----------|-------------|
25
+ | `feel_emotional_significance` | 0-1 | Meta | Overall emotional weight |
26
+ | `feel_vulnerability` | 0-1 | Meta | Personal exposure/openness |
27
+ | `feel_trauma` | 0-1 | Meta | Negative formative experience intensity |
28
+ | `feel_humor` | 0-1 | Positive | Comedic/playful quality |
29
+ | `feel_happiness` | 0-1 | Core | Positive affect / joy |
30
+ | `feel_sadness` | 0-1 | Core | Negative affect / grief / loss |
31
+ | `feel_fear` | 0-1 | Core | Threat perception / anxiety |
32
+ | `feel_anger` | 0-1 | Core | Frustration / injustice |
33
+ | `feel_surprise` | 0-1 | Core | Unexpectedness / novelty |
34
+ | `feel_disgust` | 0-1 | Core | Aversion / rejection |
35
+ | `feel_contempt` | 0-1 | Core | Superiority / dismissal |
36
+ | `feel_embarrassment` | 0-1 | Self-conscious | Social discomfort |
37
+ | `feel_shame` | 0-1 | Self-conscious | Deep self-judgment |
38
+ | `feel_guilt` | 0-1 | Self-conscious | Responsibility for harm |
39
+ | `feel_excitement` | 0-1 | Positive | Anticipatory positive arousal |
40
+ | `feel_pride` | 0-1 | Positive | Accomplishment / self-evaluation |
41
+ | `feel_valence` | **-1 to 1** | VAD | Positive-negative spectrum |
42
+ | `feel_arousal` | 0-1 | VAD | Calm to excited |
43
+ | `feel_dominance` | 0-1 | VAD | Control vs submission |
44
+ | `feel_intensity` | 0-1 | Dimensional | Overall emotional magnitude |
45
+ | `feel_coherence_tension` | 0-1 | Cognitive | Conflict with existing beliefs |
46
+
47
+ ### Layer 2: Functional Signals (10 dimensions)
48
+
49
+ | Property | Range | Biological Analog | Function |
50
+ |----------|-------|-------------------|----------|
51
+ | `feel_salience` | 0-1 | Fear/Surprise | How unexpected/novel (prediction error) |
52
+ | `feel_urgency` | 0-1 | Anger/Fear | Time-sensitivity of relevance (decay rate) |
53
+ | `feel_social_weight` | 0-1 | Trust/Disgust | Relationship/reputation impact |
54
+ | `feel_agency` | 0-1 | Pride/Shame | Caused by the bot's own actions? |
55
+ | `feel_novelty` | 0-1 | — | Uniqueness relative to collection |
56
+ | `feel_retrieval_utility` | 0-1 | — | Likelihood of future usefulness |
57
+ | `feel_narrative_importance` | 0-1 | — | Advances/anchors a personal story arc |
58
+ | `feel_aesthetic_quality` | 0-1 | — | Beauty, craft, artistry |
59
+ | `feel_valence` | (shared) | — | Scored independently in functional context |
60
+ | `feel_coherence_tension` | (shared) | — | Scored independently in functional context |
61
+
62
+ > **Note**: `feel_valence` and `feel_coherence_tension` appear in both layers but are scored independently. In Weaviate they are single properties — the REM scoring considers both emotional and functional context when setting the value.
63
+
64
+ ## Schema Addition Pattern
65
+
66
+ ```typescript
67
+ // Added to inputSchema.properties for both create_memory and update_memory:
68
+
69
+ // Layer 1: Discrete Emotions (all optional, 0-1 floats except feel_valence)
70
+ feel_emotional_significance: { type: 'number', minimum: 0, maximum: 1 },
71
+ feel_vulnerability: { type: 'number', minimum: 0, maximum: 1 },
72
+ feel_trauma: { type: 'number', minimum: 0, maximum: 1 },
73
+ feel_humor: { type: 'number', minimum: 0, maximum: 1 },
74
+ feel_happiness: { type: 'number', minimum: 0, maximum: 1 },
75
+ feel_sadness: { type: 'number', minimum: 0, maximum: 1 },
76
+ feel_fear: { type: 'number', minimum: 0, maximum: 1 },
77
+ feel_anger: { type: 'number', minimum: 0, maximum: 1 },
78
+ feel_surprise: { type: 'number', minimum: 0, maximum: 1 },
79
+ feel_disgust: { type: 'number', minimum: 0, maximum: 1 },
80
+ feel_contempt: { type: 'number', minimum: 0, maximum: 1 },
81
+ feel_embarrassment: { type: 'number', minimum: 0, maximum: 1 },
82
+ feel_shame: { type: 'number', minimum: 0, maximum: 1 },
83
+ feel_guilt: { type: 'number', minimum: 0, maximum: 1 },
84
+ feel_excitement: { type: 'number', minimum: 0, maximum: 1 },
85
+ feel_pride: { type: 'number', minimum: 0, maximum: 1 },
86
+ feel_valence: { type: 'number', minimum: -1, maximum: 1 }, // Note: -1 to 1
87
+ feel_arousal: { type: 'number', minimum: 0, maximum: 1 },
88
+ feel_dominance: { type: 'number', minimum: 0, maximum: 1 },
89
+ feel_intensity: { type: 'number', minimum: 0, maximum: 1 },
90
+ feel_coherence_tension: { type: 'number', minimum: 0, maximum: 1 },
91
+
92
+ // Layer 2: Functional Signals (all optional, 0-1 floats)
93
+ feel_salience: { type: 'number', minimum: 0, maximum: 1 },
94
+ feel_urgency: { type: 'number', minimum: 0, maximum: 1 },
95
+ feel_social_weight: { type: 'number', minimum: 0, maximum: 1 },
96
+ feel_agency: { type: 'number', minimum: 0, maximum: 1 },
97
+ feel_novelty: { type: 'number', minimum: 0, maximum: 1 },
98
+ feel_retrieval_utility: { type: 'number', minimum: 0, maximum: 1 },
99
+ feel_narrative_importance: { type: 'number', minimum: 0, maximum: 1 },
100
+ feel_aesthetic_quality: { type: 'number', minimum: 0, maximum: 1 },
101
+ ```
102
+
103
+ ## Key Decisions
104
+
105
+ - **These are hints, not permanent values**: Tool description must say "create-time hints, REM re-scores authoritatively during consolidation cycles"
106
+ - **`feel_valence` range is -1 to 1**: All other feel_* fields are 0-1. This is intentional — valence represents positive-negative spectrum.
107
+ - **`feel_valence` and `feel_coherence_tension` are shared**: They appear in both Layer 1 (discrete emotions) and Layer 2 (functional signals) conceptually, but are single Weaviate properties.
108
+ - **No composite fields on create/update**: `feel_significance`, `functional_significance`, `total_significance` are computed by REM only — they are NOT accepted on create/update.
109
+ - **Consider grouping**: Optionally group under a nested `emotions` object to avoid polluting the top-level parameter list. Evaluate whether the existing tool pattern uses nested objects or flat params.
110
+ - **31 unique properties total**: 21 Layer 1 + 10 Layer 2, but `feel_valence` and `feel_coherence_tension` overlap → 29 unique Weaviate property names.
111
+
112
+ ## Steps
113
+
114
+ 1. Update `src/tools/create-memory.ts`:
115
+ - Add all feel_* fields to inputSchema (per schema above)
116
+ - Add description note about hints vs REM authoritative scoring
117
+ - Extract feel_* fields from args and pass to core `create()` call
118
+ 2. Update `src/tools/update-memory.ts`:
119
+ - Add same feel_* fields to inputSchema
120
+ - Extract and pass to core `update()` call
121
+ 3. Write tests:
122
+ - Verify feel_* fields are passed through to core on create
123
+ - Verify feel_* fields are passed through to core on update
124
+ - Verify feel_valence accepts -1 to 1
125
+ - Verify composite fields (total_significance, etc.) are NOT accepted
126
+
127
+ ## Verification
128
+
129
+ - [ ] All 31 `feel_*` fields accepted on create_memory
130
+ - [ ] All 31 `feel_*` fields accepted on update_memory
131
+ - [ ] Fields passed through to core service calls
132
+ - [ ] `feel_valence` correctly allows -1 to 1 range
133
+ - [ ] All other `feel_*` fields correctly allow 0 to 1 range
134
+ - [ ] Composite fields NOT accepted (feel_significance, functional_significance, total_significance)
135
+ - [ ] Tool descriptions clearly state these are create-time hints
136
+ - [ ] Tests passing
137
+ - [ ] TypeScript clean
@@ -0,0 +1,135 @@
1
+ # Task 206: Add byProperty and bySignificance Modes to search_by
2
+
3
+ **Milestone**: M19 — New Search Modes, Ghost Tools & Emotional Exposure
4
+ **Status**: Not Started
5
+ **Created**: 2026-03-07
6
+ **Estimated Hours**: 2-3
7
+ **Dependencies**: Task 203 (search_by tool exists), remember-core schema with `feel_*` properties and `byProperty()` method
8
+
9
+ ---
10
+
11
+ ## Objective
12
+
13
+ Add `byProperty` and `bySignificance` modes to the `remember_search_by` tool, enabling sorting by any Weaviate property (especially emotional dimensions and composite significance scores).
14
+
15
+ ## Context
16
+
17
+ remember-core's emotional weighting design includes a generic `byProperty` sort mode that sorts by any Weaviate property name. `bySignificance` is a shorthand for `byProperty` on `total_significance`. This enables powerful emotional exploration — "show me my most traumatic memories", "find my funniest content", "what has the highest retrieval utility?"
18
+
19
+ ## Schema Changes
20
+
21
+ Update `src/tools/search-by.ts`:
22
+
23
+ 1. Add to mode enum: `'byProperty', 'bySignificance'`
24
+ 2. Add `sort_field` parameter:
25
+ ```typescript
26
+ sort_field: {
27
+ type: 'string',
28
+ description: 'Property to sort by (byProperty mode only). Any Weaviate property name, e.g. "feel_trauma", "feel_salience", "weight", "total_significance", "feel_coherence_tension"'
29
+ }
30
+ ```
31
+ 3. Update tool description to include:
32
+ ```
33
+ - byProperty: Sort by any memory property (e.g., feel_trauma, weight, feel_salience)
34
+ - bySignificance: Sort by total_significance (combined emotional + functional score from REM)
35
+ ```
36
+
37
+ ## Handler Logic
38
+
39
+ ```typescript
40
+ case 'byProperty':
41
+ if (!args.sort_field) {
42
+ return { content: [{ type: 'text', text: 'sort_field is required for byProperty mode' }], isError: true };
43
+ }
44
+ results = await services.memoryService.byProperty({
45
+ sort_field: args.sort_field,
46
+ sort_order: args.sort_order,
47
+ query: args.query,
48
+ limit: args.limit,
49
+ offset: args.offset,
50
+ filters: args.filters,
51
+ deleted_filter: args.deleted_filter
52
+ });
53
+ break;
54
+
55
+ case 'bySignificance':
56
+ // Shorthand for byProperty on total_significance
57
+ results = await services.memoryService.byProperty({
58
+ sort_field: 'total_significance',
59
+ sort_order: args.sort_order ?? 'desc',
60
+ query: args.query,
61
+ limit: args.limit,
62
+ offset: args.offset,
63
+ filters: args.filters,
64
+ deleted_filter: args.deleted_filter
65
+ });
66
+ break;
67
+ ```
68
+
69
+ ## Usage Examples (for tool description)
70
+
71
+ ```typescript
72
+ // Most emotionally significant memories
73
+ { mode: 'byProperty', sort_field: 'total_significance', sort_order: 'desc' }
74
+
75
+ // Highest coherence tension (conflicting beliefs needing reconciliation)
76
+ { mode: 'byProperty', sort_field: 'feel_coherence_tension', sort_order: 'desc' }
77
+
78
+ // Most novel memories
79
+ { mode: 'byProperty', sort_field: 'feel_novelty', sort_order: 'desc' }
80
+
81
+ // Most traumatic memories
82
+ { mode: 'byProperty', sort_field: 'feel_trauma', sort_order: 'desc' }
83
+
84
+ // Most humorous memories
85
+ { mode: 'byProperty', sort_field: 'feel_humor', sort_order: 'desc' }
86
+
87
+ // Highest retrieval utility (most likely to be useful in future queries)
88
+ { mode: 'byProperty', sort_field: 'feel_retrieval_utility', sort_order: 'desc' }
89
+
90
+ // Least visited by REM (candidates for scoring attention)
91
+ { mode: 'byProperty', sort_field: 'rem_visits', sort_order: 'asc' }
92
+
93
+ // Equivalent calls:
94
+ { mode: 'bySignificance', sort_order: 'desc' }
95
+ { mode: 'byProperty', sort_field: 'total_significance', sort_order: 'desc' }
96
+ ```
97
+
98
+ ## Three Composite Scores (sortable via byProperty)
99
+
100
+ | Property | Inputs | Purpose |
101
+ |----------|--------|---------|
102
+ | `feel_significance` | Weighted sum of Layer 1 (21 discrete emotions) | Emotional intensity composite |
103
+ | `functional_significance` | Weighted sum of Layer 2 (10 functional signals) | Functional importance composite |
104
+ | `total_significance` | Both layers combined | Overall significance for sorting |
105
+
106
+ ## Key Decisions
107
+
108
+ - **bySignificance defaults to desc**: Most significant first is the natural use case.
109
+ - **byProperty accepts ANY Weaviate property**: Not limited to feel_* fields. Can sort by `weight`, `trust`, `created_at`, `rem_visits`, etc.
110
+ - **No property validation in MCP layer**: Let core validate the property name. MCP is a thin adapter.
111
+ - **sort_field required for byProperty only**: Other modes don't use it. Return error if omitted for byProperty.
112
+
113
+ ## Steps
114
+
115
+ 1. Update `src/tools/search-by.ts`:
116
+ - Add `byProperty` and `bySignificance` to mode enum
117
+ - Add `sort_field` parameter to inputSchema
118
+ - Add handler cases per logic above
119
+ - Update tool description with examples
120
+ 2. Write tests:
121
+ - `byProperty` with various `sort_field` values (feel_trauma, feel_humor, weight, etc.)
122
+ - `byProperty` without `sort_field` returns error
123
+ - `bySignificance` dispatches to byProperty with `total_significance`
124
+ - `bySignificance` defaults sort_order to desc
125
+ - Sort order works with both modes
126
+
127
+ ## Verification
128
+
129
+ - [ ] `byProperty` mode sorts by any specified property
130
+ - [ ] `byProperty` requires `sort_field` parameter (error if missing)
131
+ - [ ] `bySignificance` is shorthand for `total_significance` sort
132
+ - [ ] `bySignificance` defaults to desc sort order
133
+ - [ ] Tool description includes examples of emotional dimension sorting
134
+ - [ ] Tests passing
135
+ - [ ] TypeScript clean