limen-ai 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/README.md +262 -232
  3. package/dist/api/agents/trust_progression.d.ts +1 -1
  4. package/dist/api/agents/trust_progression.d.ts.map +1 -1
  5. package/dist/api/agents/trust_progression.js.map +1 -1
  6. package/dist/api/chat/chat_pipeline.d.ts +4 -3
  7. package/dist/api/chat/chat_pipeline.d.ts.map +1 -1
  8. package/dist/api/chat/chat_pipeline.js +17 -6
  9. package/dist/api/chat/chat_pipeline.js.map +1 -1
  10. package/dist/api/data/data_api.d.ts.map +1 -1
  11. package/dist/api/data/data_api.js +10 -2
  12. package/dist/api/data/data_api.js.map +1 -1
  13. package/dist/api/defaults.d.ts +49 -0
  14. package/dist/api/defaults.d.ts.map +1 -0
  15. package/dist/api/defaults.js +180 -0
  16. package/dist/api/defaults.js.map +1 -0
  17. package/dist/api/facades/claim_api_impl.d.ts +29 -0
  18. package/dist/api/facades/claim_api_impl.d.ts.map +1 -0
  19. package/dist/api/facades/claim_api_impl.js +34 -0
  20. package/dist/api/facades/claim_api_impl.js.map +1 -0
  21. package/dist/api/facades/claim_facade.d.ts +7 -6
  22. package/dist/api/facades/claim_facade.d.ts.map +1 -1
  23. package/dist/api/facades/claim_facade.js +5 -5
  24. package/dist/api/facades/claim_facade.js.map +1 -1
  25. package/dist/api/facades/working_memory_api_impl.d.ts +29 -0
  26. package/dist/api/facades/working_memory_api_impl.d.ts.map +1 -0
  27. package/dist/api/facades/working_memory_api_impl.js +34 -0
  28. package/dist/api/facades/working_memory_api_impl.js.map +1 -0
  29. package/dist/api/facades/working_memory_facade.d.ts +7 -6
  30. package/dist/api/facades/working_memory_facade.d.ts.map +1 -1
  31. package/dist/api/facades/working_memory_facade.js +5 -5
  32. package/dist/api/facades/working_memory_facade.js.map +1 -1
  33. package/dist/api/governance/governed_orchestration.d.ts.map +1 -1
  34. package/dist/api/governance/governed_orchestration.js +1 -0
  35. package/dist/api/governance/governed_orchestration.js.map +1 -1
  36. package/dist/api/index.d.ts +4 -3
  37. package/dist/api/index.d.ts.map +1 -1
  38. package/dist/api/index.js +72 -36
  39. package/dist/api/index.js.map +1 -1
  40. package/dist/api/infer/infer_pipeline.d.ts +3 -1
  41. package/dist/api/infer/infer_pipeline.d.ts.map +1 -1
  42. package/dist/api/infer/infer_pipeline.js +18 -3
  43. package/dist/api/infer/infer_pipeline.js.map +1 -1
  44. package/dist/api/interfaces/api.d.ts +15 -4
  45. package/dist/api/interfaces/api.d.ts.map +1 -1
  46. package/dist/api/migration/027_interactions_retention.d.ts +15 -0
  47. package/dist/api/migration/027_interactions_retention.d.ts.map +1 -0
  48. package/dist/api/migration/027_interactions_retention.js +60 -0
  49. package/dist/api/migration/027_interactions_retention.js.map +1 -0
  50. package/dist/api/missions/mission_api.d.ts.map +1 -1
  51. package/dist/api/missions/mission_api.js +12 -5
  52. package/dist/api/missions/mission_api.js.map +1 -1
  53. package/dist/api/observability/metrics.d.ts.map +1 -1
  54. package/dist/api/observability/metrics.js +2 -1
  55. package/dist/api/observability/metrics.js.map +1 -1
  56. package/dist/budget/impl/dba_impl.d.ts +5 -1
  57. package/dist/budget/impl/dba_impl.d.ts.map +1 -1
  58. package/dist/budget/impl/dba_impl.js +13 -8
  59. package/dist/budget/impl/dba_impl.js.map +1 -1
  60. package/dist/claims/store/claim_stores.js +5 -5
  61. package/dist/claims/store/claim_stores.js.map +1 -1
  62. package/dist/governance/stores/governance_stores.d.ts.map +1 -1
  63. package/dist/governance/stores/governance_stores.js +6 -27
  64. package/dist/governance/stores/governance_stores.js.map +1 -1
  65. package/dist/kernel/audit/audit_trail.d.ts.map +1 -1
  66. package/dist/kernel/audit/audit_trail.js +15 -6
  67. package/dist/kernel/audit/audit_trail.js.map +1 -1
  68. package/dist/kernel/crypto/crypto_engine.d.ts +23 -3
  69. package/dist/kernel/crypto/crypto_engine.d.ts.map +1 -1
  70. package/dist/kernel/crypto/crypto_engine.js +79 -31
  71. package/dist/kernel/crypto/crypto_engine.js.map +1 -1
  72. package/dist/kernel/events/event_bus.d.ts +3 -3
  73. package/dist/kernel/events/event_bus.d.ts.map +1 -1
  74. package/dist/kernel/events/event_bus.js +6 -3
  75. package/dist/kernel/events/event_bus.js.map +1 -1
  76. package/dist/kernel/events/webhook_delivery.d.ts +2 -2
  77. package/dist/kernel/events/webhook_delivery.d.ts.map +1 -1
  78. package/dist/kernel/events/webhook_delivery.js +19 -17
  79. package/dist/kernel/events/webhook_delivery.js.map +1 -1
  80. package/dist/kernel/namespace/namespace_enforcer.js +1 -1
  81. package/dist/kernel/namespace/namespace_enforcer.js.map +1 -1
  82. package/dist/kernel/retention/retention_scheduler.d.ts.map +1 -1
  83. package/dist/kernel/retention/retention_scheduler.js +9 -0
  84. package/dist/kernel/retention/retention_scheduler.js.map +1 -1
  85. package/dist/orchestration/budget/budget_governance.d.ts +3 -1
  86. package/dist/orchestration/budget/budget_governance.d.ts.map +1 -1
  87. package/dist/orchestration/budget/budget_governance.js +31 -17
  88. package/dist/orchestration/budget/budget_governance.js.map +1 -1
  89. package/dist/orchestration/checkpoints/checkpoint_coordinator.d.ts +3 -1
  90. package/dist/orchestration/checkpoints/checkpoint_coordinator.d.ts.map +1 -1
  91. package/dist/orchestration/checkpoints/checkpoint_coordinator.js +34 -31
  92. package/dist/orchestration/checkpoints/checkpoint_coordinator.js.map +1 -1
  93. package/dist/orchestration/index.d.ts +2 -2
  94. package/dist/orchestration/index.d.ts.map +1 -1
  95. package/dist/orchestration/index.js +28 -8
  96. package/dist/orchestration/index.js.map +1 -1
  97. package/dist/orchestration/interfaces/orchestration.d.ts +3 -0
  98. package/dist/orchestration/interfaces/orchestration.d.ts.map +1 -1
  99. package/dist/orchestration/interfaces/orchestration.js.map +1 -1
  100. package/dist/orchestration/missions/mission_recovery.d.ts +4 -3
  101. package/dist/orchestration/missions/mission_recovery.d.ts.map +1 -1
  102. package/dist/orchestration/missions/mission_recovery.js +22 -82
  103. package/dist/orchestration/missions/mission_recovery.js.map +1 -1
  104. package/dist/orchestration/missions/mission_store.d.ts.map +1 -1
  105. package/dist/orchestration/missions/mission_store.js +11 -2
  106. package/dist/orchestration/missions/mission_store.js.map +1 -1
  107. package/dist/orchestration/syscalls/propose_task_execution.d.ts +2 -1
  108. package/dist/orchestration/syscalls/propose_task_execution.d.ts.map +1 -1
  109. package/dist/orchestration/syscalls/propose_task_execution.js +9 -7
  110. package/dist/orchestration/syscalls/propose_task_execution.js.map +1 -1
  111. package/dist/orchestration/syscalls/request_budget.d.ts +2 -1
  112. package/dist/orchestration/syscalls/request_budget.d.ts.map +1 -1
  113. package/dist/orchestration/syscalls/request_budget.js +3 -2
  114. package/dist/orchestration/syscalls/request_budget.js.map +1 -1
  115. package/dist/orchestration/syscalls/submit_result.d.ts +2 -1
  116. package/dist/orchestration/syscalls/submit_result.d.ts.map +1 -1
  117. package/dist/orchestration/syscalls/submit_result.js +6 -4
  118. package/dist/orchestration/syscalls/submit_result.js.map +1 -1
  119. package/dist/orchestration/tasks/task_graph.d.ts +2 -1
  120. package/dist/orchestration/tasks/task_graph.d.ts.map +1 -1
  121. package/dist/orchestration/tasks/task_graph.js +39 -4
  122. package/dist/orchestration/tasks/task_graph.js.map +1 -1
  123. package/dist/orchestration/transitions/transition_service.d.ts +68 -0
  124. package/dist/orchestration/transitions/transition_service.d.ts.map +1 -0
  125. package/dist/orchestration/transitions/transition_service.js +427 -0
  126. package/dist/orchestration/transitions/transition_service.js.map +1 -0
  127. package/dist/substrate/gateway/llm_gateway.d.ts +2 -2
  128. package/dist/substrate/gateway/llm_gateway.d.ts.map +1 -1
  129. package/dist/substrate/gateway/llm_gateway.js +13 -8
  130. package/dist/substrate/gateway/llm_gateway.js.map +1 -1
  131. package/dist/substrate/index.d.ts +2 -2
  132. package/dist/substrate/index.d.ts.map +1 -1
  133. package/dist/substrate/replay/replay_engine.d.ts +3 -2
  134. package/dist/substrate/replay/replay_engine.d.ts.map +1 -1
  135. package/dist/substrate/replay/replay_engine.js +3 -2
  136. package/dist/substrate/replay/replay_engine.js.map +1 -1
  137. package/dist/substrate/scheduler/task_scheduler.d.ts.map +1 -1
  138. package/dist/substrate/scheduler/task_scheduler.js +6 -6
  139. package/dist/substrate/scheduler/task_scheduler.js.map +1 -1
  140. package/dist/substrate/transport/adapters/anthropic_adapter.d.ts.map +1 -1
  141. package/dist/substrate/transport/adapters/anthropic_adapter.js +6 -0
  142. package/dist/substrate/transport/adapters/anthropic_adapter.js.map +1 -1
  143. package/dist/substrate/transport/transport_engine.d.ts.map +1 -1
  144. package/dist/substrate/transport/transport_engine.js +9 -3
  145. package/dist/substrate/transport/transport_engine.js.map +1 -1
  146. package/dist/working-memory/stores/wmp_stores.d.ts.map +1 -1
  147. package/dist/working-memory/stores/wmp_stores.js +13 -1
  148. package/dist/working-memory/stores/wmp_stores.js.map +1 -1
  149. package/package.json +7 -1
package/CHANGELOG.md CHANGED
@@ -5,13 +5,39 @@ All notable changes to Limen are documented in this file.
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
  Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.0] - 2026-03-24
9
+
10
+ ### Added
11
+ - Zero-config `createLimen()` — auto-detects LLM providers from environment variables, auto-generates dev master key, uses OS temp dir for storage
12
+ - Provider auto-detection for Anthropic, OpenAI, Gemini, Groq, Mistral, and Ollama from environment variables
13
+ - Proof pack: CI-governed evidence index at `docs/proof/` with 530 verified file:line references
14
+ - `system-calls.md` — 16 system calls, all Verified with interface, implementation, and A21 test coverage
15
+ - `invariants.md` — 134 invariants across 3 tiers (114 Verified, 1 Measured, 4 Implemented, 11 Declared, 4 Out of Scope)
16
+ - `failure-modes.md` — honest accounting: 21 traceable defenses of 45 specified (12 Verified, 8 Implemented, 1 Declared)
17
+ - `security-model.md` — 8 security mechanisms with evidence bindings and 25 declared non-protections
18
+ - `readiness.md` — capstone trust surface with explicit non-proof boundaries
19
+ - `scripts/verify-proof-pack.ts` — CI enforcement script verifying proof pack file:line references stay fresh
20
+ - Eight progressive examples (01-hello through 08-governance-visible) replacing five original examples
21
+ - Demo vs Production getting-started split in `docs/getting-started.md`
22
+
23
+ ### Changed
24
+ - `createLimen()` config parameter is now optional (zero-config when omitted)
25
+ - README restructured: zero-config hero section, "What's Running Underneath" reveal, Trust Surface with proof pack links
26
+ - Comparison table dated (March 2026) with narrowed claims and ecosystem context
27
+ - Invariant count corrected from 99 to 134 per proof pack evidence
28
+ - Examples 04 and 08 updated to use zero-config pattern
29
+ - CI workflow updated with proof pack freshness check
30
+
31
+ ### Fixed
32
+ - Examples 04 (multi-provider) and 08 (governance-visible) no longer require explicit masterKey
33
+
8
34
  ## [1.0.0] - 2026-03-23
9
35
 
10
36
  ### Added
11
37
  - Cognitive Operating System: deterministic infrastructure hosting stochastic cognition
12
38
  - Four-layer architecture: Kernel (L1), Substrate (L1.5), Orchestration (L2), API (L4)
13
39
  - 16 system calls defining the governance boundary between agents and infrastructure
14
- - 99 formally verified invariants enforced by 3,100+ tests
40
+ - 99 continuously enforced invariants backed by 3,200+ tests
15
41
  - SQLite foundation with WAL mode, ACID transactions, single dependency (`better-sqlite3`)
16
42
  - Append-only, hash-chained audit trail recording every state mutation
17
43
  - RBAC engine with role hierarchy and per-operation authorization
package/README.md CHANGED
@@ -15,86 +15,66 @@
15
15
 
16
16
  # Limen
17
17
 
18
- Your AI agents don't have a reliability problem. They have an infrastructure problem.
18
+ ```typescript
19
+ import { createLimen } from 'limen-ai';
20
+ const limen = await createLimen();
21
+ const response = limen.chat('What is quantum computing?');
22
+ console.log(await response.text);
23
+ await limen.shutdown();
24
+ ```
19
25
 
20
- Limen is a Cognitive Operating System. It does for AI agents what a kernel does for processes: isolation, resource control, lifecycle management, and deterministic behavior contracts. One production dependency. 16 system calls. 99 formally verified invariants. Every execution path typed and tested.
26
+ ```bash
27
+ ANTHROPIC_API_KEY=sk-ant-... npx tsx examples/01-hello.ts
28
+ ```
21
29
 
22
- The name is Latin for *threshold* -- the architectural boundary where deterministic infrastructure meets stochastic cognition.
30
+ Set an API key environment variable. That is the only setup. `createLimen()` auto-detects your provider, generates a dev encryption key, and provisions a local SQLite database. Three lines to chat.
23
31
 
24
32
  ---
25
33
 
26
- ## Why Limen Exists
34
+ ## What's Running Underneath
27
35
 
28
- Every serious AI application eventually builds the same infrastructure: conversation state management, token budget enforcement, provider failover, audit trails, structured output with retry, agent lifecycle control. Teams build these as ad-hoc layers on top of LLM SDKs, then spend months debugging the interactions between them.
36
+ That three-line example is not a thin wrapper around an API call. When you ran it, the engine:
29
37
 
30
- Limen replaces that entire stack with a single engine. Provider communication happens through raw HTTP -- no SDKs, no transitive dependency trees, no version conflicts. State lives in a local SQLite database you control. Every mutation is audited atomically. Every agent operates within enforced budgets and capability boundaries.
38
+ - **Created an AES-256-GCM encrypted SQLite database** with WAL mode and ACID transactions
39
+ - **Recorded an append-only, hash-chained audit entry** for every state mutation
40
+ - **Enforced RBAC authorization** on the operation
41
+ - **Tracked token usage and cost** against a budget ledger
42
+ - **Ran the request through circuit breakers and stall detection** over raw HTTP (no provider SDK)
43
+ - **Isolated your data by tenant** (single-tenant by default, multi-tenant by configuration)
31
44
 
32
- The result: AI infrastructure with the reliability guarantees of a database engine and the operational simplicity of a single `npm install`.
45
+ None of this required configuration. The governance layer runs whether you configure it or not. The difference between the three-line demo and a production deployment is explicit configuration -- not a different code path.
33
46
 
34
47
  ---
35
48
 
36
- ## How Limen Compares
37
-
38
- | | Limen | Vercel AI SDK | LangChain.js |
39
- |---|---|---|---|
40
- | **Production deps** | 1 | ~50+ | ~50+ |
41
- | **Provider SDKs required** | No (raw HTTP) | Yes (`@ai-sdk/*`) | Yes (`@langchain/*`) |
42
- | **Built-in persistence** | SQLite (WAL, local) | No | Optional (external DB) |
43
- | **Audit trail** | Hash-chained, append-only | No | LangSmith (paid SaaS) |
44
- | **Budget enforcement** | Per-mission token budgets | No | No |
45
- | **Agent governance** | 16 system calls, RBAC | No | No |
46
- | **Multi-tenant isolation** | Row-level or database-level | No | No |
47
- | **Encryption at rest** | AES-256-GCM | No | No |
48
- | **Streaming** | Yes (stall detection, timeouts) | Yes | Yes |
49
- | **Structured output** | JSON Schema + auto-retry | Zod schemas | Output parsers |
50
- | **Deterministic replay** | Yes (from recorded LLM outputs) | No | No |
51
-
52
- Limen is not a wrapper around LLM APIs. It is an operating system for AI agents. If you need a lightweight way to call an LLM, the Vercel AI SDK is excellent. If you need your agents to operate within enforced boundaries with full auditability, that is what Limen was built for.
49
+ ## Why Limen Exists
53
50
 
54
- ---
51
+ Every serious AI application eventually builds the same infrastructure: conversation state management, token budget enforcement, provider failover, audit trails, structured output with retry, agent lifecycle control. Teams build these as ad-hoc layers on top of LLM SDKs, then spend months debugging the interactions between them.
55
52
 
56
- ## Install
53
+ Limen replaces that entire stack with a single engine. Provider communication happens through raw HTTP -- no SDKs, no transitive dependency trees, no version conflicts. State lives in a local SQLite database you control. Every mutation is audited atomically. Every agent operates within enforced budgets and capability boundaries.
57
54
 
58
- ```bash
59
- npm install limen-ai
60
- ```
55
+ The result: AI infrastructure with the reliability guarantees of a database engine and the operational simplicity of a single `npm install`.
61
56
 
62
- Requires Node.js >= 22. Single production dependency: `better-sqlite3`.
57
+ The name is Latin for *threshold* -- the architectural boundary where deterministic infrastructure meets stochastic cognition.
63
58
 
64
59
  ---
65
60
 
66
- ## Quick Start
61
+ ## Progressive Examples
67
62
 
68
- ```typescript
69
- import { createLimen } from 'limen-ai';
70
- import crypto from 'node:crypto';
63
+ ### Streaming
71
64
 
72
- const limen = await createLimen({
73
- dataDir: './my-app-data',
74
- masterKey: crypto.randomBytes(32),
75
- providers: [{
76
- type: 'anthropic',
77
- baseUrl: 'https://api.anthropic.com',
78
- models: ['claude-sonnet-4-20250514'],
79
- apiKeyEnvVar: 'ANTHROPIC_API_KEY',
80
- }],
81
- });
82
-
83
- // Chat -- returns synchronously, fields resolve async
84
- const response = limen.chat('What are the key trends in renewable energy?');
85
- const text = await response.text;
86
- const metadata = await response.metadata;
87
- console.log(text);
88
- console.log(`${metadata.tokens.input} in / ${metadata.tokens.output} out`);
89
-
90
- // Stream
91
- const streamed = limen.chat('Explain quantum computing', { stream: true });
92
- for await (const chunk of streamed.stream) {
65
+ ```typescript
66
+ const result = limen.chat('Explain how neural networks learn', { stream: true });
67
+ for await (const chunk of result.stream) {
93
68
  if (chunk.type === 'content_delta') process.stdout.write(chunk.delta);
94
69
  }
70
+ ```
95
71
 
96
- // Structured output with schema validation and auto-retry
97
- const analysis = await limen.infer({
72
+ Streaming and non-streaming produce identical final results (Invariant I-26).
73
+
74
+ ### Structured Output
75
+
76
+ ```typescript
77
+ const result = await limen.infer({
98
78
  input: 'List the top 3 programming languages by popularity',
99
79
  outputSchema: {
100
80
  type: 'object',
@@ -103,10 +83,7 @@ const analysis = await limen.infer({
103
83
  type: 'array',
104
84
  items: {
105
85
  type: 'object',
106
- properties: {
107
- name: { type: 'string' },
108
- reason: { type: 'string' },
109
- },
86
+ properties: { name: { type: 'string' }, reason: { type: 'string' } },
110
87
  required: ['name', 'reason'],
111
88
  },
112
89
  },
@@ -115,32 +92,76 @@ const analysis = await limen.infer({
115
92
  },
116
93
  maxRetries: 2,
117
94
  });
118
- console.log(analysis.data); // Typed, validated, guaranteed to match schema
95
+ console.log(result.data); // Typed, validated, guaranteed to match schema
96
+ ```
119
97
 
120
- // Cleanup
121
- await limen.shutdown();
98
+ ### Sessions
99
+
100
+ ```typescript
101
+ const session = await limen.session({
102
+ agentName: 'tutor',
103
+ user: { id: 'student-1', role: 'learner' },
104
+ });
105
+
106
+ session.chat('What is photosynthesis?');
107
+ session.chat('What role does chlorophyll play in it?'); // Sees prior context
108
+ session.chat('Summarize what we discussed');
109
+
110
+ const branch = await session.fork(2); // Fork at turn 2
111
+ branch.chat('What about artificial photosynthesis?');
112
+
113
+ await branch.close();
114
+ await session.close();
122
115
  ```
123
116
 
124
- `createLimen()` returns a deeply frozen object. Every method is immutable. Two calls produce fully independent instances -- no shared state, no cross-contamination.
117
+ Context window is managed automatically -- including summarization when the window fills.
125
118
 
126
- > **Important: Master Key Management**
127
- >
128
- > The `masterKey` is used for AES-256-GCM encryption at rest. If you lose the key, encrypted data in the SQLite database becomes permanently unreadable. Do **not** use `crypto.randomBytes(32)` in production — that generates a new key on every startup.
129
- >
130
- > ```bash
131
- > # Generate once, store securely
132
- > node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" > master.key
133
- > chmod 600 master.key
134
- > ```
135
- >
136
- > ```typescript
137
- > // Load from file or environment
138
- > const masterKey = Buffer.from(process.env.LIMEN_MASTER_KEY!, 'hex');
139
- > // or
140
- > const masterKey = fs.readFileSync('./master.key', 'utf8').trim();
141
- > ```
142
- >
143
- > Keep the key out of version control. Rotate by re-encrypting: create a new engine instance with the new key and migrate data through the public API.
119
+ ### Missions
120
+
121
+ ```typescript
122
+ await limen.agents.register({
123
+ name: 'researcher',
124
+ capabilities: ['web', 'data'],
125
+ });
126
+
127
+ const mission = await limen.missions.create({
128
+ agent: 'researcher',
129
+ objective: 'Analyze the renewable energy market in Europe',
130
+ constraints: {
131
+ tokenBudget: 50_000,
132
+ deadline: new Date(Date.now() + 3_600_000).toISOString(),
133
+ capabilities: ['web', 'data'],
134
+ maxTasks: 10,
135
+ },
136
+ deliverables: [
137
+ { type: 'report', name: 'market-analysis' },
138
+ ],
139
+ });
140
+
141
+ mission.on('checkpoint', (payload) => console.log('Checkpoint:', payload));
142
+ const result = await mission.wait();
143
+ ```
144
+
145
+ Missions are budget-governed, deadline-enforced, and operate exclusively through the 16 system calls. The lifecycle transitions through: `CREATED` -> `PLANNING` -> `EXECUTING` -> `REVIEWING` -> `COMPLETED`.
146
+
147
+ See [`examples/`](examples/) for full runnable code.
148
+
149
+ ---
150
+
151
+ ## Trust Surface
152
+
153
+ Every claim in this section links to a proof document with file-and-line-number evidence. Every gap is declared.
154
+
155
+ | Claim | Status | Proof |
156
+ |---|---|---|
157
+ | 16 system calls | All Verified | [system-calls.md](docs/proof/system-calls.md) |
158
+ | 134 invariants across 3 tiers | 114 Verified, 1 Measured, 4 Implemented, 11 Declared, 4 Out of Scope | [invariants.md](docs/proof/invariants.md) |
159
+ | 21 failure mode defenses (of 45 specified) | 12 Verified, 8 Implemented, 1 Declared -- [24 have zero code presence](docs/proof/failure-modes.md) | [failure-modes.md](docs/proof/failure-modes.md) |
160
+ | 8 security mechanisms | All Verified at mechanism level -- [25 declared non-protections](docs/proof/security-model.md) | [security-model.md](docs/proof/security-model.md) |
161
+
162
+ Full evidence summary, including an explicit "What Is NOT Proven" section: [readiness.md](docs/proof/readiness.md).
163
+
164
+ Evidence classes: **Verified** = source enforcement + meaningful tests. **Implemented** = source enforcement, weak/no tests. **Measured** = quantitative measurement with threshold. **Declared** = spec/documentation only. **Out of Scope** = not applicable to current version.
144
165
 
145
166
  ---
146
167
 
@@ -174,6 +195,73 @@ Limen is built as four layers, each with a strict dependency direction: down onl
174
195
 
175
196
  ---
176
197
 
198
+ ## Providers
199
+
200
+ Six providers, zero SDKs. All communication is raw HTTP via `fetch`.
201
+
202
+ | Provider | Adapter Factory | Streaming | Auth |
203
+ |---|---|---|---|
204
+ | **Anthropic** | `createAnthropicAdapter(apiKey, baseUrl?)` | SSE | Bearer token |
205
+ | **OpenAI** | `createOpenAIAdapter(apiKey, baseUrl?)` | SSE | Bearer token |
206
+ | **Google Gemini** | `createGeminiAdapter(apiKey, baseUrl?)` | SSE | Query param |
207
+ | **Groq** | `createGroqAdapter(apiKey, baseUrl?)` | SSE | Bearer token |
208
+ | **Mistral** | `createMistralAdapter(apiKey, baseUrl?)` | SSE | Bearer token |
209
+ | **Ollama** | `createOllamaAdapter(baseUrl?)` | NDJSON | None (local) |
210
+
211
+ Each provider also has a `*FromEnv()` variant that reads the API key from the environment (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, `GROQ_API_KEY`, `MISTRAL_API_KEY`). Ollama runs locally and requires no authentication.
212
+
213
+ Configure multiple providers at the engine level:
214
+
215
+ ```typescript
216
+ const limen = await createLimen({
217
+ dataDir: './data',
218
+ masterKey: Buffer.from(process.env.LIMEN_MASTER_KEY!, 'hex'),
219
+ providers: [
220
+ {
221
+ type: 'anthropic',
222
+ baseUrl: 'https://api.anthropic.com',
223
+ models: ['claude-sonnet-4-20250514'],
224
+ apiKeyEnvVar: 'ANTHROPIC_API_KEY',
225
+ maxConcurrent: 5,
226
+ },
227
+ {
228
+ type: 'openai',
229
+ baseUrl: 'https://api.openai.com',
230
+ models: ['gpt-4o'],
231
+ apiKeyEnvVar: 'OPENAI_API_KEY',
232
+ },
233
+ {
234
+ type: 'ollama',
235
+ baseUrl: 'http://localhost:11434',
236
+ models: ['llama3.2'],
237
+ },
238
+ ],
239
+ });
240
+ ```
241
+
242
+ ---
243
+
244
+ ## How Limen Compares
245
+
246
+ *As of March 2026. Limen is a new project with near-zero community adoption. Vercel AI SDK and LangChain are mature ecosystems with large communities, extensive integrations, and production deployment track records that Limen does not have.*
247
+
248
+ | | Limen | Vercel AI SDK | LangChain.js |
249
+ |---|---|---|---|
250
+ | **Production deps** | 1 | ~50+ | ~50+ |
251
+ | **Provider communication** | Raw HTTP (no provider SDKs) | Provider SDK packages (`@ai-sdk/*`) | Provider SDK packages (`@langchain/*`) |
252
+ | **Built-in persistence** | SQLite (WAL, local) | No | Optional (external DB) |
253
+ | **Audit trail** | Hash-chained, append-only | No | LangSmith (paid SaaS) |
254
+ | **Budget enforcement** | Per-mission token budgets | No | No |
255
+ | **Agent governance** | 16 system calls, RBAC | No | No |
256
+ | **Multi-tenant isolation** | Row-level or database-level | No | No |
257
+ | **Encryption at rest** | AES-256-GCM (per-field vault) | No | No |
258
+ | **Streaming** | SSE/NDJSON with stall detection and timeouts | SSE | SSE |
259
+ | **Structured output** | JSON Schema + auto-retry | Zod schemas | Output parsers |
260
+
261
+ Limen occupies a different architectural position than these tools. Vercel AI SDK is an excellent lightweight interface for LLM communication. LangChain provides a broad ecosystem of integrations, agents, and retrieval patterns. Limen is an operating system for agent governance -- it enforces boundaries, tracks budgets, audits mutations, and isolates tenants. If your primary need is calling an LLM or composing a retrieval pipeline, those tools are more appropriate. If your primary need is enforced governance over agent behavior with full auditability, that is what Limen was built for.
262
+
263
+ ---
264
+
177
265
  ## Three Export Paths
178
266
 
179
267
  Limen ships three independent entry points. Use the full engine, the reference agent, or the transport layer alone.
@@ -204,7 +292,7 @@ const result = await agent.runMission({
204
292
  objective: 'Analyze competitive landscape for drone delivery in Southeast Asia',
205
293
  constraints: {
206
294
  tokenBudget: 50_000,
207
- deadline: '2024-12-31T23:59:59Z',
295
+ deadline: '2026-12-31T23:59:59Z',
208
296
  capabilities: ['web', 'data'],
209
297
  },
210
298
  });
@@ -251,125 +339,11 @@ engine.shutdown(); // Aborts in-flight, rejects new requests
251
339
 
252
340
  ---
253
341
 
254
- ## Providers
255
-
256
- Six providers, zero SDKs. All communication is raw HTTP via `fetch`.
257
-
258
- | Provider | Adapter Factory | Streaming | Auth |
259
- |---|---|---|---|
260
- | **Anthropic** | `createAnthropicAdapter(apiKey, baseUrl?)` | SSE | Bearer token |
261
- | **OpenAI** | `createOpenAIAdapter(apiKey, baseUrl?)` | SSE | Bearer token |
262
- | **Google Gemini** | `createGeminiAdapter(apiKey, baseUrl?)` | SSE | Query param |
263
- | **Groq** | `createGroqAdapter(apiKey, baseUrl?)` | SSE | Bearer token |
264
- | **Mistral** | `createMistralAdapter(apiKey, baseUrl?)` | SSE | Bearer token |
265
- | **Ollama** | `createOllamaAdapter(baseUrl?)` | NDJSON | None (local) |
266
-
267
- Each provider also has a `*FromEnv()` variant that reads the API key from the environment (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, `GROQ_API_KEY`, `MISTRAL_API_KEY`). Ollama runs locally and requires no authentication.
268
-
269
- Configure providers at the engine level:
270
-
271
- ```typescript
272
- const limen = await createLimen({
273
- dataDir: './data',
274
- masterKey: crypto.randomBytes(32),
275
- providers: [
276
- {
277
- type: 'anthropic',
278
- baseUrl: 'https://api.anthropic.com',
279
- models: ['claude-sonnet-4-20250514'],
280
- apiKeyEnvVar: 'ANTHROPIC_API_KEY',
281
- maxConcurrent: 5,
282
- },
283
- {
284
- type: 'openai',
285
- baseUrl: 'https://api.openai.com',
286
- models: ['gpt-4o'],
287
- apiKeyEnvVar: 'OPENAI_API_KEY',
288
- },
289
- {
290
- type: 'ollama',
291
- baseUrl: 'http://localhost:11434',
292
- models: ['llama3.2'],
293
- },
294
- ],
295
- });
296
- ```
297
-
298
- ---
299
-
300
- ## Sessions and Conversations
301
-
302
- Sessions bind a conversation to an agent and tenant context. Within a session, conversation history is maintained, turns are recorded, and the context window is managed automatically -- including summarization when the window fills.
303
-
304
- ```typescript
305
- const session = await limen.session({
306
- agentName: 'researcher',
307
- tenantId: 'tenant-1' as TenantId,
308
- user: { id: 'user-42', role: 'analyst' },
309
- });
310
-
311
- // Chat within session context
312
- const r1 = session.chat('What were last quarter earnings?');
313
- const r2 = session.chat('Compare that to the previous year');
314
-
315
- // Structured inference within the same conversation
316
- const summary = await session.infer({
317
- input: 'Summarize our conversation so far',
318
- outputSchema: SummarySchema,
319
- });
320
-
321
- // Fork conversation at a specific turn
322
- const branch = await session.fork(3);
323
-
324
- // Review history
325
- const turns = await session.history();
326
-
327
- await session.close();
328
- ```
329
-
330
- ---
331
-
332
- ## Autonomous Missions
333
-
334
- Missions are how agents do complex, multi-step work within enforced boundaries. An agent proposes an objective with a token budget and deadline. The system validates the proposal, and the agent then works through a cycle of planning (task graphs), execution, artifact creation, checkpoints, and result submission -- all through the 16 system calls.
335
-
336
- ```typescript
337
- const mission = await limen.missions.create({
338
- agent: 'researcher',
339
- objective: 'Produce a competitive analysis report',
340
- constraints: {
341
- tokenBudget: 100_000,
342
- deadline: '2024-12-31T23:59:59Z',
343
- capabilities: ['web', 'data', 'code'],
344
- maxTasks: 20,
345
- },
346
- deliverables: [
347
- { type: 'report', name: 'competitive-analysis' },
348
- { type: 'data', name: 'market-data' },
349
- ],
350
- });
351
-
352
- // Monitor
353
- mission.on('checkpoint', (payload) => {
354
- console.log('Checkpoint:', payload);
355
- });
356
-
357
- // Wait for completion
358
- const result = await mission.wait();
359
- console.log(result.summary);
360
- console.log(`Confidence: ${result.confidence}`);
361
- console.log(`Tokens used: ${result.resourcesConsumed.tokens}`);
362
- ```
363
-
364
- The mission lifecycle transitions through: `CREATED` -> `PLANNING` -> `EXECUTING` -> `REVIEWING` -> `COMPLETED`. At any point, a mission can be paused, resumed, or cancelled. Budget enforcement is continuous -- if a mission exceeds its allocation, it is blocked until more budget is requested and approved.
365
-
366
- ---
367
-
368
342
  ## The 16 System Calls
369
343
 
370
344
  Every agent interaction with the engine passes through exactly 16 system calls. This is the governance boundary. Agents propose; the system validates and executes.
371
345
 
372
- **Orchestration** mission lifecycle and task governance:
346
+ **Orchestration** -- mission lifecycle and task governance:
373
347
 
374
348
  | # | Call | What It Does |
375
349
  |---|---|---|
@@ -384,7 +358,7 @@ Every agent interaction with the engine passes through exactly 16 system calls.
384
358
  | SC-9 | `submit_result` | Deliver final results with confidence score |
385
359
  | SC-10 | `respond_checkpoint` | Answer a system checkpoint with assessment |
386
360
 
387
- **Claim Protocol** structured knowledge with provenance:
361
+ **Claim Protocol** -- structured knowledge with provenance:
388
362
 
389
363
  | # | Call | What It Does |
390
364
  |---|---|---|
@@ -392,7 +366,7 @@ Every agent interaction with the engine passes through exactly 16 system calls.
392
366
  | SC-12 | `relate_claims` | Create typed relationships between claims |
393
367
  | SC-13 | `query_claims` | Query claims by subject, predicate, mission, or artifact |
394
368
 
395
- **Working Memory** task-scoped ephemeral state:
369
+ **Working Memory** -- task-scoped ephemeral state:
396
370
 
397
371
  | # | Call | What It Does |
398
372
  |---|---|---|
@@ -404,9 +378,92 @@ An agent cannot bypass these calls. It cannot write to the database, emit lifecy
404
378
 
405
379
  ---
406
380
 
407
- ## The Invariant System
381
+ ## Configuration Reference
382
+
383
+ ```typescript
384
+ interface LimenConfig {
385
+ dataDir: string; // Where all engine state lives
386
+ masterKey: Buffer; // >= 32 bytes, for AES-256-GCM encryption
387
+ providers?: ProviderConfig[]; // LLM provider configurations
388
+ tenancy?: {
389
+ mode: 'single' | 'multi'; // Default: 'single'
390
+ isolation?: 'row-level' | 'database'; // Multi-tenant isolation strategy
391
+ };
392
+ substrate?: {
393
+ maxWorkers?: number; // Worker pool size (default: 4)
394
+ schedulerPolicy?: 'deadline' | 'fair-share' | 'budget-aware';
395
+ };
396
+ offline?: { // Offline/disconnected operation (S30)
397
+ embeddings?: boolean; // Enable local embedding cache
398
+ queueSize?: number; // Offline operation queue size
399
+ syncOnReconnect?: boolean; // Auto-sync when connectivity returns
400
+ };
401
+ hitl?: HitlConfig; // Human-in-the-loop defaults
402
+ safety?: { // Safety gate configuration (DL-5)
403
+ enabled?: boolean; // Enable pre/post-safety gates (default: true)
404
+ jitterEnabled?: boolean; // Add jitter to safety timing
405
+ };
406
+ defaultTimeoutMs?: number; // Chat/infer timeout (default: 60000)
407
+ rateLimiting?: {
408
+ apiCallsPerMinute?: number; // Default: 100
409
+ emitEventPerMinute?: number; // Event emission rate limit
410
+ maxConcurrentStreams?: number; // Default: 50
411
+ };
412
+ failoverPolicy?: 'degrade' | 'allow-overdraft' | 'block'; // Provider failure behavior (FM-12)
413
+ logger?: (event: LimenLogEvent) => void; // Structured logging callback
414
+ }
415
+ ```
416
+
417
+ All fields except `dataDir` and `masterKey` are optional. When `createLimen()` is called with no arguments, provider detection, key generation, and data directory are resolved automatically from environment variables. See [getting-started.md](docs/getting-started.md) for details.
418
+
419
+ ---
420
+
421
+ ## Quick Start Paths
422
+
423
+ ### Demo (zero-config)
424
+
425
+ ```bash
426
+ npm install limen-ai
427
+ export ANTHROPIC_API_KEY=sk-ant-... # or OPENAI_API_KEY, GEMINI_API_KEY, etc.
428
+ npx tsx examples/01-hello.ts
429
+ ```
430
+
431
+ Auto-detects provider, generates a dev encryption key (`~/.limen/dev.key`), stores data in OS temp directory. No configuration file needed.
432
+
433
+ ### Production (explicit config)
434
+
435
+ ```typescript
436
+ import { createLimen } from 'limen-ai';
408
437
 
409
- Limen enforces 99 invariants continuously. These are not guidelines or best practices. They are machine-verified properties of the running system, each backed by dedicated tests. A violation of any invariant is a system defect.
438
+ const limen = await createLimen({
439
+ dataDir: '/var/lib/myapp/limen',
440
+ masterKey: Buffer.from(process.env.LIMEN_MASTER_KEY!, 'hex'),
441
+ providers: [{
442
+ type: 'anthropic',
443
+ baseUrl: 'https://api.anthropic.com',
444
+ models: ['claude-sonnet-4-20250514'],
445
+ apiKeyEnvVar: 'ANTHROPIC_API_KEY',
446
+ }],
447
+ tenancy: { mode: 'multi', isolation: 'row-level' },
448
+ });
449
+ ```
450
+
451
+ > **Master key management:** The `masterKey` is used for AES-256-GCM encryption at rest. If you lose the key, encrypted data becomes permanently unreadable. Generate once, store securely:
452
+ >
453
+ > ```bash
454
+ > node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" > master.key
455
+ > chmod 600 master.key
456
+ > ```
457
+ >
458
+ > Keep the key out of version control. Rotate by re-encrypting: create a new engine instance with the new key and migrate data through the public API.
459
+
460
+ See [getting-started.md](docs/getting-started.md) for the full walkthrough.
461
+
462
+ ---
463
+
464
+ ## Invariant System
465
+
466
+ Limen defines 134 invariants across 3 tiers. 114 are Verified (source enforcement with dedicated tests), 1 Measured, and 19 carry lower evidence classes — see the [full evidence index](docs/proof/invariants.md). A violation of any enforced invariant is a system defect.
410
467
 
411
468
  | Invariant | Guarantee |
412
469
  |---|---|
@@ -427,7 +484,7 @@ Limen enforces 99 invariants continuously. These are not guidelines or best prac
427
484
  | **I-26** | Streaming and non-streaming produce identical results |
428
485
  | **I-28** | Pipeline phases execute in fixed, deterministic order |
429
486
 
430
- These invariants are what make AI infrastructure trustworthy. When your agent runs a mission overnight, I-03 guarantees you can audit every action it took. I-17 guarantees it never bypassed the governance layer. I-20 guarantees it didn't spawn an unbounded tree of sub-missions. I-19 guarantees no artifact was silently modified after creation.
487
+ These invariants are what make AI infrastructure trustworthy. When your agent runs a mission overnight, I-03 guarantees you can audit every action it took. I-17 guarantees it never bypassed the governance layer. I-20 guarantees it did not spawn an unbounded tree of sub-missions. I-19 guarantees no artifact was silently modified after creation.
431
488
 
432
489
  ---
433
490
 
@@ -453,33 +510,6 @@ Health distinguishes between three states: **healthy** (all subsystems operation
453
510
 
454
511
  ---
455
512
 
456
- ## Configuration Reference
457
-
458
- ```typescript
459
- interface LimenConfig {
460
- dataDir: string; // Where all engine state lives
461
- masterKey: Buffer; // >= 32 bytes, for AES-256-GCM encryption
462
- providers?: ProviderConfig[]; // LLM provider configurations
463
- tenancy?: {
464
- mode: 'single' | 'multi'; // Default: 'single'
465
- isolation?: 'row-level' | 'database'; // Multi-tenant isolation strategy
466
- };
467
- substrate?: {
468
- maxWorkers?: number; // Worker pool size (default: 4)
469
- schedulerPolicy?: 'deadline' | 'fair-share' | 'budget-aware';
470
- };
471
- hitl?: HitlConfig; // Human-in-the-loop defaults
472
- defaultTimeoutMs?: number; // Chat/infer timeout (default: 60000)
473
- rateLimiting?: {
474
- apiCallsPerMinute?: number; // Default: 100
475
- maxConcurrentStreams?: number; // Default: 50
476
- };
477
- logger?: (event: LimenLogEvent) => void; // Structured logging callback
478
- }
479
- ```
480
-
481
- ---
482
-
483
513
  ## Error Handling
484
514
 
485
515
  Every error thrown by Limen is a `LimenError` with a typed code, a human-readable message, a `retryable` flag, and an optional `cooldownMs` for rate-limited responses.
@@ -512,7 +542,7 @@ npm install
512
542
 
513
543
  npm run typecheck # TypeScript strict mode, zero errors
514
544
  npm run build # Compile to dist/
515
- npm test # Full test suite
545
+ npm test # Full test suite (2,447+ tests)
516
546
  npm run ci # typecheck + build + test
517
547
  ```
518
548
 
@@ -53,7 +53,7 @@ export declare function validatePromotion(fromLevel: TrustLevel, targetLevel: Tr
53
53
  * @param targetAgentId - The agent being promoted
54
54
  * @returns { allowed: true } if not self-promotion, { allowed: false } if blocked
55
55
  */
56
- export declare function checkSelfPromotion(ctxAgentId: AgentId | null | undefined, targetAgentId: string): {
56
+ export declare function checkSelfPromotion(ctxAgentId: AgentId | null | undefined, targetAgentId: AgentId | string): {
57
57
  allowed: true;
58
58
  } | {
59
59
  allowed: false;
@@ -1 +1 @@
1
- {"version":3,"file":"trust_progression.d.ts","sourceRoot":"","sources":["../../../src/api/agents/trust_progression.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAIhE,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,OAAO,CAAC;AAgB5E;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAExE;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,UAAU,EACvB,SAAS,EAAE,QAAQ,GAAG,OAAO,GAC5B;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CA4BpD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,EACtC,aAAa,EAAE,MAAM,GACpB;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAQxD;AAID;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAEvE;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,UAAU,EACxB,QAAQ,EAAE,iBAAiB,GAC1B,UAAU,GAAG,IAAI,CAmBnB"}
1
+ {"version":3,"file":"trust_progression.d.ts","sourceRoot":"","sources":["../../../src/api/agents/trust_progression.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAIhE,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,OAAO,CAAC;AAgB5E;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAExE;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,UAAU,EACvB,SAAS,EAAE,QAAQ,GAAG,OAAO,GAC5B;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CA4BpD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,EACtC,aAAa,EAAE,OAAO,GAAG,MAAM,GAC9B;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAQxD;AAID;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAEvE;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,UAAU,EACxB,QAAQ,EAAE,iBAAiB,GAC1B,UAAU,GAAG,IAAI,CAmBnB"}