@lucern/sdk 0.2.0-alpha.13 → 0.2.0-alpha.3
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.
- package/README.md +112 -621
- package/dist/index.js +3447 -6249
- package/dist/index.js.map +1 -1
- package/dist/{contracts → lucern/contracts/src}/auth-session.contract.d.ts +12 -14
- package/dist/{contracts → lucern/contracts/src}/context-pack.contract.d.ts +58 -56
- package/dist/{contracts → lucern/contracts/src}/lens-filter.contract.d.ts +8 -10
- package/dist/lucern/contracts/src/lens-workflow.contract.d.ts +84 -0
- package/dist/lucern/contracts/src/mcp-tools.contract.d.ts +151 -0
- package/dist/lucern/contracts/src/workflow-runtime.contract.d.ts +161 -0
- package/dist/lucern/mcp-server/src/context-pack-policy.d.ts +119 -0
- package/dist/lucern/mcp-server/src/context-pack-schema.d.ts +18 -0
- package/dist/lucern/modules/graph-primitives/src/ontology-matching.d.ts +78 -0
- package/dist/lucern/modules/graph-primitives/src/text-matching.d.ts +53 -0
- package/dist/lucern/packages/client-core/src/beliefs.d.ts +30 -0
- package/dist/lucern/packages/client-core/src/context.d.ts +29 -0
- package/dist/lucern/packages/client-core/src/contradictions.d.ts +11 -0
- package/dist/lucern/packages/client-core/src/edges.d.ts +11 -0
- package/dist/lucern/packages/client-core/src/events.d.ts +9 -0
- package/dist/lucern/packages/client-core/src/evidence.d.ts +21 -0
- package/dist/lucern/packages/client-core/src/graph.d.ts +17 -0
- package/dist/lucern/packages/client-core/src/identity.d.ts +7 -0
- package/dist/lucern/packages/client-core/src/ids.d.ts +7 -0
- package/dist/lucern/packages/client-core/src/ontologies.d.ts +13 -0
- package/dist/lucern/packages/client-core/src/questions.d.ts +39 -0
- package/dist/lucern/packages/client-core/src/search.d.ts +7 -0
- package/dist/lucern/packages/client-core/src/tasks.d.ts +13 -0
- package/dist/lucern/packages/client-core/src/topics.d.ts +17 -0
- package/dist/lucern/packages/client-core/src/webhooks.d.ts +35 -0
- package/dist/lucern/packages/client-core/src/worktrees.d.ts +17 -0
- package/dist/lucern/packages/domain-beliefs/src/beliefs.d.ts +283 -0
- package/dist/lucern/packages/domain-beliefs/src/index.d.ts +1 -0
- package/dist/lucern/packages/domain-context/src/compile.d.ts +11 -0
- package/dist/{contextPackCompiler.d.ts → lucern/packages/domain-context/src/context-pack-compiler.d.ts} +10 -11
- package/dist/lucern/packages/domain-context/src/index.d.ts +4 -0
- package/dist/lucern/packages/domain-context/src/ports.d.ts +58 -0
- package/dist/lucern/packages/domain-context/src/public-types.d.ts +1 -0
- package/dist/lucern/packages/domain-edges/src/contradictions.d.ts +59 -0
- package/dist/lucern/packages/domain-edges/src/edges.d.ts +91 -0
- package/dist/lucern/packages/domain-edges/src/index.d.ts +2 -0
- package/dist/lucern/packages/domain-evidence/src/evidence.d.ts +115 -0
- package/dist/lucern/packages/domain-evidence/src/index.d.ts +1 -0
- package/dist/lucern/packages/domain-graph/src/graph.d.ts +150 -0
- package/dist/lucern/packages/domain-identity/src/index.d.ts +1 -0
- package/dist/lucern/packages/domain-identity/src/whoami.d.ts +13 -0
- package/dist/lucern/packages/domain-ontologies/src/ontologies.d.ts +123 -0
- package/dist/lucern/packages/domain-questions/src/index.d.ts +1 -0
- package/dist/lucern/packages/domain-questions/src/questions.d.ts +147 -0
- package/dist/lucern/packages/domain-search/src/search.d.ts +97 -0
- package/dist/lucern/packages/domain-tasks/src/index.d.ts +1 -0
- package/dist/lucern/packages/domain-tasks/src/tasks.d.ts +102 -0
- package/dist/lucern/packages/domain-topics/src/index.d.ts +1 -0
- package/dist/lucern/packages/domain-topics/src/topics.d.ts +147 -0
- package/dist/lucern/packages/domain-worktrees/src/index.d.ts +1 -0
- package/dist/lucern/packages/domain-worktrees/src/worktrees.d.ts +185 -0
- package/dist/lucern/packages/events/src/index.d.ts +4 -0
- package/dist/lucern/packages/events/src/matching.d.ts +3 -0
- package/dist/lucern/packages/events/src/outbox.d.ts +15 -0
- package/dist/lucern/packages/events/src/types.d.ts +151 -0
- package/dist/lucern/packages/events/src/webhooks.d.ts +9 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/beliefs.d.ts +15 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/context.d.ts +12 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/contradictions.d.ts +7 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/edges.d.ts +7 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/events.d.ts +6 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/evidence.d.ts +21 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/graph.d.ts +10 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/identity.d.ts +5 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/ontologies.d.ts +8 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/questions.d.ts +39 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/search.d.ts +5 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/tasks.d.ts +8 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/topics.d.ts +10 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/webhooks.d.ts +16 -0
- package/dist/lucern/packages/sdk-typescript/src/facade/worktrees.d.ts +10 -0
- package/dist/lucern/packages/sdk-typescript/src/index.d.ts +28 -0
- package/dist/packages/sdk/src/adminClient.d.ts +89 -0
- package/dist/packages/sdk/src/answersClient.d.ts +5 -0
- package/dist/{audiencesClient.d.ts → packages/sdk/src/audiencesClient.d.ts} +18 -30
- package/dist/packages/sdk/src/auditClient.d.ts +21 -0
- package/dist/packages/sdk/src/beliefsClient.d.ts +52 -0
- package/dist/packages/sdk/src/client.d.ts +1558 -0
- package/dist/packages/sdk/src/contextClient.d.ts +9 -0
- package/dist/packages/sdk/src/contracts/api-enums.contract.d.ts +79 -0
- package/dist/{controlObjectOwnership.d.ts → packages/sdk/src/controlObjectOwnership.d.ts} +18 -35
- package/dist/{coreClient.d.ts → packages/sdk/src/coreClient.d.ts} +14 -38
- package/dist/packages/sdk/src/customTools.d.ts +65 -0
- package/dist/packages/sdk/src/decisionsClient.d.ts +97 -0
- package/dist/packages/sdk/src/graphClient.d.ts +191 -0
- package/dist/{harnessClient.d.ts → packages/sdk/src/harnessClient.d.ts} +33 -127
- package/dist/packages/sdk/src/identityClient.d.ts +104 -0
- package/dist/packages/sdk/src/index.d.ts +28 -0
- package/dist/packages/sdk/src/learningClient.d.ts +37 -0
- package/dist/{mcpParityClient.d.ts → packages/sdk/src/mcpParityClient.d.ts} +5 -11
- package/dist/packages/sdk/src/mcpParitySurface.d.ts +8 -0
- package/dist/{ontologyClient.d.ts → packages/sdk/src/ontologyClient.d.ts} +22 -44
- package/dist/packages/sdk/src/packsClient.d.ts +101 -0
- package/dist/{policyClient.d.ts → packages/sdk/src/policyClient.d.ts} +18 -113
- package/dist/packages/sdk/src/reportsClient.d.ts +31 -0
- package/dist/packages/sdk/src/schemaClient.d.ts +54 -0
- package/dist/packages/sdk/src/sdkSurface.d.ts +55 -0
- package/dist/packages/sdk/src/topicsClient.d.ts +45 -0
- package/dist/packages/sdk/src/types.d.ts +470 -0
- package/dist/packages/sdk/src/version.d.ts +2 -0
- package/dist/packages/sdk/src/workflowClient.d.ts +252 -0
- package/package.json +37 -92
- package/CHANGELOG.md +0 -13
- package/dist/adminClient.d.ts +0 -409
- package/dist/adminClient.js +0 -755
- package/dist/adminClient.js.map +0 -1
- package/dist/answersClient.d.ts +0 -23
- package/dist/answersClient.js +0 -333
- package/dist/answersClient.js.map +0 -1
- package/dist/audience/index.d.ts +0 -38
- package/dist/audience/index.js +0 -110
- package/dist/audience/index.js.map +0 -1
- package/dist/audiencesClient.js +0 -472
- package/dist/audiencesClient.js.map +0 -1
- package/dist/auditClient.d.ts +0 -29
- package/dist/auditClient.js +0 -386
- package/dist/auditClient.js.map +0 -1
- package/dist/beliefs/index.d.ts +0 -465
- package/dist/beliefs/index.js +0 -6433
- package/dist/beliefs/index.js.map +0 -1
- package/dist/beliefs/lifecycle.d.ts +0 -24
- package/dist/beliefs/lifecycle.js +0 -98
- package/dist/beliefs/lifecycle.js.map +0 -1
- package/dist/beliefsClient.d.ts +0 -241
- package/dist/beliefsClient.js +0 -646
- package/dist/beliefsClient.js.map +0 -1
- package/dist/client.d.ts +0 -2398
- package/dist/client.js +0 -6411
- package/dist/client.js.map +0 -1
- package/dist/contextClient.d.ts +0 -27
- package/dist/contextClient.js +0 -396
- package/dist/contextClient.js.map +0 -1
- package/dist/contextFacade.d.ts +0 -2
- package/dist/contextFacade.js +0 -73
- package/dist/contextFacade.js.map +0 -1
- package/dist/contextPackCompiler.js +0 -1091
- package/dist/contextPackCompiler.js.map +0 -1
- package/dist/contextPackPolicy.d.ts +0 -84
- package/dist/contextPackPolicy.js +0 -347
- package/dist/contextPackPolicy.js.map +0 -1
- package/dist/contextPackSchema.d.ts +0 -7
- package/dist/contextPackSchema.js +0 -203
- package/dist/contextPackSchema.js.map +0 -1
- package/dist/contextTypes.d.ts +0 -135
- package/dist/contextTypes.js +0 -3
- package/dist/contextTypes.js.map +0 -1
- package/dist/contracts/api-enums.contract.d.ts +0 -81
- package/dist/contracts/api-enums.contract.js +0 -98
- package/dist/contracts/api-enums.contract.js.map +0 -1
- package/dist/contracts/auth-session.contract.js +0 -48
- package/dist/contracts/auth-session.contract.js.map +0 -1
- package/dist/contracts/context-pack.contract.js +0 -98
- package/dist/contracts/context-pack.contract.js.map +0 -1
- package/dist/contracts/contextPack.d.ts +0 -1
- package/dist/contracts/contextPack.js +0 -98
- package/dist/contracts/contextPack.js.map +0 -1
- package/dist/contracts/index.d.ts +0 -9
- package/dist/contracts/index.js +0 -4928
- package/dist/contracts/index.js.map +0 -1
- package/dist/contracts/lens-filter.contract.js +0 -71
- package/dist/contracts/lens-filter.contract.js.map +0 -1
- package/dist/contracts/lens-workflow.contract.d.ts +0 -87
- package/dist/contracts/lens-workflow.contract.js +0 -123
- package/dist/contracts/lens-workflow.contract.js.map +0 -1
- package/dist/contracts/lensFilter.d.ts +0 -1
- package/dist/contracts/lensFilter.js +0 -71
- package/dist/contracts/lensFilter.js.map +0 -1
- package/dist/contracts/lensWorkflow.d.ts +0 -2
- package/dist/contracts/lensWorkflow.js +0 -123
- package/dist/contracts/lensWorkflow.js.map +0 -1
- package/dist/contracts/mcp-tools.contract.d.ts +0 -1
- package/dist/contracts/mcp-tools.contract.js +0 -3016
- package/dist/contracts/mcp-tools.contract.js.map +0 -1
- package/dist/contracts/mcpTools.d.ts +0 -1
- package/dist/contracts/mcpTools.js +0 -3016
- package/dist/contracts/mcpTools.js.map +0 -1
- package/dist/contracts/prompt.contract.d.ts +0 -26
- package/dist/contracts/prompt.contract.js +0 -12
- package/dist/contracts/prompt.contract.js.map +0 -1
- package/dist/contracts/prompt.d.ts +0 -1
- package/dist/contracts/prompt.js +0 -12
- package/dist/contracts/prompt.js.map +0 -1
- package/dist/contracts/sdk-tools.contract.d.ts +0 -2
- package/dist/contracts/sdk-tools.contract.js +0 -4164
- package/dist/contracts/sdk-tools.contract.js.map +0 -1
- package/dist/contracts/sdkTools.d.ts +0 -2
- package/dist/contracts/sdkTools.js +0 -4164
- package/dist/contracts/sdkTools.js.map +0 -1
- package/dist/contracts/workflow-runtime.contract.d.ts +0 -163
- package/dist/contracts/workflow-runtime.contract.js +0 -245
- package/dist/contracts/workflow-runtime.contract.js.map +0 -1
- package/dist/contracts/workflowRuntime.d.ts +0 -1
- package/dist/contracts/workflowRuntime.js +0 -245
- package/dist/contracts/workflowRuntime.js.map +0 -1
- package/dist/contradictions/index.d.ts +0 -158
- package/dist/contradictions/index.js +0 -6427
- package/dist/contradictions/index.js.map +0 -1
- package/dist/controlObjectOwnership.js +0 -215
- package/dist/controlObjectOwnership.js.map +0 -1
- package/dist/coreClient.js +0 -339
- package/dist/coreClient.js.map +0 -1
- package/dist/customTools.d.ts +0 -88
- package/dist/customTools.js +0 -248
- package/dist/customTools.js.map +0 -1
- package/dist/decisions/index.d.ts +0 -68
- package/dist/decisions/index.js +0 -6429
- package/dist/decisions/index.js.map +0 -1
- package/dist/decisionsClient.d.ts +0 -111
- package/dist/decisionsClient.js +0 -522
- package/dist/decisionsClient.js.map +0 -1
- package/dist/domainContext.d.ts +0 -1
- package/dist/domainContext.js +0 -3
- package/dist/domainContext.js.map +0 -1
- package/dist/edges/index.d.ts +0 -204
- package/dist/edges/index.js +0 -6428
- package/dist/edges/index.js.map +0 -1
- package/dist/events.d.ts +0 -178
- package/dist/events.js +0 -251
- package/dist/events.js.map +0 -1
- package/dist/eventsCore.d.ts +0 -49
- package/dist/eventsCore.js +0 -429
- package/dist/eventsCore.js.map +0 -1
- package/dist/evidence/index.d.ts +0 -295
- package/dist/evidence/index.js +0 -6428
- package/dist/evidence/index.js.map +0 -1
- package/dist/evidenceClient.d.ts +0 -119
- package/dist/evidenceClient.js +0 -350
- package/dist/evidenceClient.js.map +0 -1
- package/dist/facade/context.d.ts +0 -18
- package/dist/facade/context.js +0 -73
- package/dist/facade/context.js.map +0 -1
- package/dist/gatewayFacades.d.ts +0 -589
- package/dist/gatewayFacades.js +0 -2006
- package/dist/gatewayFacades.js.map +0 -1
- package/dist/graphClient.d.ts +0 -271
- package/dist/graphClient.js +0 -698
- package/dist/graphClient.js.map +0 -1
- package/dist/harnessClient.js +0 -607
- package/dist/harnessClient.js.map +0 -1
- package/dist/identityClient.d.ts +0 -140
- package/dist/identityClient.js +0 -497
- package/dist/identityClient.js.map +0 -1
- package/dist/index.d.ts +0 -45
- package/dist/learningClient.d.ts +0 -46
- package/dist/learningClient.js +0 -409
- package/dist/learningClient.js.map +0 -1
- package/dist/lenses/index.d.ts +0 -194
- package/dist/lenses/index.js +0 -6427
- package/dist/lenses/index.js.map +0 -1
- package/dist/mcpParityClient.js +0 -516
- package/dist/mcpParityClient.js.map +0 -1
- package/dist/mcpParitySurface.d.ts +0 -12
- package/dist/mcpParitySurface.js +0 -65
- package/dist/mcpParitySurface.js.map +0 -1
- package/dist/mcpTools-DPZxowDX.d.ts +0 -254
- package/dist/nodes/index.d.ts +0 -62
- package/dist/nodes/index.js +0 -6429
- package/dist/nodes/index.js.map +0 -1
- package/dist/ontologies/index.d.ts +0 -178
- package/dist/ontologies/index.js +0 -6430
- package/dist/ontologies/index.js.map +0 -1
- package/dist/ontologyClient.js +0 -513
- package/dist/ontologyClient.js.map +0 -1
- package/dist/opinion.d.ts +0 -11
- package/dist/opinion.js +0 -35
- package/dist/opinion.js.map +0 -1
- package/dist/packRuntime.d.ts +0 -2
- package/dist/packRuntime.js +0 -3
- package/dist/packRuntime.js.map +0 -1
- package/dist/packsClient.d.ts +0 -131
- package/dist/packsClient.js +0 -525
- package/dist/packsClient.js.map +0 -1
- package/dist/policyClient.js +0 -625
- package/dist/policyClient.js.map +0 -1
- package/dist/questions/index.d.ts +0 -297
- package/dist/questions/index.js +0 -6430
- package/dist/questions/index.js.map +0 -1
- package/dist/realtime/index.d.ts +0 -29
- package/dist/realtime/index.js +0 -23
- package/dist/realtime/index.js.map +0 -1
- package/dist/realtime/refs.d.ts +0 -17
- package/dist/realtime/refs.js +0 -9
- package/dist/realtime/refs.js.map +0 -1
- package/dist/reportsClient.d.ts +0 -41
- package/dist/reportsClient.js +0 -418
- package/dist/reportsClient.js.map +0 -1
- package/dist/schemaClient.d.ts +0 -64
- package/dist/schemaClient.js +0 -434
- package/dist/schemaClient.js.map +0 -1
- package/dist/sdkSurface.d.ts +0 -61
- package/dist/sdkSurface.js +0 -112
- package/dist/sdkSurface.js.map +0 -1
- package/dist/sdkTools-CwXJDACb.d.ts +0 -150
- package/dist/sourcesClient.d.ts +0 -24
- package/dist/sourcesClient.js +0 -339
- package/dist/sourcesClient.js.map +0 -1
- package/dist/topics/index.d.ts +0 -68
- package/dist/topics/index.js +0 -6428
- package/dist/topics/index.js.map +0 -1
- package/dist/topicsClient.d.ts +0 -84
- package/dist/topicsClient.js +0 -492
- package/dist/topicsClient.js.map +0 -1
- package/dist/types.d.ts +0 -715
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
- package/dist/version.d.ts +0 -4
- package/dist/version.js +0 -6
- package/dist/version.js.map +0 -1
- package/dist/workflowClient.d.ts +0 -316
- package/dist/workflowClient.js +0 -830
- package/dist/workflowClient.js.map +0 -1
- package/dist/worktrees/index.d.ts +0 -210
- package/dist/worktrees/index.js +0 -6430
- package/dist/worktrees/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,52 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
The reasoning operating system for AI-native applications.
|
|
4
4
|
|
|
5
|
-
Your AI agent reads 50 documents
|
|
5
|
+
Your AI agent reads 50 documents. It generates insights. A week later, it reads 50 more — and has no memory of what it learned before. Every session starts from zero.
|
|
6
6
|
|
|
7
|
-
Lucern gives your
|
|
7
|
+
Lucern fixes this. It gives your application a knowledge graph that accumulates understanding over time. Beliefs strengthen or weaken as evidence arrives. Contradictions are detected, not hidden. Your agents get smarter with every interaction because the graph remembers what was learned, when, and why.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
12
|
npm install @lucern/sdk
|
|
11
13
|
```
|
|
12
14
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
`@lucern/sdk` is the canonical public interface for Lucern.
|
|
16
|
-
|
|
17
|
-
- Build applications, automations, and backend integrations against the SDK first.
|
|
18
|
-
- Treat `/api/platform/v1/*` as the transport mirror of the SDK surface.
|
|
19
|
-
- Treat MCP as an agent-facing client of the same surface, not as a privileged bypass around SDK or HTTP semantics.
|
|
20
|
-
|
|
21
|
-
IA-7 closes the remaining SDK surface gaps needed for SDK-first clients:
|
|
22
|
-
|
|
23
|
-
- Kernel mutations that previously only existed behind route or MCP adapters now have SDK wrappers across beliefs, evidence, questions, edges, topics, worktrees, and nodes.
|
|
24
|
-
- `lucern.identity.whoami()` exposes resolved principal context for service principals, tenant API keys, and interactive users.
|
|
25
|
-
- Public SDK types now export `SdkPrincipalContext` plus the `Platform*Record` and `Workflow*Record` families for typed client code.
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
import {
|
|
29
|
-
createLucernClient,
|
|
30
|
-
type PlatformBeliefRecord,
|
|
31
|
-
type SdkPrincipalContext,
|
|
32
|
-
type WorkflowWorktreeRecord,
|
|
33
|
-
} from "@lucern/sdk";
|
|
34
|
-
|
|
35
|
-
const lucern = createLucernClient({
|
|
36
|
-
apiKey: process.env.LUCERN_API_KEY,
|
|
37
|
-
baseUrl: "https://api.lucern.ai",
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
const identity = await lucern.identity.whoami();
|
|
41
|
-
const principal: SdkPrincipalContext = identity.data;
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## The Full Developer Journey
|
|
45
|
-
|
|
46
|
-
This walkthrough mirrors what a developer building an AI-powered code review system would experience in a real coding session. Every API call is something you would actually use.
|
|
47
|
-
|
|
48
|
-
### 1. Set Up Your Reasoning Scope
|
|
15
|
+
## Quickstart — Build an Agent That Remembers
|
|
49
16
|
|
|
50
|
-
|
|
17
|
+
Your agent processes customer support tickets and builds an evolving understanding of product issues:
|
|
51
18
|
|
|
52
19
|
```typescript
|
|
53
20
|
import { createLucernClient } from "@lucern/sdk";
|
|
@@ -57,660 +24,184 @@ const lucern = createLucernClient({
|
|
|
57
24
|
baseUrl: "https://api.lucern.ai",
|
|
58
25
|
});
|
|
59
26
|
|
|
60
|
-
// Create a
|
|
61
|
-
const
|
|
62
|
-
name: "
|
|
27
|
+
// Create a reasoning scope
|
|
28
|
+
const topic = await lucern.topics.create({
|
|
29
|
+
name: "Product Issue Tracker",
|
|
63
30
|
type: "domain",
|
|
64
31
|
});
|
|
32
|
+
const topicId = topic.data.topicId;
|
|
65
33
|
|
|
66
|
-
//
|
|
67
|
-
const
|
|
68
|
-
name: "Security Patterns",
|
|
69
|
-
type: "theme",
|
|
70
|
-
parentTopicId: codeQuality.data.topicId,
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
const performanceTopic = await lucern.topics.create({
|
|
74
|
-
name: "Performance Patterns",
|
|
75
|
-
type: "theme",
|
|
76
|
-
parentTopicId: codeQuality.data.topicId,
|
|
77
|
-
});
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### 2. Populate the Graph With What You Know
|
|
81
|
-
|
|
82
|
-
Beliefs represent understanding at different epistemic levels: facts (verified), beliefs (confident), hypotheses (testing), and assumptions (untested).
|
|
83
|
-
|
|
84
|
-
```typescript
|
|
85
|
-
const topicId = securityTopic.data.topicId;
|
|
86
|
-
|
|
87
|
-
// A fact — verified and anchored
|
|
88
|
-
const sqlFact = await lucern.beliefs.create({
|
|
89
|
-
topicId,
|
|
90
|
-
baseRate: 0.5,
|
|
91
|
-
canonicalText: "Parameterized queries prevent SQL injection in all major database drivers",
|
|
92
|
-
beliefType: "fact",
|
|
93
|
-
});
|
|
94
|
-
await lucern.beliefs.modulateConfidence(sqlFact.data.nodeId, {
|
|
95
|
-
confidence: 0.95,
|
|
96
|
-
trigger: "evidence_added",
|
|
97
|
-
rationale: "OWASP verified, industry standard for 20+ years",
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// A belief — confident from observation
|
|
101
|
-
const patternBelief = await lucern.beliefs.create({
|
|
102
|
-
topicId,
|
|
103
|
-
baseRate: 0.5,
|
|
104
|
-
canonicalText: "Most security vulnerabilities in our codebase come from unvalidated user input at API boundaries, not from cryptographic weaknesses",
|
|
105
|
-
});
|
|
106
|
-
await lucern.beliefs.modulateConfidence(patternBelief.data.nodeId, {
|
|
107
|
-
confidence: 0.82,
|
|
108
|
-
trigger: "evidence_added",
|
|
109
|
-
rationale: "Last 6 months of security audits: 14 input validation issues, 1 crypto issue",
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
// A hypothesis — under active testing
|
|
113
|
-
const hypothesis = await lucern.beliefs.create({
|
|
114
|
-
topicId,
|
|
115
|
-
baseRate: 0.5,
|
|
116
|
-
canonicalText: "Automated static analysis catches fewer than 30% of the input validation vulnerabilities that human reviewers find",
|
|
117
|
-
beliefType: "hypothesis",
|
|
118
|
-
});
|
|
119
|
-
await lucern.beliefs.modulateConfidence(hypothesis.data.nodeId, {
|
|
120
|
-
confidence: 0.6,
|
|
121
|
-
trigger: "manual",
|
|
122
|
-
rationale: "Anecdotal — need to run a proper comparison study",
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
// An assumption — untested but used as a basis for decisions
|
|
126
|
-
const assumption = await lucern.beliefs.create({
|
|
127
|
-
topicId,
|
|
128
|
-
baseRate: 0.5,
|
|
129
|
-
canonicalText: "Our CI pipeline runs all static analysis rules on every PR",
|
|
130
|
-
beliefType: "assumption",
|
|
131
|
-
});
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### 3. Connect Beliefs With Edges
|
|
135
|
-
|
|
136
|
-
Edges express the reasoning relationships between beliefs.
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
// The pattern belief depends on the SQL injection fact
|
|
140
|
-
await lucern.graph.createEdge({
|
|
141
|
-
topicId,
|
|
142
|
-
sourceId: patternBelief.data.nodeId,
|
|
143
|
-
targetId: sqlFact.data.nodeId,
|
|
144
|
-
edgeType: "depends_on",
|
|
145
|
-
reasoning: "Input validation pattern includes SQL injection as a subclass",
|
|
146
|
-
reasoningMethod: "deductive",
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
// The hypothesis is derived from the pattern belief
|
|
150
|
-
await lucern.graph.createEdge({
|
|
34
|
+
// Your agent processes a batch of support tickets and forms a belief
|
|
35
|
+
const belief = await lucern.beliefs.create({
|
|
151
36
|
topicId,
|
|
152
|
-
|
|
153
|
-
targetId: patternBelief.data.nodeId,
|
|
154
|
-
edgeType: "derived_from",
|
|
155
|
-
reasoning: "If most vulns are input validation, and static analysis misses them, the tooling gap is at the input boundary",
|
|
156
|
-
reasoningMethod: "inductive",
|
|
37
|
+
canonicalText: "Authentication timeout errors are caused by the session refresh race condition, not the auth provider",
|
|
157
38
|
});
|
|
158
39
|
|
|
159
|
-
//
|
|
160
|
-
await lucern.
|
|
161
|
-
topicId,
|
|
162
|
-
sourceId: hypothesis.data.nodeId,
|
|
163
|
-
targetId: assumption.data.nodeId,
|
|
164
|
-
edgeType: "depends_on",
|
|
165
|
-
reasoning: "If the CI pipeline is not running all rules, the comparison would be invalid",
|
|
166
|
-
reasoningMethod: "deductive",
|
|
167
|
-
});
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### 4. Open an Investigation With a Worktree
|
|
171
|
-
|
|
172
|
-
Worktrees are focused investigations — like a feature branch for knowledge. You test beliefs, gather evidence, and merge the findings.
|
|
173
|
-
|
|
174
|
-
```typescript
|
|
175
|
-
const investigation = await lucern.worktrees.create({
|
|
40
|
+
// Attach the evidence that led to this belief
|
|
41
|
+
await lucern.evidence.create({
|
|
176
42
|
topicId,
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
43
|
+
text: "12 of 15 timeout tickets occur within 200ms of token refresh. Stack traces show concurrent refresh calls.",
|
|
44
|
+
targetId: belief.data.nodeId,
|
|
45
|
+
weight: 0.85,
|
|
180
46
|
});
|
|
181
47
|
|
|
182
|
-
//
|
|
183
|
-
await lucern.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
linkedQuestionId: comparisonQuestion.data.questionId,
|
|
188
|
-
taskType: "data_collection",
|
|
48
|
+
// Score confidence based on evidence strength
|
|
49
|
+
await lucern.beliefs.modulateConfidence(belief.data.nodeId, {
|
|
50
|
+
confidence: 0.75,
|
|
51
|
+
trigger: "evidence_added",
|
|
52
|
+
rationale: "Strong correlation in timing data, but haven't reproduced in staging yet",
|
|
189
53
|
});
|
|
190
54
|
|
|
191
|
-
|
|
55
|
+
// Flag what would change this understanding
|
|
56
|
+
await lucern.questions.create({
|
|
192
57
|
topicId,
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
58
|
+
text: "Does disabling concurrent refresh eliminate the timeout pattern?",
|
|
59
|
+
priority: "high",
|
|
60
|
+
linkedBeliefId: belief.data.nodeId,
|
|
196
61
|
});
|
|
197
62
|
```
|
|
198
63
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
Your agent processes the results and commits evidence to the graph.
|
|
64
|
+
Next week, your agent processes more tickets:
|
|
202
65
|
|
|
203
66
|
```typescript
|
|
204
|
-
//
|
|
205
|
-
await lucern.evidence.create({
|
|
206
|
-
topicId,
|
|
207
|
-
text: "Semgrep + CodeQL found 23 issues across 50 PRs. 18 were true positives. Categories: 12 input validation, 4 auth bypass patterns, 2 information disclosure.",
|
|
208
|
-
sourceUrl: "ci://semgrep-run/batch-50pr-comparison",
|
|
209
|
-
targetId: hypothesis.data.nodeId,
|
|
210
|
-
weight: 0.6, // partially supports
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
// Human review results
|
|
67
|
+
// New evidence arrives that contradicts the original belief
|
|
214
68
|
await lucern.evidence.create({
|
|
215
69
|
topicId,
|
|
216
|
-
text: "
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
weight: 0.9, // strongly supports — 18/34 = 53%, even worse than hypothesized
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
// Answer the question with data
|
|
223
|
-
const comparisonQuestion = await lucern.questions.create({
|
|
224
|
-
topicId,
|
|
225
|
-
text: "What percentage of vulnerabilities does static analysis catch compared to human reviewers?",
|
|
226
|
-
priority: "high",
|
|
227
|
-
linkedBeliefId: hypothesis.data.nodeId,
|
|
70
|
+
text: "Timeouts persist after disabling concurrent refresh. Network traces show upstream latency spikes from the auth provider during peak hours.",
|
|
71
|
+
targetId: belief.data.nodeId,
|
|
72
|
+
weight: -0.7, // contradicts
|
|
228
73
|
});
|
|
229
74
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
confidence:
|
|
233
|
-
evidenceIds: [staticEvidence.data.nodeId, humanEvidence.data.nodeId],
|
|
234
|
-
});
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
### 6. Fork a Belief When Understanding Evolves
|
|
238
|
-
|
|
239
|
-
The original hypothesis said "less than 30%." The data shows 53% — but the story is more nuanced. Fork the belief to capture the evolved understanding.
|
|
240
|
-
|
|
241
|
-
```typescript
|
|
242
|
-
// Drop confidence on the original (it was too pessimistic about overall catch rate)
|
|
243
|
-
await lucern.beliefs.modulateConfidence(hypothesis.data.nodeId, {
|
|
244
|
-
confidence: 0.2,
|
|
75
|
+
// Confidence drops — the graph tracks the evolution
|
|
76
|
+
await lucern.beliefs.modulateConfidence(belief.data.nodeId, {
|
|
77
|
+
confidence: 0.3,
|
|
245
78
|
trigger: "evidence_added",
|
|
246
|
-
rationale: "
|
|
79
|
+
rationale: "Fix attempt failed. Evidence now points to upstream provider, not our code.",
|
|
247
80
|
});
|
|
248
81
|
|
|
249
|
-
// Fork
|
|
250
|
-
const
|
|
251
|
-
newFormulation: "
|
|
252
|
-
forkReason: "
|
|
82
|
+
// Fork the belief — understanding has evolved
|
|
83
|
+
const revised = await lucern.beliefs.fork(belief.data.nodeId, {
|
|
84
|
+
newFormulation: "Authentication timeouts are caused by upstream provider latency during peak hours, compounded by our lack of request queuing",
|
|
85
|
+
forkReason: "contradiction_response",
|
|
253
86
|
});
|
|
254
87
|
|
|
255
|
-
await lucern.beliefs.modulateConfidence(
|
|
256
|
-
confidence: 0.
|
|
88
|
+
await lucern.beliefs.modulateConfidence(revised.data.nodeId, {
|
|
89
|
+
confidence: 0.82,
|
|
257
90
|
trigger: "evidence_added",
|
|
258
|
-
rationale: "
|
|
91
|
+
rationale: "Network traces confirm provider latency. Queuing fix in PR #847 eliminated 90% of timeouts in staging.",
|
|
259
92
|
});
|
|
93
|
+
```
|
|
260
94
|
|
|
261
|
-
|
|
262
|
-
const actionable = await lucern.beliefs.create({
|
|
263
|
-
topicId,
|
|
264
|
-
baseRate: 0.5,
|
|
265
|
-
canonicalText: "Human code review should focus on business logic and concurrency — the categories where static analysis provides zero coverage",
|
|
266
|
-
beliefType: "belief",
|
|
267
|
-
});
|
|
95
|
+
The graph now tells the complete story: your agent initially believed the issue was a race condition (75% confidence), new evidence contradicted that (dropped to 30%), and the understanding evolved to identify the real cause (82% confidence on the revised belief). Every step is traceable.
|
|
268
96
|
|
|
269
|
-
|
|
270
|
-
confidence: 0.85,
|
|
271
|
-
trigger: "worktree_outcome",
|
|
272
|
-
rationale: "Direct implication of the comparison study findings",
|
|
273
|
-
});
|
|
97
|
+
## Why This Matters
|
|
274
98
|
|
|
275
|
-
|
|
276
|
-
await lucern.graph.createEdge({
|
|
277
|
-
topicId,
|
|
278
|
-
sourceId: actionable.data.nodeId,
|
|
279
|
-
targetId: evolved.data.nodeId,
|
|
280
|
-
edgeType: "derived_from",
|
|
281
|
-
reasoning: "The review focus recommendation follows directly from the coverage gap data",
|
|
282
|
-
reasoningMethod: "deductive",
|
|
283
|
-
});
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
### 7. Compile Context for Your Next Agent Session
|
|
99
|
+
Without Lucern, your agent would process the second batch of tickets with no memory of the first. It would re-discover the race condition theory, waste time investigating it again, and maybe reach the right answer — or maybe not.
|
|
287
100
|
|
|
288
|
-
|
|
101
|
+
With Lucern, the agent reads its prior beliefs before processing new tickets. It knows what it already tried. It knows what questions are still open. It starts from understanding, not from zero.
|
|
289
102
|
|
|
290
103
|
```typescript
|
|
104
|
+
// Before processing new data, the agent reads its current understanding
|
|
291
105
|
const context = await lucern.context.compile(topicId, {
|
|
292
|
-
query: "
|
|
106
|
+
query: "authentication timeout root cause",
|
|
293
107
|
ranking: "weighted_v1",
|
|
294
108
|
tokenBudget: 2000,
|
|
295
109
|
});
|
|
296
110
|
|
|
297
|
-
// context
|
|
298
|
-
// -
|
|
299
|
-
// -
|
|
300
|
-
// - contradictions
|
|
301
|
-
// -
|
|
302
|
-
|
|
303
|
-
// Your agent starts from understanding, not from zero
|
|
304
|
-
console.log(`
|
|
305
|
-
${context.data.summary.totalBeliefs} beliefs in scope
|
|
306
|
-
${context.data.summary.openQuestions} open questions
|
|
307
|
-
${context.data.summary.contradictions} unresolved contradictions
|
|
308
|
-
`);
|
|
309
|
-
```
|
|
111
|
+
// The context pack contains:
|
|
112
|
+
// - Active beliefs ranked by relevance and confidence
|
|
113
|
+
// - Open questions that still need answers
|
|
114
|
+
// - Unresolved contradictions the agent should address
|
|
115
|
+
// - Recent evidence for grounding
|
|
310
116
|
|
|
311
|
-
|
|
117
|
+
// Feed this to your LLM as working memory
|
|
118
|
+
const prompt = `
|
|
119
|
+
Current understanding:
|
|
120
|
+
${context.data.activeBeliefs.map(b =>
|
|
121
|
+
`[${b.confidence}] ${b.canonicalText}`
|
|
122
|
+
).join("\n ")}
|
|
312
123
|
|
|
313
|
-
|
|
124
|
+
Open questions:
|
|
125
|
+
${context.data.openQuestions.map(q => q.text).join("\n ")}
|
|
126
|
+
|
|
127
|
+
Given this foundation, analyze the following new tickets...
|
|
128
|
+
`;
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
This is the compound intelligence loop. Read from the graph, reason, write back. Every cycle makes the next one smarter.
|
|
314
132
|
|
|
315
133
|
## Core Concepts
|
|
316
134
|
|
|
317
135
|
| Concept | What It Does |
|
|
318
136
|
|---------|-------------|
|
|
319
|
-
| **Topic** | Scopes reasoning
|
|
320
|
-
| **Belief** | A statement with a confidence score
|
|
321
|
-
| **Evidence** | A
|
|
322
|
-
| **Question** | An open investigation
|
|
323
|
-
| **Contradiction** | An explicit tension between
|
|
324
|
-
| **Worktree** | A focused investigation
|
|
325
|
-
| **
|
|
326
|
-
| **Confidence** | 0 to 1 score with append-only history. Every change has a trigger and rationale. |
|
|
327
|
-
| **Task** | Execution work linked to a question or worktree. |
|
|
328
|
-
| **Context Pack** | The graph compiled into ranked, budgeted context for LLM injection. |
|
|
137
|
+
| **Topic** | Scopes reasoning to a domain (like a database for understanding) |
|
|
138
|
+
| **Belief** | A statement held to be true, with a confidence score that changes over time |
|
|
139
|
+
| **Evidence** | A fact that supports or contradicts a belief, with weight and source |
|
|
140
|
+
| **Question** | An open investigation that drives evidence collection |
|
|
141
|
+
| **Contradiction** | An explicit tension between beliefs that must be addressed |
|
|
142
|
+
| **Worktree** | A focused investigation (branch, test hypotheses, merge findings) |
|
|
143
|
+
| **Confidence** | A 0-to-1 score on every belief, with append-only history showing how it changed |
|
|
329
144
|
|
|
330
145
|
## SDK Surface
|
|
331
146
|
|
|
332
147
|
```typescript
|
|
333
148
|
const lucern = createLucernClient({ apiKey, baseUrl });
|
|
334
149
|
|
|
335
|
-
lucern.beliefs // Create, fork,
|
|
336
|
-
lucern.evidence // Add
|
|
337
|
-
lucern.questions //
|
|
338
|
-
lucern.contradictions //
|
|
339
|
-
lucern.topics //
|
|
340
|
-
lucern.worktrees //
|
|
341
|
-
lucern.
|
|
342
|
-
lucern.
|
|
343
|
-
lucern.ontologies //
|
|
344
|
-
lucern.tasks //
|
|
150
|
+
lucern.beliefs // Create, fork, archive, score beliefs
|
|
151
|
+
lucern.evidence // Add evidence, link to beliefs with weight
|
|
152
|
+
lucern.questions // Track what needs investigation
|
|
153
|
+
lucern.contradictions // Detect and manage tensions
|
|
154
|
+
lucern.topics // Organize reasoning into domains
|
|
155
|
+
lucern.worktrees // Run focused investigations
|
|
156
|
+
lucern.context // Compile the graph into agent-ready context
|
|
157
|
+
lucern.graph // Traverse, analyze structure, detect bias
|
|
158
|
+
lucern.ontologies // Define domain vocabulary
|
|
159
|
+
lucern.tasks // Track execution work
|
|
345
160
|
lucern.audit // Full mutation history
|
|
346
|
-
lucern.identity // API keys and sessions
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
## Graph Intelligence
|
|
350
|
-
|
|
351
|
-
The graph doesn't just store knowledge — it analyzes itself.
|
|
352
|
-
|
|
353
|
-
### Structural Analysis
|
|
354
|
-
|
|
355
|
-
```typescript
|
|
356
|
-
// Run the full analysis suite: PageRank, Louvain clustering,
|
|
357
|
-
// Tarjan SCC, spectral analysis, confirmation bias detection
|
|
358
|
-
const analysis = await lucern.graph.analyze({ topicId });
|
|
359
|
-
|
|
360
|
-
// Which beliefs are most central to your reasoning?
|
|
361
|
-
analysis.data.pageRank.topNodes.forEach(node => {
|
|
362
|
-
console.log(`${node.canonicalText} — centrality: ${node.score}`);
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
// Are there isolated belief clusters that should be connected?
|
|
366
|
-
analysis.data.communities.forEach(cluster => {
|
|
367
|
-
console.log(`Cluster "${cluster.label}": ${cluster.nodeCount} beliefs`);
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
// Any circular dependencies in your reasoning?
|
|
371
|
-
if (analysis.data.cycles.length > 0) {
|
|
372
|
-
console.warn(`Found ${analysis.data.cycles.length} circular reasoning chains`);
|
|
373
|
-
}
|
|
161
|
+
lucern.identity // Manage API keys and sessions
|
|
374
162
|
```
|
|
375
163
|
|
|
376
|
-
|
|
164
|
+
## Edge Types
|
|
377
165
|
|
|
378
|
-
|
|
379
|
-
// Are you only collecting evidence that supports your beliefs?
|
|
380
|
-
const bias = await lucern.graph.detectBias({ topicId });
|
|
381
|
-
|
|
382
|
-
bias.data.beliefs.forEach(b => {
|
|
383
|
-
if (b.riskLevel === "critical") {
|
|
384
|
-
console.warn(
|
|
385
|
-
`"${b.canonicalText}" has ${b.supportingEvidence} supporting ` +
|
|
386
|
-
`and ${b.contradictingEvidence} contradicting evidence — ` +
|
|
387
|
-
`one-sided evidence base`
|
|
388
|
-
);
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
### Find Gaps in Your Reasoning
|
|
394
|
-
|
|
395
|
-
```typescript
|
|
396
|
-
// What beliefs have no evidence? What questions have no answers?
|
|
397
|
-
const gaps = await lucern.graph.findGaps({ topicId });
|
|
398
|
-
|
|
399
|
-
console.log(`Beliefs without evidence: ${gaps.data.unsupportedBeliefs.length}`);
|
|
400
|
-
console.log(`Beliefs without questions: ${gaps.data.untestedBeliefs.length}`);
|
|
401
|
-
console.log(`Orphan evidence: ${gaps.data.unlinkedEvidence.length}`);
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
### Falsification — What Would Disprove Your Beliefs?
|
|
405
|
-
|
|
406
|
-
```typescript
|
|
407
|
-
// Generate the questions most likely to disprove your strongest beliefs
|
|
408
|
-
const questions = await lucern.graph.falsify({ topicId });
|
|
409
|
-
|
|
410
|
-
questions.data.forEach(q => {
|
|
411
|
-
console.log(`To disprove "${q.beliefText}", ask: "${q.question}"`);
|
|
412
|
-
});
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
### Traverse the Graph
|
|
166
|
+
Six canonical reasoning relationships:
|
|
416
167
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
traversal.data.nodes.forEach(node => {
|
|
426
|
-
console.log(`[${node.epistemicLayer}] ${node.canonicalText}`);
|
|
427
|
-
});
|
|
428
|
-
```
|
|
168
|
+
| Edge | Meaning |
|
|
169
|
+
|------|---------|
|
|
170
|
+
| `supports` | Evidence reinforces a belief |
|
|
171
|
+
| `informs` | Evidence bears on a belief (directional, weighted) |
|
|
172
|
+
| `depends_on` | Belief B requires belief A to hold |
|
|
173
|
+
| `derived_from` | Belief was derived from another (lineage) |
|
|
174
|
+
| `contains` | Structural containment |
|
|
175
|
+
| `tests` | Question tests a belief (falsification link) |
|
|
429
176
|
|
|
430
|
-
##
|
|
177
|
+
## Custom Tools
|
|
431
178
|
|
|
432
|
-
|
|
179
|
+
Extend the graph with domain operations any agent can invoke:
|
|
433
180
|
|
|
434
181
|
```typescript
|
|
435
|
-
|
|
436
|
-
query: "security review priorities",
|
|
437
|
-
ranking: "weighted_v1",
|
|
438
|
-
tokenBudget: 3000,
|
|
439
|
-
includeEntities: true,
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
// The context pack is structured for direct prompt injection
|
|
443
|
-
const systemPrompt = `
|
|
444
|
-
You are a security-focused code reviewer. Your reasoning state:
|
|
445
|
-
|
|
446
|
-
FACTS (high confidence, treat as ground truth):
|
|
447
|
-
${context.data.invariants
|
|
448
|
-
.map(b => `- [${b.confidence}] ${b.canonicalText}`)
|
|
449
|
-
.join("\n")}
|
|
450
|
-
|
|
451
|
-
ACTIVE BELIEFS (current understanding, may evolve):
|
|
452
|
-
${context.data.activeBeliefs
|
|
453
|
-
.map(b => `- [${b.confidence}] ${b.canonicalText}`)
|
|
454
|
-
.join("\n")}
|
|
455
|
-
|
|
456
|
-
OPEN QUESTIONS (unresolved — investigate these):
|
|
457
|
-
${context.data.openQuestions
|
|
458
|
-
.map(q => `- [${q.priority}] ${q.text}`)
|
|
459
|
-
.join("\n")}
|
|
460
|
-
|
|
461
|
-
CONTRADICTIONS (tensions you must address):
|
|
462
|
-
${context.data.contradictions
|
|
463
|
-
.map(c => `- [${c.severity}] ${c.description}`)
|
|
464
|
-
.join("\n")}
|
|
465
|
-
|
|
466
|
-
RULES:
|
|
467
|
-
- If your analysis contradicts an active belief, flag it explicitly
|
|
468
|
-
- If you discover evidence for an open question, answer it
|
|
469
|
-
- Never silently override a high-confidence belief without evidence
|
|
470
|
-
- When uncertain, create a new question rather than stating a conclusion
|
|
471
|
-
`;
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
### Let the LLM Write Back to the Graph
|
|
475
|
-
|
|
476
|
-
```typescript
|
|
477
|
-
// After your LLM generates analysis, parse its output
|
|
478
|
-
// and write structured findings back to the graph
|
|
479
|
-
|
|
480
|
-
const findings = await llm.generate({
|
|
481
|
-
system: systemPrompt,
|
|
482
|
-
prompt: `Review this PR diff and identify security concerns:\n${prDiff}`,
|
|
483
|
-
tools: [{
|
|
484
|
-
name: "record_finding",
|
|
485
|
-
description: "Record a security finding as evidence in the reasoning graph",
|
|
486
|
-
parameters: {
|
|
487
|
-
finding: { type: "string" },
|
|
488
|
-
severity: { type: "string", enum: ["low", "medium", "high", "critical"] },
|
|
489
|
-
relatedBeliefId: { type: "string", description: "ID of the belief this relates to" },
|
|
490
|
-
supportsOrContradicts: { type: "number", description: "-1 to 1" },
|
|
491
|
-
},
|
|
492
|
-
}],
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
// Each tool call becomes evidence in the graph
|
|
496
|
-
for (const call of findings.toolCalls) {
|
|
497
|
-
await lucern.evidence.create({
|
|
498
|
-
topicId,
|
|
499
|
-
text: call.args.finding,
|
|
500
|
-
sourceUrl: `pr://review/${prNumber}`,
|
|
501
|
-
targetId: call.args.relatedBeliefId,
|
|
502
|
-
weight: call.args.supportsOrContradicts,
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
### Search the Graph Semantically
|
|
508
|
-
|
|
509
|
-
```typescript
|
|
510
|
-
// Find beliefs related to a natural language query
|
|
511
|
-
const results = await lucern.search.beliefs({
|
|
512
|
-
topicId,
|
|
513
|
-
query: "race conditions in authentication",
|
|
514
|
-
minConfidence: 0.5,
|
|
515
|
-
limit: 10,
|
|
516
|
-
});
|
|
517
|
-
|
|
518
|
-
results.data.forEach(b => {
|
|
519
|
-
console.log(`[${b.confidence}] ${b.canonicalText}`);
|
|
520
|
-
});
|
|
521
|
-
|
|
522
|
-
// Search evidence
|
|
523
|
-
const evidence = await lucern.search.evidence({
|
|
524
|
-
topicId,
|
|
525
|
-
query: "token refresh timing data",
|
|
526
|
-
limit: 5,
|
|
527
|
-
});
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
## Agent Configuration
|
|
531
|
-
|
|
532
|
-
### CLAUDE.md / AGENTS.md Integration
|
|
533
|
-
|
|
534
|
-
Add Lucern context to your coding agent's system instructions:
|
|
535
|
-
|
|
536
|
-
```markdown
|
|
537
|
-
<!-- In your CLAUDE.md or AGENTS.md -->
|
|
538
|
-
|
|
539
|
-
## Reasoning Graph
|
|
540
|
-
|
|
541
|
-
This project uses Lucern for knowledge management. Before making
|
|
542
|
-
architectural decisions, check the reasoning graph:
|
|
543
|
-
|
|
544
|
-
- Read current beliefs: `lucern.beliefs.list({ topicId: "..." })`
|
|
545
|
-
- Check for contradictions: `lucern.contradictions.list({ topicId: "..." })`
|
|
546
|
-
- Compile context before analysis: `lucern.context.compile(topicId, { query: "..." })`
|
|
547
|
-
|
|
548
|
-
After making decisions, write them back:
|
|
549
|
-
- Create beliefs for architectural decisions
|
|
550
|
-
- Add evidence linking to the code/PR that validates them
|
|
551
|
-
- Flag contradictions when new evidence conflicts with existing beliefs
|
|
552
|
-
- Answer open questions when your work resolves them
|
|
182
|
+
import { z } from "zod";
|
|
553
183
|
|
|
554
|
-
Confidence scale:
|
|
555
|
-
- 0.90+: Verified in production
|
|
556
|
-
- 0.80-0.90: Strong evidence, working implementation
|
|
557
|
-
- 0.70-0.80: Directionally right, needs validation
|
|
558
|
-
- Below 0.70: Hypothesis, needs investigation
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
### Claude Code Skill
|
|
562
|
-
|
|
563
|
-
Create a Lucern skill for your coding agents at `~/.claude/skills/lucern-sdk/SKILL.md`:
|
|
564
|
-
|
|
565
|
-
```markdown
|
|
566
|
-
# Lucern SDK Skill
|
|
567
|
-
|
|
568
|
-
Use this skill when building features that read or write to the
|
|
569
|
-
reasoning graph, or when the user asks about beliefs, evidence,
|
|
570
|
-
contradictions, or knowledge state.
|
|
571
|
-
|
|
572
|
-
## Before Starting Work
|
|
573
|
-
|
|
574
|
-
Compile the current context to understand what the graph knows:
|
|
575
|
-
|
|
576
|
-
\`\`\`typescript
|
|
577
|
-
const context = await lucern.context.compile(topicId, {
|
|
578
|
-
query: "<what you're working on>",
|
|
579
|
-
tokenBudget: 2000,
|
|
580
|
-
});
|
|
581
|
-
\`\`\`
|
|
582
|
-
|
|
583
|
-
Check for open questions related to your task. If one exists, your work
|
|
584
|
-
should aim to answer it.
|
|
585
|
-
|
|
586
|
-
## After Completing Work
|
|
587
|
-
|
|
588
|
-
Record what you learned:
|
|
589
|
-
|
|
590
|
-
\`\`\`typescript
|
|
591
|
-
// Create a belief for decisions made
|
|
592
|
-
await lucern.beliefs.create({
|
|
593
|
-
topicId,
|
|
594
|
-
baseRate: 0.5,
|
|
595
|
-
canonicalText: "<what you now believe to be true>",
|
|
596
|
-
});
|
|
597
|
-
|
|
598
|
-
// Add evidence from your implementation
|
|
599
|
-
await lucern.evidence.create({
|
|
600
|
-
topicId,
|
|
601
|
-
text: "<what you observed or built>",
|
|
602
|
-
sourceUrl: "commit://<sha>",
|
|
603
|
-
targetId: beliefId,
|
|
604
|
-
weight: 0.8,
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
// Answer questions your work resolved
|
|
608
|
-
await lucern.questions.answer(questionId, {
|
|
609
|
-
text: "<the answer>",
|
|
610
|
-
confidence: "strong",
|
|
611
|
-
});
|
|
612
|
-
\`\`\`
|
|
613
|
-
```
|
|
614
|
-
|
|
615
|
-
### Custom Tool Registration for Agents
|
|
616
|
-
|
|
617
|
-
Give your agents domain-specific capabilities that interact with the graph:
|
|
618
|
-
|
|
619
|
-
```typescript
|
|
620
184
|
lucern.tools.register({
|
|
621
|
-
namespace: "
|
|
622
|
-
name: "
|
|
623
|
-
description: "
|
|
185
|
+
namespace: "support",
|
|
186
|
+
name: "classify_ticket",
|
|
187
|
+
description: "Classify a support ticket and link it to relevant beliefs",
|
|
624
188
|
inputSchema: z.object({
|
|
625
|
-
|
|
626
|
-
|
|
189
|
+
ticketId: z.string(),
|
|
190
|
+
content: z.string(),
|
|
627
191
|
topicId: z.string(),
|
|
628
192
|
}),
|
|
629
193
|
outputSchema: z.object({
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
currentConfidence: z.number(),
|
|
634
|
-
impact: z.enum(["strengthens", "weakens", "invalidates"]),
|
|
635
|
-
})),
|
|
194
|
+
category: z.string(),
|
|
195
|
+
linkedBeliefs: z.array(z.string()),
|
|
196
|
+
suggestedQuestions: z.array(z.string()),
|
|
636
197
|
}),
|
|
637
|
-
handler: async ({
|
|
638
|
-
//
|
|
639
|
-
|
|
640
|
-
topicId,
|
|
641
|
-
query: `${filePath} ${changeDescription}`,
|
|
642
|
-
});
|
|
643
|
-
// Analyze impact...
|
|
644
|
-
return { affectedBeliefs: analyzeImpact(related, changeDescription) };
|
|
198
|
+
handler: async ({ ticketId, content, topicId }) => {
|
|
199
|
+
// Your classification logic
|
|
200
|
+
return classifyAndLink(ticketId, content, topicId);
|
|
645
201
|
},
|
|
646
202
|
});
|
|
647
203
|
```
|
|
648
204
|
|
|
649
|
-
## Worktree Patterns
|
|
650
|
-
|
|
651
|
-
### List and Resume Investigations
|
|
652
|
-
|
|
653
|
-
```typescript
|
|
654
|
-
// See all active investigations
|
|
655
|
-
const worktrees = await lucern.worktrees.list({
|
|
656
|
-
topicId,
|
|
657
|
-
status: "active",
|
|
658
|
-
});
|
|
659
|
-
|
|
660
|
-
worktrees.data.forEach(wt => {
|
|
661
|
-
console.log(`${wt.title} — phase: ${wt.phase}, beliefs: ${wt.beliefCount}`);
|
|
662
|
-
});
|
|
663
|
-
|
|
664
|
-
// Get the full state of an investigation
|
|
665
|
-
const investigation = await lucern.worktrees.get(worktreeId);
|
|
666
|
-
console.log(`Hypothesis: ${investigation.data.hypothesis}`);
|
|
667
|
-
console.log(`Questions: ${investigation.data.questionCount} open`);
|
|
668
|
-
console.log(`Evidence: ${investigation.data.evidenceCount} collected`);
|
|
669
|
-
```
|
|
670
|
-
|
|
671
|
-
### Merge an Investigation
|
|
672
|
-
|
|
673
|
-
When the investigation is complete, merge findings into the main graph:
|
|
674
|
-
|
|
675
|
-
```typescript
|
|
676
|
-
await lucern.worktrees.merge(worktreeId, {
|
|
677
|
-
summary: "Static analysis catches 53% of vulns overall but has zero coverage for business logic flaws",
|
|
678
|
-
outcomes: [
|
|
679
|
-
{
|
|
680
|
-
beliefId: hypothesis.data.nodeId,
|
|
681
|
-
confidence: 0.2,
|
|
682
|
-
rationale: "Overall catch rate was 53%, not <30% — but the category breakdown is more important",
|
|
683
|
-
},
|
|
684
|
-
{
|
|
685
|
-
beliefId: evolved.data.nodeId,
|
|
686
|
-
confidence: 0.88,
|
|
687
|
-
rationale: "Direct comparison data confirms the coverage gap hypothesis at category level",
|
|
688
|
-
},
|
|
689
|
-
],
|
|
690
|
-
});
|
|
691
|
-
```
|
|
692
|
-
|
|
693
|
-
## Confidence History
|
|
694
|
-
|
|
695
|
-
Every confidence change is recorded with full provenance:
|
|
696
|
-
|
|
697
|
-
```typescript
|
|
698
|
-
const history = await lucern.beliefs.confidenceHistory(beliefId);
|
|
699
|
-
|
|
700
|
-
history.data.forEach(entry => {
|
|
701
|
-
console.log(
|
|
702
|
-
`${new Date(entry.timestamp).toISOString()} ` +
|
|
703
|
-
`${entry.previousConfidence} -> ${entry.confidence} ` +
|
|
704
|
-
`[${entry.trigger}] ${entry.rationale}`
|
|
705
|
-
);
|
|
706
|
-
});
|
|
707
|
-
|
|
708
|
-
// Example output:
|
|
709
|
-
// 2026-04-10T14:00:00Z null -> 0.60 [manual] Anecdotal observation
|
|
710
|
-
// 2026-04-11T09:30:00Z 0.60 -> 0.75 [evidence_added] Semgrep data supports
|
|
711
|
-
// 2026-04-11T16:00:00Z 0.75 -> 0.20 [evidence_added] Comparison study contradicted
|
|
712
|
-
```
|
|
713
|
-
|
|
714
205
|
## Authentication
|
|
715
206
|
|
|
716
207
|
```typescript
|