Cognitive infrastructure for AI agents — beliefs that decay, governance that enforces, knowledge that heals itself.
Requires Node.js >= 22. ESM-only package (
"type": "module").
npm install limen-ai
Run with: npx tsx yourscript.ts
Optional, for semantic/vector search:
npm install sqlite-vec
- Decay in recall —
effectiveConfidencenow decays on every read (was only in search) - Automated retention — background scheduler cleans expired data automatically
- Replay verification — mission determinism verified via state snapshots
- Auto-connection — relationship suggestions fire automatically on claim assertion
- Consent enforcement — claim assertion blocked without active consent (when configured)
- Classification filtering — claims filtered by clearance level at query and search time
- Key rotation — atomic re-encryption of all vault entries with new master key
- 11 new MCP tools — 36 total tools, full CLI parity
- Dispute fix —
disputedflag correctly recomputes after contradicting claim retracted
import { createLimen } from 'limen-ai';
const limen = await createLimen();
limen.remember('entity:user:alice', 'preference.food', 'loves Thai food');
const beliefs = limen.recall('entity:user:alice');
if (beliefs.ok) {
console.log(beliefs.value[0].value); // "loves Thai food"
console.log(beliefs.value[0].confidence); // 0.7 (governed ceiling)
console.log(beliefs.value[0].effectiveConfidence); // decays over time
}
const results = limen.search('Thai');
if (results.ok) {
console.log(results.value[0].belief.value); // "loves Thai food"
console.log(results.value[0].score); // relevance * confidence
}
await limen.shutdown();createLimen() with no arguments auto-detects LLM providers, generates a dev encryption key, and provisions a local SQLite database. Copy, paste, run. If no LLM provider is configured, core CRUD (remember, recall, search, forget) works in degraded mode — only cognitive features (chat, infer, verify, narrative) require a provider.
Most AI memory systems store data — key-value pairs, vector embeddings, chat history. Limen stores beliefs.
Beliefs, not data. Every claim has a confidence score, a temporal anchor, and a decay curve. A belief stored 90 days ago with no reinforcement is weaker than one stored yesterday. This is computed on every read — nothing is stored. effectiveConfidence always reflects the current state of belief.
Governance, not storage. Auto-extracted claims are capped at 0.7 confidence — the maxAutoConfidence ceiling prevents confidence laundering. Structural conflict detection flags contradictions on write. Cascade retraction penalizes downstream beliefs when a source is retracted. PII detection blocks sensitive data before it reaches the database. Protected predicates prevent unauthorized mutation of critical knowledge.
Cognition, not retrieval. The engine consolidates duplicate beliefs, computes importance scores, suggests connections between claims, generates narrative snapshots of knowledge state, and optionally self-heals by auto-retracting derived claims whose parents have decayed below threshold.
| Method | Description |
|---|---|
remember(subject, predicate, value, options?) |
Store a belief with confidence and temporal anchoring |
remember(text, options?) |
Store a free-text observation (auto-generates subject) |
recall(subject?, predicate?, options?) |
Retrieve beliefs, filtered by subject/predicate, with decay applied |
search(query, options?) |
Full-text search across all beliefs (FTS5 + BM25) |
forget(claimId, reason?) |
Retract a belief (governed, audited, never deleted). Reason: 'incorrect' | 'superseded' | 'expired' | 'manual' (default) |
connect(claimId1, claimId2, type) |
Relate beliefs: supports, contradicts, supersedes, derived_from |
reflect(entries) |
Batch-store categorized learnings (decisions, patterns, warnings, findings) |
// Beliefs decay without reinforcement (FSRS power-decay)
// R(t) = (1 + t/(9*S))^-1, where S is stability in days
const beliefs = limen.recall('entity:project:limen');
if (beliefs.ok) {
const b = beliefs.value[0];
console.log(b.confidence); // 0.7 (original, governed ceiling)
console.log(b.effectiveConfidence); // 0.57 (after 60d decay with S=90)
console.log(b.freshness); // "stale" | "aging" | "fresh"
}
// Wrongness containment: confidence is capped
const r = limen.remember('entity:market:ev', 'size.2025', '$45B', { confidence: 0.95 });
// r.value.confidence === 0.7 (capped, not 0.95)
// Conflict detection is automatic
limen.remember('entity:market:ev', 'size.2025', '$52B');
// ^ creates a 'contradicts' relationship with the first claim
// Batch-store learnings
limen.reflect([
{ category: 'decision', statement: 'Chose FSRS over exponential decay', confidence: 0.85 },
{ category: 'warning', statement: 'FTS5 trigram index doubles storage', confidence: 0.7 },
]);The cognitive namespace provides knowledge health diagnostics and active knowledge management.
| Method | Description |
|---|---|
cognitive.health(config?) |
Knowledge health report: freshness distribution, conflicts, gaps, stale domains |
cognitive.consolidate(options?) |
Merge similar claims, archive stale ones, suggest contradiction resolutions |
cognitive.importance(claimId, weights?) |
5-factor composite importance score for a claim |
cognitive.narrative(missionId?) |
Snapshot of knowledge state — threads, themes, evolution over time |
cognitive.verify(claimId) |
Verify a claim via external provider (async, advisory only) |
cognitive.suggestConnections(claimId) |
KNN-based relationship suggestions via embedding similarity |
cognitive.acceptSuggestion(id) |
Accept a pending connection suggestion |
cognitive.rejectSuggestion(id) |
Reject a pending connection suggestion |
// Knowledge health diagnostics
const health = limen.cognitive.health();
if (health.ok) {
console.log(health.value.totalClaims); // total active claims
console.log(health.value.freshness); // { fresh: N, aging: N, stale: N }
console.log(health.value.conflicts.unresolved); // unresolved contradictions
console.log(health.value.gaps); // predicates with no recent claims
}
// Consolidation: merge duplicates, archive stale, suggest resolutions
const result = limen.cognitive.consolidate({ dryRun: true });
if (result.ok) {
console.log(result.value.merged); // claims merged
console.log(result.value.archived); // claims archived
console.log(result.value.suggestedResolutions); // contradiction resolutions
}
// Importance scoring
const score = limen.cognitive.importance(claimId);
if (score.ok) {
console.log(score.value.score); // 0.0-1.0 weighted composite
console.log(score.value.factors); // { accessFrequency, recency, connectionDensity, confidence, governanceWeight }
}
// Knowledge narrative
const narrative = limen.cognitive.narrative();
if (narrative.ok) {
console.log(narrative.value.threads); // thematic threads across claims
console.log(narrative.value.momentum); // 'growing' | 'stable' | 'declining'
}Classification, access control, compliance, and audit infrastructure.
| Method | Description |
|---|---|
governance.erasure(request) |
GDPR Article 17 erasure with certificate generation |
governance.exportAudit(options) |
SOC 2 Type II audit package export |
governance.addRule(rule) |
Add a data classification rule |
governance.removeRule(ruleId) |
Remove a classification rule |
governance.listRules() |
List all active classification rules |
governance.protectPredicate(rule) |
Protect a predicate from unauthorized mutation |
governance.listProtectedPredicates() |
List all protected predicate rules |
// GDPR erasure with audit certificate
const erasure = limen.governance.erasure({
dataSubjectId: 'user:alice',
reason: 'Right to erasure request',
requestedBy: 'dpo@company.com',
});
if (erasure.ok) {
console.log(erasure.value.certificateId); // audit-grade certificate
console.log(erasure.value.claimsErased); // count
}
// Protect critical predicates
limen.governance.protectPredicate({
predicatePattern: 'governance.*',
requiredRole: 'admin',
description: 'Governance claims require admin role',
});
// SOC 2 audit export
const audit = limen.governance.exportAudit({
fromDate: '2026-01-01T00:00:00Z',
toDate: '2026-04-01T00:00:00Z',
format: 'json',
});Limen applies security controls before data reaches storage.
PII Detection. Configurable patterns detect and block or redact PII (emails, phone numbers, SSNs, credit cards) before claims are stored. Detections are logged. Sensitivity levels control enforcement.
Injection Defense. Claim content is sanitized against prompt injection patterns. SQL injection via FTS5 queries is neutralized. Subject/predicate formats are validated against URI patterns.
Consent Enforcement. CRUD for data subject consent records with enforcement on claim assertion. When security.consent.required is true, claims about entities are blocked without active consent. Consent status (active, revoked, expired) is computed on read. All mutations produce audit trail entries.
Classification Filtering. Claims are classified at assertion time (unrestricted, internal, confidential, restricted, critical). Query and search results are filtered by the requesting agent's clearance level, derived from trust progression (untrusted=0, probationary=1, trusted=2, admin=4).
Key Rotation. Atomic re-encryption of all vault entries with a new master key. Transactional — partial failure rolls back completely. Audit trail records every rotation event.
Poisoning Defense. The maxAutoConfidence ceiling (default 0.7) prevents any programmatic source from laundering high-confidence claims. Only human-verified claims via evidence_path grounding can exceed the ceiling.
// Consent management
limen.consent.register({
dataSubjectId: 'user:alice',
scope: 'knowledge-storage',
basis: 'consent',
expiresAt: '2027-01-01T00:00:00Z',
});
const consent = limen.consent.check('user:alice', 'knowledge-storage');
// consent.value.status === 'active' | 'revoked' | 'expired'Semantic search, hybrid search, and duplicate detection. Requires the optional sqlite-vec dependency.
npm install sqlite-vec
import { createLimen } from 'limen-ai';
const limen = await createLimen({
vector: {
provider: yourEmbeddingProvider, // (query: string) => Promise<Float32Array>
dimensions: 384,
},
});
// Embed pending claims (call after batch inserts)
await limen.embedPending();
// Semantic search — finds conceptually similar beliefs
const results = await limen.semanticSearch('food preferences');
// Hybrid search — combines FTS5 keyword + vector similarity
const hybrid = limen.search('Thai food', { mode: 'hybrid' });
// Duplicate detection before storing
const dup = await limen.checkDuplicate(
'entity:user:alice', 'preference.food', 'loves Thai cuisine'
);
if (dup.ok && dup.value.isDuplicate) {
console.log(dup.value.similarClaimId); // existing claim
console.log(dup.value.similarity); // 0.0-1.0
}
// Embedding statistics
const stats = limen.embeddingStats();
if (stats.ok) {
console.log(stats.value.totalEmbedded);
console.log(stats.value.pendingCount);
}Without sqlite-vec, semanticSearch() falls back to full-text search. The core engine functions identically with or without vector capabilities.
When a parent claim is retracted or decays below threshold, derived claims can be automatically retracted in a cascade. This is opt-in.
const limen = await createLimen({
selfHealing: {
enabled: true,
autoRetractThreshold: 0.1, // retract derived claims when parent drops below this
maxCascadeDepth: 5, // prevent unbounded recursion
},
});
// If "entity:source:data" is retracted...
limen.forget(sourceClaimId, 'incorrect');
// ...all claims with derived_from relationships to it
// are auto-retracted if their effective confidence < 0.1Disabled by default. Existing applications upgrading from earlier versions see no behavior changes unless explicitly configured.
All fields optional. createLimen() with no arguments runs in zero-config mode.
| Option | Type | Default | Description |
|---|---|---|---|
dataDir |
string |
OS temp dir | Where all engine state lives |
masterKey |
Buffer |
Auto-generated | AES-256-GCM encryption key (>= 32 bytes) |
providers |
ProviderConfig[] |
Auto-detected | LLM provider configurations |
tenancy.mode |
'single' | 'multi' |
'single' |
Tenancy model |
tenancy.isolation |
'row-level' | 'database' |
'row-level' |
Multi-tenant isolation strategy |
cognitive.maxAutoConfidence |
number |
0.7 |
Confidence ceiling for auto-extracted claims |
autoConflict |
boolean |
true |
Structural conflict detection on assertion |
selfHealing.enabled |
boolean |
false |
Auto-retraction cascades (opt-in) |
selfHealing.autoRetractThreshold |
number |
0.1 |
Effective confidence floor for derived claims |
selfHealing.maxCascadeDepth |
number |
5 |
Maximum cascade recursion depth |
vector.provider |
EmbeddingProvider |
undefined |
Embedding function for semantic search |
vector.dimensions |
number |
undefined |
Embedding vector dimensions |
requireRbac |
boolean |
false |
Enforce RBAC + classification filtering |
security.consent.required |
boolean |
false |
Enforce consent check on claim assertion |
maintenance.retentionEnabled |
boolean |
true |
Automatic retention scheduling |
maintenance.retentionIntervalMs |
number |
86400000 |
Retention check interval (24h default) |
cognitive.autoSuggestConnections |
boolean |
true |
Auto-suggest connections on claim assertion |
defaultTimeoutMs |
number |
60000 |
Chat/infer timeout (ms) |
rateLimiting.apiCallsPerMinute |
number |
100 |
API rate limit |
failoverPolicy |
'degrade' | 'allow-overdraft' | 'block' |
'degrade' |
Provider failure behavior |
logger |
(event) => void |
No-op | Structured logging callback |
Limen includes a full CLI with JSON output for every operation.
npm install -g limen-cli
limen init # initialize database
limen remember --subject entity:user:alice --predicate preference.food --value "loves Thai"
limen recall --subject entity:user:alice
limen search --query "Thai food"
limen forget --claimId <id> --reason incorrect
limen health # knowledge health report
limen consolidate # merge, archive, resolve
limen importance --claimId <id> # 5-factor importance score
limen maintenance-retention # run retention manuallyAll 36 MCP tools have CLI equivalents. Run limen --help for the full list.
Add to ~/.claude/mcp.json:
{
"mcpServers": {
"limen": {
"command": "npx",
"args": ["-y", "limen-mcp"],
"env": {
"LIMEN_DATA_DIR": "/path/to/your/data"
}
}
}
}36 tools available: limen_remember, limen_recall, limen_search, limen_forget, limen_connect, limen_reflect, limen_consolidate, limen_importance, limen_narrative, limen_verify, limen_suggest_connections, limen_replay_verify, limen_consent_register, limen_consent_check, limen_maintenance_retention, limen_governance_erasure, limen_governance_audit_export, and more.
API Surface createLimen(), remember(), recall(), search(), cognitive.*,
governance.*, consent.*, on(), exportData(), importData()
Orchestration Missions, task graphs, budgets, 16 system calls
Substrate LLM gateway, transport engine, worker pool
Kernel SQLite (WAL), audit trail, RBAC, crypto, events
Layers depend downward only. The kernel knows nothing about AI. The API composes everything into a single frozen Limen object via Object.freeze.
4,000+ tests. 134+ invariants across 3 tiers. 16 system calls. 36 MCP tools. 1 production dependency (better-sqlite3). Every state mutation is audited in a hash-chained, append-only trail. RBAC on every operation. AES-256-GCM encryption at rest. Consent enforcement. Classification-filtered retrieval. Automated retention scheduling.
What is proven:
- Every invariant in docs/proof/invariants.md links to a file and line number in the source. CI verifies these references stay fresh.
- 16 system calls, each with interface, implementation, and dual-path test coverage (success + rejection). Evidence: docs/proof/system-calls.md.
- Security model with 8 mechanisms and 25 declared non-protections. Evidence: docs/proof/security-model.md.
- Failure mode defenses with honest accounting. Evidence: docs/proof/failure-modes.md.
What is not:
- Limen is not a vector database. Semantic search requires an external embedding provider and the optional
sqlite-vecdependency. - Limen does not guarantee real-time performance at scale. SQLite with WAL mode is the foundation — appropriate for single-node deployments with thousands to low millions of claims.
- The cognitive engine (consolidation, narrative, importance) uses heuristic algorithms, not ML models. Results are deterministic but approximate.
- Self-healing cascades are opt-in and advisory by design. They retract derived claims but do not rewrite or repair them.
Full trust surface with file-and-line evidence: docs/proof/readiness.md.
Limen depends on better-sqlite3, which requires native C++ compilation.
Windows without Visual Studio Build Tools:
npm install --global windows-build-tools # or install Visual Studio Build Tools manually
npm install limen-aiDocker slim / Alpine Linux (musl):
# Alpine: install build dependencies
RUN apk add --no-cache python3 make g++
RUN npm install limen-ai
# Debian slim: install build-essential
RUN apt-get update && apt-get install -y python3 make g++ && rm -rf /var/lib/apt/lists/*
RUN npm install limen-aiNode.js version: Limen requires Node.js >= 22. Check with node --version.
CI environments (GitHub Actions, etc.):
# GitHub Actions: Node.js 22 is required
- uses: actions/setup-node@v4
with:
node-version: '22'If npm install fails with node-gyp errors, ensure a C++ toolchain is available. On macOS: xcode-select --install. On Linux: apt install build-essential or yum groupinstall "Development Tools".
Built by SolisHQ