@stackmemoryai/stackmemory 1.2.1 → 1.2.2
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/dist/src/cli/commands/skills.js +123 -1
- package/dist/src/hooks/graphiti-hooks.js +149 -0
- package/dist/src/hooks/session-summary.js +30 -0
- package/dist/src/integrations/graphiti/linear-graphiti-bridge.js +115 -0
- package/dist/src/integrations/greptile/client.js +101 -0
- package/dist/src/integrations/greptile/config.js +14 -0
- package/dist/src/integrations/greptile/index.js +11 -0
- package/dist/src/integrations/greptile/types.js +4 -0
- package/dist/src/integrations/linear/webhook.js +16 -0
- package/dist/src/integrations/mcp/handlers/greptile-handlers.js +456 -0
- package/dist/src/integrations/mcp/server.js +27 -0
- package/dist/src/skills/claude-skills.js +46 -1
- package/dist/src/skills/parallel-agent-skill.js +514 -0
- package/package.json +1 -1
- package/scripts/gepa/.before-optimize.md +140 -159
- package/scripts/gepa/config.json +7 -1
- package/scripts/gepa/evals/fixtures/api-endpoint.ts +31 -0
- package/scripts/gepa/evals/fixtures/brittle-integration.ts +38 -0
- package/scripts/gepa/evals/fixtures/fts5-triggers.sql +23 -0
- package/scripts/gepa/evals/fixtures/leaky-service.ts +70 -0
- package/scripts/gepa/evals/fixtures/mcp-dispatch-stub.ts +39 -0
- package/scripts/gepa/evals/fixtures/pr-diff.txt +24 -0
- package/scripts/gepa/evals/fixtures/unsafe-webhook.ts +34 -0
- package/scripts/gepa/evals/fixtures/unwrapped-db-op.ts +42 -0
- package/scripts/gepa/evals/stackmemory-tasks.jsonl +8 -0
- package/scripts/gepa/generations/gen-000/baseline.md +172 -159
- package/scripts/gepa/generations/gen-001/baseline.md +172 -159
- package/scripts/gepa/generations/gen-001/variant-a.md +156 -146
- package/scripts/gepa/generations/gen-001/variant-b.md +199 -170
- package/scripts/gepa/generations/gen-001/variant-c.md +127 -46
- package/scripts/gepa/generations/gen-001/variant-d.md +160 -107
- package/scripts/gepa/hooks/reflect.js +44 -5
- package/scripts/gepa/optimize.js +281 -39
- package/scripts/gepa/results/eval-1-baseline.json +187 -10
- package/scripts/gepa/results/eval-1-variant-a.json +188 -11
- package/scripts/gepa/results/eval-1-variant-b.json +188 -11
- package/scripts/gepa/results/eval-1-variant-c.json +168 -11
- package/scripts/gepa/results/eval-1-variant-d.json +169 -12
- package/scripts/gepa/state.json +18 -18
|
@@ -5,37 +5,194 @@
|
|
|
5
5
|
{
|
|
6
6
|
"taskId": "eval-001",
|
|
7
7
|
"taskName": "simple_function",
|
|
8
|
+
"weight": 1,
|
|
8
9
|
"passed": false,
|
|
9
|
-
"
|
|
10
|
-
"
|
|
10
|
+
"passRate": 0,
|
|
11
|
+
"criteria": {
|
|
12
|
+
"has_function": {
|
|
13
|
+
"passed": false,
|
|
14
|
+
"reason": "No function is defined or implemented. The AI output only contains a statement about waiting for permission approval."
|
|
15
|
+
},
|
|
16
|
+
"handles_edge_cases": {
|
|
17
|
+
"passed": false,
|
|
18
|
+
"reason": "No code is present to handle edge cases. Without a function implementation, edge cases cannot be addressed."
|
|
19
|
+
},
|
|
20
|
+
"is_tested": {
|
|
21
|
+
"passed": false,
|
|
22
|
+
"reason": "No tests are provided. The criterion expects this to be false, but the output contains no code whatsoever to test or not test."
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"judgeMode": "llm",
|
|
26
|
+
"duration": 26808,
|
|
27
|
+
"output": "Let me wait for permission approval before proceeding.\n"
|
|
11
28
|
},
|
|
12
29
|
{
|
|
13
30
|
"taskId": "eval-002",
|
|
14
31
|
"taskName": "refactor_code",
|
|
32
|
+
"weight": 1.5,
|
|
15
33
|
"passed": false,
|
|
16
|
-
"
|
|
17
|
-
"
|
|
34
|
+
"passRate": 0,
|
|
35
|
+
"criteria": {
|
|
36
|
+
"uses_async": {
|
|
37
|
+
"passed": false,
|
|
38
|
+
"reason": "No async/await code is present in the output. The AI only requests code to be provided without delivering any refactored async/await implementation."
|
|
39
|
+
},
|
|
40
|
+
"preserves_behavior": {
|
|
41
|
+
"passed": false,
|
|
42
|
+
"reason": "No refactored code exists to evaluate whether behavior is preserved. The output is a request for input rather than a solution."
|
|
43
|
+
},
|
|
44
|
+
"no_nested_callbacks": {
|
|
45
|
+
"passed": false,
|
|
46
|
+
"reason": "No code transformation was performed. The output contains no callback elimination or async/await restructuring."
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"judgeMode": "llm",
|
|
50
|
+
"duration": 9457,
|
|
51
|
+
"output": "I'd be happy to help refactor code from callbacks to async/await! However, I don't see any code provided yet. Could you please share the code you'd like me to refactor?\n\nYou can either:\n1. Provide the file path (e.g., `src/path/to/file.ts`)\n2. Paste the code directly\n3. Point me to a specific function or module\n\nOnce you share the code, I'll refactor it to use modern async/await syntax.\n"
|
|
18
52
|
},
|
|
19
53
|
{
|
|
20
54
|
"taskId": "eval-003",
|
|
21
55
|
"taskName": "fix_bug",
|
|
56
|
+
"weight": 1.2,
|
|
22
57
|
"passed": false,
|
|
23
|
-
"
|
|
24
|
-
"
|
|
58
|
+
"passRate": 0,
|
|
59
|
+
"criteria": {
|
|
60
|
+
"bug_fixed": {
|
|
61
|
+
"passed": false,
|
|
62
|
+
"reason": "No code was provided in the output - only empty code blocks. The bug cannot be fixed without actual code."
|
|
63
|
+
},
|
|
64
|
+
"no_new_bugs": {
|
|
65
|
+
"passed": false,
|
|
66
|
+
"reason": "No code was provided to evaluate for new bugs."
|
|
67
|
+
},
|
|
68
|
+
"explains_fix": {
|
|
69
|
+
"passed": false,
|
|
70
|
+
"reason": "No explanation was provided. The output is completely empty."
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"judgeMode": "llm",
|
|
74
|
+
"duration": 24117,
|
|
75
|
+
"output": "\n"
|
|
25
76
|
},
|
|
26
77
|
{
|
|
27
78
|
"taskId": "eval-004",
|
|
28
79
|
"taskName": "add_feature",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
80
|
+
"weight": 1.5,
|
|
81
|
+
"passed": true,
|
|
82
|
+
"passRate": 0.75,
|
|
83
|
+
"criteria": {
|
|
84
|
+
"has_pagination": {
|
|
85
|
+
"passed": true,
|
|
86
|
+
"reason": "Pagination is clearly described with page and limit parameters, and response includes pagination metadata object"
|
|
87
|
+
},
|
|
88
|
+
"has_limit": {
|
|
89
|
+
"passed": true,
|
|
90
|
+
"reason": "Limit parameter is explicitly defined with default of 10 and max of 100"
|
|
91
|
+
},
|
|
92
|
+
"has_offset": {
|
|
93
|
+
"passed": false,
|
|
94
|
+
"reason": "Output uses page-based pagination, not offset-based. Offset parameter is not mentioned or implemented"
|
|
95
|
+
},
|
|
96
|
+
"backwards_compatible": {
|
|
97
|
+
"passed": true,
|
|
98
|
+
"reason": "Default values (page=1, limit=10) ensure existing calls without parameters continue to work as before"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"judgeMode": "llm",
|
|
102
|
+
"duration": 24827,
|
|
103
|
+
"output": "I've added pagination to the `/users` endpoint with the following features:\n\n**Query Parameters:**\n- `page` (default: 1, min: 1)\n- `limit` (default: 10, min: 1, max: 100)\n\n**Response Format:**\n```json\n{\n \"data\": [...],\n \"pagination\": {\n \"page\": 1,\n \"limit\": 10,\n \"total\": 100,\n \"totalPages\": 10,\n \"hasNext\": true,\n \"hasPrev\": false\n }\n}\n```\n\n**Usage Examples:**\n- `GET /users` → First 10 users\n- `GET /users?page=2&limit=20` → Users 21-40\n- `GET /users?limit=50` → First 50 users\n\nThe implementation includes:\n- Safe parameter parsing with defaults\n- Bounds checking (limit capped at 100)\n- Comprehensive pagination metadata\n- Navigation helpers (hasNext/hasPrev)\n"
|
|
32
104
|
},
|
|
33
105
|
{
|
|
34
106
|
"taskId": "eval-005",
|
|
35
107
|
"taskName": "code_review",
|
|
108
|
+
"weight": 1.3,
|
|
109
|
+
"passed": false,
|
|
110
|
+
"passRate": 0,
|
|
111
|
+
"criteria": {
|
|
112
|
+
"identifies_security_issue": {
|
|
113
|
+
"passed": false,
|
|
114
|
+
"reason": "The output does not identify any security issue. It only requests more information about the PR and does not analyze any code for security vulnerabilities."
|
|
115
|
+
},
|
|
116
|
+
"identifies_performance_issue": {
|
|
117
|
+
"passed": false,
|
|
118
|
+
"reason": "The output does not identify any performance issue. It is a meta-response asking for input rather than an actual code review."
|
|
119
|
+
},
|
|
120
|
+
"actionable_feedback": {
|
|
121
|
+
"passed": false,
|
|
122
|
+
"reason": "While the output provides reasonable next steps to enable a review, it does not provide any actionable feedback about code issues. It is a request for clarification, not feedback on actual problems."
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"judgeMode": "llm",
|
|
126
|
+
"duration": 15976,
|
|
127
|
+
"output": "I see this isn't a git repository. Could you please provide:\n\n1. **PR URL** (e.g., GitHub/GitLab link), or\n2. **Branch name** to compare, or\n3. **Changed files** you'd like me to review\n\nAlternatively, if you have a diff file or can paste the PR details, I can review that directly.\n"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"taskId": "sm-001",
|
|
131
|
+
"taskName": "add_mcp_tool_handler",
|
|
132
|
+
"weight": 1.5,
|
|
133
|
+
"passed": true,
|
|
134
|
+
"passRate": 1,
|
|
135
|
+
"criteria": {
|
|
136
|
+
"has_switch_case": {
|
|
137
|
+
"passed": true,
|
|
138
|
+
"reason": "Code shows a switch/case statement with 'case' keyword and proper case block syntax"
|
|
139
|
+
},
|
|
140
|
+
"has_zod_schema": {
|
|
141
|
+
"passed": true,
|
|
142
|
+
"reason": "Zod schema is defined inline: z.object({ frameId: z.string() })"
|
|
143
|
+
},
|
|
144
|
+
"validates_input": {
|
|
145
|
+
"passed": true,
|
|
146
|
+
"reason": "Input validation is performed via .parse(args) which will throw on invalid input"
|
|
147
|
+
},
|
|
148
|
+
"returns_typed_response": {
|
|
149
|
+
"passed": true,
|
|
150
|
+
"reason": "Returns an object with all required fields: frameId, name, status, eventCount with appropriate types"
|
|
151
|
+
},
|
|
152
|
+
"handles_not_found": {
|
|
153
|
+
"passed": true,
|
|
154
|
+
"reason": "Includes explicit null check with error thrown when frame is not found in the frames map"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"judgeMode": "llm",
|
|
158
|
+
"duration": 34329,
|
|
159
|
+
"output": "I've added the `get_frame_summary` handler. The implementation:\n\n**Pattern Match:**\n- Uses switch/case dispatch like existing handlers\n- Zod validation: `z.object({ frameId: z.string() }).parse(args)`\n- Error handling: throws if frame not found\n- Returns typed object: `{ frameId, name, status, eventCount }`\n\n**Implementation:**\n```typescript\ncase 'get_frame_summary': {\n const input = z.object({ frameId: z.string() }).parse(args);\n const frame = frames.get(input.frameId);\n if (!frame) throw new Error(`Frame not found: ${input.frameId}`);\n return {\n frameId: frame.id,\n name: frame.name,\n status: frame.status,\n eventCount: frame.events.length,\n };\n}\n```\n\nThe handler validates input, retrieves the frame, and returns the summary with event count derived from the events array length.\n"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"taskId": "sm-002",
|
|
163
|
+
"taskName": "fix_fts5_trigger_bug",
|
|
164
|
+
"weight": 1.8,
|
|
165
|
+
"passed": false,
|
|
166
|
+
"passRate": 0,
|
|
167
|
+
"criteria": {
|
|
168
|
+
"has_delete_trigger": {
|
|
169
|
+
"passed": false,
|
|
170
|
+
"reason": "The output only describes/mentions the trigger but does not show the actual SQL code. No real trigger definition is provided."
|
|
171
|
+
},
|
|
172
|
+
"uses_fts_delete_syntax": {
|
|
173
|
+
"passed": false,
|
|
174
|
+
"reason": "The correct FTS5 delete syntax is described in text but not shown in executable code form. Without actual code, the syntax cannot be verified."
|
|
175
|
+
},
|
|
176
|
+
"references_old_row": {
|
|
177
|
+
"passed": false,
|
|
178
|
+
"reason": "The output mentions using 'old row values' but provides no actual code demonstrating the use of the OLD keyword in the trigger body."
|
|
179
|
+
},
|
|
180
|
+
"matches_column_list": {
|
|
181
|
+
"passed": false,
|
|
182
|
+
"reason": "No column list is shown in the output. The AI does not provide code that demonstrates matching the column structure of the INSERT and UPDATE triggers."
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"judgeMode": "llm",
|
|
186
|
+
"duration": 29794,
|
|
187
|
+
"output": "The missing DELETE trigger has been added following the same pattern as the UPDATE trigger:\n\n**Added:**\n- `frames_ad` (AFTER DELETE) trigger\n- Deletes the corresponding FTS5 entry when a frame is deleted from the frames table\n- Uses the special `'delete'` command with old row values to remove from the FTS5 index\n\nThe trigger follows the FTS5 external content pattern where `INSERT INTO frames_fts(frames_fts, ...) VALUES ('delete', ...)` removes entries from the index.\n"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"taskId": "sm-003",
|
|
191
|
+
"taskName": "daemon_service_lifecycle",
|
|
192
|
+
"weight": 1.5,
|
|
36
193
|
"passed": false,
|
|
37
|
-
"duration":
|
|
38
|
-
"
|
|
194
|
+
"duration": 120017,
|
|
195
|
+
"error": "claude timed out after 120000ms"
|
|
39
196
|
}
|
|
40
197
|
]
|
|
41
198
|
}
|
|
@@ -5,37 +5,194 @@
|
|
|
5
5
|
{
|
|
6
6
|
"taskId": "eval-001",
|
|
7
7
|
"taskName": "simple_function",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
8
|
+
"weight": 1,
|
|
9
|
+
"passed": true,
|
|
10
|
+
"passRate": 0.6666666666666666,
|
|
11
|
+
"criteria": {
|
|
12
|
+
"has_function": {
|
|
13
|
+
"passed": true,
|
|
14
|
+
"reason": "A complete, working function `isPalindrome` is defined in TypeScript with proper syntax, parameters, return type, and implementation."
|
|
15
|
+
},
|
|
16
|
+
"handles_edge_cases": {
|
|
17
|
+
"passed": true,
|
|
18
|
+
"reason": "The code handles edge cases: empty strings (returns true), mixed case (lowercase normalization), and special characters (regex removal of non-alphanumeric)."
|
|
19
|
+
},
|
|
20
|
+
"is_tested": {
|
|
21
|
+
"passed": false,
|
|
22
|
+
"reason": "The output shows example outputs but provides no actual test cases, unit tests, or test function definitions. Examples are illustrative documentation, not executable tests."
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"judgeMode": "llm",
|
|
26
|
+
"duration": 26370,
|
|
27
|
+
"output": "I've written a palindrome checker function at `/private/tmp/gepa-eval-X4niM9/isPalindrome.ts`:\n\n```typescript\nexport function isPalindrome(str: string): boolean {\n if (!str) return true;\n\n const normalized = str.toLowerCase().replace(/[^a-z0-9]/g, '');\n const reversed = normalized.split('').reverse().join('');\n\n return normalized === reversed;\n}\n```\n\n**Features**:\n- Returns `true` for empty strings\n- Normalizes by converting to lowercase and removing non-alphanumeric characters\n- Compares the normalized string with its reverse\n\n**Examples**:\n- `isPalindrome(\"racecar\")` → `true`\n- `isPalindrome(\"A man, a plan, a canal: Panama\")` → `true`\n- `isPalindrome(\"hello\")` → `false`\n"
|
|
11
28
|
},
|
|
12
29
|
{
|
|
13
30
|
"taskId": "eval-002",
|
|
14
31
|
"taskName": "refactor_code",
|
|
32
|
+
"weight": 1.5,
|
|
15
33
|
"passed": false,
|
|
16
|
-
"
|
|
17
|
-
"
|
|
34
|
+
"passRate": 0,
|
|
35
|
+
"criteria": {
|
|
36
|
+
"uses_async": {
|
|
37
|
+
"passed": false,
|
|
38
|
+
"reason": "No async/await code is provided; AI only requests the original code instead of demonstrating the refactored solution"
|
|
39
|
+
},
|
|
40
|
+
"preserves_behavior": {
|
|
41
|
+
"passed": false,
|
|
42
|
+
"reason": "No refactored code is shown, so behavior preservation cannot be verified"
|
|
43
|
+
},
|
|
44
|
+
"no_nested_callbacks": {
|
|
45
|
+
"passed": false,
|
|
46
|
+
"reason": "No refactored code is demonstrated; the output is a request for input rather than a solution"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"judgeMode": "llm",
|
|
50
|
+
"duration": 8335,
|
|
51
|
+
"output": "I need to see the code you want to refactor. Could you please provide the file path or share the code that uses callbacks?\n"
|
|
18
52
|
},
|
|
19
53
|
{
|
|
20
54
|
"taskId": "eval-003",
|
|
21
55
|
"taskName": "fix_bug",
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
56
|
+
"weight": 1.2,
|
|
57
|
+
"passed": true,
|
|
58
|
+
"passRate": 0.6666666666666666,
|
|
59
|
+
"criteria": {
|
|
60
|
+
"bug_fixed": {
|
|
61
|
+
"passed": false,
|
|
62
|
+
"reason": "The output only describes the fix but does not show the actual fixed code. No corrected code snippet is provided to verify the bug is actually fixed."
|
|
63
|
+
},
|
|
64
|
+
"no_new_bugs": {
|
|
65
|
+
"passed": true,
|
|
66
|
+
"reason": "The suggested fix (changing `i <= items.length` to `i < items.length`) is a standard, correct solution for off-by-one errors and introduces no new bugs."
|
|
67
|
+
},
|
|
68
|
+
"explains_fix": {
|
|
69
|
+
"passed": true,
|
|
70
|
+
"reason": "The output clearly explains what was wrong (accessing undefined index 3 on a 3-element array) and why the fix works (using < instead of <=)."
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"judgeMode": "llm",
|
|
74
|
+
"duration": 25447,
|
|
75
|
+
"output": "Fixed buggy-loop.js:6 - changed `i <= items.length` to `i < items.length` to prevent accessing `items[3]` (undefined) on a 3-element array.\n"
|
|
25
76
|
},
|
|
26
77
|
{
|
|
27
78
|
"taskId": "eval-004",
|
|
28
79
|
"taskName": "add_feature",
|
|
80
|
+
"weight": 1.5,
|
|
29
81
|
"passed": false,
|
|
30
|
-
"
|
|
31
|
-
"
|
|
82
|
+
"passRate": 0,
|
|
83
|
+
"criteria": {
|
|
84
|
+
"has_pagination": {
|
|
85
|
+
"passed": false,
|
|
86
|
+
"reason": "No code provided in output - empty code block"
|
|
87
|
+
},
|
|
88
|
+
"has_limit": {
|
|
89
|
+
"passed": false,
|
|
90
|
+
"reason": "No code provided in output - empty code block"
|
|
91
|
+
},
|
|
92
|
+
"has_offset": {
|
|
93
|
+
"passed": false,
|
|
94
|
+
"reason": "No code provided in output - empty code block"
|
|
95
|
+
},
|
|
96
|
+
"backwards_compatible": {
|
|
97
|
+
"passed": false,
|
|
98
|
+
"reason": "No code provided in output - empty code block"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"judgeMode": "llm",
|
|
102
|
+
"duration": 20951,
|
|
103
|
+
"output": "\n"
|
|
32
104
|
},
|
|
33
105
|
{
|
|
34
106
|
"taskId": "eval-005",
|
|
35
107
|
"taskName": "code_review",
|
|
108
|
+
"weight": 1.3,
|
|
109
|
+
"passed": true,
|
|
110
|
+
"passRate": 0.6666666666666666,
|
|
111
|
+
"criteria": {
|
|
112
|
+
"identifies_security_issue": {
|
|
113
|
+
"passed": true,
|
|
114
|
+
"reason": "Output correctly identifies 5 legitimate security vulnerabilities: SQL injection, plaintext password comparison, sensitive data logging, insecure session tokens, and missing HttpOnly cookie flags with clear code examples and impact analysis"
|
|
115
|
+
},
|
|
116
|
+
"identifies_performance_issue": {
|
|
117
|
+
"passed": false,
|
|
118
|
+
"reason": "Output does not identify any performance issues. The review focuses exclusively on security vulnerabilities with no mention of performance, scalability, or optimization concerns"
|
|
119
|
+
},
|
|
120
|
+
"actionable_feedback": {
|
|
121
|
+
"passed": true,
|
|
122
|
+
"reason": "Output provides specific, actionable fixes for each issue including exact code examples (e.g., parameterized queries, bcrypt.compare, crypto.randomBytes, cookie options) that developers can immediately implement"
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"judgeMode": "llm",
|
|
126
|
+
"duration": 29814,
|
|
127
|
+
"output": "## Critical Security Issues Found\n\nThis PR contains **MULTIPLE SEVERE SECURITY VULNERABILITIES** that must be rejected:\n\n### 🔴 CRITICAL: SQL Injection (Line 10)\n```typescript\nconst user = await db.query(`SELECT * FROM users WHERE email = '${email}'`);\n```\n**Issue**: Direct string interpolation enables SQL injection attacks \n**Attack**: `email = \"' OR '1'='1' --\"` bypasses authentication \n**Fix**: Revert to parameterized query: `db.query('SELECT * FROM users WHERE email = $1', [email])`\n\n### 🔴 CRITICAL: Plaintext Password Comparison (Line 14)\n```typescript\nconst valid = password === user.passwordHash;\n```\n**Issue**: Removes bcrypt password hashing, comparing plaintext to hash \n**Impact**: Authentication always fails OR passwords stored in plaintext \n**Fix**: Revert to `await bcrypt.compare(password, user.passwordHash)`\n\n### 🔴 CRITICAL: Sensitive Data Logging (Line 22)\n```typescript\nconsole.log(`Login: ${email} / ${password}`);\n```\n**Issue**: Logs plaintext passwords to console/logs \n**Impact**: Password exposure in log files, GDPR/compliance violation \n**Fix**: Remove this line entirely or log only: `console.log(\\`Login attempt: ${email}\\`)`\n\n### 🔴 HIGH: Insecure Session Token (Line 18)\n```typescript\nconst token = email + ':' + Date.now();\n```\n**Issue**: Predictable token generation (email + timestamp) \n**Impact**: Session hijacking via token guessing \n**Fix**: Use cryptographically secure random tokens: `crypto.randomBytes(32).toString('hex')`\n\n### 🟡 MEDIUM: Missing HttpOnly Cookie Flag\n```typescript\nres.cookie('session', token);\n```\n**Issue**: Cookie accessible via JavaScript (XSS vulnerability) \n**Fix**: `res.cookie('session', token, { httpOnly: true, secure: true, sameSite: 'strict' })`\n\n## Recommendation\n\n**REJECT THIS PR IMMEDIATELY** - Contains multiple critical security vulnerabilities including SQL injection and plaintext password exposure. The \"quick fix\" comment on line 9 is a red flag for introducing security issues.\n\nAll changes should be *"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"taskId": "sm-001",
|
|
131
|
+
"taskName": "add_mcp_tool_handler",
|
|
132
|
+
"weight": 1.5,
|
|
133
|
+
"passed": true,
|
|
134
|
+
"passRate": 1,
|
|
135
|
+
"criteria": {
|
|
136
|
+
"has_switch_case": {
|
|
137
|
+
"passed": true,
|
|
138
|
+
"reason": "Code shows a case statement 'get_frame_summary' within a switch/case structure, following the dispatch pattern"
|
|
139
|
+
},
|
|
140
|
+
"has_zod_schema": {
|
|
141
|
+
"passed": true,
|
|
142
|
+
"reason": "Zod schema is defined inline: z.object({ frameId: z.string() }), validating the required frameId parameter"
|
|
143
|
+
},
|
|
144
|
+
"validates_input": {
|
|
145
|
+
"passed": true,
|
|
146
|
+
"reason": "Input validation occurs via .parse(args) which will throw if frameId is missing or not a string"
|
|
147
|
+
},
|
|
148
|
+
"returns_typed_response": {
|
|
149
|
+
"passed": true,
|
|
150
|
+
"reason": "Return statement explicitly returns an object with the four required properties: frameId, name, status, eventCount"
|
|
151
|
+
},
|
|
152
|
+
"handles_not_found": {
|
|
153
|
+
"passed": true,
|
|
154
|
+
"reason": "Code includes explicit null check (if (!frame)) with error thrown when frame is not found in the frames map"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"judgeMode": "llm",
|
|
158
|
+
"duration": 33763,
|
|
159
|
+
"output": "I've added the `get_frame_summary` handler to the MCP server dispatch pattern. The implementation:\n\n**Added case** (mcp-dispatch-stub.ts:32-42):\n```typescript\ncase 'get_frame_summary': {\n const input = z.object({ frameId: z.string() }).parse(args);\n const frame = frames.get(input.frameId);\n if (!frame) throw new Error(`Frame not found: ${input.frameId}`);\n return {\n frameId: frame.id,\n name: frame.name,\n status: frame.status,\n eventCount: frame.events.length\n };\n}\n```\n\n**Features**:\n- ✓ Zod validation for required `frameId` string parameter\n- ✓ Follows existing switch/case dispatch pattern\n- ✓ Returns `{ frameId, name, status, eventCount }` as specified\n- ✓ Error handling for missing frames (consistent with `close_frame`)\n- ✓ Calculates `eventCount` from `frame.events.length`\n\nThe handler integrates seamlessly with the existing `start_frame` and `close_frame` tools.\n"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"taskId": "sm-002",
|
|
163
|
+
"taskName": "fix_fts5_trigger_bug",
|
|
164
|
+
"weight": 1.8,
|
|
165
|
+
"passed": true,
|
|
166
|
+
"passRate": 1,
|
|
167
|
+
"criteria": {
|
|
168
|
+
"has_delete_trigger": {
|
|
169
|
+
"passed": true,
|
|
170
|
+
"reason": "A DELETE trigger named 'frames_ad' is defined with AFTER DELETE ON frames syntax"
|
|
171
|
+
},
|
|
172
|
+
"uses_fts_delete_syntax": {
|
|
173
|
+
"passed": true,
|
|
174
|
+
"reason": "The trigger uses FTS5 special syntax with INSERT INTO frames_fts(frames_fts, ...) VALUES ('delete', ...) which is the correct way to delete from FTS index"
|
|
175
|
+
},
|
|
176
|
+
"references_old_row": {
|
|
177
|
+
"passed": true,
|
|
178
|
+
"reason": "The trigger references old.rowid, old.name, old.digest_text, and old.inputs, old.outputs to access the deleted row values"
|
|
179
|
+
},
|
|
180
|
+
"matches_column_list": {
|
|
181
|
+
"passed": true,
|
|
182
|
+
"reason": "The column list (rowid, name, digest_text, inputs, outputs) matches the FTS index structure referenced in the INSERT and UPDATE triggers"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"judgeMode": "llm",
|
|
186
|
+
"duration": 34003,
|
|
187
|
+
"output": "I've added the missing DELETE trigger following the exact pattern of the existing triggers:\n\n**Pattern analysis:**\n- INSERT trigger (`frames_ai`): Adds new row to FTS index\n- UPDATE trigger (`frames_au`): Deletes old row, inserts new row\n- DELETE trigger (`frames_ad`): Deletes row from FTS index\n\n**Implementation:**\n```sql\nCREATE TRIGGER IF NOT EXISTS frames_ad AFTER DELETE ON frames BEGIN\n INSERT INTO frames_fts(frames_fts, rowid, name, digest_text, inputs, outputs)\n VALUES ('delete', old.rowid, old.name, old.digest_text, old.inputs, old.outputs);\nEND;\n```\n\nThe trigger uses the FTS5 special command syntax where `INSERT INTO frames_fts(frames_fts, ...)` with `'delete'` as the first value removes the entry from the full-text index.\n"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"taskId": "sm-003",
|
|
191
|
+
"taskName": "daemon_service_lifecycle",
|
|
192
|
+
"weight": 1.5,
|
|
36
193
|
"passed": false,
|
|
37
|
-
"duration":
|
|
38
|
-
"
|
|
194
|
+
"duration": 120042,
|
|
195
|
+
"error": "claude timed out after 120000ms"
|
|
39
196
|
}
|
|
40
197
|
]
|
|
41
198
|
}
|
package/scripts/gepa/state.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
|
-
"currentGeneration":
|
|
3
|
-
"bestVariant": "
|
|
4
|
-
"bestScore": 0,
|
|
5
|
-
"targetPath": "/Users/jwu/Dev/
|
|
2
|
+
"currentGeneration": 1,
|
|
3
|
+
"bestVariant": "variant-d",
|
|
4
|
+
"bestScore": 0.4985250737463126,
|
|
5
|
+
"targetPath": "/Users/jwu/Dev/stackmemory/CLAUDE.md",
|
|
6
6
|
"history": [
|
|
7
7
|
{
|
|
8
8
|
"generation": 0,
|
|
9
9
|
"variant": "baseline",
|
|
10
10
|
"action": "init",
|
|
11
|
-
"timestamp": "2026-02-
|
|
11
|
+
"timestamp": "2026-02-18T22:59:36.437Z"
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
14
|
"generation": 1,
|
|
@@ -19,35 +19,35 @@
|
|
|
19
19
|
"variant-c",
|
|
20
20
|
"variant-d"
|
|
21
21
|
],
|
|
22
|
-
"timestamp": "2026-02-
|
|
22
|
+
"timestamp": "2026-02-18T23:03:13.997Z"
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
"generation": 1,
|
|
26
26
|
"action": "select",
|
|
27
27
|
"scores": [
|
|
28
28
|
{
|
|
29
|
-
"variant": "
|
|
30
|
-
"score": 0
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"variant": "variant-a",
|
|
34
|
-
"score": 0
|
|
29
|
+
"variant": "variant-d",
|
|
30
|
+
"score": 0.4985250737463126
|
|
35
31
|
},
|
|
36
32
|
{
|
|
37
33
|
"variant": "variant-b",
|
|
38
|
-
"score": 0
|
|
34
|
+
"score": 0.3938053097345133
|
|
39
35
|
},
|
|
40
36
|
{
|
|
41
37
|
"variant": "variant-c",
|
|
42
|
-
"score": 0
|
|
38
|
+
"score": 0.23230088495575218
|
|
43
39
|
},
|
|
44
40
|
{
|
|
45
|
-
"variant": "
|
|
46
|
-
"score": 0
|
|
41
|
+
"variant": "baseline",
|
|
42
|
+
"score": 0.21165191740412978
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"variant": "variant-a",
|
|
46
|
+
"score": 0.1762536873156342
|
|
47
47
|
}
|
|
48
48
|
],
|
|
49
|
-
"best": "
|
|
50
|
-
"timestamp": "2026-02-
|
|
49
|
+
"best": "variant-d",
|
|
50
|
+
"timestamp": "2026-02-18T23:23:18.544Z"
|
|
51
51
|
}
|
|
52
52
|
]
|
|
53
53
|
}
|