76 lines
11 KiB
Plaintext
76 lines
11 KiB
Plaintext
[2026-05-14T17:52:29.428Z] RESULT
|
||
============================================================
|
||
{
|
||
"success": true,
|
||
"output": "The codebase has no custom application source code — it's a claude-flow framework runtime with only configuration files and a SQLite schema. I can't analyze N+1 patterns, React renders, or memory leaks (none of those exist here), but I can surface real findings from what's actually present.\n\n---\n\n## Performance Analysis\n\n### What this project is\n\nThis is a pure configuration/runtime environment: `claude-flow.config.json`, `.swarm/state.json`, and `data/memory/schema.sql`. There is no application JavaScript, TypeScript, React, Python, or backend code to analyze. All JS/TS files are third-party `node_modules`.\n\n---\n\n### Findings from the SQL schema (`data/memory/schema.sql`)\n\n**1. Vectors stored as JSON text — high serialization cost**\n\n`data/memory/schema.sql:22`\n```sql\nembedding TEXT -- stored as JSON array string\n```\nEvery vector similarity computation requires deserializing a JSON string to a float array. For 384-dim vectors with `cosine` distance, this is significant.\n\n**Fix:** Use `BLOB` for binary-packed float32 arrays (4 bytes × 384 = 1,536 bytes vs. ~2,300+ bytes as JSON text), and unpack in the query layer:\n```sql\nembedding BLOB -- pack as Float32Array buffer\n```\n\n**2. Missing composite indexes for common access patterns**\n\n`data/memory/schema.sql:48–54`\n\nQueries like `WHERE namespace = ? AND status = 'active'` or `WHERE namespace = ? AND type = ?` hit two separate indexes with a merge, instead of one. The schema only creates single-column indexes.\n\n**Fix:**\n```sql\nCREATE INDEX IF NOT EXISTS idx_memory_ns_status ON memory_entries(namespace, status);\nCREATE INDEX IF NOT EXISTS idx_memory_ns_type ON memory_entries(namespace, type);\nCREATE INDEX IF NOT EXISTS idx_patterns_type_confidence ON patterns(pattern_type, confidence DESC);\n```\n\n**3. Write amplification on every memory read**\n\n`data/memory/schema.sql:38–40`\n```sql\naccess_count INTEGER DEFAULT 0,\nlast_accessed_at INTEGER,\n```\nEvery `memory_retrieve` call triggers an `UPDATE` on the row to increment `access_count` and update `last_accessed_at`. Under concurrent reads this serializes writes in SQLite WAL mode.\n\n**Fix:** Batch access tracking via a separate `access_log` table, flushed periodically, instead of mutating the primary row on each read:\n```sql\nCREATE TABLE access_log (\n memory_id TEXT NOT NULL,\n accessed_at INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)\n);\n-- Aggregate into memory_entries on a schedule, not per-access\n```\n\n**4. Known bug: vector dimension mismatch crashes all vector ops**\n\n`data/memory/schema.sql:303–308` (comment on line 305)\n```sql\n-- HNSW rejects inserts whose dim does not match this row,\n-- so a 768 here breaks every memory_store --vector (#1947)\nINSERT OR IGNORE INTO vector_indexes (id, name, dimensions) VALUES\n ('default', 'default', 384),\n ('patterns', 'patterns', 384);\n```\nThe `INSERT OR IGNORE` means if a stale row with `dimensions=768` already exists in the database, no correction happens and all vector ops silently fail.\n\n**Fix:**\n```sql\nINSERT OR REPLACE INTO vector_indexes (id, name, dimensions) VALUES\n ('default', 'default', 384),\n ('patterns', 'patterns', 384);\n```\n\n**5. Sessions store full state as a JSON blob**\n\n`data/memory/schema.sql:232`\n```sql\nstate TEXT NOT NULL -- JSON object with full session state\n```\nFor long-running sessions, this blob grows unboundedly and is read/written in full on every session update. There's no incremental update path.\n\n**Fix:** Split session state into normalized columns for frequently-accessed fields (`current_task`, `agent_count`, etc.) and reserve the blob for cold/rarely-accessed context.\n\n---\n\n### Configuration observations (`claude-flow.config.json`)\n\n| Setting | Current | Concern |\n|---|---|---|\n| `memory.cacheSize` | `1000` | Reasonable, but no TTL or eviction policy documented |\n| `swarm.healthCheckInterval` | `30000ms` | 30s polling — fine for most loads |\n| `agents.timeout` | `300000ms` | 5 min hard timeout — agents doing heavy memory ops may hit this |\n| `mcp.autoStart` | `false` | Means daemon must be started manually; risk of stale PIDs in `.claude-flow/daemon.pid` |\n\n---\n\n### Summary\n\nThe only analyzable assets are the SQLite schema and config. No React, no ORM queries, no application JS/TS to audit for the other categories you listed. The highest-impact items are the **JSON-encoded vector blobs** (#1 above) and the **`INSERT OR IGNORE` bug #1947** (#4), since those affect all memory and vector search operations.\n",
|
||
"parsedOutput": {
|
||
"sections": [
|
||
{
|
||
"title": "Performance Analysis",
|
||
"content": "\n",
|
||
"level": 2
|
||
},
|
||
{
|
||
"title": "What this project is",
|
||
"content": "\nThis is a pure configuration/runtime environment: `claude-flow.config.json`, `.swarm/state.json`, and `data/memory/schema.sql`. There is no application JavaScript, TypeScript, React, Python, or backend code to analyze. All JS/TS files are third-party `node_modules`.\n\n---\n\n",
|
||
"level": 3
|
||
},
|
||
{
|
||
"title": "Findings from the SQL schema (`data/memory/schema.sql`)",
|
||
"content": "\n**1. Vectors stored as JSON text — high serialization cost**\n\n`data/memory/schema.sql:22`\n```sql\nembedding TEXT -- stored as JSON array string\n```\nEvery vector similarity computation requires deserializing a JSON string to a float array. For 384-dim vectors with `cosine` distance, this is significant.\n\n**Fix:** Use `BLOB` for binary-packed float32 arrays (4 bytes × 384 = 1,536 bytes vs. ~2,300+ bytes as JSON text), and unpack in the query layer:\n```sql\nembedding BLOB -- pack as Float32Array buffer\n```\n\n**2. Missing composite indexes for common access patterns**\n\n`data/memory/schema.sql:48–54`\n\nQueries like `WHERE namespace = ? AND status = 'active'` or `WHERE namespace = ? AND type = ?` hit two separate indexes with a merge, instead of one. The schema only creates single-column indexes.\n\n**Fix:**\n```sql\nCREATE INDEX IF NOT EXISTS idx_memory_ns_status ON memory_entries(namespace, status);\nCREATE INDEX IF NOT EXISTS idx_memory_ns_type ON memory_entries(namespace, type);\nCREATE INDEX IF NOT EXISTS idx_patterns_type_confidence ON patterns(pattern_type, confidence DESC);\n```\n\n**3. Write amplification on every memory read**\n\n`data/memory/schema.sql:38–40`\n```sql\naccess_count INTEGER DEFAULT 0,\nlast_accessed_at INTEGER,\n```\nEvery `memory_retrieve` call triggers an `UPDATE` on the row to increment `access_count` and update `last_accessed_at`. Under concurrent reads this serializes writes in SQLite WAL mode.\n\n**Fix:** Batch access tracking via a separate `access_log` table, flushed periodically, instead of mutating the primary row on each read:\n```sql\nCREATE TABLE access_log (\n memory_id TEXT NOT NULL,\n accessed_at INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)\n);\n-- Aggregate into memory_entries on a schedule, not per-access\n```\n\n**4. Known bug: vector dimension mismatch crashes all vector ops**\n\n`data/memory/schema.sql:303–308` (comment on line 305)\n```sql\n-- HNSW rejects inserts whose dim does not match this row,\n-- so a 768 here breaks every memory_store --vector (#1947)\nINSERT OR IGNORE INTO vector_indexes (id, name, dimensions) VALUES\n ('default', 'default', 384),\n ('patterns', 'patterns', 384);\n```\nThe `INSERT OR IGNORE` means if a stale row with `dimensions=768` already exists in the database, no correction happens and all vector ops silently fail.\n\n**Fix:**\n```sql\nINSERT OR REPLACE INTO vector_indexes (id, name, dimensions) VALUES\n ('default', 'default', 384),\n ('patterns', 'patterns', 384);\n```\n\n**5. Sessions store full state as a JSON blob**\n\n`data/memory/schema.sql:232`\n```sql\nstate TEXT NOT NULL -- JSON object with full session state\n```\nFor long-running sessions, this blob grows unboundedly and is read/written in full on every session update. There's no incremental update path.\n\n**Fix:** Split session state into normalized columns for frequently-accessed fields (`current_task`, `agent_count`, etc.) and reserve the blob for cold/rarely-accessed context.\n\n---\n\n",
|
||
"level": 3
|
||
},
|
||
{
|
||
"title": "Configuration observations (`claude-flow.config.json`)",
|
||
"content": "\n| Setting | Current | Concern |\n|---|---|---|\n| `memory.cacheSize` | `1000` | Reasonable, but no TTL or eviction policy documented |\n| `swarm.healthCheckInterval` | `30000ms` | 30s polling — fine for most loads |\n| `agents.timeout` | `300000ms` | 5 min hard timeout — agents doing heavy memory ops may hit this |\n| `mcp.autoStart` | `false` | Means daemon must be started manually; risk of stale PIDs in `.claude-flow/daemon.pid` |\n\n---\n\n",
|
||
"level": 3
|
||
},
|
||
{
|
||
"title": "Summary",
|
||
"content": "The only analyzable assets are the SQLite schema and config. No React, no ORM queries, no application JS/TS to audit for the other categories you listed. The highest-impact items are the **JSON-encoded vector blobs** (#1 above) and the **`INSERT OR IGNORE` bug #1947** (#4), since those affect all memory and vector search operations.",
|
||
"level": 3
|
||
}
|
||
],
|
||
"codeBlocks": [
|
||
{
|
||
"language": "sql",
|
||
"code": "embedding TEXT -- stored as JSON array string"
|
||
},
|
||
{
|
||
"language": "sql",
|
||
"code": "embedding BLOB -- pack as Float32Array buffer"
|
||
},
|
||
{
|
||
"language": "sql",
|
||
"code": "CREATE INDEX IF NOT EXISTS idx_memory_ns_status ON memory_entries(namespace, status);\nCREATE INDEX IF NOT EXISTS idx_memory_ns_type ON memory_entries(namespace, type);\nCREATE INDEX IF NOT EXISTS idx_patterns_type_confidence ON patterns(pattern_type, confidence DESC);"
|
||
},
|
||
{
|
||
"language": "sql",
|
||
"code": "access_count INTEGER DEFAULT 0,\nlast_accessed_at INTEGER,"
|
||
},
|
||
{
|
||
"language": "sql",
|
||
"code": "CREATE TABLE access_log (\n memory_id TEXT NOT NULL,\n accessed_at INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)\n);\n-- Aggregate into memory_entries on a schedule, not per-access"
|
||
},
|
||
{
|
||
"language": "sql",
|
||
"code": "-- HNSW rejects inserts whose dim does not match this row,\n-- so a 768 here breaks every memory_store --vector (#1947)\nINSERT OR IGNORE INTO vector_indexes (id, name, dimensions) VALUES\n ('default', 'default', 384),\n ('patterns', 'patterns', 384);"
|
||
},
|
||
{
|
||
"language": "sql",
|
||
"code": "INSERT OR REPLACE INTO vector_indexes (id, name, dimensions) VALUES\n ('default', 'default', 384),\n ('patterns', 'patterns', 384);"
|
||
},
|
||
{
|
||
"language": "sql",
|
||
"code": "state TEXT NOT NULL -- JSON object with full session state"
|
||
}
|
||
]
|
||
},
|
||
"durationMs": 61315,
|
||
"model": "sonnet",
|
||
"sandboxMode": "permissive",
|
||
"workerType": "optimize",
|
||
"timestamp": "2026-05-14T17:52:29.427Z",
|
||
"executionId": "optimize_1778781088112_7y7z80"
|
||
}
|