Database/Rule Engine/6 Capabilities/Business Unification - Thorough Audit (2026-07-15 22:40)
Audit Method
Scan the entire server/ directory from scratch, examining all 418 .js files, collecting evidence file:line by file:line, without inference.
Distinguish between 'real runtime require' and 'JSDoc type annotations'/'comments' to avoid false positives.
Summary of Findings
| Dimension | Unified? | Evidence |
|---|---|---|
| Driver Technology | ✅ Single better-sqlite3 | Runtime require('better-sqlite3') appears only once in the entire repository: sqlite-compat.js:25 |
| Driver Mixing | ✅ Cleared | sql.js 0 occurrences; sqlite3 1 occurrence (ai-task-manager.js, known tech-debt) |
| DB Path | ✅ Normalized | createDatabaseFresh(L189)=createDatabase(L190), no independent instances |
| Invocation Method | ✅ db-adapter facade | _adapter=require('./sqlite-compat') L81/90/104; createDatabase called in 114 places |
| Rule Library Path | ✅ Unique | 14+ places point to server/data/rule_engine.db |
| Rule Engine Instance | ✅ Single connection, multiple instances from same source | 7 occurrences of new UnifiedRuleEngine all pass the same underlying singleton DB |
| 6 Major Capabilities | ✅ Same pipeline | Three-layer closed loop: dispatcher→runtime→engine; all 8 capabilities handled by engine.execute* |
| Business Implementation | ✅ Mainly unified | aml.js, etc., go through getSciotDb()→dbAdapter.createDatabase→singleton |
Detailed evidence
Driven reference count (excluding node_modules)
- sql.js: 0 locations (cleared)
- better-sqlite3: runtime actual require only at sqlite-compat.js:25
- Note: Previous '29 locations' was a false positive, including 9 JSDoc import('better-sqlite3').Database type annotations + comments
- sqlite3: 1 location at server/services/ai-task-manager.js:6 (known tech-debt)
- mysql2: 11 locations (external library, reasonable)
Singleton path (sqlite-compat.js)
- L25: betterSqlite3 = require('better-sqlite3')
- L84: db = new betterSqlite3(realPath, {...})
- L123: function wrapDatabase(db, realPath)
- L179: function createDatabase(dbPath) → path normalization → singleton cache
- L189: function createDatabaseFresh(dbPath) { return createDatabase(dbPath); } // same singleton
db-adapter facade (db-adapter.js)
- L81/90/104: _adapter = require('./sqlite-compat')
- L153: return sqliteCompat.createDatabase(dbPathOrName)
- L217-227: module.exports = { createDatabase, createDatabaseFresh, getDb, ... }
- Conclusion: db-adapter is a pure thin wrapper of sqlite-compat, both sharing the same underlying singleton.
Multiple rule engine instances share the same source (core/rule-engine.js + caller).
- L234: class UnifiedRuleEngine
- L236: this._instId = 'RE-' + random // Unique ID per instance, but underlying DB is shared.
- Locations of new UnifiedRuleEngine:
- capability-runtime.js:59 (main, _initRuleEngine L49-64 single-point initialization).
- digital-staff/llm-brain.js:134 → db=createDatabase(server/data/rule_engine.db) L128
- routes/doc-agent.js:98 → ruleDb=createDatabase(server/data/rule_engine.db) L94
- routes/rule-engine.js:40 → getRuleEngine(db) reuses the passed-in singleton.
- routes/rule-workbench-api.js:20
- scripts/health-check.js:94 (script, not runtime).
- Conclusion: Multiple engine instances, but the underlying DB connection and all 2413 rules are identical, representing a 'multiple instances, single connection' architecture, not a split.
Six major capabilities share the same pipeline (capability-runtime.js).
- validate L835 (engine.execute 2).
- identify L872 (1).
- repair L952 (1).
- optimize L1126 (1).
- compare L1212 (2).
- create L1388 (1).
- inspect L1660 (2).
- generate L1276 (1).
- Dispatch: capability-dispatcher.js → getRuntime() → runtimecapability (L90-100).
- Consistent pattern: rule engine first → fallback to LLM if no rule → error if both fail
Business implementation (aml.js forensics)
- L606: function getSciotDb()
- L621: const dbAdapter = require('../db-adapter')
- L631: _sciotDb = dbAdapter.createDatabase(dbPath) // singleton
- L34/45/60/95/527...: const sciotDb = getSciotDb() // 30+ occurrences throughout file
- Fallback branch L204-211: only falls back to aml.db standalone library when db-adapter is unavailable (try-catch protected, normally not triggered)
Known tech-debt (not introduced this round, scheduled separately)
- ai-task-manager.js:6 native sqlite3 callback driver (ai_tasks.db not in singleton, API incompatible)
- ai-inspector.js:49 read-only sql.js memory snapshot (read-only, no write risk)
- 4 instances of new SQL.Database under server/scripts/* (build/migration scripts, not runtime)
Relationship to '9 API 404s'
- Completely unrelated. Root cause of the 9 API 404s is missing manual HTTP route dispatch in server.js (0 dispatches for these 9 endpoints within handleRequest), belonging to business routing layer technical debt.
- DB unification achieved ≠ business routing functionality complete; the two are orthogonal dimensions.
Self-correction
The previous judgment error in 'DB fix closure' was not about 'whether unification was achieved' (unification was indeed achieved), but about 'not simultaneously clarifying that 9 APIs in the business routing layer still return 404'. This round has audited from scratch to provide the complete picture.
BossAgents