Files
infinite/.claude-flow/logs/headless/testgaps_1778778639030_dr01yr_result.log
2026-05-14 21:08:13 +00:00

75 lines
35 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[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.01.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 (01) | 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.01.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 (01) | 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"
}