/ __quarantined_tests__ / agents / architect-coverage2.test.js
architect-coverage2.test.js
   1  /**
   2   * Comprehensive Coverage Tests for Architect Agent (architect-coverage2)
   3   *
   4   * Targets uncovered code paths to close the coverage gap.
   5   * Covers: detectSemanticDocChanges, getJsFiles, checkComplexity depth issues,
   6   * auditDocumentation focus areas, reviewDesign over-engineering patterns,
   7   * updateDocumentation commit path, createDesignProposal PO approval paths,
   8   * reviewImplementationPlan approved path, checkBranchHealth branch scenarios,
   9   * profilePerformance critical severity, processTask string context parsing, and more.
  10   *
  11   * IMPORTANT: No writes to ./logs/ or ./db/sites.db - all paths use /tmp or in-memory.
  12   */
  13  
  14  import { test, describe, mock } from 'node:test';
  15  import assert from 'node:assert/strict';
  16  import Database from 'better-sqlite3';
  17  import { rmSync, writeFileSync, mkdirSync } from 'fs';
  18  import { join } from 'path';
  19  import { tmpdir } from 'os';
  20  
  21  process.env.AGENT_IMMEDIATE_INVOCATION = 'false';
  22  process.env.AGENT_REALTIME_NOTIFICATIONS = 'false';
  23  
  24  // ============================================================
  25  // Mock BEFORE importing architect module
  26  // (mock.module calls must come before any imports of architect.js)
  27  // ============================================================
  28  
  29  // Mock agent-claude-api.js to avoid real LLM calls
  30  mock.module('../../src/agents/utils/agent-claude-api.js', {
  31    namedExports: {
  32      generateCode: async (_agentName, _taskId, _target, prompt, _existing) => {
  33        // Return responses tailored to the type of request
  34        if (prompt && prompt.includes('No documentation updates required')) {
  35          return 'No documentation updates required.';
  36        }
  37        if (prompt && prompt.includes('semantic changes')) {
  38          // Simulate finding some semantic doc changes
  39          return `- [README.md]: New API added - Add documentation for new endpoint
  40  - [CLAUDE.md]: Pipeline modified - Update pipeline stage documentation`;
  41        }
  42        // Default: approval response with no high-severity issues
  43        return `**Summary**: Test implementation summary
  44  
  45  **Issues**:
  46  - [medium] Consider splitting large files
  47  
  48  **Recommendations**:
  49  - Add more tests
  50  
  51  **Approval**: yes
  52  
  53  Updated documentation content.
  54  This is the complete updated file.`;
  55      },
  56      simpleLLMCall: async _prompt => {
  57        return 'No documentation updates required.';
  58      },
  59      resetDb: () => {},
  60    },
  61  });
  62  
  63  // Mock file-operations.js to avoid path whitelist restrictions
  64  let mockReadResult = { content: '# Documentation\n\nSome content here.\n', path: '' };
  65  const mockWriteResult = { success: true, backupPath: '/tmp/backup-doc.md' };
  66  
  67  mock.module('../../src/agents/utils/file-operations.js', {
  68    namedExports: {
  69      readFile: async filePath => ({ content: mockReadResult.content, path: filePath }),
  70      writeFile: async (_filePath, _content, _options) => mockWriteResult,
  71      editFile: async (_filePath, _edits) => ({ success: true }),
  72      fileExists: async _filePath => true,
  73      listFiles: async _dir => [],
  74      resetDb: () => {},
  75    },
  76  });
  77  
  78  // Dynamic imports AFTER mocks are registered
  79  const { ArchitectAgent } = await import('../../src/agents/architect.js');
  80  const { resetDb: resetBaseDb } = await import('../../src/agents/base-agent.js');
  81  const { resetDbConnection: resetTaskManagerDb } =
  82    await import('../../src/agents/utils/task-manager.js');
  83  const { resetDb: resetMessageManagerDb } =
  84    await import('../../src/agents/utils/message-manager.js');
  85  
  86  // ============================================================
  87  // Full DB Schema
  88  // ============================================================
  89  
  90  const FULL_SCHEMA = `
  91    CREATE TABLE IF NOT EXISTS agent_tasks (
  92      id INTEGER PRIMARY KEY AUTOINCREMENT,
  93      task_type TEXT NOT NULL,
  94      assigned_to TEXT NOT NULL,
  95      created_by TEXT,
  96      status TEXT DEFAULT 'pending',
  97      priority INTEGER DEFAULT 5,
  98      context_json TEXT,
  99      result_json TEXT,
 100      parent_task_id INTEGER,
 101      error_message TEXT,
 102      reviewed_by TEXT,
 103      approval_json TEXT,
 104      created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
 105      started_at DATETIME,
 106      completed_at DATETIME,
 107      retry_count INTEGER DEFAULT 0
 108    );
 109    CREATE TABLE IF NOT EXISTS agent_logs (
 110      id INTEGER PRIMARY KEY AUTOINCREMENT,
 111      task_id INTEGER,
 112      agent_name TEXT NOT NULL,
 113      log_level TEXT,
 114      message TEXT NOT NULL,
 115      data_json TEXT,
 116      created_at DATETIME DEFAULT CURRENT_TIMESTAMP
 117    );
 118    CREATE TABLE IF NOT EXISTS agent_state (
 119      agent_name TEXT PRIMARY KEY,
 120      last_active DATETIME DEFAULT CURRENT_TIMESTAMP,
 121      current_task_id INTEGER,
 122      status TEXT DEFAULT 'idle',
 123      metrics_json TEXT
 124    );
 125    CREATE TABLE IF NOT EXISTS agent_llm_usage (
 126      id INTEGER PRIMARY KEY AUTOINCREMENT,
 127      agent_name TEXT NOT NULL,
 128      task_id INTEGER,
 129      model TEXT NOT NULL,
 130      prompt_tokens INTEGER NOT NULL,
 131      completion_tokens INTEGER NOT NULL,
 132      cost_usd REAL NOT NULL,
 133      created_at DATETIME DEFAULT CURRENT_TIMESTAMP
 134    );
 135    CREATE TABLE IF NOT EXISTS pipeline_metrics (
 136      id INTEGER PRIMARY KEY AUTOINCREMENT,
 137      stage_name TEXT NOT NULL,
 138      sites_processed INTEGER DEFAULT 0,
 139      sites_succeeded INTEGER DEFAULT 0,
 140      sites_failed INTEGER DEFAULT 0,
 141      duration_ms INTEGER NOT NULL,
 142      started_at DATETIME NOT NULL,
 143      finished_at DATETIME NOT NULL,
 144      created_at DATETIME DEFAULT CURRENT_TIMESTAMP
 145    );
 146    CREATE TABLE IF NOT EXISTS agent_outcomes (
 147      id INTEGER PRIMARY KEY AUTOINCREMENT,
 148      task_id INTEGER NOT NULL,
 149      agent_name TEXT NOT NULL,
 150      task_type TEXT NOT NULL,
 151      outcome TEXT NOT NULL CHECK(outcome IN ('success', 'failure')),
 152      context_json TEXT,
 153      result_json TEXT,
 154      duration_ms INTEGER,
 155      created_at DATETIME DEFAULT CURRENT_TIMESTAMP
 156    );
 157    CREATE TABLE IF NOT EXISTS agent_messages (
 158      id INTEGER PRIMARY KEY AUTOINCREMENT,
 159      task_id INTEGER,
 160      from_agent TEXT NOT NULL,
 161      to_agent TEXT NOT NULL,
 162      message_type TEXT NOT NULL,
 163      content TEXT NOT NULL,
 164      metadata_json TEXT,
 165      created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
 166      read_at DATETIME
 167    );
 168    CREATE TABLE IF NOT EXISTS human_review_queue (
 169      id INTEGER PRIMARY KEY AUTOINCREMENT,
 170      file TEXT,
 171      reason TEXT,
 172      type TEXT,
 173      priority TEXT DEFAULT 'medium',
 174      status TEXT DEFAULT 'pending',
 175      created_at TEXT DEFAULT (datetime('now')),
 176      reviewed_at TEXT,
 177      reviewed_by TEXT,
 178      notes TEXT
 179    );
 180    INSERT OR IGNORE INTO agent_state (agent_name, status) VALUES ('architect', 'idle');
 181    INSERT OR IGNORE INTO agent_state (agent_name, status) VALUES ('developer', 'idle');
 182    INSERT OR IGNORE INTO agent_state (agent_name, status) VALUES ('monitor', 'idle');
 183  `;
 184  
 185  // ============================================================
 186  // Test helpers
 187  // ============================================================
 188  
 189  function createTestDb(dbPath) {
 190    const db = new Database(dbPath);
 191    db.pragma('foreign_keys = ON');
 192    db.exec(FULL_SCHEMA);
 193    return db;
 194  }
 195  
 196  async function createTestEnv(dbPath) {
 197    resetBaseDb();
 198    resetTaskManagerDb();
 199    resetMessageManagerDb();
 200  
 201    try {
 202      rmSync(dbPath, { force: true });
 203    } catch (_e) {
 204      // ignore
 205    }
 206  
 207    const db = createTestDb(dbPath);
 208    process.env.DATABASE_PATH = dbPath;
 209  
 210    const agent = new ArchitectAgent();
 211    await agent.initialize();
 212  
 213    return {
 214      db,
 215      agent,
 216      cleanup: () => {
 217        resetBaseDb();
 218        resetTaskManagerDb();
 219        resetMessageManagerDb();
 220        try {
 221          db.close();
 222        } catch (_e) {
 223          // ignore
 224        }
 225        try {
 226          rmSync(dbPath, { force: true });
 227        } catch (_e) {
 228          // ignore
 229        }
 230      },
 231    };
 232  }
 233  
 234  function insertTask(db, taskType, contextJson) {
 235    return db
 236      .prepare(
 237        `INSERT INTO agent_tasks (task_type, assigned_to, status, context_json)
 238         VALUES (?, 'architect', 'running', ?) RETURNING id`
 239      )
 240      .get(taskType, contextJson !== undefined ? JSON.stringify(contextJson) : null).id;
 241  }
 242  
 243  function getTask(db, taskId) {
 244    const row = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 245    if (row && row.context_json && typeof row.context_json === 'string') {
 246      try {
 247        row.context_json = JSON.parse(row.context_json);
 248      } catch (_e) {
 249        // ignore
 250      }
 251    }
 252    return row;
 253  }
 254  
 255  // ============================================================
 256  // 1. processTask: string context_json parsing path
 257  // ============================================================
 258  
 259  describe('ArchitectAgent Coverage2 - processTask context_json parsing', () => {
 260    test('parses string context_json into object before routing', async () => {
 261      const dbPath = join(tmpdir(), `arch-cov2-ptparse-${Date.now()}.db`);
 262      const { db, agent, cleanup } = await createTestEnv(dbPath);
 263      try {
 264        // Insert task with string context_json (not yet parsed) - simulate raw DB value
 265        const taskId = db
 266          .prepare(
 267            `INSERT INTO agent_tasks (task_type, assigned_to, status, context_json)
 268             VALUES (?, 'architect', 'running', ?) RETURNING id`
 269          )
 270          .get('review_design', JSON.stringify({ files: [] })).id;
 271  
 272        // Get raw row without parsing context_json
 273        const row = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 274        // context_json is still a string here - processTask should handle it
 275        assert.strictEqual(
 276          typeof row.context_json,
 277          'string',
 278          'context_json should be string before parsing'
 279        );
 280  
 281        // processTask handles string context_json
 282        await agent.processTask(row);
 283  
 284        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 285        assert.ok(
 286          ['completed', 'failed'].includes(updated.status),
 287          `Should complete or fail, got: ${updated.status}`
 288        );
 289      } finally {
 290        cleanup();
 291      }
 292    });
 293  
 294    test('handles null context_json by defaulting to empty object', async () => {
 295      const dbPath = join(tmpdir(), `arch-cov2-ptnull-${Date.now()}.db`);
 296      const { db, agent, cleanup } = await createTestEnv(dbPath);
 297      try {
 298        const taskId = insertTask(db, 'review_design', null);
 299        const task = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 300        // Null context_json - processTask sets it to {}
 301        task.context_json = null;
 302  
 303        await agent.processTask(task);
 304  
 305        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 306        assert.ok(
 307          ['completed', 'failed'].includes(updated.status),
 308          `Should complete or fail, got: ${updated.status}`
 309        );
 310      } finally {
 311        cleanup();
 312      }
 313    });
 314  });
 315  
 316  // ============================================================
 317  // 2. reviewDesign: over-engineering pattern detection
 318  // ============================================================
 319  
 320  describe('ArchitectAgent Coverage2 - reviewDesign over-engineering patterns', () => {
 321    test('detects Factory class pattern as over-engineering', async () => {
 322      const dbPath = join(tmpdir(), `arch-cov2-rdoe1-${Date.now()}.db`);
 323      const { db, agent, cleanup } = await createTestEnv(dbPath);
 324      try {
 325        // Write a file with a Factory pattern
 326        const tmpFile = join(tmpdir(), `factory-test-${Date.now()}.js`);
 327        writeFileSync(
 328          tmpFile,
 329          'class SiteFactory {\n  create() { return {}; }\n}\nexport default SiteFactory;\n'
 330        );
 331  
 332        const taskId = insertTask(db, 'review_design', { files: [tmpFile] });
 333        const task = getTask(db, taskId);
 334  
 335        await agent.reviewDesign(task);
 336  
 337        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 338        assert.strictEqual(updated.status, 'completed', 'Should complete');
 339        const result = JSON.parse(updated.result_json || '{}');
 340        assert.ok(Array.isArray(result.issues), 'Should have issues array');
 341        // Should detect over_engineering issue from Factory class
 342        const oeIssue = result.issues.find(i => i.type === 'over_engineering');
 343        assert.ok(oeIssue, 'Should detect Factory class as over-engineering');
 344        assert.strictEqual(oeIssue.severity, 'low', 'Over-engineering severity should be low');
 345  
 346        try {
 347          rmSync(tmpFile, { force: true });
 348        } catch (_e) {
 349          /* ignore */
 350        }
 351      } finally {
 352        cleanup();
 353      }
 354    });
 355  
 356    test('detects Builder class pattern as over-engineering', async () => {
 357      const dbPath = join(tmpdir(), `arch-cov2-rdoe2-${Date.now()}.db`);
 358      const { db, agent, cleanup } = await createTestEnv(dbPath);
 359      try {
 360        const tmpFile = join(tmpdir(), `builder-test-${Date.now()}.js`);
 361        writeFileSync(tmpFile, 'class QueryBuilder {\n  build() { return "query"; }\n}\n');
 362  
 363        const taskId = insertTask(db, 'review_design', { files: [tmpFile] });
 364        const task = getTask(db, taskId);
 365  
 366        await agent.reviewDesign(task);
 367  
 368        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 369        assert.strictEqual(updated.status, 'completed');
 370        const result = JSON.parse(updated.result_json || '{}');
 371        const oeIssue = result.issues.find(i => i.type === 'over_engineering');
 372        assert.ok(oeIssue, 'Should detect Builder class as over-engineering');
 373  
 374        try {
 375          rmSync(tmpFile, { force: true });
 376        } catch (_e) {
 377          /* ignore */
 378        }
 379      } finally {
 380        cleanup();
 381      }
 382    });
 383  
 384    test('detects Strategy class pattern as over-engineering', async () => {
 385      const dbPath = join(tmpdir(), `arch-cov2-rdoe3-${Date.now()}.db`);
 386      const { db, agent, cleanup } = await createTestEnv(dbPath);
 387      try {
 388        const tmpFile = join(tmpdir(), `strategy-test-${Date.now()}.js`);
 389        writeFileSync(tmpFile, 'class PricingStrategy {\n  calculate() { return 100; }\n}\n');
 390  
 391        const taskId = insertTask(db, 'review_design', { files: [tmpFile] });
 392        const task = getTask(db, taskId);
 393  
 394        await agent.reviewDesign(task);
 395  
 396        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 397        assert.strictEqual(updated.status, 'completed');
 398        const result = JSON.parse(updated.result_json || '{}');
 399        const oeIssue = result.issues.find(i => i.type === 'over_engineering');
 400        assert.ok(oeIssue, 'Should detect Strategy class as over-engineering');
 401  
 402        try {
 403          rmSync(tmpFile, { force: true });
 404        } catch (_e) {
 405          /* ignore */
 406        }
 407      } finally {
 408        cleanup();
 409      }
 410    });
 411  
 412    test('approves design with no high-severity issues', async () => {
 413      const dbPath = join(tmpdir(), `arch-cov2-rdapprove-${Date.now()}.db`);
 414      const { db, agent, cleanup } = await createTestEnv(dbPath);
 415      try {
 416        const tmpFile = join(tmpdir(), `simple-test-${Date.now()}.js`);
 417        // Simple file with < 150 lines and no anti-patterns
 418        writeFileSync(tmpFile, 'export function hello() { return "world"; }\n');
 419  
 420        const taskId = insertTask(db, 'review_design', { files: [tmpFile] });
 421        const task = getTask(db, taskId);
 422  
 423        await agent.reviewDesign(task);
 424  
 425        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 426        assert.strictEqual(updated.status, 'completed');
 427        const result = JSON.parse(updated.result_json || '{}');
 428        assert.strictEqual(result.approved, true, 'Simple file should be approved');
 429  
 430        try {
 431          rmSync(tmpFile, { force: true });
 432        } catch (_e) {
 433          /* ignore */
 434        }
 435      } finally {
 436        cleanup();
 437      }
 438    });
 439  
 440    test('generates recommendations for found issues', async () => {
 441      const dbPath = join(tmpdir(), `arch-cov2-rdrec-${Date.now()}.db`);
 442      const { db, agent, cleanup } = await createTestEnv(dbPath);
 443      try {
 444        const tmpFile = join(tmpdir(), `large-factory-${Date.now()}.js`);
 445        // Large file (200 lines) with Factory pattern
 446        const lines = Array(200).fill('const x = 1;');
 447        lines.push('class DataFactory { create() {} }');
 448        writeFileSync(tmpFile, lines.join('\n'));
 449  
 450        const taskId = insertTask(db, 'review_design', { files: [tmpFile] });
 451        const task = getTask(db, taskId);
 452  
 453        await agent.reviewDesign(task);
 454  
 455        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 456        assert.strictEqual(updated.status, 'completed');
 457        const result = JSON.parse(updated.result_json || '{}');
 458        assert.ok(Array.isArray(result.recommendations), 'Should have recommendations');
 459        assert.ok(result.recommendations.length > 0, 'Should have at least one recommendation');
 460  
 461        try {
 462          rmSync(tmpFile, { force: true });
 463        } catch (_e) {
 464          /* ignore */
 465        }
 466      } finally {
 467        cleanup();
 468      }
 469    });
 470  });
 471  
 472  // ============================================================
 473  // 3. checkComplexity: deep nesting detection (depth > 4)
 474  // ============================================================
 475  
 476  describe('ArchitectAgent Coverage2 - checkComplexity nesting detection', () => {
 477    test('detects max_depth violation in deeply nested code', async () => {
 478      const dbPath = join(tmpdir(), `arch-cov2-ccdepth-${Date.now()}.db`);
 479      const { db, agent, cleanup } = await createTestEnv(dbPath);
 480      try {
 481        const tmpFile = join(tmpdir(), `deeply-nested-${Date.now()}.js`);
 482        // Create code with 6 levels of nesting (exceeds limit of 4)
 483        writeFileSync(
 484          tmpFile,
 485          `function level1() {
 486    if (a) {
 487      while (b) {
 488        for (let i = 0; i < n; i++) {
 489          if (c) {
 490            switch (d) {
 491              case 'x': { doSomething(); break; }
 492            }
 493          }
 494        }
 495      }
 496    }
 497  }`
 498        );
 499  
 500        const taskId = insertTask(db, 'check_complexity', { files: [tmpFile] });
 501        const task = getTask(db, taskId);
 502  
 503        await agent.checkComplexity(task);
 504  
 505        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 506        assert.strictEqual(updated.status, 'completed');
 507        const result = JSON.parse(updated.result_json || '{}');
 508        assert.ok(Array.isArray(result.issues), 'Should have issues array');
 509  
 510        const depthIssue = result.issues.find(i => i.type === 'max_depth');
 511        assert.ok(depthIssue, 'Should detect max_depth issue');
 512        assert.strictEqual(depthIssue.limit, 4, 'Depth limit should be 4');
 513        assert.ok(depthIssue.current > 4, `Depth should exceed 4, got ${depthIssue.current}`);
 514  
 515        try {
 516          rmSync(tmpFile, { force: true });
 517        } catch (_e) {
 518          /* ignore */
 519        }
 520      } finally {
 521        cleanup();
 522      }
 523    });
 524  
 525    test('creates suggest_refactor task for files with depth violations', async () => {
 526      const dbPath = join(tmpdir(), `arch-cov2-ccrefactor-${Date.now()}.db`);
 527      const { db, agent, cleanup } = await createTestEnv(dbPath);
 528      try {
 529        const tmpFile = join(tmpdir(), `nested-code-${Date.now()}.js`);
 530        // 5-level nesting exceeds limit
 531        writeFileSync(
 532          tmpFile,
 533          'function a() { if(1) { while(2) { for(;;) { if(3) { doIt(); } } } } }'
 534        );
 535  
 536        const taskId = insertTask(db, 'check_complexity', { files: [tmpFile] });
 537        const task = getTask(db, taskId);
 538  
 539        await agent.checkComplexity(task);
 540  
 541        // Verify suggest_refactor task was created for depth violation
 542        const refactorTasks = db
 543          .prepare(
 544            `SELECT * FROM agent_tasks WHERE task_type = 'suggest_refactor' ORDER BY id DESC LIMIT 5`
 545          )
 546          .all();
 547  
 548        assert.ok(
 549          refactorTasks.length > 0,
 550          'Should create suggest_refactor tasks for depth violations'
 551        );
 552  
 553        try {
 554          rmSync(tmpFile, { force: true });
 555        } catch (_e) {
 556          /* ignore */
 557        }
 558      } finally {
 559        cleanup();
 560      }
 561    });
 562  
 563    test('checkComplexity without files list uses getJsFiles fallback', async () => {
 564      const dbPath = join(tmpdir(), `arch-cov2-ccnofiles-${Date.now()}.db`);
 565      const { db, agent, cleanup } = await createTestEnv(dbPath);
 566      try {
 567        // No files in context - should use getJsFiles() to find all JS files
 568        const taskId = insertTask(db, 'check_complexity', {});
 569        const task = getTask(db, taskId);
 570  
 571        // This will call getJsFiles() internally (via execSync 'find src -name "*.js"')
 572        await agent.checkComplexity(task);
 573  
 574        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 575        assert.strictEqual(
 576          updated.status,
 577          'completed',
 578          'Should complete even scanning all src files'
 579        );
 580        const result = JSON.parse(updated.result_json || '{}');
 581        assert.ok(typeof result.files_checked === 'number', 'Should report files_checked count');
 582        // When no files specified, getJsFiles() is called which returns src/ files
 583        // files_checked could be 0 if src/ doesn't exist in test context or many files
 584      } finally {
 585        cleanup();
 586      }
 587    });
 588  });
 589  
 590  // ============================================================
 591  // 4. auditDocumentation: focus_areas filtering
 592  // ============================================================
 593  
 594  describe('ArchitectAgent Coverage2 - auditDocumentation focus areas', () => {
 595    test('audits only agent_system focus area', async () => {
 596      const dbPath = join(tmpdir(), `arch-cov2-adagent-${Date.now()}.db`);
 597      const { db, agent, cleanup } = await createTestEnv(dbPath);
 598      try {
 599        const taskId = insertTask(db, 'audit_documentation', {
 600          scope: 'agent_system',
 601          focus_areas: ['agent_system'],
 602        });
 603        const task = getTask(db, taskId);
 604  
 605        await agent.auditDocumentation(task);
 606  
 607        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 608        assert.ok(
 609          ['completed', 'failed'].includes(updated.status),
 610          `Should complete or fail, got: ${updated.status}`
 611        );
 612        if (updated.status === 'completed') {
 613          const result = JSON.parse(updated.result_json || '{}');
 614          assert.ok(
 615            typeof result.total_discrepancies === 'number',
 616            'Should have total_discrepancies'
 617          );
 618        }
 619      } finally {
 620        cleanup();
 621      }
 622    });
 623  
 624    test('audits only pipeline_monitoring focus area', async () => {
 625      const dbPath = join(tmpdir(), `arch-cov2-adpipeline-${Date.now()}.db`);
 626      const { db, agent, cleanup } = await createTestEnv(dbPath);
 627      try {
 628        const taskId = insertTask(db, 'audit_documentation', {
 629          scope: 'pipeline',
 630          focus_areas: ['pipeline_monitoring'],
 631        });
 632        const task = getTask(db, taskId);
 633  
 634        await agent.auditDocumentation(task);
 635  
 636        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 637        assert.ok(['completed', 'failed'].includes(updated.status), `Should complete or fail`);
 638      } finally {
 639        cleanup();
 640      }
 641    });
 642  
 643    test('audits only error_detection focus area', async () => {
 644      const dbPath = join(tmpdir(), `arch-cov2-aderror-${Date.now()}.db`);
 645      const { db, agent, cleanup } = await createTestEnv(dbPath);
 646      try {
 647        const taskId = insertTask(db, 'audit_documentation', {
 648          scope: 'error_detection',
 649          focus_areas: ['error_detection'],
 650        });
 651        const task = getTask(db, taskId);
 652  
 653        await agent.auditDocumentation(task);
 654  
 655        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 656        assert.ok(['completed', 'failed'].includes(updated.status), `Should complete or fail`);
 657      } finally {
 658        cleanup();
 659      }
 660    });
 661  
 662    test('audits all focus areas when focus_areas is null (default)', async () => {
 663      const dbPath = join(tmpdir(), `arch-cov2-adall-${Date.now()}.db`);
 664      const { db, agent, cleanup } = await createTestEnv(dbPath);
 665      try {
 666        const taskId = insertTask(db, 'audit_documentation', {
 667          scope: 'full',
 668          // No focus_areas specified → audits all
 669        });
 670        const task = getTask(db, taskId);
 671  
 672        await agent.auditDocumentation(task);
 673  
 674        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 675        assert.ok(['completed', 'failed'].includes(updated.status), `Should complete or fail`);
 676      } finally {
 677        cleanup();
 678      }
 679    });
 680  
 681    test('adds high-severity discrepancies to human review queue', async () => {
 682      const dbPath = join(tmpdir(), `arch-cov2-adhigh-${Date.now()}.db`);
 683      const { db, agent, cleanup } = await createTestEnv(dbPath);
 684      try {
 685        const taskId = insertTask(db, 'audit_documentation', {
 686          focus_areas: ['agent_system', 'pipeline_monitoring', 'error_detection'],
 687        });
 688        const task = getTask(db, taskId);
 689  
 690        await agent.auditDocumentation(task);
 691  
 692        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 693        assert.ok(['completed', 'failed'].includes(updated.status), `Should complete or fail`);
 694  
 695        // If completed, verify result structure
 696        if (updated.status === 'completed') {
 697          const result = JSON.parse(updated.result_json || '{}');
 698          assert.ok(typeof result.discrepancies !== 'undefined', 'Should have discrepancies field');
 699          assert.ok(typeof result.high_severity === 'number', 'Should have high_severity count');
 700        }
 701      } finally {
 702        cleanup();
 703      }
 704    });
 705  });
 706  
 707  // ============================================================
 708  // 5. detectSemanticDocChanges
 709  // ============================================================
 710  
 711  describe('ArchitectAgent Coverage2 - detectSemanticDocChanges', () => {
 712    test('returns empty array when no code files provided', async () => {
 713      const dbPath = join(tmpdir(), `arch-cov2-dsdc1-${Date.now()}.db`);
 714      const { agent, cleanup } = await createTestEnv(dbPath);
 715      try {
 716        const result = await agent.detectSemanticDocChanges([]);
 717        assert.ok(Array.isArray(result), 'Should return array');
 718        assert.strictEqual(result.length, 0, 'Should return empty array for no files');
 719      } finally {
 720        cleanup();
 721      }
 722    });
 723  
 724    test('returns stale items when LLM detects doc changes', async () => {
 725      const dbPath = join(tmpdir(), `arch-cov2-dsdc2-${Date.now()}.db`);
 726      const { agent, cleanup } = await createTestEnv(dbPath);
 727      try {
 728        // Use a real file that likely has git history
 729        const result = await agent.detectSemanticDocChanges(['src/agents/architect.js']);
 730        assert.ok(Array.isArray(result), 'Should return array');
 731        // Result could be empty or have items depending on mock response
 732      } finally {
 733        cleanup();
 734      }
 735    });
 736  
 737    test('handles git diff errors gracefully for new files', async () => {
 738      const dbPath = join(tmpdir(), `arch-cov2-dsdc3-${Date.now()}.db`);
 739      const { agent, cleanup } = await createTestEnv(dbPath);
 740      try {
 741        // Non-existent file - git diff will fail, should be handled gracefully
 742        const result = await agent.detectSemanticDocChanges(['/nonexistent/new-file.js']);
 743        assert.ok(Array.isArray(result), 'Should return array even for non-existent files');
 744      } finally {
 745        cleanup();
 746      }
 747    });
 748  
 749    test('limits analysis to first 5 files', async () => {
 750      const dbPath = join(tmpdir(), `arch-cov2-dsdc4-${Date.now()}.db`);
 751      const { agent, cleanup } = await createTestEnv(dbPath);
 752      try {
 753        // Provide 7 files - should only process 5
 754        const files = [
 755          'src/agents/architect.js',
 756          'src/agents/base-agent.js',
 757          'src/score.js',
 758          'src/scrape.js',
 759          'src/capture.js',
 760          'src/enrich.js',
 761          'src/proposals.js',
 762        ];
 763        const result = await agent.detectSemanticDocChanges(files);
 764        assert.ok(Array.isArray(result), 'Should return array');
 765      } finally {
 766        cleanup();
 767      }
 768    });
 769  });
 770  
 771  // ============================================================
 772  // 6. updateDocumentation: code fences removal + commit path
 773  // ============================================================
 774  
 775  describe('ArchitectAgent Coverage2 - updateDocumentation commit paths', () => {
 776    test('removes markdown code fences from generated documentation', async () => {
 777      const dbPath = join(tmpdir(), `arch-cov2-udcodefence-${Date.now()}.db`);
 778      const { db, agent, cleanup } = await createTestEnv(dbPath);
 779      try {
 780        // The mock generateCode always returns a response - we test the fence stripping
 781        // by checking that the process runs correctly end-to-end
 782        const taskId = insertTask(db, 'update_documentation', {
 783          stale_items: [
 784            {
 785              file: 'README.md',
 786              reason: 'New feature added',
 787              fix: 'Update README with new feature docs',
 788            },
 789          ],
 790          files: ['src/feature.js'],
 791        });
 792        const task = getTask(db, taskId);
 793  
 794        await agent.updateDocumentation(task);
 795  
 796        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 797        assert.ok(
 798          ['completed', 'failed'].includes(updated.status),
 799          `Should complete or fail, got: ${updated.status}`
 800        );
 801        if (updated.status === 'completed') {
 802          const result = JSON.parse(updated.result_json || '{}');
 803          assert.ok(Array.isArray(result.updated), 'Should have updated array');
 804          assert.ok(Array.isArray(result.errors), 'Should have errors array');
 805        }
 806      } finally {
 807        cleanup();
 808      }
 809    });
 810  
 811    test('verifies documentation after updates', async () => {
 812      const dbPath = join(tmpdir(), `arch-cov2-udverify-${Date.now()}.db`);
 813      const { db, agent, cleanup } = await createTestEnv(dbPath);
 814      try {
 815        const taskId = insertTask(db, 'update_documentation', {
 816          stale_items: [
 817            { file: 'CLAUDE.md', reason: 'Pipeline modified', fix: 'Update pipeline docs' },
 818          ],
 819        });
 820        const task = getTask(db, taskId);
 821  
 822        await agent.updateDocumentation(task);
 823  
 824        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 825        assert.ok(['completed', 'failed'].includes(updated.status), `Should complete or fail`);
 826        if (updated.status === 'completed') {
 827          const result = JSON.parse(updated.result_json || '{}');
 828          // verifyDocumentation is called and result stored
 829          assert.ok(result.verification !== undefined, 'Should have verification results');
 830        }
 831      } finally {
 832        cleanup();
 833      }
 834    });
 835  
 836    test('uses identifyAffectedDocs when files provided but no stale_items', async () => {
 837      const dbPath = join(tmpdir(), `arch-cov2-udidentify-${Date.now()}.db`);
 838      const { db, agent, cleanup } = await createTestEnv(dbPath);
 839      try {
 840        const taskId = insertTask(db, 'update_documentation', {
 841          // No stale_items - will call identifyAffectedDocs with files
 842          files: ['db/migrations/050-test.sql'],
 843          change_type: 'new_feature',
 844        });
 845        const task = getTask(db, taskId);
 846  
 847        await agent.updateDocumentation(task);
 848  
 849        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 850        assert.ok(['completed', 'failed'].includes(updated.status), `Should complete or fail`);
 851      } finally {
 852        cleanup();
 853      }
 854    });
 855  });
 856  
 857  // ============================================================
 858  // 7. createDesignProposal: PO approval path (significant change)
 859  // ============================================================
 860  
 861  describe('ArchitectAgent Coverage2 - createDesignProposal PO approval paths', () => {
 862    test('requests PO approval for significant changes', async () => {
 863      const dbPath = join(tmpdir(), `arch-cov2-cdpsig-${Date.now()}.db`);
 864      const { db, agent, cleanup } = await createTestEnv(dbPath);
 865      try {
 866        const taskId = insertTask(db, 'design_proposal', {
 867          feature_description: 'Complete rewrite of the pipeline engine',
 868          significance: 'significant',
 869          requirements: ['Zero downtime', 'Backward compatible'],
 870        });
 871        const task = getTask(db, taskId);
 872  
 873        await agent.createDesignProposal(task);
 874  
 875        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 876        // Significant → needs PO approval → blocked
 877        assert.ok(
 878          ['completed', 'blocked', 'failed'].includes(updated.status),
 879          `Should be completed, blocked, or failed - got: ${updated.status}`
 880        );
 881      } finally {
 882        cleanup();
 883      }
 884    });
 885  
 886    test('auto-approves minor changes without PO approval', async () => {
 887      const dbPath = join(tmpdir(), `arch-cov2-cdpminor-${Date.now()}.db`);
 888      const { db, agent, cleanup } = await createTestEnv(dbPath);
 889      try {
 890        const taskId = insertTask(db, 'design_proposal', {
 891          feature_description: 'Add console.log statement for debugging',
 892          significance: 'minor',
 893        });
 894        const task = getTask(db, taskId);
 895  
 896        await agent.createDesignProposal(task);
 897  
 898        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 899        assert.ok(
 900          ['completed', 'blocked', 'failed'].includes(updated.status),
 901          `Should resolve to a valid status: ${updated.status}`
 902        );
 903      } finally {
 904        cleanup();
 905      }
 906    });
 907  
 908    test('fails when context has no feature_description and no error_message', async () => {
 909      const dbPath = join(tmpdir(), `arch-cov2-cdpfail-${Date.now()}.db`);
 910      const { db, agent, cleanup } = await createTestEnv(dbPath);
 911      try {
 912        const taskId = insertTask(db, 'design_proposal', {
 913          // Neither feature_description nor error_message
 914          significance: 'major',
 915        });
 916        const task = getTask(db, taskId);
 917  
 918        await agent.createDesignProposal(task);
 919  
 920        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 921        assert.strictEqual(updated.status, 'failed', 'Should fail with missing description');
 922        assert.ok(
 923          updated.error_message && updated.error_message.length > 0,
 924          'Should have error message'
 925        );
 926      } finally {
 927        cleanup();
 928      }
 929    });
 930  
 931    test('uses error_message as feature_description for bug fix workflows', async () => {
 932      const dbPath = join(tmpdir(), `arch-cov2-cdpbug-${Date.now()}.db`);
 933      const { db, agent, cleanup } = await createTestEnv(dbPath);
 934      try {
 935        const taskId = insertTask(db, 'design_proposal', {
 936          error_message: 'ReferenceError: cannot read property of undefined',
 937          error_type: 'ReferenceError',
 938          significance: 'minor',
 939        });
 940        const task = getTask(db, taskId);
 941  
 942        await agent.createDesignProposal(task);
 943  
 944        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 945        // Should NOT fail due to missing feature_description since error_message substitutes
 946        if (updated.status === 'failed') {
 947          assert.ok(
 948            !updated.error_message.includes('feature_description'),
 949            'Error should not mention feature_description when error_message was present'
 950          );
 951        } else {
 952          assert.ok(
 953            ['completed', 'blocked'].includes(updated.status),
 954            `Should proceed without feature_description error: ${updated.status}`
 955          );
 956        }
 957      } finally {
 958        cleanup();
 959      }
 960    });
 961  
 962    test('analyzes specific files when files_to_analyze provided', async () => {
 963      const dbPath = join(tmpdir(), `arch-cov2-cdpfiles-${Date.now()}.db`);
 964      const { db, agent, cleanup } = await createTestEnv(dbPath);
 965      try {
 966        const taskId = insertTask(db, 'design_proposal', {
 967          feature_description: 'Refactor scoring module',
 968          files_to_analyze: ['src/score.js'],
 969          significance: 'minor',
 970        });
 971        const task = getTask(db, taskId);
 972  
 973        await agent.createDesignProposal(task);
 974  
 975        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
 976        assert.ok(
 977          ['completed', 'blocked', 'failed'].includes(updated.status),
 978          `Should resolve: ${updated.status}`
 979        );
 980      } finally {
 981        cleanup();
 982      }
 983    });
 984  });
 985  
 986  // ============================================================
 987  // 8. reviewImplementationPlan: approved path with good coverage
 988  // ============================================================
 989  
 990  describe('ArchitectAgent Coverage2 - reviewImplementationPlan approval paths', () => {
 991    test('approves plan with 90% coverage target and no high-severity issues', async () => {
 992      const dbPath = join(tmpdir(), `arch-cov2-ripapprove-${Date.now()}.db`);
 993      const { db, agent, cleanup } = await createTestEnv(dbPath);
 994      try {
 995        // Create parent task that will be approved
 996        const parentId = db
 997          .prepare(
 998            `INSERT INTO agent_tasks (task_type, assigned_to, status, context_json) VALUES (?, ?, ?, ?) RETURNING id`
 999          )
1000          .get(
1001            'implement_feature',
1002            'developer',
1003            'blocked',
1004            JSON.stringify({ feature: 'caching' })
1005          ).id;
1006  
1007        const taskId = insertTask(db, 'technical_review', {
1008          implementation_plan: {
1009            summary: 'Add Redis-style in-memory caching',
1010            files_to_modify: ['README.md'],
1011            documentation_updates: true,
1012            test_plan: {
1013              coverage_target: 90,
1014              test_files: ['tests/cache.test.js'],
1015            },
1016            breaking_changes: [],
1017            requires_migration: false,
1018            estimated_effort: 2,
1019          },
1020          original_task_id: parentId,
1021        });
1022        const task = getTask(db, taskId);
1023  
1024        await agent.reviewImplementationPlan(task);
1025  
1026        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1027        assert.ok(
1028          ['completed', 'failed'].includes(updated.status),
1029          `Should complete or fail: ${updated.status}`
1030        );
1031      } finally {
1032        cleanup();
1033      }
1034    });
1035  
1036    test('fails plan with missing test_plan entirely', async () => {
1037      const dbPath = join(tmpdir(), `arch-cov2-ripnotestplan-${Date.now()}.db`);
1038      const { db, agent, cleanup } = await createTestEnv(dbPath);
1039      try {
1040        const parentId = db
1041          .prepare(
1042            `INSERT INTO agent_tasks (task_type, assigned_to, status, context_json) VALUES (?, ?, ?, ?) RETURNING id`
1043          )
1044          .get('implement_feature', 'developer', 'blocked', JSON.stringify({})).id;
1045  
1046        const taskId = insertTask(db, 'technical_review', {
1047          implementation_plan: {
1048            summary: 'Quick fix',
1049            files_to_modify: ['README.md'],
1050            documentation_updates: true,
1051            // No test_plan at all
1052          },
1053          original_task_id: parentId,
1054        });
1055        const task = getTask(db, taskId);
1056  
1057        await agent.reviewImplementationPlan(task);
1058  
1059        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1060        assert.ok(
1061          ['completed', 'failed'].includes(updated.status),
1062          `Should complete or fail: ${updated.status}`
1063        );
1064      } finally {
1065        cleanup();
1066      }
1067    });
1068  
1069    test('flags low coverage target as high-severity issue', async () => {
1070      const dbPath = join(tmpdir(), `arch-cov2-riplowcov-${Date.now()}.db`);
1071      const { db, agent, cleanup } = await createTestEnv(dbPath);
1072      try {
1073        const parentId = db
1074          .prepare(
1075            `INSERT INTO agent_tasks (task_type, assigned_to, status, context_json) VALUES (?, ?, ?, ?) RETURNING id`
1076          )
1077          .get('implement_feature', 'developer', 'blocked', JSON.stringify({})).id;
1078  
1079        const taskId = insertTask(db, 'technical_review', {
1080          implementation_plan: {
1081            summary: 'Quick patch',
1082            files_to_modify: ['README.md'],
1083            documentation_updates: true,
1084            test_plan: { coverage_target: 50 }, // Well below 85%
1085          },
1086          original_task_id: parentId,
1087        });
1088        const task = getTask(db, taskId);
1089  
1090        await agent.reviewImplementationPlan(task);
1091  
1092        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1093        assert.ok(
1094          ['completed', 'failed'].includes(updated.status),
1095          `Should complete or fail: ${updated.status}`
1096        );
1097        // Low coverage should cause failure
1098        if (updated.status === 'failed') {
1099          assert.ok(
1100            updated.error_message.includes('high-severity'),
1101            'Error should mention high-severity issues'
1102          );
1103        }
1104      } finally {
1105        cleanup();
1106      }
1107    });
1108  });
1109  
1110  // ============================================================
1111  // 9. checkBranchHealth: diverged autofix branch scenario
1112  // ============================================================
1113  
1114  describe('ArchitectAgent Coverage2 - checkBranchHealth scenarios', () => {
1115    test('handles check with both flags disabled', async () => {
1116      const dbPath = join(tmpdir(), `arch-cov2-cbhboth-${Date.now()}.db`);
1117      const { db, agent, cleanup } = await createTestEnv(dbPath);
1118      try {
1119        const taskId = insertTask(db, 'check_branch_health', {
1120          check_stale_branches: false,
1121          ensure_autofix_aligned: false,
1122        });
1123        const task = getTask(db, taskId);
1124  
1125        await agent.checkBranchHealth(task);
1126  
1127        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1128        assert.ok(
1129          ['completed', 'failed'].includes(updated.status),
1130          `Should complete or fail: ${updated.status}`
1131        );
1132        if (updated.status === 'completed') {
1133          const result = JSON.parse(updated.result_json || '{}');
1134          assert.strictEqual(result.total_issues, 0, 'No issues when both checks disabled');
1135        }
1136      } finally {
1137        cleanup();
1138      }
1139    });
1140  
1141    test('runs with default context when context_json is empty', async () => {
1142      const dbPath = join(tmpdir(), `arch-cov2-cbhdefault-${Date.now()}.db`);
1143      const { db, agent, cleanup } = await createTestEnv(dbPath);
1144      try {
1145        const taskId = insertTask(db, 'check_branch_health', {});
1146        const task = getTask(db, taskId);
1147  
1148        await agent.checkBranchHealth(task);
1149  
1150        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1151        assert.ok(
1152          ['completed', 'failed'].includes(updated.status),
1153          `Should complete or fail: ${updated.status}`
1154        );
1155      } finally {
1156        cleanup();
1157      }
1158    });
1159  
1160    test('detects issues and counts them correctly in result', async () => {
1161      const dbPath = join(tmpdir(), `arch-cov2-cbhcount-${Date.now()}.db`);
1162      const { db, agent, cleanup } = await createTestEnv(dbPath);
1163      try {
1164        const taskId = insertTask(db, 'check_branch_health', {
1165          check_stale_branches: true,
1166          ensure_autofix_aligned: true,
1167          max_divergence_commits: 0, // Very strict - autofix must be 0 commits behind
1168        });
1169        const task = getTask(db, taskId);
1170  
1171        await agent.checkBranchHealth(task);
1172  
1173        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1174        assert.ok(
1175          ['completed', 'failed'].includes(updated.status),
1176          `Should complete or fail: ${updated.status}`
1177        );
1178        if (updated.status === 'completed') {
1179          const result = JSON.parse(updated.result_json || '{}');
1180          assert.ok(typeof result.stale_branches === 'number', 'Should have stale_branches count');
1181          assert.ok(
1182            typeof result.missing_branches === 'number',
1183            'Should have missing_branches count'
1184          );
1185          assert.strictEqual(
1186            result.total_issues,
1187            result.issues.length,
1188            'total_issues should match issues array length'
1189          );
1190        }
1191      } finally {
1192        cleanup();
1193      }
1194    });
1195  });
1196  
1197  // ============================================================
1198  // 10. profilePerformance: critical severity bottlenecks
1199  // ============================================================
1200  
1201  describe('ArchitectAgent Coverage2 - profilePerformance severity levels', () => {
1202    test('creates suggest_refactor for critical severity bottleneck (5x threshold)', async () => {
1203      const dbPath = join(tmpdir(), `arch-cov2-pfpcritical-${Date.now()}.db`);
1204      const { db, agent, cleanup } = await createTestEnv(dbPath);
1205      try {
1206        const now = new Date().toISOString();
1207        const pastHour = new Date(Date.now() - 3600000).toISOString();
1208  
1209        // Insert a critical bottleneck: 600000ms avg when threshold is 60000ms (10x!)
1210        db.prepare(
1211          `INSERT INTO pipeline_metrics (stage_name, sites_processed, sites_succeeded, sites_failed, duration_ms, started_at, finished_at) VALUES (?, ?, ?, ?, ?, ?, ?)`
1212        ).run('assets', 10, 5, 5, 600000, pastHour, now);
1213  
1214        const taskId = insertTask(db, 'profile_performance', {
1215          threshold_ms: 60000,
1216          days_back: 7,
1217        });
1218        const task = getTask(db, taskId);
1219  
1220        await agent.profilePerformance(task);
1221  
1222        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1223        assert.strictEqual(updated.status, 'completed', 'Should complete');
1224        const result = JSON.parse(updated.result_json || '{}');
1225        assert.ok(result.bottlenecks.length > 0, 'Should identify assets as bottleneck');
1226  
1227        const assetBottleneck = result.bottlenecks.find(b => b.stage === 'assets');
1228        assert.ok(assetBottleneck, 'Should identify assets stage');
1229        assert.strictEqual(
1230          assetBottleneck.severity,
1231          'critical',
1232          'Should be critical severity (10x threshold)'
1233        );
1234        assert.ok(typeof assetBottleneck.failure_rate === 'number', 'Should have failure_rate');
1235  
1236        // Verify suggest_refactor tasks created for critical severity
1237        const refactorTasks = db
1238          .prepare(`SELECT * FROM agent_tasks WHERE task_type = 'suggest_refactor' ORDER BY id DESC`)
1239          .all();
1240        assert.ok(
1241          refactorTasks.length > 0,
1242          'Should create suggest_refactor tasks for critical bottlenecks'
1243        );
1244  
1245        // Critical severity gets priority 8
1246        const criticalTask = refactorTasks.find(t => t.priority === 8);
1247        assert.ok(criticalTask, 'Critical bottleneck refactor task should have priority 8');
1248      } finally {
1249        cleanup();
1250      }
1251    });
1252  
1253    test('creates suggest_refactor for high severity bottleneck (3-4.9x threshold) with priority 6', async () => {
1254      const dbPath = join(tmpdir(), `arch-cov2-pfphigh-${Date.now()}.db`);
1255      const { db, agent, cleanup } = await createTestEnv(dbPath);
1256      try {
1257        const now = new Date().toISOString();
1258        const pastHour = new Date(Date.now() - 3600000).toISOString();
1259  
1260        // High severity: 3.5x threshold
1261        db.prepare(
1262          `INSERT INTO pipeline_metrics (stage_name, sites_processed, sites_succeeded, sites_failed, duration_ms, started_at, finished_at) VALUES (?, ?, ?, ?, ?, ?, ?)`
1263        ).run('scoring', 20, 18, 2, 210000, pastHour, now);
1264  
1265        const taskId = insertTask(db, 'profile_performance', {
1266          threshold_ms: 60000,
1267          days_back: 7,
1268        });
1269        const task = getTask(db, taskId);
1270  
1271        await agent.profilePerformance(task);
1272  
1273        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1274        assert.strictEqual(updated.status, 'completed');
1275        const result = JSON.parse(updated.result_json || '{}');
1276        const scoringBottleneck = result.bottlenecks.find(b => b.stage === 'scoring');
1277        assert.ok(scoringBottleneck, 'Should find scoring bottleneck');
1278        assert.strictEqual(scoringBottleneck.severity, 'high', 'Should be high severity');
1279  
1280        const refactorTasks = db
1281          .prepare(`SELECT * FROM agent_tasks WHERE task_type = 'suggest_refactor' ORDER BY id DESC`)
1282          .all();
1283        assert.ok(refactorTasks.length > 0, 'Should create refactor tasks for high severity');
1284        const highTask = refactorTasks.find(t => t.priority === 6);
1285        assert.ok(highTask, 'High severity should have priority 6');
1286      } finally {
1287        cleanup();
1288      }
1289    });
1290  
1291    test('does not create refactor task for medium/low severity bottlenecks', async () => {
1292      const dbPath = join(tmpdir(), `arch-cov2-pfpmedium-${Date.now()}.db`);
1293      const { db, agent, cleanup } = await createTestEnv(dbPath);
1294      try {
1295        const now = new Date().toISOString();
1296        const pastHour = new Date(Date.now() - 3600000).toISOString();
1297  
1298        // Medium severity: 2.5x threshold = 150000ms
1299        db.prepare(
1300          `INSERT INTO pipeline_metrics (stage_name, sites_processed, sites_succeeded, sites_failed, duration_ms, started_at, finished_at) VALUES (?, ?, ?, ?, ?, ?, ?)`
1301        ).run('enrichment', 15, 15, 0, 150000, pastHour, now);
1302  
1303        const taskId = insertTask(db, 'profile_performance', {
1304          threshold_ms: 60000,
1305          days_back: 7,
1306        });
1307        const task = getTask(db, taskId);
1308  
1309        await agent.profilePerformance(task);
1310  
1311        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1312        assert.strictEqual(updated.status, 'completed');
1313        const result = JSON.parse(updated.result_json || '{}');
1314  
1315        const enrichmentBottleneck = result.bottlenecks.find(b => b.stage === 'enrichment');
1316        if (enrichmentBottleneck) {
1317          assert.ok(
1318            ['medium', 'low'].includes(enrichmentBottleneck.severity),
1319            `Should be medium or low severity: ${enrichmentBottleneck.severity}`
1320          );
1321        }
1322      } finally {
1323        cleanup();
1324      }
1325    });
1326  
1327    test('calculates failure_rate correctly for bottlenecks', async () => {
1328      const dbPath = join(tmpdir(), `arch-cov2-pfpfailrate-${Date.now()}.db`);
1329      const { db, agent, cleanup } = await createTestEnv(dbPath);
1330      try {
1331        const now = new Date().toISOString();
1332        const pastHour = new Date(Date.now() - 3600000).toISOString();
1333  
1334        // 50% failure rate: 10 successes, 10 failures
1335        db.prepare(
1336          `INSERT INTO pipeline_metrics (stage_name, sites_processed, sites_succeeded, sites_failed, duration_ms, started_at, finished_at) VALUES (?, ?, ?, ?, ?, ?, ?)`
1337        ).run('outreach', 20, 10, 10, 400000, pastHour, now);
1338  
1339        const taskId = insertTask(db, 'profile_performance', {
1340          threshold_ms: 60000,
1341          days_back: 7,
1342        });
1343        const task = getTask(db, taskId);
1344  
1345        await agent.profilePerformance(task);
1346  
1347        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1348        assert.strictEqual(updated.status, 'completed');
1349        const result = JSON.parse(updated.result_json || '{}');
1350  
1351        const outreachBottleneck = result.bottlenecks.find(b => b.stage === 'outreach');
1352        if (outreachBottleneck) {
1353          assert.ok(outreachBottleneck.failure_rate > 0, 'Should report non-zero failure rate');
1354          // 50% failure rate
1355          assert.ok(
1356            Math.abs(outreachBottleneck.failure_rate - 50) < 1,
1357            `Failure rate should be ~50%, got ${outreachBottleneck.failure_rate}`
1358          );
1359        }
1360      } finally {
1361        cleanup();
1362      }
1363    });
1364  });
1365  
1366  // ============================================================
1367  // 11. verifyDocumentation: all check types
1368  // Note: verifyDocumentation uses mocked readFile from file-operations.js
1369  // The mock returns '# Documentation\n\nSome content here.\n' by default.
1370  // We test the check logic by temporarily overriding mockReadResult.
1371  // ============================================================
1372  
1373  describe('ArchitectAgent Coverage2 - verifyDocumentation checks', () => {
1374    test('detects TODO markers as documentation warning via mock content', async () => {
1375      const dbPath = join(tmpdir(), `arch-cov2-vdtodo-${Date.now()}.db`);
1376      const { agent, cleanup } = await createTestEnv(dbPath);
1377      try {
1378        // Override mock to return content with TODO
1379        mockReadResult = { content: '# Documentation\n\nTODO: Update this section\n', path: '' };
1380  
1381        const results = await agent.verifyDocumentation(['README.md']);
1382  
1383        // Should warn about TODO markers
1384        assert.ok(
1385          results.warnings.length > 0 || results.verified.length > 0,
1386          'Should process documentation files'
1387        );
1388        // If warnings exist, they should flag no_todo_markers
1389        if (results.warnings.length > 0) {
1390          const warning = results.warnings.find(w => w.issues.includes('no_todo_markers'));
1391          assert.ok(warning, 'Should flag no_todo_markers for TODO content');
1392        }
1393      } finally {
1394        mockReadResult = { content: '# Documentation\n\nSome content here.\n', path: '' };
1395        cleanup();
1396      }
1397    });
1398  
1399    test('detects FIXME markers as documentation warning via mock content', async () => {
1400      const dbPath = join(tmpdir(), `arch-cov2-vdfixme-${Date.now()}.db`);
1401      const { agent, cleanup } = await createTestEnv(dbPath);
1402      try {
1403        mockReadResult = { content: '# Documentation\n\nFIXME: This section is wrong\n', path: '' };
1404  
1405        const results = await agent.verifyDocumentation(['CLAUDE.md']);
1406  
1407        assert.ok(
1408          results.warnings.length > 0 || results.verified.length > 0,
1409          'Should process documentation files'
1410        );
1411        if (results.warnings.length > 0) {
1412          // FIXME triggers no_todo_markers check
1413          const hasRelevantWarning = results.warnings.some(
1414            w => w.issues.includes('no_todo_markers') || w.issues.length > 0
1415          );
1416          assert.ok(hasRelevantWarning, 'Should have documentation warning');
1417        }
1418      } finally {
1419        mockReadResult = { content: '# Documentation\n\nSome content here.\n', path: '' };
1420        cleanup();
1421      }
1422    });
1423  
1424    test('detects [placeholder] text as documentation warning via mock content', async () => {
1425      const dbPath = join(tmpdir(), `arch-cov2-vdplaceholder-${Date.now()}.db`);
1426      const { agent, cleanup } = await createTestEnv(dbPath);
1427      try {
1428        mockReadResult = {
1429          content: '# Documentation\n\n[placeholder] content goes here\n',
1430          path: '',
1431        };
1432  
1433        const results = await agent.verifyDocumentation(['docs/test.md']);
1434  
1435        assert.ok(
1436          results.warnings.length > 0 || results.verified.length > 0,
1437          'Should process documentation files'
1438        );
1439        if (results.warnings.length > 0) {
1440          const hasPlaceholderWarning = results.warnings.some(
1441            w => w.issues.includes('no_placeholder_text') || w.issues.length > 0
1442          );
1443          assert.ok(hasPlaceholderWarning, 'Should have placeholder warning');
1444        }
1445      } finally {
1446        mockReadResult = { content: '# Documentation\n\nSome content here.\n', path: '' };
1447        cleanup();
1448      }
1449    });
1450  
1451    test('detects TBD text as documentation warning via mock content', async () => {
1452      const dbPath = join(tmpdir(), `arch-cov2-vdtbd-${Date.now()}.db`);
1453      const { agent, cleanup } = await createTestEnv(dbPath);
1454      try {
1455        mockReadResult = { content: '# Documentation\n\nSection: TBD\n', path: '' };
1456  
1457        const results = await agent.verifyDocumentation(['docs/overview.md']);
1458  
1459        assert.ok(
1460          results.warnings.length > 0 || results.verified.length > 0,
1461          'Should process documentation files'
1462        );
1463      } finally {
1464        mockReadResult = { content: '# Documentation\n\nSome content here.\n', path: '' };
1465        cleanup();
1466      }
1467    });
1468  
1469    test('detects missing # header in markdown file via mock content', async () => {
1470      const dbPath = join(tmpdir(), `arch-cov2-vdnoheader-${Date.now()}.db`);
1471      const { agent, cleanup } = await createTestEnv(dbPath);
1472      try {
1473        // Content with NO # header - proper_formatting check should fail
1474        mockReadResult = { content: 'This is content without a markdown header.\n', path: '' };
1475  
1476        const results = await agent.verifyDocumentation(['docs/no-header.md']);
1477  
1478        assert.ok(
1479          results.warnings.length > 0 || results.verified.length > 0,
1480          'Should process documentation files'
1481        );
1482        if (results.warnings.length > 0) {
1483          const hasFormattingWarning = results.warnings.some(
1484            w => w.issues.includes('proper_formatting') || w.issues.length > 0
1485          );
1486          assert.ok(hasFormattingWarning, 'Should flag proper_formatting for missing header');
1487        }
1488      } finally {
1489        mockReadResult = { content: '# Documentation\n\nSome content here.\n', path: '' };
1490        cleanup();
1491      }
1492    });
1493  
1494    test('verifies good documentation with no issues', async () => {
1495      const dbPath = join(tmpdir(), `arch-cov2-vdgood-${Date.now()}.db`);
1496      const { agent, cleanup } = await createTestEnv(dbPath);
1497      try {
1498        // Good content - passes all checks
1499        mockReadResult = {
1500          content: '# Documentation\n\nThis is properly formatted content.\n',
1501          path: '',
1502        };
1503  
1504        const results = await agent.verifyDocumentation(['README.md']);
1505  
1506        assert.ok(results.verified.length > 0, 'Should verify good documentation');
1507        assert.strictEqual(results.warnings.length, 0, 'Should have no warnings for good docs');
1508      } finally {
1509        mockReadResult = { content: '# Documentation\n\nSome content here.\n', path: '' };
1510        cleanup();
1511      }
1512    });
1513  });
1514  
1515  // ============================================================
1516  // 12. identifyAffectedDocs: pipeline stage detection
1517  // ============================================================
1518  
1519  describe('ArchitectAgent Coverage2 - identifyAffectedDocs pipeline stage detection', () => {
1520    test('detects src/pipeline files as requiring CLAUDE.md update', async () => {
1521      const dbPath = join(tmpdir(), `arch-cov2-iadpipeline-${Date.now()}.db`);
1522      const { agent, cleanup } = await createTestEnv(dbPath);
1523      try {
1524        const affected = agent.identifyAffectedDocs(['src/pipeline-service.js'], 'bug_fix');
1525  
1526        assert.ok(Array.isArray(affected), 'Should return array');
1527        const claudeMd = affected.find(d => d.file === 'CLAUDE.md');
1528        assert.ok(claudeMd, 'Should identify CLAUDE.md for pipeline changes');
1529        assert.ok(claudeMd.reason.includes('Pipeline'), 'Reason should mention pipeline');
1530      } finally {
1531        cleanup();
1532      }
1533    });
1534  
1535    test('detects src/stages/ files as requiring CLAUDE.md update', async () => {
1536      const dbPath = join(tmpdir(), `arch-cov2-iadstages-${Date.now()}.db`);
1537      const { agent, cleanup } = await createTestEnv(dbPath);
1538      try {
1539        const affected = agent.identifyAffectedDocs(['src/stages/scoring.js'], 'new_feature');
1540  
1541        assert.ok(Array.isArray(affected), 'Should return array');
1542        const claudeMd = affected.find(d => d.file === 'CLAUDE.md');
1543        assert.ok(claudeMd, 'Should identify CLAUDE.md for stage changes');
1544      } finally {
1545        cleanup();
1546      }
1547    });
1548  
1549    test('returns empty array for unrelated files', async () => {
1550      const dbPath = join(tmpdir(), `arch-cov2-iadnone-${Date.now()}.db`);
1551      const { agent, cleanup } = await createTestEnv(dbPath);
1552      try {
1553        // File with no env vars and not a recognized pattern
1554        const affected = agent.identifyAffectedDocs(['random-untracked-file.txt'], 'update');
1555        assert.ok(Array.isArray(affected), 'Should return array');
1556        // No special patterns recognized
1557        assert.strictEqual(affected.length, 0, 'Should not affect any docs for unrelated files');
1558      } finally {
1559        cleanup();
1560      }
1561    });
1562  });
1563  
1564  // ============================================================
1565  // 13. parseGitLog: edge cases
1566  // ============================================================
1567  
1568  describe('ArchitectAgent Coverage2 - parseGitLog edge cases', () => {
1569    test('deduplicates files appearing in multiple commits', async () => {
1570      const dbPath = join(tmpdir(), `arch-cov2-pgldedup-${Date.now()}.db`);
1571      const { agent, cleanup } = await createTestEnv(dbPath);
1572      try {
1573        const gitLog = `abc123 feat: first commit
1574  src/feature.js
1575  src/utils.js
1576  
1577  def456 fix: second commit
1578  src/feature.js
1579  src/other.js`;
1580  
1581        const files = agent.parseGitLog(gitLog);
1582        assert.ok(Array.isArray(files), 'Should return array');
1583        // feature.js appears twice but should be deduplicated
1584        const featureOccurrences = files.filter(f => f === 'src/feature.js');
1585        assert.strictEqual(
1586          featureOccurrences.length,
1587          1,
1588          'feature.js should appear only once after dedup'
1589        );
1590      } finally {
1591        cleanup();
1592      }
1593    });
1594  
1595    test('handles empty git log gracefully', async () => {
1596      const dbPath = join(tmpdir(), `arch-cov2-pglempty-${Date.now()}.db`);
1597      const { agent, cleanup } = await createTestEnv(dbPath);
1598      try {
1599        const files = agent.parseGitLog('');
1600        assert.ok(Array.isArray(files), 'Should return array');
1601        assert.strictEqual(files.length, 0, 'Should return empty array for empty log');
1602      } finally {
1603        cleanup();
1604      }
1605    });
1606  
1607    test('skips commit hash lines correctly', async () => {
1608      const dbPath = join(tmpdir(), `arch-cov2-pglhash-${Date.now()}.db`);
1609      const { agent, cleanup } = await createTestEnv(dbPath);
1610      try {
1611        const gitLog = `a1b2c3d feat: add feature
1612  src/new-file.js
1613  
1614  e4f5a6b fix: bug fix
1615  src/bugfix.js`;
1616  
1617        const files = agent.parseGitLog(gitLog);
1618        // Should only have file paths, not commit hashes
1619        const commitLines = files.filter(f => /^[a-f0-9]{7}/.test(f));
1620        assert.strictEqual(commitLines.length, 0, 'Should not include commit hash lines');
1621        assert.ok(files.length >= 2, 'Should include file paths');
1622      } finally {
1623        cleanup();
1624      }
1625    });
1626  });
1627  
1628  // ============================================================
1629  // 14. checkDocumentationFreshness: specific rule paths
1630  // ============================================================
1631  
1632  describe('ArchitectAgent Coverage2 - checkDocumentationFreshness rule paths', () => {
1633    test('completes with documentation_fresh when no stale items found', async () => {
1634      const dbPath = join(tmpdir(), `arch-cov2-cdffresh-${Date.now()}.db`);
1635      const { db, agent, cleanup } = await createTestEnv(dbPath);
1636      try {
1637        const taskId = insertTask(db, 'check_documentation_freshness', {});
1638        const task = getTask(db, taskId);
1639  
1640        await agent.checkDocumentationFreshness(task);
1641  
1642        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1643        assert.ok(
1644          ['completed', 'failed'].includes(updated.status),
1645          `Should complete or fail: ${updated.status}`
1646        );
1647        if (updated.status === 'completed') {
1648          const result = JSON.parse(updated.result_json || '{}');
1649          assert.ok(result.stale_items !== undefined, 'Should have stale_items field');
1650        }
1651      } finally {
1652        cleanup();
1653      }
1654    });
1655  
1656    test('creates update_documentation task when stale items found', async () => {
1657      const dbPath = join(tmpdir(), `arch-cov2-cdfstale-${Date.now()}.db`);
1658      const { db, agent, cleanup } = await createTestEnv(dbPath);
1659      try {
1660        // The checkDocumentationFreshness reads git log and checks various rules
1661        // We just verify it runs end-to-end without crashing
1662        const taskId = insertTask(db, 'check_documentation_freshness', {});
1663        const task = getTask(db, taskId);
1664  
1665        await agent.checkDocumentationFreshness(task);
1666  
1667        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1668        assert.ok(
1669          ['completed', 'failed'].includes(updated.status),
1670          `Should complete or fail: ${updated.status}`
1671        );
1672  
1673        // If it found stale items, it should have created an update task
1674        if (updated.status === 'completed') {
1675          const result = JSON.parse(updated.result_json || '{}');
1676          if (result.stale_items && result.stale_items.length > 0) {
1677            assert.ok(result.update_task_id, 'Should create update task when stale items found');
1678          } else {
1679            assert.strictEqual(
1680              result.documentation_fresh,
1681              true,
1682              'Should mark docs as fresh when no stale items'
1683            );
1684          }
1685        }
1686      } finally {
1687        cleanup();
1688      }
1689    });
1690  });
1691  
1692  // ============================================================
1693  // 15. processTask error propagation
1694  // ============================================================
1695  
1696  describe('ArchitectAgent Coverage2 - processTask error propagation', () => {
1697    test('propagates error when method throws', async () => {
1698      const dbPath = join(tmpdir(), `arch-cov2-pterror-${Date.now()}.db`);
1699      const { db, agent, cleanup } = await createTestEnv(dbPath);
1700      try {
1701        const taskId = insertTask(db, 'review_design', { files: [] });
1702        const task = getTask(db, taskId);
1703  
1704        // Monkey-patch reviewDesign to throw
1705        const origReviewDesign = agent.reviewDesign.bind(agent);
1706        agent.reviewDesign = async _task => {
1707          throw new Error('Forced test error in reviewDesign');
1708        };
1709  
1710        await assert.rejects(
1711          () => agent.processTask(task),
1712          err => {
1713            assert.ok(err.message.includes('Forced test error'), 'Should propagate the error');
1714            return true;
1715          }
1716        );
1717  
1718        agent.reviewDesign = origReviewDesign;
1719      } finally {
1720        cleanup();
1721      }
1722    });
1723  
1724    test('handles all delegatable task types through processTask', async () => {
1725      const delegatableTypes = [
1726        'fix_bug',
1727        'implement_feature',
1728        'investigate_issue',
1729        'create_automation',
1730      ];
1731  
1732      for (const taskType of delegatableTypes) {
1733        const dbPath = join(tmpdir(), `arch-cov2-ptdelegate-${taskType}-${Date.now()}.db`);
1734        const { db, agent, cleanup } = await createTestEnv(dbPath);
1735        try {
1736          const taskId = insertTask(db, taskType, { description: `Test ${taskType}` });
1737          const task = getTask(db, taskId);
1738  
1739          await agent.processTask(task);
1740  
1741          const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1742          assert.ok(
1743            ['completed', 'failed', 'pending'].includes(updated.status),
1744            `${taskType} should delegate and resolve: ${updated.status}`
1745          );
1746        } finally {
1747          cleanup();
1748        }
1749      }
1750    });
1751  });
1752  
1753  // ============================================================
1754  // 16. analyzeCodebase: empty filesToAnalyze path
1755  // ============================================================
1756  
1757  describe('ArchitectAgent Coverage2 - analyzeCodebase edge cases', () => {
1758    test('returns fallback when filesToAnalyze is empty array', async () => {
1759      const dbPath = join(tmpdir(), `arch-cov2-acbempty-${Date.now()}.db`);
1760      const { agent, cleanup } = await createTestEnv(dbPath);
1761      try {
1762        const context = await agent.analyzeCodebase('test feature', []);
1763        // Empty array falls through to general search
1764        assert.ok(typeof context === 'string', 'Should return string');
1765      } finally {
1766        cleanup();
1767      }
1768    });
1769  
1770    test('limits specific files to 5 when more are provided', async () => {
1771      const dbPath = join(tmpdir(), `arch-cov2-acblimit-${Date.now()}.db`);
1772      const { agent, cleanup } = await createTestEnv(dbPath);
1773      try {
1774        // The mock readFile always succeeds, so we can test the 5-file limit
1775        const manyFiles = [
1776          'src/score.js',
1777          'src/scrape.js',
1778          'src/capture.js',
1779          'src/enrich.js',
1780          'src/proposals.js',
1781          'src/outreach.js', // 6th file - should be ignored
1782        ];
1783        const context = await agent.analyzeCodebase('test feature', manyFiles);
1784        assert.ok(typeof context === 'string', 'Should return string context');
1785        assert.ok(context.length > 0, 'Context should not be empty');
1786      } finally {
1787        cleanup();
1788      }
1789    });
1790  });
1791  
1792  // ============================================================
1793  // 17. performAutomatedReviewChecks: edge cases
1794  // ============================================================
1795  
1796  describe('ArchitectAgent Coverage2 - performAutomatedReviewChecks comprehensive', () => {
1797    test('handles plan with no files_to_modify', async () => {
1798      const dbPath = join(tmpdir(), `arch-cov2-parcnofiles-${Date.now()}.db`);
1799      const { agent, cleanup } = await createTestEnv(dbPath);
1800      try {
1801        const plan = {
1802          // No files_to_modify field
1803          test_plan: { coverage_target: 90 },
1804          documentation_updates: true,
1805        };
1806        const issues = await agent.performAutomatedReviewChecks(plan);
1807        assert.ok(Array.isArray(issues), 'Should return array');
1808        // No files → no max_lines_risk issues
1809        const lineIssues = issues.filter(i => i.type === 'max_lines_risk');
1810        assert.strictEqual(lineIssues.length, 0, 'Should have no line issues when no files provided');
1811      } finally {
1812        cleanup();
1813      }
1814    });
1815  
1816    test('checks real file when it exists and has >130 lines', async () => {
1817      const dbPath = join(tmpdir(), `arch-cov2-parcreal-${Date.now()}.db`);
1818      const { agent, cleanup } = await createTestEnv(dbPath);
1819      try {
1820        // architect.js itself has >130 lines (it has ~1859 lines!)
1821        const plan = {
1822          files_to_modify: ['src/agents/architect.js'],
1823          test_plan: { coverage_target: 90 },
1824          documentation_updates: true,
1825        };
1826        const issues = await agent.performAutomatedReviewChecks(plan);
1827        assert.ok(Array.isArray(issues), 'Should return array');
1828        // architect.js is huge so should trigger max_lines_risk
1829        const lineIssue = issues.find(i => i.type === 'max_lines_risk');
1830        assert.ok(lineIssue, 'Should detect max_lines_risk for architect.js (>130 lines)');
1831        assert.strictEqual(lineIssue.severity, 'medium', 'max_lines_risk should be medium severity');
1832      } finally {
1833        cleanup();
1834      }
1835    });
1836  });
1837  
1838  // ============================================================
1839  // 18. reviewDocumentation with warnings triggers human review queue
1840  // ============================================================
1841  
1842  describe('ArchitectAgent Coverage2 - reviewDocumentation human review queue', () => {
1843    test('adds to human review queue when documentation has warnings', async () => {
1844      const dbPath = join(tmpdir(), `arch-cov2-rvdqueue-${Date.now()}.db`);
1845      const { db, agent, cleanup } = await createTestEnv(dbPath);
1846      try {
1847        // Create a file with issues
1848        const tmpFile = join(tmpdir(), `warning-doc-${Date.now()}.md`);
1849        writeFileSync(tmpFile, 'No header - just content with TODO: fix this');
1850  
1851        const taskId = insertTask(db, 'review_documentation', {
1852          files: [tmpFile],
1853        });
1854        const task = getTask(db, taskId);
1855  
1856        await agent.reviewDocumentation(task);
1857  
1858        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1859        assert.strictEqual(updated.status, 'completed', 'Should complete');
1860        const result = JSON.parse(updated.result_json || '{}');
1861        // verifyDocumentation uses mock readFile, so result depends on mock content
1862        assert.ok(
1863          result.verified !== undefined || result.warnings !== undefined,
1864          'Should have result data'
1865        );
1866  
1867        try {
1868          rmSync(tmpFile, { force: true });
1869        } catch (_e) {
1870          /* ignore */
1871        }
1872      } finally {
1873        cleanup();
1874      }
1875    });
1876  
1877    test('uses default doc files when no files specified in context', async () => {
1878      const dbPath = join(tmpdir(), `arch-cov2-rvddefaults-${Date.now()}.db`);
1879      const { db, agent, cleanup } = await createTestEnv(dbPath);
1880      try {
1881        const taskId = insertTask(db, 'review_documentation', {
1882          // No files - should use defaults: ['README.md', 'CLAUDE.md', 'docs/06-automation/agent-system.md']
1883        });
1884        const task = getTask(db, taskId);
1885  
1886        await agent.reviewDocumentation(task);
1887  
1888        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
1889        assert.strictEqual(updated.status, 'completed', 'Should complete with default files');
1890      } finally {
1891        cleanup();
1892      }
1893    });
1894  });
1895  
1896  // ============================================================
1897  // 19. classifyPerformanceIssue: all boundary conditions
1898  // ============================================================
1899  
1900  describe('ArchitectAgent Coverage2 - classifyPerformanceIssue boundaries', () => {
1901    test('exactly at 5x threshold returns critical', async () => {
1902      const dbPath = join(tmpdir(), `arch-cov2-cpi5x-${Date.now()}.db`);
1903      const { agent, cleanup } = await createTestEnv(dbPath);
1904      try {
1905        // 5x exactly: 300000 / 60000 = 5.0 → critical
1906        assert.strictEqual(agent.classifyPerformanceIssue(300000, 60000), 'critical');
1907      } finally {
1908        cleanup();
1909      }
1910    });
1911  
1912    test('just below 5x returns high', async () => {
1913      const dbPath = join(tmpdir(), `arch-cov2-cpibelow5x-${Date.now()}.db`);
1914      const { agent, cleanup } = await createTestEnv(dbPath);
1915      try {
1916        // 4.9x: 294000 / 60000 = 4.9 → high (not critical)
1917        assert.strictEqual(agent.classifyPerformanceIssue(294000, 60000), 'high');
1918      } finally {
1919        cleanup();
1920      }
1921    });
1922  
1923    test('exactly at 3x threshold returns high', async () => {
1924      const dbPath = join(tmpdir(), `arch-cov2-cpi3x-${Date.now()}.db`);
1925      const { agent, cleanup } = await createTestEnv(dbPath);
1926      try {
1927        // 3x exactly: 180000 / 60000 = 3.0 → high
1928        assert.strictEqual(agent.classifyPerformanceIssue(180000, 60000), 'high');
1929      } finally {
1930        cleanup();
1931      }
1932    });
1933  
1934    test('exactly at 2x threshold returns medium', async () => {
1935      const dbPath = join(tmpdir(), `arch-cov2-cpi2x-${Date.now()}.db`);
1936      const { agent, cleanup } = await createTestEnv(dbPath);
1937      try {
1938        // 2x exactly: 120000 / 60000 = 2.0 → medium
1939        assert.strictEqual(agent.classifyPerformanceIssue(120000, 60000), 'medium');
1940      } finally {
1941        cleanup();
1942      }
1943    });
1944  
1945    test('just below 2x returns low', async () => {
1946      const dbPath = join(tmpdir(), `arch-cov2-cpilow-${Date.now()}.db`);
1947      const { agent, cleanup } = await createTestEnv(dbPath);
1948      try {
1949        // 1.9x: 114000 / 60000 = 1.9 → low
1950        assert.strictEqual(agent.classifyPerformanceIssue(114000, 60000), 'low');
1951      } finally {
1952        cleanup();
1953      }
1954    });
1955  });
1956  
1957  // ============================================================
1958  // 20. getJsFiles: direct test
1959  // ============================================================
1960  
1961  describe('ArchitectAgent Coverage2 - getJsFiles', () => {
1962    test('returns array of JS files from src/', async () => {
1963      const dbPath = join(tmpdir(), `arch-cov2-getjs-${Date.now()}.db`);
1964      const { agent, cleanup } = await createTestEnv(dbPath);
1965      try {
1966        const files = await agent.getJsFiles();
1967        assert.ok(Array.isArray(files), 'Should return array');
1968        // In the 333Method project, src/ has many .js files
1969        if (files.length > 0) {
1970          assert.ok(
1971            files.every(f => f.endsWith('.js')),
1972            'All files should end with .js'
1973          );
1974          assert.ok(
1975            files.every(f => f.startsWith('src/')),
1976            'All files should be in src/'
1977          );
1978        }
1979      } finally {
1980        cleanup();
1981      }
1982    });
1983  });
1984  
1985  // ============================================================
1986  // 21. suggestRefactor: all complexity_issues patterns
1987  // ============================================================
1988  
1989  describe('ArchitectAgent Coverage2 - suggestRefactor all patterns', () => {
1990    test('detects all three issue types in one call', async () => {
1991      const dbPath = join(tmpdir(), `arch-cov2-srall-${Date.now()}.db`);
1992      const { db, agent, cleanup } = await createTestEnv(dbPath);
1993      try {
1994        const taskId = insertTask(db, 'suggest_refactor', {
1995          file: 'src/complex-module.js',
1996          complexity_issues: [
1997            'deeply nested callbacks found',
1998            'too many parameter arguments',
1999            'high cyclomatic complexity detected',
2000          ],
2001        });
2002        const task = getTask(db, taskId);
2003  
2004        await agent.suggestRefactor(task);
2005  
2006        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
2007        assert.strictEqual(updated.status, 'completed');
2008        const result = JSON.parse(updated.result_json || '{}');
2009        assert.ok(Array.isArray(result.suggestions), 'Should have suggestions');
2010        assert.ok(
2011          result.suggestions.length >= 3,
2012          'Should have at least 3 suggestions for 3 issue types'
2013        );
2014  
2015        // Verify all suggestion types are present
2016        const types = result.suggestions.map(s => s.type);
2017        assert.ok(
2018          types.includes('extract_function'),
2019          'Should have extract_function suggestion for nested'
2020        );
2021        assert.ok(
2022          types.includes('configuration_object'),
2023          'Should have configuration_object for parameters'
2024        );
2025        assert.ok(
2026          types.includes('simplify_conditionals'),
2027          'Should have simplify_conditionals for cyclomatic complexity'
2028        );
2029      } finally {
2030        cleanup();
2031      }
2032    });
2033  
2034    test('handles null/undefined complexity_issues gracefully', async () => {
2035      const dbPath = join(tmpdir(), `arch-cov2-srnull-${Date.now()}.db`);
2036      const { db, agent, cleanup } = await createTestEnv(dbPath);
2037      try {
2038        const taskId = insertTask(db, 'suggest_refactor', {
2039          file: 'src/module.js',
2040          // No complexity_issues field
2041        });
2042        const task = getTask(db, taskId);
2043  
2044        await agent.suggestRefactor(task);
2045  
2046        const updated = db.prepare('SELECT * FROM agent_tasks WHERE id = ?').get(taskId);
2047        assert.strictEqual(updated.status, 'completed', 'Should complete with no complexity issues');
2048        const result = JSON.parse(updated.result_json || '{}');
2049        assert.strictEqual(result.note, 'No refactoring needed', 'Should note no refactoring needed');
2050      } finally {
2051        cleanup();
2052      }
2053    });
2054  });
2055  
2056  // ============================================================
2057  // 22. checkErrorDetectionWorkflow: various states
2058  // ============================================================
2059  
2060  describe('ArchitectAgent Coverage2 - checkErrorDetectionWorkflow states', () => {
2061    test('returns true when scan_logs task has running status', async () => {
2062      const dbPath = join(tmpdir(), `arch-cov2-cedwrunning-${Date.now()}.db`);
2063      const { db, agent, cleanup } = await createTestEnv(dbPath);
2064      try {
2065        // Insert a running scan_logs task
2066        db.prepare(`INSERT INTO agent_tasks (task_type, assigned_to, status) VALUES (?, ?, ?)`).run(
2067          'scan_logs',
2068          'monitor',
2069          'running'
2070        );
2071  
2072        const result = await agent.checkErrorDetectionWorkflow();
2073        assert.strictEqual(result, true, 'Should return true when scan_logs task is running');
2074      } finally {
2075        cleanup();
2076      }
2077    });
2078  
2079    test('handles database errors gracefully', async () => {
2080      const dbPath = join(tmpdir(), `arch-cov2-cedwdberror-${Date.now()}.db`);
2081      const { agent, cleanup } = await createTestEnv(dbPath);
2082      try {
2083        // Point to invalid DATABASE_PATH to trigger error
2084        process.env.DATABASE_PATH = '/invalid/path/that/does/not/exist.db';
2085        const result = await agent.checkErrorDetectionWorkflow();
2086        // Should return false on error (not throw)
2087        assert.strictEqual(result, false, 'Should return false on database error');
2088      } finally {
2089        // Restore the original db path
2090        process.env.DATABASE_PATH = dbPath;
2091        cleanup();
2092      }
2093    });
2094  });
2095  
2096  // ============================================================
2097  // 23. summarizeChanges: many files truncation
2098  // ============================================================
2099  
2100  describe('ArchitectAgent Coverage2 - summarizeChanges file limits', () => {
2101    test('processes up to 10 files maximum', async () => {
2102      const dbPath = join(tmpdir(), `arch-cov2-sclimit-${Date.now()}.db`);
2103      const { agent, cleanup } = await createTestEnv(dbPath);
2104      try {
2105        // Provide 12 files - should only process 10
2106        const manyFiles = [
2107          'src/score.js',
2108          'src/scrape.js',
2109          'src/capture.js',
2110          'src/enrich.js',
2111          'src/proposals.js',
2112          'src/outreach.js',
2113          'src/inbound.js',
2114          'src/keywords.js',
2115          'src/pipeline.js',
2116          'src/utils.js',
2117          'src/extra1.js', // 11th
2118          'src/extra2.js', // 12th
2119        ];
2120        const summary = await agent.summarizeChanges(manyFiles);
2121        assert.ok(typeof summary === 'string', 'Should return string');
2122        assert.ok(summary.length > 0, 'Summary should not be empty');
2123      } finally {
2124        cleanup();
2125      }
2126    });
2127  });