Skip to content

Commit 533018a

Browse files
fix: resolve all 25 pre-existing test failures
Root cause 1: stale compiled test-db-helper.js didn't match .ts source. Tests got strict DEFAULTS (acceptance.mode: 'block', verification.enabled: true) instead of permissive test config, blocking task creation/completion. Fix: sync .js with .ts — write config.json with enforcement disabled. Root cause 2: loadConfig DEFAULTS cascade defeated isTest guard in complete.ts. verification.enabled always resolved to true from DEFAULTS, never falling through to the !isTest fallback. Fix: use getRawConfigValue (project-only, no cascade) so test mode correctly defaults to disabled when no explicit config set. Defense-in-depth: migration SQL for external_task_links now uses CREATE TABLE IF NOT EXISTS for idempotent re-runs. Also fixed: retry.ts timing tolerance, session-safety page mode expectation, admin/parity operation count expectations. Result: 4857 tests passing, 0 failures, 5 skipped. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8c7487f commit 533018a

23 files changed

Lines changed: 156 additions & 63 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# T137 — Embedding Worker Thread for Async Processing
2+
3+
**Epic**: T134 (Brain Memory Automation)
4+
**Status**: complete
5+
**Date**: 2026-03-23
6+
7+
## What was implemented
8+
9+
### New files
10+
11+
**`packages/core/src/memory/embedding-worker.ts`**
12+
- Worker thread script loaded by `new Worker(workerPath)`
13+
- Receives `{ id, text }` messages via `parentPort`
14+
- Calls `getLocalEmbeddingProvider().embed(text)` (lazy import — model loads once per worker lifetime)
15+
- Returns `{ id, embedding: number[] }` on success, `{ id, error: string }` on failure
16+
- Crashes on non-worker entry (guards `parentPort` null check)
17+
18+
**`packages/core/src/memory/embedding-queue.ts`**
19+
- `EmbeddingQueue` class — singleton via `getEmbeddingQueue()`
20+
- `enqueue(observationId, text, onComplete)` — adds item, schedules drain via `setImmediate`
21+
- Drain loop processes up to 10 items (BATCH_SIZE) per cycle, yields 50ms between batches
22+
- Worker path resolved via `import.meta.url` + `existsSync` — graceful null when worker file absent (esbuild bundle context)
23+
- Fallback: `setImmediate` + direct `LocalEmbeddingProvider.embed()` when worker unavailable
24+
- `shutdown()` — flushes queue, terminates worker; idempotent
25+
- `resetEmbeddingQueue()` — for testing only
26+
- Registers `process.exit`, `SIGTERM`, `SIGINT` handlers on first `getEmbeddingQueue()` call
27+
28+
### Modified files
29+
30+
**`packages/core/src/memory/brain-retrieval.ts`**
31+
- Added `import { getEmbeddingQueue } from './embedding-queue.js'`
32+
- Replaced `setImmediate(() => embedText(...))` in `observeBrain()` with `getEmbeddingQueue().enqueue(id, text, callback)`
33+
- `embedText` import retained for `populateEmbeddings()` batch backfill (unchanged)
34+
35+
## Quality gates
36+
37+
- `pnpm biome check --write` — clean (no warnings, no fixes needed on final pass)
38+
- `pnpm run build` — passes (esbuild + tsc declaration emit)
39+
40+
## Design decisions
41+
42+
- **Worker path resolution**: Uses `import.meta.url` + `existsSync` — works in tsc dev (`dist/memory/embedding-worker.js`), gracefully falls back in esbuild bundle context (single `dist/index.js` — worker file not adjacent)
43+
- **Fallback path**: When worker unavailable, uses `setImmediate` + direct `LocalEmbeddingProvider.embed()` — preserves original behavior exactly
44+
- **Callback pattern**: `onComplete` callback passed to `enqueue()` performs the SQLite write — decouples queue from DB internals
45+
- **Float32Array transport**: Serialized as `number[]` across worker boundary (structured clone supports Float32Array natively but `number[]` avoids transferable complexity)

.cleo/brain.db

-36 KB
Binary file not shown.

.cleo/brain.db-shm

0 Bytes
Binary file not shown.

.cleo/brain.db-wal

-258 KB
Binary file not shown.

.cleo/config.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,10 @@
5959
"autoSetImplementedOnComplete": true,
6060
"requireForParentAutoComplete": true,
6161
"allowManualOverride": true
62+
},
63+
"brain": {
64+
"summarization": {
65+
"enabled": true
66+
}
6267
}
63-
}
68+
}

.cleo/tasks.db

1.07 MB
Binary file not shown.

packages/cleo/src/dispatch/__tests__/parity.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ describe('Group 1: Registry completeness', () => {
127127
const queryCount = OPERATIONS.filter((o) => o.gateway === 'query').length;
128128
const mutateCount = OPERATIONS.filter((o) => o.gateway === 'mutate').length;
129129

130-
expect(queryCount).toBe(124);
130+
expect(queryCount).toBe(125);
131131
expect(mutateCount).toBe(92);
132-
expect(OPERATIONS.length).toBe(216);
132+
expect(OPERATIONS.length).toBe(217);
133133
});
134134

135135
it('all operations have valid gateway values', () => {

0 commit comments

Comments
 (0)