@tangle-network/agent-knowledge 6.1.11 → 7.0.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.
- package/AGENTS.md +9 -0
- package/CHANGELOG.md +25 -0
- package/README.md +1 -1
- package/dist/benchmarks/index.d.ts +1 -1
- package/dist/benchmarks/index.js +1 -1
- package/dist/{benchmarks-CmW6iORW.js → benchmarks-C8L7HJb4.js} +2 -2
- package/dist/{benchmarks-CmW6iORW.js.map → benchmarks-C8L7HJb4.js.map} +1 -1
- package/dist/cli.js +1 -1
- package/dist/{ids-DRqPZ42_.js → ids-Bevz_pXV.js} +6 -2
- package/dist/ids-Bevz_pXV.js.map +1 -0
- package/dist/{index-CIW3G4s_.d.ts → index-D0wc4GYg.d.ts} +2 -2
- package/dist/{index-CIW3G4s_.d.ts.map → index-D0wc4GYg.d.ts.map} +1 -1
- package/dist/{index-CGBctbit.d.ts → index-Dwp3Mx-w.d.ts} +3 -3
- package/dist/{index-CGBctbit.d.ts.map → index-Dwp3Mx-w.d.ts.map} +1 -1
- package/dist/index.d.ts +377 -43
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +294 -198
- package/dist/index.js.map +1 -1
- package/dist/{inspect-DAXpFyrs.js → inspect-CJQGYuKa.js} +809 -17
- package/dist/inspect-CJQGYuKa.js.map +1 -0
- package/dist/memory/index.d.ts +2 -2
- package/dist/memory/index.js +2 -2
- package/dist/{memory-C6KPRhoU.js → memory-CIYRB_Q8.js} +3 -3
- package/dist/{memory-C6KPRhoU.js.map → memory-CIYRB_Q8.js.map} +1 -1
- package/dist/sources/index.js +1 -1
- package/dist/types-BOfmvDe-.d.ts +306 -0
- package/dist/{types-DcCCzreS.d.ts.map → types-BOfmvDe-.d.ts.map} +1 -1
- package/dist/viz/index.d.ts +1 -1
- package/docs/architecture.md +32 -0
- package/package.json +1 -1
- package/dist/ids-DRqPZ42_.js.map +0 -1
- package/dist/inspect-DAXpFyrs.js.map +0 -1
- package/dist/types-DcCCzreS.d.ts +0 -175
package/dist/sources/index.js
CHANGED
|
@@ -0,0 +1,306 @@
|
|
|
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
|
+
/** Immutable identity of one exact version of an original source URI. */
|
|
231
|
+
interface ResearchSourceVersion {
|
|
232
|
+
/** Canonical source-registry id for this URI and content hash. */
|
|
233
|
+
sourceId: KnowledgeId;
|
|
234
|
+
/** The URI supplied before the source was copied into the raw-source store. */
|
|
235
|
+
uri: string;
|
|
236
|
+
/** SHA-256 of the exact submitted source text. */
|
|
237
|
+
contentHash: string;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* One immutable claim extraction observed while a source is being verified.
|
|
241
|
+
*
|
|
242
|
+
* An observation is deliberately separate from `ResearchClaimRecord`: source
|
|
243
|
+
* verification happens before source registration, and a process can die in
|
|
244
|
+
* between. The observation is durable immediately, but it contributes support
|
|
245
|
+
* to a claim only after its expected registry id, original URI, and content hash
|
|
246
|
+
* appear together in the ledger's independently confirmed `registeredSources` set.
|
|
247
|
+
*/
|
|
248
|
+
interface ResearchClaimEvidence {
|
|
249
|
+
/** Stable identity of this claim/source/contradiction observation. */
|
|
250
|
+
id: string;
|
|
251
|
+
claimId: string;
|
|
252
|
+
text: string;
|
|
253
|
+
/** Canonical source-registry id expected for this source version. */
|
|
254
|
+
sourceId: KnowledgeId;
|
|
255
|
+
sourceUri: string;
|
|
256
|
+
/** SHA-256 of the exact source text from which this observation was extracted. */
|
|
257
|
+
sourceContentHash: string;
|
|
258
|
+
/** Existing claim this observation directly contradicts, when reported. */
|
|
259
|
+
contradictsClaimId?: string;
|
|
260
|
+
firstSeenRound: number;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* The durable record of one research run's belief state: which claims were
|
|
264
|
+
* extracted, how independently each is supported, which contradict which, and
|
|
265
|
+
* which deep sub-questions are still open.
|
|
266
|
+
*
|
|
267
|
+
* `id` names the run — one knowledge base can host several, and they must not
|
|
268
|
+
* overwrite each other, so the store addresses ledgers by this id.
|
|
269
|
+
*/
|
|
270
|
+
interface ResearchClaimLedger {
|
|
271
|
+
/** Persistent contract version; version 2 binds evidence to source content. */
|
|
272
|
+
schemaVersion: 2;
|
|
273
|
+
id: string;
|
|
274
|
+
/** The research goal this ledger accumulated evidence for. */
|
|
275
|
+
goal?: string;
|
|
276
|
+
/** ISO timestamp of the last write. */
|
|
277
|
+
updatedAt: string;
|
|
278
|
+
/** How many rounds the driver has folded steer for. */
|
|
279
|
+
rounds: number;
|
|
280
|
+
/**
|
|
281
|
+
* Highest round durably announced before its synchronous question-generation
|
|
282
|
+
* step began. Greater than `rounds` only while a round needs crash recovery.
|
|
283
|
+
*/
|
|
284
|
+
preparedRounds?: number;
|
|
285
|
+
/**
|
|
286
|
+
* Extracted evidence, including observations whose source registration has
|
|
287
|
+
* not yet been confirmed. Pending observations never count toward claims.
|
|
288
|
+
*/
|
|
289
|
+
claimEvidence: ResearchClaimEvidence[];
|
|
290
|
+
/** Exact source-registry identities confirmed after their raw bytes were stored. */
|
|
291
|
+
registeredSources: ResearchSourceVersion[];
|
|
292
|
+
claims: ResearchClaimRecord[];
|
|
293
|
+
questions: DeepQuestion[];
|
|
294
|
+
}
|
|
295
|
+
interface KnowledgeRelease {
|
|
296
|
+
id: string;
|
|
297
|
+
candidateId: string;
|
|
298
|
+
createdAt: string;
|
|
299
|
+
promoted: boolean;
|
|
300
|
+
scorecard?: unknown;
|
|
301
|
+
runRecordIds?: string[];
|
|
302
|
+
metadata?: Record<string, unknown>;
|
|
303
|
+
}
|
|
304
|
+
//#endregion
|
|
305
|
+
export { TrackedClaim as A, ResearchClaimEvidence as C, SourceAnchor as D, ResearchSourceVersion as E, SourceRecord 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, SourceRegistry 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 };
|
|
306
|
+
//# sourceMappingURL=types-BOfmvDe-.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types-
|
|
1
|
+
{"version":3,"file":"types-BOfmvDe-.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;;;UAIe;;EAEf,UAAU;;EAEV;;EAEA;;;;;;;;;;;UAYe;;EAEf;EACA;EACA;;EAEA,UAAU;EACV;;EAEA;;EAEA;EACA;;;;;;;;;;UAWe;;EAEf;EACA;;EAEA;;EAEA;;EAEA;;;;;EAKA;;;;;EAKA,eAAe;;EAEf,mBAAmB;EACnB,QAAQ;EACR,WAAW;;UAGI;EACf;EACA;EACA;EACA;EACA;EACA;EACA,WAAW"}
|
package/dist/viz/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as KnowledgeGraphNode, l as KnowledgeGraph, u as KnowledgeGraphEdge } from "../types-BOfmvDe-.js";
|
|
2
2
|
//#region src/viz/index.d.ts
|
|
3
3
|
interface KnowledgeVizNode extends KnowledgeGraphNode {
|
|
4
4
|
degree: number;
|
package/docs/architecture.md
CHANGED
|
@@ -28,6 +28,38 @@ 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 snapshots the proposal and persists a `ResearchClaimEvidence` observation containing the expected registry id, original URI, and full content hash; that observation cannot affect claim support or completion by itself.
|
|
55
|
+
After the exact submitted bytes are durable, `runVerifiedResearchLoop` passes the resulting `SourceRecord` to `commitSources`.
|
|
56
|
+
The ledger materializes only observations whose complete source identity matches a confirmed record, so reusing one URI for different bytes cannot activate the wrong claims and a crash on either side resumes safely.
|
|
57
|
+
Unversioned URI-only ledgers cannot prove which bytes produced their observations; reads and writes fail with `ClaimLedgerMigrationRequiredError` and preserve the original file for an explicit archive-and-reverify migration.
|
|
58
|
+
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.
|
|
59
|
+
|
|
60
|
+
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.
|
|
61
|
+
These are exported from the package entrypoint; consumers that keep their own journals should use them rather than reimplement them.
|
|
62
|
+
|
|
31
63
|
## Runtime Loop
|
|
32
64
|
|
|
33
65
|
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": "
|
|
3
|
+
"version": "7.0.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": {
|
package/dist/ids-DRqPZ42_.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ids-DRqPZ42_.js","names":[],"sources":["../src/ids.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\n\nexport function sha256(text: string): string {\n return createHash('sha256').update(text).digest('hex')\n}\n\nexport function slugify(input: string): string {\n const out = input\n .trim()\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9\\u4e00-\\u9fff]+/g, '-')\n .replace(/^-+|-+$/g, '')\n return out || 'untitled'\n}\n\nexport function stableId(prefix: string, content: string): string {\n return `${prefix}_${sha256(content).slice(0, 16)}`\n}\n"],"mappings":";;AAEA,SAAgB,OAAO,MAAsB;CAC3C,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK;AACvD;AAEA,SAAgB,QAAQ,OAAuB;CAQ7C,OAPY,MACT,KAAK,CAAC,CACN,YAAY,CAAC,CACb,UAAU,MAAM,CAAC,CACjB,QAAQ,oBAAoB,EAAE,CAAC,CAC/B,QAAQ,4BAA4B,GAAG,CAAC,CACxC,QAAQ,YAAY,EACd,KAAK;AAChB;AAEA,SAAgB,SAAS,QAAgB,SAAyB;CAChE,OAAO,GAAG,OAAO,GAAG,OAAO,OAAO,CAAC,CAAC,MAAM,GAAG,EAAE;AACjD"}
|