Cecil ships with a full integration test that exercises every major subsystem:
npx tsx scripts/test-v2.tsThis runs 16 tests covering:
| Test | What it verifies |
|---|---|
init() |
SQLite + Qdrant + world model initialize |
getSubjectName() |
Name resolves from seed or world model |
setSubjectName() |
Runtime name override works |
worldModel.summary() |
World model query works |
worldModel.entities() |
Entity listing |
worldModel.entities('person') |
Entity filtering by kind |
worldModel.beliefs() |
Belief listing (includes validFrom/validTo) |
worldModel.beliefsAsOf(date) |
Temporal belief query |
worldModel.openLoops() |
Open loop listing |
worldModel.contradictions() |
Contradiction listing |
recall() |
Memory search returns results |
store() |
Memory storage works |
recall stored memory |
Stored memory is immediately retrievable |
chat() |
LLM responds with memory context |
turn() |
Full cycle (chat + observe) |
maintenance(dryRun) |
Maintenance pipeline runs without errors |
reflect() |
Reflection agent generates analysis |
- Qdrant running (
docker compose up -d) - LLM endpoint running (local model server or cloud API)
- Existing memory data (optional — some tests work without it)
npx tsc --noEmitMust pass with zero errors before any commit.
npm run lintnpx tsx --eval "import { observe } from './cecil/observer'; console.log('ok')"npm run world-modelRename or delete identity/seed.md, then:
npm run devOpen http://localhost:3000 — should go straight to chat.
npm run memory:inspect -- --query="test query" --windownpm run reflect -- --patternsnpm run maintenance -- --dry-run
npm run maintenance -- --dry-run --semantic-dedup # Verify semantic dedup reports processed countnpm run mcpShould start without errors and wait for stdio input.
npm run memory:auditReports:
- Total records and events
- Memory types present
- Source pipelines writing
- Stale or low-quality records
- Duplicate detection
- Optional ranked recall preview
This is the first thing to check when Cecil's answers feel generic or blank.
npm run world-model -- --beliefs # Should show from:/to: fields on beliefsAfter a conversation, check that memories have domain tags:
npm run memory:inspect # Look for domain field in outputAfter a multi-turn conversation, check for exchange-pair memory keys:
sqlite3 memory/structured-memory.sqlite "SELECT memory_key FROM memory_current WHERE memory_key LIKE '%pair%' LIMIT 5"If you modify recall behavior, verify with:
GET /api/memory?query=your+query&includeWindow=true
This shows the exact recall window Cecil would use for that query, including evidence tiers and source labels.