@tangle-network/agent-knowledge 6.1.11 → 6.2.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.
@@ -0,0 +1,291 @@
1
+ //#region src/types.d.ts
2
+ type KnowledgeId = string;
3
+ interface SourceAnchor {
4
+ id: string;
5
+ sourceId: string;
6
+ label?: string;
7
+ page?: number;
8
+ lineStart?: number;
9
+ lineEnd?: number;
10
+ charStart?: number;
11
+ charEnd?: number;
12
+ timestampMs?: number;
13
+ metadata?: Record<string, unknown>;
14
+ }
15
+ interface SourceRecord {
16
+ id: KnowledgeId;
17
+ uri: string;
18
+ title?: string;
19
+ mediaType?: string;
20
+ contentHash: string;
21
+ text?: string;
22
+ anchors?: SourceAnchor[];
23
+ /** ISO timestamp after which consumers should treat this source as stale. */
24
+ validUntil?: string;
25
+ /** ISO timestamp for the last successful source freshness verification. */
26
+ lastVerifiedAt?: string;
27
+ metadata?: Record<string, unknown>;
28
+ createdAt: string;
29
+ }
30
+ interface SourceRegistry {
31
+ generatedAt: string;
32
+ sources: SourceRecord[];
33
+ }
34
+ interface ClaimRef {
35
+ sourceId: string;
36
+ anchorId?: string;
37
+ quote?: string;
38
+ }
39
+ interface KnowledgeClaim {
40
+ id: KnowledgeId;
41
+ text: string;
42
+ refs: ClaimRef[];
43
+ confidence?: number;
44
+ status?: 'draft' | 'active' | 'superseded' | 'rejected';
45
+ metadata?: Record<string, unknown>;
46
+ }
47
+ interface KnowledgeRelation {
48
+ sourceId: KnowledgeId;
49
+ targetId: KnowledgeId;
50
+ predicate: string;
51
+ weight?: number;
52
+ metadata?: Record<string, unknown>;
53
+ }
54
+ interface KnowledgeUnit {
55
+ id: KnowledgeId;
56
+ title: string;
57
+ text: string;
58
+ claims?: KnowledgeClaim[];
59
+ relations?: KnowledgeRelation[];
60
+ sourceIds?: string[];
61
+ tags?: string[];
62
+ metadata?: Record<string, unknown>;
63
+ updatedAt?: string;
64
+ }
65
+ interface KnowledgePage {
66
+ id: KnowledgeId;
67
+ path: string;
68
+ title: string;
69
+ text: string;
70
+ frontmatter: Record<string, unknown>;
71
+ sourceIds: string[];
72
+ tags: string[];
73
+ outLinks: string[];
74
+ }
75
+ interface KnowledgeGraphNode {
76
+ id: KnowledgeId;
77
+ title: string;
78
+ path: string;
79
+ tags: string[];
80
+ sourceIds: string[];
81
+ outDegree: number;
82
+ inDegree: number;
83
+ }
84
+ interface KnowledgeGraphEdge {
85
+ source: KnowledgeId;
86
+ target: KnowledgeId;
87
+ weight: number;
88
+ reasons: string[];
89
+ }
90
+ interface KnowledgeGraph {
91
+ nodes: KnowledgeGraphNode[];
92
+ edges: KnowledgeGraphEdge[];
93
+ }
94
+ interface KnowledgeIndex {
95
+ root: string;
96
+ generatedAt: string;
97
+ sources: SourceRecord[];
98
+ pages: KnowledgePage[];
99
+ graph: KnowledgeGraph;
100
+ }
101
+ interface KnowledgeSearchResult {
102
+ page: KnowledgePage;
103
+ /**
104
+ * Raw reciprocal rank fusion score. Mathematically meaningful for ordering
105
+ * but not on a [0, 1] confidence scale — typical absolute values are in the
106
+ * 0.01–0.05 range. Equal to `rrfScore`; preserved as `score` for backward
107
+ * compatibility with consumers built against earlier releases.
108
+ */
109
+ score: number;
110
+ /** Alias of `score` — the raw RRF value. Use this when intent matters. */
111
+ rrfScore: number;
112
+ /**
113
+ * Score linearly normalized to [0, 1] relative to the top hit *in this
114
+ * result set*. The top hit is always 1 (when present); subsequent hits are
115
+ * `score / topScore`. Designed to match human intuition for "how confident
116
+ * is this match" — safe to compare against fixed thresholds. Note: this is
117
+ * a within-set ranking, not a cross-query absolute confidence.
118
+ */
119
+ normalizedScore: number;
120
+ rank: number;
121
+ snippet: string;
122
+ reasons: string[];
123
+ }
124
+ interface KnowledgeLintFinding {
125
+ type: 'broken-link' | 'orphan' | 'no-outlinks' | 'uncited-claim' | 'missing-source' | 'duplicate-title' | 'duplicate-page-id' | 'duplicate-source-hash' | 'missing-frontmatter';
126
+ severity: 'info' | 'warning' | 'error';
127
+ page?: string;
128
+ message: string;
129
+ metadata?: Record<string, unknown>;
130
+ }
131
+ interface KnowledgePolicy {
132
+ id: string;
133
+ description?: string;
134
+ requiredCitationRate?: number;
135
+ allowedPathPrefixes?: string[];
136
+ metadata?: Record<string, unknown>;
137
+ }
138
+ interface KnowledgeBaseCandidate {
139
+ id: KnowledgeId;
140
+ units: KnowledgeUnit[];
141
+ retrievalPolicy?: string;
142
+ synthesisPolicy?: string;
143
+ questionPolicy?: string;
144
+ updatePolicy?: string;
145
+ metadata?: Record<string, unknown>;
146
+ }
147
+ interface KnowledgeWriteBlock {
148
+ path: string;
149
+ content: string;
150
+ }
151
+ interface KnowledgeWriteParseResult {
152
+ blocks: KnowledgeWriteBlock[];
153
+ warnings: string[];
154
+ }
155
+ /**
156
+ * The event vocabulary, as a value so the runtime schema is DERIVED from it
157
+ * rather than restated. A restated copy in `schemas.ts` drifted: it omitted
158
+ * `research.iteration`, which is the only event `runVerifiedResearchLoop`
159
+ * produces, so every attempt to store one would have been rejected. Nothing
160
+ * caught it because nothing ever stored an event. Add a type here and the
161
+ * schema accepts it in the same edit.
162
+ */
163
+ declare const KNOWLEDGE_EVENT_TYPES: readonly ['source.added', 'proposal.applied', 'index.built', 'lint.run', 'research.iteration', 'optimization.run', 'release.promoted', 'release.rejected'];
164
+ type KnowledgeEventType = (typeof KNOWLEDGE_EVENT_TYPES)[number];
165
+ interface KnowledgeEvent {
166
+ id: string;
167
+ type: KnowledgeEventType;
168
+ createdAt: string;
169
+ actor?: string;
170
+ target?: string;
171
+ metadata?: Record<string, unknown>;
172
+ }
173
+ /** The four deep sub-question kinds a research driver raises to drive depth. */
174
+ type DeepQuestionKind = 'comparative' | 'mechanism' | 'gap' | 'contradiction';
175
+ /**
176
+ * A deep sub-question the research driver folds into the worker's next prompt.
177
+ *
178
+ * Lives here, next to the other record types, because it is persisted state:
179
+ * `addressed` is the half of the completion oracle that cannot be recomputed
180
+ * from the claim ledger alone, so a run that loses it reports "complete" for
181
+ * questions nobody ever answered.
182
+ */
183
+ interface DeepQuestion {
184
+ kind: DeepQuestionKind;
185
+ text: string;
186
+ /** sha256-derived stable id, so "addressed" can be tracked across rounds. */
187
+ id: string;
188
+ /** Claim id(s) this question interrogates (for contradiction/mechanism kinds). */
189
+ claimIds: string[];
190
+ /** True once a later round's evidence addressed it. */
191
+ addressed: boolean;
192
+ /** The round this question was raised in. */
193
+ raisedRound: number;
194
+ }
195
+ /** One live tracked claim exposed by the research-driving API. */
196
+ interface TrackedClaim {
197
+ id: string;
198
+ /** The claim text as first extracted (kept for prompts/audit). */
199
+ text: string;
200
+ /** Canonical hosts of the INDEPENDENT sources that assert this claim. */
201
+ supportingHosts: Set<string>;
202
+ /** Source URIs that assert this claim (provenance; may share a host). */
203
+ supportingUris: string[];
204
+ /** Claim ids this claim was found to CONTRADICT (and vice versa). */
205
+ contradicts: Set<string>;
206
+ /**
207
+ * CONTESTED = a contradiction the loop surfaced but could not resolve to a
208
+ * single supported claim. A contested claim counts as "settled enough to be
209
+ * done" (we report the disagreement) even with < 2 independent sources.
210
+ */
211
+ contested: boolean;
212
+ firstSeenRound: number;
213
+ }
214
+ /**
215
+ * JSON-safe form of a tracked claim stored in a research claim ledger.
216
+ *
217
+ * The live `TrackedClaim` contract retains its published `Set` fields.
218
+ * Durable records use sorted arrays because `JSON.stringify` turns a `Set`
219
+ * into `{}`, which would erase every corroboration count and contradiction.
220
+ */
221
+ interface ResearchClaimRecord {
222
+ id: string;
223
+ text: string;
224
+ supportingHosts: string[];
225
+ supportingUris: string[];
226
+ contradicts: string[];
227
+ contested: boolean;
228
+ firstSeenRound: number;
229
+ }
230
+ /**
231
+ * One immutable claim extraction observed while a source is being verified.
232
+ *
233
+ * An observation is deliberately separate from `ResearchClaimRecord`: source
234
+ * verification happens before source registration, and a process can die in
235
+ * between. The observation is durable immediately, but it contributes support
236
+ * to a claim only after `sourceUri` appears in the ledger's independently
237
+ * confirmed `registeredSourceUris` set.
238
+ */
239
+ interface ResearchClaimEvidence {
240
+ /** Stable identity of this claim/source/contradiction observation. */
241
+ id: string;
242
+ claimId: string;
243
+ text: string;
244
+ sourceUri: string;
245
+ /** Existing claim this observation directly contradicts, when reported. */
246
+ contradictsClaimId?: string;
247
+ firstSeenRound: number;
248
+ }
249
+ /**
250
+ * The durable record of one research run's belief state: which claims were
251
+ * extracted, how independently each is supported, which contradict which, and
252
+ * which deep sub-questions are still open.
253
+ *
254
+ * `id` names the run — one knowledge base can host several, and they must not
255
+ * overwrite each other, so the store addresses ledgers by this id.
256
+ */
257
+ interface ResearchClaimLedger {
258
+ id: string;
259
+ /** The research goal this ledger accumulated evidence for. */
260
+ goal?: string;
261
+ /** ISO timestamp of the last write. */
262
+ updatedAt: string;
263
+ /** How many rounds the driver has folded steer for. */
264
+ rounds: number;
265
+ /**
266
+ * Highest round durably announced before its synchronous question-generation
267
+ * step began. Greater than `rounds` only while a round needs crash recovery.
268
+ */
269
+ preparedRounds?: number;
270
+ /**
271
+ * Extracted evidence, including observations whose source registration has
272
+ * not yet been confirmed. Pending observations never count toward claims.
273
+ */
274
+ claimEvidence: ResearchClaimEvidence[];
275
+ /** Exact original source URIs confirmed present in the source registry. */
276
+ registeredSourceUris: string[];
277
+ claims: ResearchClaimRecord[];
278
+ questions: DeepQuestion[];
279
+ }
280
+ interface KnowledgeRelease {
281
+ id: string;
282
+ candidateId: string;
283
+ createdAt: string;
284
+ promoted: boolean;
285
+ scorecard?: unknown;
286
+ runRecordIds?: string[];
287
+ metadata?: Record<string, unknown>;
288
+ }
289
+ //#endregion
290
+ export { ResearchClaimEvidence as C, SourceRecord as D, SourceAnchor as E, SourceRegistry as O, KnowledgeWriteParseResult as S, ResearchClaimRecord as T, KnowledgeRelation as _, KnowledgeBaseCandidate as a, KnowledgeUnit as b, KnowledgeEventType as c, KnowledgeGraphNode as d, KnowledgeId as f, KnowledgePolicy as g, KnowledgePage as h, KNOWLEDGE_EVENT_TYPES as i, TrackedClaim as k, KnowledgeGraph as l, KnowledgeLintFinding as m, DeepQuestion as n, KnowledgeClaim as o, KnowledgeIndex as p, DeepQuestionKind as r, KnowledgeEvent as s, ClaimRef as t, KnowledgeGraphEdge as u, KnowledgeRelease as v, ResearchClaimLedger as w, KnowledgeWriteBlock as x, KnowledgeSearchResult as y };
291
+ //# sourceMappingURL=types-Cd57BPRt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types-DcCCzreS.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";KAAY;UAEK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;;UAGI;EACf,IAAI;EACJ;EACA;EACA;EACA;EACA;EACA,UAAU;;EAEV;;EAEA;EACA,WAAW;EACX;;UAGe;EACf;EACA,SAAS;;UAGM;EACf;EACA;EACA;;UAGe;EACf,IAAI;EACJ;EACA,MAAM;EACN;EACA;EACA,WAAW;;UAGI;EACf,UAAU;EACV,UAAU;EACV;EACA;EACA,WAAW;;UAGI;EACf,IAAI;EACJ;EACA;EACA,SAAS;EACT,YAAY;EACZ;EACA;EACA,WAAW;EACX;;UAGe;EACf,IAAI;EACJ;EACA;EACA;EACA,aAAa;EACb;EACA;EACA;;UAGe;EACf,IAAI;EACJ;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf,QAAQ;EACR,QAAQ;EACR;EACA;;UAGe;EACf,OAAO;EACP,OAAO;;UAGQ;EACf;EACA;EACA,SAAS;EACT,OAAO;EACP,OAAO;;UAGQ;EACf,MAAM;;;;;;;EAON;;EAEA;;;;;;;;EAQA;EACA;EACA;EACA;;UAGe;EACf;EAUA;EACA;EACA;EACA,WAAW;;UAGI;EACf;EACA;EACA;EACA;EACA,WAAW;;UAGI;EACf,IAAI;EACJ,OAAO;EACP;EACA;EACA;EACA;EACA,WAAW;;UAGI;EACf;EACA;;UAGe;EACf,QAAQ;EACR;;KAGU;UAUK;EACf;EACA,MAAM;EACN;EACA;EACA;EACA,WAAW;;UAGI;EACf;EACA;EACA;EACA;EACA;EACA;EACA,WAAW"}
1
+ {"version":3,"file":"types-Cd57BPRt.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";KAAY;UAEK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;;UAGI;EACf,IAAI;EACJ;EACA;EACA;EACA;EACA;EACA,UAAU;;EAEV;;EAEA;EACA,WAAW;EACX;;UAGe;EACf;EACA,SAAS;;UAGM;EACf;EACA;EACA;;UAGe;EACf,IAAI;EACJ;EACA,MAAM;EACN;EACA;EACA,WAAW;;UAGI;EACf,UAAU;EACV,UAAU;EACV;EACA;EACA,WAAW;;UAGI;EACf,IAAI;EACJ;EACA;EACA,SAAS;EACT,YAAY;EACZ;EACA;EACA,WAAW;EACX;;UAGe;EACf,IAAI;EACJ;EACA;EACA;EACA,aAAa;EACb;EACA;EACA;;UAGe;EACf,IAAI;EACJ;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf,QAAQ;EACR,QAAQ;EACR;EACA;;UAGe;EACf,OAAO;EACP,OAAO;;UAGQ;EACf;EACA;EACA,SAAS;EACT,OAAO;EACP,OAAO;;UAGQ;EACf,MAAM;;;;;;;EAON;;EAEA;;;;;;;;EAQA;EACA;EACA;EACA;;UAGe;EACf;EAUA;EACA;EACA;EACA,WAAW;;UAGI;EACf;EACA;EACA;EACA;EACA,WAAW;;UAGI;EACf,IAAI;EACJ,OAAO;EACP;EACA;EACA;EACA;EACA,WAAW;;UAGI;EACf;EACA;;UAGe;EACf,QAAQ;EACR;;;;;;;;;;cAWW;KAWD,6BAA6B;UAExB;EACf;EACA,MAAM;EACN;EACA;EACA;EACA,WAAW;;;KAID;;;;;;;;;UAUK;EACf,MAAM;EACN;;EAEA;;EAEA;;EAEA;;EAEA;;;UAIe;EACf;;EAEA;;EAEA,iBAAiB;;EAEjB;;EAEA,aAAa;;;;;;EAMb;EACA;;;;;;;;;UAUe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;;UAYe;;EAEf;EACA;EACA;EACA;;EAEA;EACA;;;;;;;;;;UAWe;EACf;;EAEA;;EAEA;;EAEA;;;;;EAKA;;;;;EAKA,eAAe;;EAEf;EACA,QAAQ;EACR,WAAW;;UAGI;EACf;EACA;EACA;EACA;EACA;EACA;EACA,WAAW"}
@@ -1,4 +1,4 @@
1
- import { c as KnowledgeGraphNode, o as KnowledgeGraph, s as KnowledgeGraphEdge } from "../types-DcCCzreS.js";
1
+ import { d as KnowledgeGraphNode, l as KnowledgeGraph, u as KnowledgeGraphEdge } from "../types-Cd57BPRt.js";
2
2
  //#region src/viz/index.d.ts
3
3
  interface KnowledgeVizNode extends KnowledgeGraphNode {
4
4
  degree: number;
@@ -28,6 +28,36 @@ Product apps own domain policies, provider accounts, vector stores, source adapt
28
28
 
29
29
  Core does not own a D1 schema or fleet dispatcher. Apps wire `KbStore` and `KnowledgeDiscoveryDispatcher` to their tenancy, queue, budget, auth, and sandbox systems.
30
30
 
31
+ ## On-disk layout
32
+
33
+ `new FileSystemKbStore({ root })` is the explicit knowledge-base-root form and owns everything under `<root>/.agent-knowledge/`.
34
+ The published `new FileSystemKbStore(directory)` form remains a direct record directory, so upgrading does not silently move an existing store.
35
+ When that string is the canonical `<root>/.agent-knowledge` directory, both forms use the root's one mutation lock; retaining the path must not create a second lock for the same files.
36
+
37
+ | Path | Record |
38
+ | --- | --- |
39
+ | `.agent-knowledge/index.json` | the built knowledge index (`writeKnowledgeIndex` writes it through this store) |
40
+ | `.agent-knowledge/events.json` | the knowledge event log, including one `research.iteration` per research-loop round |
41
+ | `.agent-knowledge/claim-ledgers/<id>.json` | one research run's claim ledger — corroboration counts, contradiction edges, open deep questions |
42
+ | `.agent-knowledge/sources.json` | the immutable source registry |
43
+ | `.agent-knowledge/mutation.lock.durable`, `mutation-epoch.json`, `file-transactions/` | the cross-process mutation lock and its crash-recovery state |
44
+
45
+ The root is also the directory `withKnowledgeMutation` locks, so every record above is written under one lock and one epoch.
46
+ There is exactly one writer per file: a second index writer alongside this one is a defect, not a variation.
47
+
48
+ A claim ledger is the one record several writers legitimately share — a resumed run beside a live one, or several workers researching one goal in parallel.
49
+ They reach it through `mergeClaimLedger(id, merge)`, which holds the mutation lock across the read, the merge, and the write, so no writer can build its record from a value another writer has already replaced.
50
+ `putClaimLedger` writes the whole record and is correct only for a single writer.
51
+ The combining rule is `mergeClaimLedgers`: support and contradiction edges union, `contested` and `addressed` latch on, `firstSeenRound` moves earlier, and every collection is sorted — so the merge is commutative, associative, and idempotent, and the bytes on disk depend on the evidence rather than on scheduling.
52
+ Ledgers for two different goals refuse to merge (`ClaimLedgerGoalConflictError`) rather than pooling unrelated evidence into one corroboration count.
53
+ The live driver exposes the published Set-based `TrackedClaim`; the ledger stores a separate `ResearchClaimRecord` with sorted arrays so JSON serialization cannot erase those sets.
54
+ Source verification first persists a `ResearchClaimEvidence` observation that cannot affect claim support or completion, then `runVerifiedResearchLoop` calls `commitSources` only after the source registry write succeeds.
55
+ The ledger unions those observations with exact confirmed original source URIs and materializes only their intersection, so a crash on either side resumes safely without treating an absent source as evidence or losing a registered source's claim.
56
+ Before synchronous question generation, the persistent driver records `preparedRounds`; a resume reconstructs and checkpoints any prepared round whose questions were interrupted, and the loop publishes its `research.iteration` event only after that checkpoint succeeds.
57
+
58
+ Every write in this layer goes through `durable-fs` (`writeFileDurable`, `writeJsonDurableWithinRoot`) — temp file, fsync, atomic rename, fsync parent, through `O_NOFOLLOW` descriptors anchored via `/proc/self/fd` so a directory swapped for a symlink mid-write cannot redirect it outside the root.
59
+ These are exported from the package entrypoint; consumers that keep their own journals should use them rather than reimplement them.
60
+
31
61
  ## Runtime Loop
32
62
 
33
63
  1. Normalize sources into immutable source records.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-knowledge",
3
- "version": "6.1.11",
3
+ "version": "6.2.0",
4
4
  "description": "Build, search, evaluate, and improve source-backed knowledge bases.",
5
5
  "homepage": "https://github.com/tangle-network/agent-knowledge#readme",
6
6
  "repository": {