Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions memory-health.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import { existsSync, unlinkSync } from 'node:fs'

// initMemory() builds the FTS5 table with the libsimple Chinese tokenizer when
// that extension is present (deployed runtime, not CI). Every raw connection
// this test opens must load it too, or INSERTs fail with "no such tokenizer:
// simple". Same helper as cold-pool-gate.test.mjs.
const __simple_ext = resolve(dirname(fileURLToPath(import.meta.url)), 'lib', 'libsimple-windows-x64', 'simple')
function tryLoadSimple(conn) {
try {
if (existsSync(__simple_ext + '.dll') || existsSync(__simple_ext)) conn.loadExtension(__simple_ext)
} catch {}
return conn
}

const __dirname = dirname(fileURLToPath(import.meta.url))
const DB_PATH = process.env.TOKENMEM_DB_PATH
if (!DB_PATH) {
Expand Down Expand Up @@ -57,7 +69,7 @@ function check(label, cond, detail = '') {
storeMemory({ content: 'concrete rule violation', memoryLevel: 'concrete_trace', importance: 8, memoryType: 'long_term' })
// Age some rows backward via raw SQL to trip surface-cold / dead-knowledge.
const Database = (await import('better-sqlite3')).default
const db = new Database(DB_PATH)
const db = tryLoadSimple(new Database(DB_PATH))
db.prepare('UPDATE memories SET last_accessed = ?, created_at = ? WHERE content LIKE ?').run(now - D45, now - D45, '%stale meta%')
db.prepare('UPDATE memories SET last_accessed = ?, decay_score = 0.2 WHERE content LIKE ?').run(now - D45, '%op log%')
db.close()
Expand Down Expand Up @@ -117,7 +129,7 @@ function check(label, cond, detail = '') {
// ── --consolidate --dry-run: no writes ──
{
const Database = (await import('better-sqlite3')).default
const dbBefore = new Database(DB_PATH, { readonly: true })
const dbBefore = tryLoadSimple(new Database(DB_PATH, { readonly: true }))
const active_before = dbBefore.prepare('SELECT COUNT(*) c FROM memories WHERE deleted_at IS NULL').get().c
dbBefore.close()

Expand All @@ -131,7 +143,7 @@ function check(label, cond, detail = '') {
check('--consolidate --dry-run marks dryRun=true', result?.dryRun === true)
check('--consolidate --dry-run reports level_migrate', typeof result?.level_migrate === 'object')

const dbAfter = new Database(DB_PATH, { readonly: true })
const dbAfter = tryLoadSimple(new Database(DB_PATH, { readonly: true }))
const active_after = dbAfter.prepare('SELECT COUNT(*) c FROM memories WHERE deleted_at IS NULL').get().c
dbAfter.close()
check('--consolidate --dry-run did NOT mutate', active_before === active_after, `${active_before} -> ${active_after}`)
Expand Down Expand Up @@ -163,7 +175,7 @@ function check(label, cond, detail = '') {
{
// Age enough meta rows to have at least one demotion candidate again.
const Database = (await import('better-sqlite3')).default
const db = new Database(DB_PATH)
const db = tryLoadSimple(new Database(DB_PATH))
const D45 = 45 * 86400_000
db.prepare('UPDATE memories SET last_accessed = ?, created_at = ?, memory_level = ?, access_count = 0 WHERE rowid = (SELECT MIN(rowid) FROM memories WHERE deleted_at IS NULL)')
.run(Date.now() - D45, Date.now() - D45, 'meta_knowledge')
Expand Down Expand Up @@ -202,7 +214,7 @@ function check(label, cond, detail = '') {
{
const Database = (await import('node:module')).createRequire(import.meta.url)('better-sqlite3')
const { detectNearDup } = await import('./memory-health.mjs')
const db = new Database(DB_PATH)
const db = tryLoadSimple(new Database(DB_PATH))

const DAY = 86400_000
const now = Date.now()
Expand Down Expand Up @@ -262,7 +274,7 @@ function check(label, cond, detail = '') {
{
const { detectShrinkVictims } = await import('./memory-health.mjs')
const Database = (await import('better-sqlite3')).default
const db = new Database(DB_PATH)
const db = tryLoadSimple(new Database(DB_PATH))

const OPS = 'ops entry: http://10.0.0.5:9000 root, /api/svc/v1 routes, SVC_TOKEN and SVC_URL env, '
+ 'code at C:/work/svc/, handler src/http.mjs, schema src/db.mjs. '
Expand Down Expand Up @@ -330,7 +342,7 @@ function check(label, cond, detail = '') {
{
const { detectBlindspot } = await import('./memory-health.mjs')
const Database = (await import('better-sqlite3')).default
const db = new Database(DB_PATH)
const db = tryLoadSimple(new Database(DB_PATH))

// Assert the branch, not the build. Whether recall_log exists at this point
// depends on which engine created DB_PATH — a build that instruments recall
Expand Down
12 changes: 12 additions & 0 deletions vector-blob.integration.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,19 @@ const DB_PATH = process.env.TOKENMEM_DB_PATH
? resolve(__dirname_at, 'engram.db')
: resolve(__dirname_at, 'tokenmem.db'))

// initMemory() builds the FTS5 table with the libsimple Chinese tokenizer when
// that extension is present (it is in the deployed runtime, not in CI). A second
// raw connection must load it too, or the FTS trigger on INSERT fails with
// "no such tokenizer: simple". Same helper as cold-pool-gate.test.mjs.
const SIMPLE_EXT_PATH = resolve(__dirname_at, 'lib', 'libsimple-windows-x64', 'simple')
function tryLoadSimple(conn) {
try {
if (existsSync(SIMPLE_EXT_PATH + '.dll') || existsSync(SIMPLE_EXT_PATH)) conn.loadExtension(SIMPLE_EXT_PATH)
} catch {}
}

const db = new Database(DB_PATH)
tryLoadSimple(db)

let pass = 0, fail = 0
const ok = (name, cond) => {
Expand Down
Loading