[2026-05-14T17:13:46.824Z] RESULT ============================================================ { "success": true, "output": "---\n\n## Test Coverage Analysis: `/home/code/infinite`\n\n### Current State\n\nThis project contains **zero source files and zero tests**. It is a Ruflo/Claude Flow agent orchestration workspace — a framework installation, not an application. The only testable artifacts are:\n\n- `data/memory/schema.sql` — SQLite schema with 9 tables\n- `claude-flow.config.json` — agent/swarm configuration\n- `package.json` — single dependency: `agentic-flow@^2.0.11`\n\n**Test coverage: 0% (nothing to cover yet)**\n\n---\n\n### Gap Analysis\n\nThe gaps fall into three categories based on what actually exists.\n\n---\n\n#### 1. Database Schema Tests (schema.sql)\n\nThe schema has constraints, CHECK clauses, foreign keys, and indexes that are completely untested.\n\n**Untested constraints:**\n- `memory_entries.type` CHECK: `('semantic','episodic','procedural','working','pattern')`\n- `memory_entries.status` CHECK: `('active','archived','deleted')`\n- `memory_entries` UNIQUE: `(namespace, key)`\n- `patterns.pattern_type` CHECK: 8 valid values\n- `patterns.confidence` — no range constraint (0.0–1.0 is documented but not enforced)\n- `patterns.parent_id` FK self-reference\n- `trajectories.extracted_pattern_id` FK → `patterns.id`\n- `trajectory_steps.trajectory_id` FK → `trajectories.id`\n- `pattern_history.pattern_id` FK → `patterns.id`\n- `vector_indexes` UNIQUE `name` constraint\n\n**Test skeletons:**\n\n```javascript\n// tests/schema.test.js\nimport Database from 'better-sqlite3';\nimport { readFileSync } from 'fs';\n\nlet db;\nbeforeEach(() => {\n db = new Database(':memory:');\n db.exec(readFileSync('data/memory/schema.sql', 'utf8'));\n});\nafterEach(() => db.close());\n\ndescribe('memory_entries constraints', () => {\n test('rejects invalid type value', () => {\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,content,type) VALUES ('1','k','v','invalid')\")\n .run()\n ).toThrow();\n });\n\n test('enforces unique (namespace, key)', () => {\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('1','k','ns','v')\").run();\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('2','k','ns','v2')\").run()\n ).toThrow(/UNIQUE/);\n });\n\n test('allows same key in different namespaces', () => {\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('1','k','ns1','v')\").run();\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('2','k','ns2','v2')\").run()\n ).not.toThrow();\n });\n\n test('rejects invalid status', () => {\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,content,status) VALUES ('1','k','v','unknown')\").run()\n ).toThrow();\n });\n\n test('access_count defaults to 0', () => {\n db.prepare(\"INSERT INTO memory_entries (id,key,content) VALUES ('1','k','v')\").run();\n const row = db.prepare(\"SELECT access_count FROM memory_entries WHERE id='1'\").get();\n expect(row.access_count).toBe(0);\n });\n});\n\ndescribe('patterns constraints', () => {\n test('rejects invalid pattern_type', () => {\n expect(() =>\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action)\n VALUES ('1','n','bad-type','cond','act')`).run()\n ).toThrow();\n });\n\n test('confidence defaults to 0.5', () => {\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action)\n VALUES ('1','n','task-routing','cond','act')`).run();\n const row = db.prepare(\"SELECT confidence FROM patterns WHERE id='1'\").get();\n expect(row.confidence).toBe(0.5);\n });\n\n test('self-referential parent_id FK is enforced', () => {\n expect(() =>\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action,parent_id)\n VALUES ('1','n','task-routing','c','a','nonexistent')`).run()\n ).toThrow(/FOREIGN KEY/);\n });\n\n test('accepts valid pattern_type values', () => {\n const types = ['task-routing','error-recovery','optimization','learning',\n 'coordination','prediction','code-pattern','workflow'];\n types.forEach((t, i) => {\n expect(() =>\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action)\n VALUES ('${i}','n','${t}','c','a')`).run()\n ).not.toThrow();\n });\n });\n});\n\ndescribe('pattern_history FK', () => {\n test('rejects history entry for nonexistent pattern', () => {\n expect(() =>\n db.prepare(`INSERT INTO pattern_history (pattern_id,version,change_type)\n VALUES ('ghost',1,'created')`).run()\n ).toThrow(/FOREIGN KEY/);\n });\n});\n\ndescribe('trajectories', () => {\n test('rejects invalid verdict', () => {\n expect(() =>\n db.prepare(`INSERT INTO trajectories (id,verdict) VALUES ('1','wrong')`).run()\n ).toThrow();\n });\n\n test('allows NULL verdict', () => {\n expect(() =>\n db.prepare(`INSERT INTO trajectories (id) VALUES ('1')`).run()\n ).not.toThrow();\n });\n});\n\ndescribe('vector_indexes', () => {\n test('enforces unique name', () => {\n expect(() =>\n db.prepare(`INSERT INTO vector_indexes (id,name,dimensions) VALUES ('x','default',384)`).run()\n ).toThrow(/UNIQUE/); // 'default' already seeded\n });\n\n test('rejects invalid metric', () => {\n expect(() =>\n db.prepare(`INSERT INTO vector_indexes (id,name,dimensions,metric) VALUES ('y','idx',384,'hamming')`).run()\n ).toThrow();\n });\n});\n```\n\n---\n\n#### 2. Configuration Validation Tests (claude-flow.config.json)\n\nThe config is loaded at runtime with no validation layer. Missing fields or bad values silently corrupt agent behavior.\n\n**Untested edge cases:**\n- `maxAgents` set to 0 or negative\n- `memory.persistPath` pointing to unwritable directory\n- `mcp.serverPort` out of range (0 or >65535)\n- `swarm.topology` set to unsupported value\n- Missing required fields (e.g., `memory.backend`)\n\n```javascript\n// tests/config.test.js\nimport { readFileSync } from 'fs';\n\nconst loadConfig = () => JSON.parse(readFileSync('claude-flow.config.json', 'utf8'));\n\ndescribe('claude-flow.config.json integrity', () => {\n test('loads without throwing', () => {\n expect(() => loadConfig()).not.toThrow();\n });\n\n test('has required top-level keys', () => {\n const config = loadConfig();\n const required = ['agents', 'swarm', 'memory', 'mcp', 'cli', 'hooks'];\n required.forEach(key => expect(config).toHaveProperty(key));\n });\n\n test('maxConcurrent is a positive integer', () => {\n const { agents } = loadConfig();\n expect(agents.maxConcurrent).toBeGreaterThan(0);\n expect(Number.isInteger(agents.maxConcurrent)).toBe(true);\n });\n\n test('swarm topology is a known value', () => {\n const validTopologies = ['hierarchical', 'mesh', 'star', 'ring', 'hierarchical-mesh'];\n const { swarm } = loadConfig();\n expect(validTopologies).toContain(swarm.topology);\n });\n\n test('memory backend is valid', () => {\n const { memory } = loadConfig();\n expect(['hybrid', 'sqlite', 'in-memory']).toContain(memory.backend);\n });\n\n test('mcp port is in valid range', () => {\n const { mcp } = loadConfig();\n expect(mcp.serverPort).toBeGreaterThan(0);\n expect(mcp.serverPort).toBeLessThanOrEqual(65535);\n });\n\n test('vector dimensions match HNSW default index', () => {\n // Must be 384 to match Xenova/all-MiniLM-L6-v2 and the seeded vector_indexes row\n const { memory } = loadConfig();\n expect(memory.vectorDimension).toBe(384);\n });\n\n test('hooks.enabled is boolean', () => {\n const { hooks } = loadConfig();\n expect(typeof hooks.enabled).toBe('boolean');\n });\n});\n```\n\n---\n\n#### 3. Missing Integration Tests (agentic-flow dependency)\n\nThe only runtime dependency is `agentic-flow@^2.0.11`. There are no integration tests verifying the package is actually functional in this environment.\n\n**Gaps:**\n- Package resolves and imports correctly\n- Database initializes from schema without errors\n- Memory store/retrieve round-trip works\n- Pattern insert/query round-trip works\n- Session create/restore works\n- HNSW index operations (insert + search) within dimension constraints\n\n```javascript\n// tests/integration/memory.test.js\nimport { execSync } from 'child_process';\n\ndescribe('agentic-flow integration', () => {\n test('package resolves from node_modules', () => {\n expect(() => require('agentic-flow')).not.toThrow();\n });\n\n test('memory store and retrieve round-trip', () => {\n const result = execSync(\n 'npx @claude-flow/cli@latest memory store --key test-key --value \"hello\" --namespace test',\n { encoding: 'utf8' }\n );\n expect(result).toMatch(/stored|success/i);\n\n const retrieved = execSync(\n 'npx @claude-flow/cli@latest memory retrieve --key test-key --namespace test',\n { encoding: 'utf8' }\n );\n expect(retrieved).toContain('hello');\n });\n\n test('memory search returns results after store', () => {\n const result = execSync(\n 'npx @claude-flow/cli@latest memory search --query \"hello\" --namespace test',\n { encoding: 'utf8' }\n );\n expect(result).toMatch(/test-key|hello/i);\n });\n\n test('system health passes', () => {\n const result = execSync('npx @claude-flow/cli@latest doctor', { encoding: 'utf8' });\n expect(result).not.toMatch(/CRITICAL|FATAL/i);\n });\n});\n```\n\n---\n\n#### 4. Missing Error Handling Tests\n\nThese scenarios are entirely absent:\n\n| Scenario | Risk |\n|----------|------|\n| Schema applied to already-initialized DB | Double-init causes silent data loss |\n| `memory.db` missing at startup | Crash or silent null reads |\n| Config file not found | Unhandled exception in daemon |\n| Vector insert with wrong dimensions | Silently rejected (bug #1947 documented in schema) |\n| `expires_at` in the past on insert | Stale entries immediately readable |\n\n```javascript\n// tests/error-handling.test.js\nimport Database from 'better-sqlite3';\nimport { readFileSync } from 'fs';\n\ndescribe('double-init safety', () => {\n test('applying schema twice is idempotent (IF NOT EXISTS guards work)', () => {\n const db = new Database(':memory:');\n const schema = readFileSync('data/memory/schema.sql', 'utf8');\n expect(() => {\n db.exec(schema);\n db.exec(schema); // second application must not throw\n }).not.toThrow();\n db.close();\n });\n});\n\ndescribe('vector dimension guard', () => {\n test('HNSW index rejects insert with mismatched dimensions', () => {\n // The schema seeds vector_indexes.dimensions=384.\n // Inserting an embedding with 768 dims must be caught by application layer.\n // This test documents the known gap (#1947) until a DB CHECK is added.\n const db = new Database(':memory:');\n db.exec(readFileSync('data/memory/schema.sql', 'utf8'));\n const idx = db.prepare(\"SELECT dimensions FROM vector_indexes WHERE name='default'\").get();\n expect(idx.dimensions).toBe(384); // guard: seed value must stay 384\n db.close();\n });\n});\n\ndescribe('expiry semantics', () => {\n test('expired entries are still retrievable (no automatic purge)', () => {\n const db = new Database(':memory:');\n db.exec(readFileSync('data/memory/schema.sql', 'utf8'));\n const past = Date.now() - 1000;\n db.prepare(`INSERT INTO memory_entries (id,key,content,expires_at) VALUES ('1','k','v',${past})`).run();\n const row = db.prepare(\"SELECT * FROM memory_entries WHERE id='1'\").get();\n expect(row).toBeTruthy(); // expired but still readable — app must filter\n db.close();\n });\n});\n```\n\n---\n\n### Summary of Gaps\n\n| Gap | Priority | Effort |\n|-----|----------|--------|\n| Schema constraint tests | High | Low — pure SQL, no deps |\n| Config validation tests | High | Low — JSON parsing only |\n| Double-init idempotency | High | Low |\n| Vector dimension mismatch handling | High | Medium |\n| `agentic-flow` integration round-trip | Medium | Medium — needs CLI available |\n| Expiry/TTL filtering logic | Medium | Low |\n| `confidence` range enforcement (0–1) | Low | Low — add DB CHECK or app guard |\n| Session restore after crash | Medium | High — needs daemon lifecycle |\n\n**Recommended first step:** Add `better-sqlite3` and `jest` to `package.json`, then implement the schema constraint tests — they require no external services, run in-memory, and cover the highest-risk invariants (FK integrity, CHECK constraints, the documented dimension bug #1947).\n", "parsedOutput": { "sections": [ { "title": "Test Coverage Analysis: `/home/code/infinite`", "content": "\n", "level": 2 }, { "title": "Current State", "content": "\nThis project contains **zero source files and zero tests**. It is a Ruflo/Claude Flow agent orchestration workspace — a framework installation, not an application. The only testable artifacts are:\n\n- `data/memory/schema.sql` — SQLite schema with 9 tables\n- `claude-flow.config.json` — agent/swarm configuration\n- `package.json` — single dependency: `agentic-flow@^2.0.11`\n\n**Test coverage: 0% (nothing to cover yet)**\n\n---\n\n", "level": 3 }, { "title": "Gap Analysis", "content": "\nThe gaps fall into three categories based on what actually exists.\n\n---\n\n", "level": 3 }, { "title": "1. Database Schema Tests (schema.sql)", "content": "\nThe schema has constraints, CHECK clauses, foreign keys, and indexes that are completely untested.\n\n**Untested constraints:**\n- `memory_entries.type` CHECK: `('semantic','episodic','procedural','working','pattern')`\n- `memory_entries.status` CHECK: `('active','archived','deleted')`\n- `memory_entries` UNIQUE: `(namespace, key)`\n- `patterns.pattern_type` CHECK: 8 valid values\n- `patterns.confidence` — no range constraint (0.0–1.0 is documented but not enforced)\n- `patterns.parent_id` FK self-reference\n- `trajectories.extracted_pattern_id` FK → `patterns.id`\n- `trajectory_steps.trajectory_id` FK → `trajectories.id`\n- `pattern_history.pattern_id` FK → `patterns.id`\n- `vector_indexes` UNIQUE `name` constraint\n\n**Test skeletons:**\n\n```javascript\n// tests/schema.test.js\nimport Database from 'better-sqlite3';\nimport { readFileSync } from 'fs';\n\nlet db;\nbeforeEach(() => {\n db = new Database(':memory:');\n db.exec(readFileSync('data/memory/schema.sql', 'utf8'));\n});\nafterEach(() => db.close());\n\ndescribe('memory_entries constraints', () => {\n test('rejects invalid type value', () => {\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,content,type) VALUES ('1','k','v','invalid')\")\n .run()\n ).toThrow();\n });\n\n test('enforces unique (namespace, key)', () => {\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('1','k','ns','v')\").run();\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('2','k','ns','v2')\").run()\n ).toThrow(/UNIQUE/);\n });\n\n test('allows same key in different namespaces', () => {\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('1','k','ns1','v')\").run();\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('2','k','ns2','v2')\").run()\n ).not.toThrow();\n });\n\n test('rejects invalid status', () => {\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,content,status) VALUES ('1','k','v','unknown')\").run()\n ).toThrow();\n });\n\n test('access_count defaults to 0', () => {\n db.prepare(\"INSERT INTO memory_entries (id,key,content) VALUES ('1','k','v')\").run();\n const row = db.prepare(\"SELECT access_count FROM memory_entries WHERE id='1'\").get();\n expect(row.access_count).toBe(0);\n });\n});\n\ndescribe('patterns constraints', () => {\n test('rejects invalid pattern_type', () => {\n expect(() =>\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action)\n VALUES ('1','n','bad-type','cond','act')`).run()\n ).toThrow();\n });\n\n test('confidence defaults to 0.5', () => {\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action)\n VALUES ('1','n','task-routing','cond','act')`).run();\n const row = db.prepare(\"SELECT confidence FROM patterns WHERE id='1'\").get();\n expect(row.confidence).toBe(0.5);\n });\n\n test('self-referential parent_id FK is enforced', () => {\n expect(() =>\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action,parent_id)\n VALUES ('1','n','task-routing','c','a','nonexistent')`).run()\n ).toThrow(/FOREIGN KEY/);\n });\n\n test('accepts valid pattern_type values', () => {\n const types = ['task-routing','error-recovery','optimization','learning',\n 'coordination','prediction','code-pattern','workflow'];\n types.forEach((t, i) => {\n expect(() =>\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action)\n VALUES ('${i}','n','${t}','c','a')`).run()\n ).not.toThrow();\n });\n });\n});\n\ndescribe('pattern_history FK', () => {\n test('rejects history entry for nonexistent pattern', () => {\n expect(() =>\n db.prepare(`INSERT INTO pattern_history (pattern_id,version,change_type)\n VALUES ('ghost',1,'created')`).run()\n ).toThrow(/FOREIGN KEY/);\n });\n});\n\ndescribe('trajectories', () => {\n test('rejects invalid verdict', () => {\n expect(() =>\n db.prepare(`INSERT INTO trajectories (id,verdict) VALUES ('1','wrong')`).run()\n ).toThrow();\n });\n\n test('allows NULL verdict', () => {\n expect(() =>\n db.prepare(`INSERT INTO trajectories (id) VALUES ('1')`).run()\n ).not.toThrow();\n });\n});\n\ndescribe('vector_indexes', () => {\n test('enforces unique name', () => {\n expect(() =>\n db.prepare(`INSERT INTO vector_indexes (id,name,dimensions) VALUES ('x','default',384)`).run()\n ).toThrow(/UNIQUE/); // 'default' already seeded\n });\n\n test('rejects invalid metric', () => {\n expect(() =>\n db.prepare(`INSERT INTO vector_indexes (id,name,dimensions,metric) VALUES ('y','idx',384,'hamming')`).run()\n ).toThrow();\n });\n});\n```\n\n---\n\n", "level": 4 }, { "title": "2. Configuration Validation Tests (claude-flow.config.json)", "content": "\nThe config is loaded at runtime with no validation layer. Missing fields or bad values silently corrupt agent behavior.\n\n**Untested edge cases:**\n- `maxAgents` set to 0 or negative\n- `memory.persistPath` pointing to unwritable directory\n- `mcp.serverPort` out of range (0 or >65535)\n- `swarm.topology` set to unsupported value\n- Missing required fields (e.g., `memory.backend`)\n\n```javascript\n// tests/config.test.js\nimport { readFileSync } from 'fs';\n\nconst loadConfig = () => JSON.parse(readFileSync('claude-flow.config.json', 'utf8'));\n\ndescribe('claude-flow.config.json integrity', () => {\n test('loads without throwing', () => {\n expect(() => loadConfig()).not.toThrow();\n });\n\n test('has required top-level keys', () => {\n const config = loadConfig();\n const required = ['agents', 'swarm', 'memory', 'mcp', 'cli', 'hooks'];\n required.forEach(key => expect(config).toHaveProperty(key));\n });\n\n test('maxConcurrent is a positive integer', () => {\n const { agents } = loadConfig();\n expect(agents.maxConcurrent).toBeGreaterThan(0);\n expect(Number.isInteger(agents.maxConcurrent)).toBe(true);\n });\n\n test('swarm topology is a known value', () => {\n const validTopologies = ['hierarchical', 'mesh', 'star', 'ring', 'hierarchical-mesh'];\n const { swarm } = loadConfig();\n expect(validTopologies).toContain(swarm.topology);\n });\n\n test('memory backend is valid', () => {\n const { memory } = loadConfig();\n expect(['hybrid', 'sqlite', 'in-memory']).toContain(memory.backend);\n });\n\n test('mcp port is in valid range', () => {\n const { mcp } = loadConfig();\n expect(mcp.serverPort).toBeGreaterThan(0);\n expect(mcp.serverPort).toBeLessThanOrEqual(65535);\n });\n\n test('vector dimensions match HNSW default index', () => {\n // Must be 384 to match Xenova/all-MiniLM-L6-v2 and the seeded vector_indexes row\n const { memory } = loadConfig();\n expect(memory.vectorDimension).toBe(384);\n });\n\n test('hooks.enabled is boolean', () => {\n const { hooks } = loadConfig();\n expect(typeof hooks.enabled).toBe('boolean');\n });\n});\n```\n\n---\n\n", "level": 4 }, { "title": "3. Missing Integration Tests (agentic-flow dependency)", "content": "\nThe only runtime dependency is `agentic-flow@^2.0.11`. There are no integration tests verifying the package is actually functional in this environment.\n\n**Gaps:**\n- Package resolves and imports correctly\n- Database initializes from schema without errors\n- Memory store/retrieve round-trip works\n- Pattern insert/query round-trip works\n- Session create/restore works\n- HNSW index operations (insert + search) within dimension constraints\n\n```javascript\n// tests/integration/memory.test.js\nimport { execSync } from 'child_process';\n\ndescribe('agentic-flow integration', () => {\n test('package resolves from node_modules', () => {\n expect(() => require('agentic-flow')).not.toThrow();\n });\n\n test('memory store and retrieve round-trip', () => {\n const result = execSync(\n 'npx @claude-flow/cli@latest memory store --key test-key --value \"hello\" --namespace test',\n { encoding: 'utf8' }\n );\n expect(result).toMatch(/stored|success/i);\n\n const retrieved = execSync(\n 'npx @claude-flow/cli@latest memory retrieve --key test-key --namespace test',\n { encoding: 'utf8' }\n );\n expect(retrieved).toContain('hello');\n });\n\n test('memory search returns results after store', () => {\n const result = execSync(\n 'npx @claude-flow/cli@latest memory search --query \"hello\" --namespace test',\n { encoding: 'utf8' }\n );\n expect(result).toMatch(/test-key|hello/i);\n });\n\n test('system health passes', () => {\n const result = execSync('npx @claude-flow/cli@latest doctor', { encoding: 'utf8' });\n expect(result).not.toMatch(/CRITICAL|FATAL/i);\n });\n});\n```\n\n---\n\n", "level": 4 }, { "title": "4. Missing Error Handling Tests", "content": "\nThese scenarios are entirely absent:\n\n| Scenario | Risk |\n|----------|------|\n| Schema applied to already-initialized DB | Double-init causes silent data loss |\n| `memory.db` missing at startup | Crash or silent null reads |\n| Config file not found | Unhandled exception in daemon |\n| Vector insert with wrong dimensions | Silently rejected (bug #1947 documented in schema) |\n| `expires_at` in the past on insert | Stale entries immediately readable |\n\n```javascript\n// tests/error-handling.test.js\nimport Database from 'better-sqlite3';\nimport { readFileSync } from 'fs';\n\ndescribe('double-init safety', () => {\n test('applying schema twice is idempotent (IF NOT EXISTS guards work)', () => {\n const db = new Database(':memory:');\n const schema = readFileSync('data/memory/schema.sql', 'utf8');\n expect(() => {\n db.exec(schema);\n db.exec(schema); // second application must not throw\n }).not.toThrow();\n db.close();\n });\n});\n\ndescribe('vector dimension guard', () => {\n test('HNSW index rejects insert with mismatched dimensions', () => {\n // The schema seeds vector_indexes.dimensions=384.\n // Inserting an embedding with 768 dims must be caught by application layer.\n // This test documents the known gap (#1947) until a DB CHECK is added.\n const db = new Database(':memory:');\n db.exec(readFileSync('data/memory/schema.sql', 'utf8'));\n const idx = db.prepare(\"SELECT dimensions FROM vector_indexes WHERE name='default'\").get();\n expect(idx.dimensions).toBe(384); // guard: seed value must stay 384\n db.close();\n });\n});\n\ndescribe('expiry semantics', () => {\n test('expired entries are still retrievable (no automatic purge)', () => {\n const db = new Database(':memory:');\n db.exec(readFileSync('data/memory/schema.sql', 'utf8'));\n const past = Date.now() - 1000;\n db.prepare(`INSERT INTO memory_entries (id,key,content,expires_at) VALUES ('1','k','v',${past})`).run();\n const row = db.prepare(\"SELECT * FROM memory_entries WHERE id='1'\").get();\n expect(row).toBeTruthy(); // expired but still readable — app must filter\n db.close();\n });\n});\n```\n\n---\n\n", "level": 4 }, { "title": "Summary of Gaps", "content": "| Gap | Priority | Effort |\n|-----|----------|--------|\n| Schema constraint tests | High | Low — pure SQL, no deps |\n| Config validation tests | High | Low — JSON parsing only |\n| Double-init idempotency | High | Low |\n| Vector dimension mismatch handling | High | Medium |\n| `agentic-flow` integration round-trip | Medium | Medium — needs CLI available |\n| Expiry/TTL filtering logic | Medium | Low |\n| `confidence` range enforcement (0–1) | Low | Low — add DB CHECK or app guard |\n| Session restore after crash | Medium | High — needs daemon lifecycle |\n\n**Recommended first step:** Add `better-sqlite3` and `jest` to `package.json`, then implement the schema constraint tests — they require no external services, run in-memory, and cover the highest-risk invariants (FK integrity, CHECK constraints, the documented dimension bug #1947).", "level": 3 } ], "codeBlocks": [ { "language": "javascript", "code": "// tests/schema.test.js\nimport Database from 'better-sqlite3';\nimport { readFileSync } from 'fs';\n\nlet db;\nbeforeEach(() => {\n db = new Database(':memory:');\n db.exec(readFileSync('data/memory/schema.sql', 'utf8'));\n});\nafterEach(() => db.close());\n\ndescribe('memory_entries constraints', () => {\n test('rejects invalid type value', () => {\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,content,type) VALUES ('1','k','v','invalid')\")\n .run()\n ).toThrow();\n });\n\n test('enforces unique (namespace, key)', () => {\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('1','k','ns','v')\").run();\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('2','k','ns','v2')\").run()\n ).toThrow(/UNIQUE/);\n });\n\n test('allows same key in different namespaces', () => {\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('1','k','ns1','v')\").run();\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,namespace,content) VALUES ('2','k','ns2','v2')\").run()\n ).not.toThrow();\n });\n\n test('rejects invalid status', () => {\n expect(() =>\n db.prepare(\"INSERT INTO memory_entries (id,key,content,status) VALUES ('1','k','v','unknown')\").run()\n ).toThrow();\n });\n\n test('access_count defaults to 0', () => {\n db.prepare(\"INSERT INTO memory_entries (id,key,content) VALUES ('1','k','v')\").run();\n const row = db.prepare(\"SELECT access_count FROM memory_entries WHERE id='1'\").get();\n expect(row.access_count).toBe(0);\n });\n});\n\ndescribe('patterns constraints', () => {\n test('rejects invalid pattern_type', () => {\n expect(() =>\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action)\n VALUES ('1','n','bad-type','cond','act')`).run()\n ).toThrow();\n });\n\n test('confidence defaults to 0.5', () => {\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action)\n VALUES ('1','n','task-routing','cond','act')`).run();\n const row = db.prepare(\"SELECT confidence FROM patterns WHERE id='1'\").get();\n expect(row.confidence).toBe(0.5);\n });\n\n test('self-referential parent_id FK is enforced', () => {\n expect(() =>\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action,parent_id)\n VALUES ('1','n','task-routing','c','a','nonexistent')`).run()\n ).toThrow(/FOREIGN KEY/);\n });\n\n test('accepts valid pattern_type values', () => {\n const types = ['task-routing','error-recovery','optimization','learning',\n 'coordination','prediction','code-pattern','workflow'];\n types.forEach((t, i) => {\n expect(() =>\n db.prepare(`INSERT INTO patterns (id,name,pattern_type,condition,action)\n VALUES ('${i}','n','${t}','c','a')`).run()\n ).not.toThrow();\n });\n });\n});\n\ndescribe('pattern_history FK', () => {\n test('rejects history entry for nonexistent pattern', () => {\n expect(() =>\n db.prepare(`INSERT INTO pattern_history (pattern_id,version,change_type)\n VALUES ('ghost',1,'created')`).run()\n ).toThrow(/FOREIGN KEY/);\n });\n});\n\ndescribe('trajectories', () => {\n test('rejects invalid verdict', () => {\n expect(() =>\n db.prepare(`INSERT INTO trajectories (id,verdict) VALUES ('1','wrong')`).run()\n ).toThrow();\n });\n\n test('allows NULL verdict', () => {\n expect(() =>\n db.prepare(`INSERT INTO trajectories (id) VALUES ('1')`).run()\n ).not.toThrow();\n });\n});\n\ndescribe('vector_indexes', () => {\n test('enforces unique name', () => {\n expect(() =>\n db.prepare(`INSERT INTO vector_indexes (id,name,dimensions) VALUES ('x','default',384)`).run()\n ).toThrow(/UNIQUE/); // 'default' already seeded\n });\n\n test('rejects invalid metric', () => {\n expect(() =>\n db.prepare(`INSERT INTO vector_indexes (id,name,dimensions,metric) VALUES ('y','idx',384,'hamming')`).run()\n ).toThrow();\n });\n});" }, { "language": "javascript", "code": "// tests/config.test.js\nimport { readFileSync } from 'fs';\n\nconst loadConfig = () => JSON.parse(readFileSync('claude-flow.config.json', 'utf8'));\n\ndescribe('claude-flow.config.json integrity', () => {\n test('loads without throwing', () => {\n expect(() => loadConfig()).not.toThrow();\n });\n\n test('has required top-level keys', () => {\n const config = loadConfig();\n const required = ['agents', 'swarm', 'memory', 'mcp', 'cli', 'hooks'];\n required.forEach(key => expect(config).toHaveProperty(key));\n });\n\n test('maxConcurrent is a positive integer', () => {\n const { agents } = loadConfig();\n expect(agents.maxConcurrent).toBeGreaterThan(0);\n expect(Number.isInteger(agents.maxConcurrent)).toBe(true);\n });\n\n test('swarm topology is a known value', () => {\n const validTopologies = ['hierarchical', 'mesh', 'star', 'ring', 'hierarchical-mesh'];\n const { swarm } = loadConfig();\n expect(validTopologies).toContain(swarm.topology);\n });\n\n test('memory backend is valid', () => {\n const { memory } = loadConfig();\n expect(['hybrid', 'sqlite', 'in-memory']).toContain(memory.backend);\n });\n\n test('mcp port is in valid range', () => {\n const { mcp } = loadConfig();\n expect(mcp.serverPort).toBeGreaterThan(0);\n expect(mcp.serverPort).toBeLessThanOrEqual(65535);\n });\n\n test('vector dimensions match HNSW default index', () => {\n // Must be 384 to match Xenova/all-MiniLM-L6-v2 and the seeded vector_indexes row\n const { memory } = loadConfig();\n expect(memory.vectorDimension).toBe(384);\n });\n\n test('hooks.enabled is boolean', () => {\n const { hooks } = loadConfig();\n expect(typeof hooks.enabled).toBe('boolean');\n });\n});" }, { "language": "javascript", "code": "// tests/integration/memory.test.js\nimport { execSync } from 'child_process';\n\ndescribe('agentic-flow integration', () => {\n test('package resolves from node_modules', () => {\n expect(() => require('agentic-flow')).not.toThrow();\n });\n\n test('memory store and retrieve round-trip', () => {\n const result = execSync(\n 'npx @claude-flow/cli@latest memory store --key test-key --value \"hello\" --namespace test',\n { encoding: 'utf8' }\n );\n expect(result).toMatch(/stored|success/i);\n\n const retrieved = execSync(\n 'npx @claude-flow/cli@latest memory retrieve --key test-key --namespace test',\n { encoding: 'utf8' }\n );\n expect(retrieved).toContain('hello');\n });\n\n test('memory search returns results after store', () => {\n const result = execSync(\n 'npx @claude-flow/cli@latest memory search --query \"hello\" --namespace test',\n { encoding: 'utf8' }\n );\n expect(result).toMatch(/test-key|hello/i);\n });\n\n test('system health passes', () => {\n const result = execSync('npx @claude-flow/cli@latest doctor', { encoding: 'utf8' });\n expect(result).not.toMatch(/CRITICAL|FATAL/i);\n });\n});" }, { "language": "javascript", "code": "// tests/error-handling.test.js\nimport Database from 'better-sqlite3';\nimport { readFileSync } from 'fs';\n\ndescribe('double-init safety', () => {\n test('applying schema twice is idempotent (IF NOT EXISTS guards work)', () => {\n const db = new Database(':memory:');\n const schema = readFileSync('data/memory/schema.sql', 'utf8');\n expect(() => {\n db.exec(schema);\n db.exec(schema); // second application must not throw\n }).not.toThrow();\n db.close();\n });\n});\n\ndescribe('vector dimension guard', () => {\n test('HNSW index rejects insert with mismatched dimensions', () => {\n // The schema seeds vector_indexes.dimensions=384.\n // Inserting an embedding with 768 dims must be caught by application layer.\n // This test documents the known gap (#1947) until a DB CHECK is added.\n const db = new Database(':memory:');\n db.exec(readFileSync('data/memory/schema.sql', 'utf8'));\n const idx = db.prepare(\"SELECT dimensions FROM vector_indexes WHERE name='default'\").get();\n expect(idx.dimensions).toBe(384); // guard: seed value must stay 384\n db.close();\n });\n});\n\ndescribe('expiry semantics', () => {\n test('expired entries are still retrievable (no automatic purge)', () => {\n const db = new Database(':memory:');\n db.exec(readFileSync('data/memory/schema.sql', 'utf8'));\n const past = Date.now() - 1000;\n db.prepare(`INSERT INTO memory_entries (id,key,content,expires_at) VALUES ('1','k','v',${past})`).run();\n const row = db.prepare(\"SELECT * FROM memory_entries WHERE id='1'\").get();\n expect(row).toBeTruthy(); // expired but still readable — app must filter\n db.close();\n });\n});" } ] }, "durationMs": 187794, "model": "sonnet", "sandboxMode": "permissive", "workerType": "testgaps", "timestamp": "2026-05-14T17:13:46.824Z", "executionId": "testgaps_1778778639030_dr01yr" }