@tangle-network/agent-knowledge 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/AGENTS.md +32 -18
  2. package/CHANGELOG.md +32 -0
  3. package/README.md +31 -19
  4. package/dist/benchmarks/index.d.ts +51 -3
  5. package/dist/benchmarks/index.js +1 -1
  6. package/dist/{chunk-EUAXSBMH.js → chunk-AKYJG2MR.js} +224 -224
  7. package/dist/chunk-AKYJG2MR.js.map +1 -0
  8. package/dist/{chunk-DW6APRTX.js → chunk-BBCIB4UL.js} +2486 -2457
  9. package/dist/chunk-BBCIB4UL.js.map +1 -0
  10. package/dist/{chunk-UWOTQNBI.js → chunk-CPMLJYA3.js} +1886 -1842
  11. package/dist/chunk-CPMLJYA3.js.map +1 -0
  12. package/dist/{chunk-WCYW2GDA.js → chunk-MYFM6LKH.js} +2 -2
  13. package/dist/chunk-MYFM6LKH.js.map +1 -0
  14. package/dist/cli.js +1 -1
  15. package/dist/index.d.ts +48 -52
  16. package/dist/index.js +2906 -2874
  17. package/dist/index.js.map +1 -1
  18. package/dist/memory/index.d.ts +129 -6
  19. package/dist/memory/index.js +2 -2
  20. package/dist/sources/index.d.ts +17 -33
  21. package/dist/sources/index.js +1 -1
  22. package/dist/{index-Bqg1mBPt.d.ts → types-DP38encz.d.ts} +127 -284
  23. package/docs/eval/investment-material-facts.md +28 -29
  24. package/docs/eval/rag-eval-roadmap.md +6 -5
  25. package/docs/results/adaptive.md +13 -13
  26. package/docs/results/claim-grounding.md +11 -11
  27. package/docs/results/cost-quality.md +4 -4
  28. package/docs/results/investment-thesis.md +56 -56
  29. package/docs/results/research-driving.md +54 -54
  30. package/docs/two-agent-research-ab.md +94 -94
  31. package/package.json +4 -7
  32. package/dist/chunk-DW6APRTX.js.map +0 -1
  33. package/dist/chunk-EUAXSBMH.js.map +0 -1
  34. package/dist/chunk-UWOTQNBI.js.map +0 -1
  35. package/dist/chunk-WCYW2GDA.js.map +0 -1
@@ -10,34 +10,34 @@ fixed. A *worker* agent searches the web and proposes sources for the knowledge
10
10
  base's open gaps; a *driver* agent vets each proposed source before it commits,
11
11
  fills gaps the worker missed, and decides when the base is complete. Over 9
12
12
  machine-learning topics at equal compute, the two-agent loop admitted **2.3–2.7
13
- fewer sources per topic at identical coverage** 95% bootstrap intervals
13
+ fewer sources per topic at identical coverage**, 95% bootstrap intervals
14
14
  [1.78, 2.89] and [2.22, 3.00] across two independent runs, both above zero. The
15
15
  effect is real and reproduces. But the mechanism is not the one we set out to
16
- test: reading the rejection logs, most of the gain is **de-duplication** the
17
- same paper fetched from arXiv, OpenReview, and the NeurIPS proceedings not the
16
+ test: reading the rejection logs, most of the gain is **de-duplication**, the
17
+ same paper fetched from arXiv, OpenReview, and the NeurIPS proceedings, not the
18
18
  relevance filtering we expected. Pricing the verifier's calls (we added per-arm
19
19
  router-usage instrumentation) shows the cleanliness costs roughly **5× the
20
- dollars, 9× the tokens, and 3× the latency** of the single agent and that the
20
+ dollars, 9× the tokens, and 3× the latency** of the single agent, and that the
21
21
  original "equal passes" framing hid this, because it charged the verify step as
22
22
  one pass while it is actually one LLM call per proposed source. Since the win is
23
23
  de-dup-dominated, a deterministic content hash recovers most of the cleanliness at
24
- ~none of the premium. We then asked the sharper question is there an error band
25
- where an LLM verifier *does* earn its dollar? and found two, on opposite sides of
24
+ ~none of the premium. We then asked the sharper question, is there an error band
25
+ where an LLM verifier *does* earn its dollar?, and found two, on opposite sides of
26
26
  the ledger. **Misattributed citations** (an on-topic, unique, real source whose
27
27
  cited claim never appears in the page) are caught by a $0 deterministic
28
28
  text-presence check that the LLM relevance judge misses 1 in 5 times, because the
29
29
  judge structurally never sees the claim. And we built the deployable shape the
30
- cost result implied an **adaptive driver** that runs free dedup, then free
30
+ cost result implied, an **adaptive driver** that runs free dedup, then free
31
31
  heuristic triage, and escalates to the LLM only on the ambiguous tail: it cuts
32
32
  LLM verifier calls 76% and dollars 74%, recovering the de-dup half of the
33
- verifier's cleanliness while honestly giving up the relevance-judgment half on a
33
+ verifier's cleanliness while giving up the relevance-judgment half on a
34
34
  source pool dominated by authoritative hosts. The verifier earns its dollar on
35
35
  misattribution, not on de-duplication; the right production loop spends it only
36
36
  where the cheap signals can't decide. Finally we ask the harder question this whole
37
- metric can't reach a filter agent can only make the base *carry less*, never
38
- *answer more* by building the opposite agent (a **driving** driver that chases
37
+ metric can't reach, a filter agent can only make the base *carry less*, never
38
+ *answer more*, by building the opposite agent (a **driving** driver that chases
39
39
  depth and corroboration instead of pruning) and the opposite metric (a firewalled
40
- exam of 20 held-out **deep questions**, $0-graded). It is an honest null: driving
40
+ exam of 20 held-out **deep questions**, $0-graded). The result is null: driving
41
41
  does **not** reliably beat plain collection at answering hard questions, and costs
42
42
  **12–16×** more; the verdict flips with the compute budget, the signature of web
43
43
  variance rather than a real topology effect, and it still ties a blind worker even
@@ -46,15 +46,15 @@ when forced to run its full multi-round mechanism (§9).
46
46
  ## 1. Setup
47
47
 
48
48
  A research agent building a knowledge base accumulates sources. A single agent both
49
- finds sources and, implicitly, decides which to keep it grades its own work. The
49
+ finds sources and, implicitly, decides which to keep, it grades its own work. The
50
50
  hypothesis is the usual one for verification: separating the producer (find
51
51
  sources) from the checker (keep the good ones) should yield a cleaner result, for
52
52
  the same reason a second pair of eyes catches typos the author misses.
53
53
 
54
54
  The trap in any "more agents help" claim is compute. Two agents that simply do more
55
- work will of course produce more that is a bigger budget, not a finding. So the
56
- comparison must hold total compute fixed and ask whether the *topology* splitting
57
- find from check beats spending the same compute on a single agent that just finds
55
+ work will of course produce more, that is a bigger budget, not a finding. So the
56
+ comparison must hold total compute fixed and ask whether the *topology*, splitting
57
+ find from check, beats spending the same compute on a single agent that just finds
58
58
  more. And once topology shows an effect, the second question is what it costs: a
59
59
  cleaner base bought at 5× the inference is a different product decision than one
60
60
  bought for free.
@@ -65,9 +65,9 @@ bought for free.
65
65
 
66
66
  The loop has two roles (`src/two-agent-research-loop.ts`, `runTwoAgentResearchLoop`):
67
67
 
68
- - **Worker** primary research. Each round it reads the open gaps and proposes
68
+ - **Worker**: primary research. Each round it reads the open gaps and proposes
69
69
  sources to close them (`ResearchWorker: (ctx: { gaps, steer }) => proposals`).
70
- - **Driver** does three things (`ResearchDriver`): `verifySource` vets each
70
+ - **Driver**: does three things (`ResearchDriver`): `verifySource` vets each
71
71
  proposed source before it commits (dedup against the base, then reject sources
72
72
  that aren't relevant); `research` runs the driver's own gap-fill pass over gaps
73
73
  the worker missed; `foldGaps` turns the still-open gaps into a `steer` string for
@@ -80,7 +80,7 @@ reports no blocking gaps left.
80
80
 
81
81
  Note what the driver→worker hand-off is and isn't: the driver *steers* the worker
82
82
  by handing it the remaining readiness gaps (`foldGaps`), which is a deterministic
83
- formatting of unmet requirements not an LLM authoring a fresh instruction. The
83
+ formatting of unmet requirements, not an LLM authoring a fresh instruction. The
84
84
  driver's LLM work is in `verifySource` (one call per proposed source) and its own
85
85
  `research` pass. This matters for §4.2: the verify step is N calls, not one, and
86
86
  the cost framing turns on that.
@@ -90,14 +90,14 @@ The readiness gate is `scoreKnowledgeReadiness` (from `agent-eval`). It scores
90
90
  'blocking'` requirements gate. Coverage below is the fraction of a topic's blocking
91
91
  requirements met.
92
92
 
93
- ### 2.2 What the agents are — an honest note
93
+ ### 2.2 Implementation note
94
94
 
95
95
  The agents in the live run are **not** `AgentProfile`s on a coding harness. The
96
96
  worker is a hand-wired pipeline (`src/web-research-worker.ts`,
97
97
  `createWebResearchWorker`): glm-5.2 turns the gaps into search queries → a real web
98
98
  search over the Tangle router (`POST /v1/search`) → each hit is fetched with the
99
99
  repo's `politeFetch` and reduced to text with `htmlToText` → citing pages are
100
- proposed. It talks to the router directly through `createTangleRouterClient` no
100
+ proposed. It talks to the router directly through `createTangleRouterClient`, no
101
101
  claude-code / opencode / sandbox harness, and no dynamic harness selection. The
102
102
  driver (`createVerifyingResearchDriver`) is one glm-5.2 chat call per source.
103
103
 
@@ -109,7 +109,7 @@ Agent profiles and sandbox-backed runners now live in `agent-runtime`; this pack
109
109
  Compute is counted in agent passes. A two-agent round = 1 worker pass + 1
110
110
  verify pass = 2 passes; a single-agent iteration = 1 pass. Both arms gate on the
111
111
  *same* readiness criterion and stop as soon as it is met, so neither is starved.
112
- We budget-match by passes, not rounds the single-agent loop gets more rounds to
112
+ We budget-match by passes, not rounds, the single-agent loop gets more rounds to
113
113
  spend the compute the two-agent loop spends on verification. The harness asserts,
114
114
  per topic, that the two-agent loop spent no more passes than the single-agent loop
115
115
  and that both stayed under the ceiling; if that ever fails the comparison has
@@ -137,7 +137,7 @@ results / trade-offs). Seven are "narrow-scope-inside-a-broad-space" (e.g.
137
137
  broad space to leak in; two are clean controls (*the transformer architecture*,
138
138
  *gradient descent*).
139
139
 
140
- ## 3. Result 1 cleanliness: the verifier admits fewer sources at equal coverage
140
+ ## 3. Result 1: cleanliness: the verifier admits fewer sources at equal coverage
141
141
 
142
142
  The cleanliness signal is the **admitted-source count**: on live data there is no
143
143
  oracle, so "fewer sources admitted at equal coverage" is the measurable proxy for
@@ -157,7 +157,7 @@ oracle, so "fewer sources admitted at equal coverage" is the measurable proxy fo
157
157
  | **mean Δ** | | **2.33** | **2.67** |
158
158
  | **95% CI** (paired bootstrap) | | **[1.78, 2.89]** | **[2.22, 3.00]** |
159
159
 
160
- Coverage was **1.00 on every topic, both arms, both runs** the verifier never
160
+ Coverage was **1.00 on every topic, both arms, both runs**, the verifier never
161
161
  cost completeness. Both bootstrap intervals (`pairedBootstrap`, from `agent-eval`)
162
162
  are above zero. The effect reproduces; its exact magnitude varies run-to-run with
163
163
  what the web returns (one topic swung Δ = 0→1→3 across separate runs during
@@ -166,10 +166,10 @@ development).
166
166
  A third, cost-instrumented run (the one priced in §4.2) was noisier: mean Δ **+1.56,
167
167
  95% CI [0.33, 2.67]**, with two topics where the two-agent loop admitted *more* than
168
168
  the single agent (KV-cache quantization −1, gradient descent −1). The interval still
169
- clears zero, but it is the lower-bound run a reminder that the magnitude is
169
+ clears zero, but it is the lower-bound run, a reminder that the magnitude is
170
170
  web-variance-bound, while the sign is stable.
171
171
 
172
- ## 4. Result 2 what the verifier does, and what it costs
172
+ ## 4. Result 2: what the verifier does, and what it costs
173
173
 
174
174
  ### 4.1 Mostly de-duplication
175
175
 
@@ -181,18 +181,18 @@ We classified each rejection by the verifier's own stated reason:
181
181
  | off-scope (broad space leaked in) | 3 | 2 |
182
182
  | junk page (aggregator / marketing / explainer) | 3 | 0 |
183
183
 
184
- The dominant mechanism is **de-duplication** canonical papers mirrored across
185
- arXiv, OpenReview, and the NeurIPS proceedings and it fires regardless of band.
184
+ The dominant mechanism is **de-duplication**, canonical papers mirrored across
185
+ arXiv, OpenReview, and the NeurIPS proceedings, and it fires regardless of band.
186
186
  The off-scope rejection we set out to measure is real (on *self-speculative
187
187
  decoding* the verifier correctly dropped three general *speculative decoding* papers
188
188
  that use a *separate* draft model) but it is the minority, and it does not
189
189
  concentrate on the narrow topics as hypothesized: narrow mean Δ = 2.14 vs clean
190
- 3.00. The strong form of our hypothesis narrow-in-broad pays more is **refuted
190
+ 3.00. The strong form of our hypothesis, narrow-in-broad pays more, is **refuted
191
191
  in magnitude, confirmed only in mechanism**.
192
192
 
193
193
  The practical reading: most of the win is "you fetched the same PDF three times,"
194
194
  which a content hash catches for free. The LLM's distinctive contribution is the
195
- page that *looks* on-topic but isn't the self-speculative-vs-separate-draft
195
+ page that *looks* on-topic but isn't, the self-speculative-vs-separate-draft
196
196
  distinction a string match would miss.
197
197
 
198
198
  ### 4.2 The inference premium (and what "equal passes" hid)
@@ -207,59 +207,59 @@ distinction a string match would miss.
207
207
  | tokens (in+out) | ~4,900 | ~530 | ~9× |
208
208
  | cost (USD) | ~$0.0072 | ~$0.0013 | ~5.5× |
209
209
  | latency (wall) | ~37 s | ~11 s | ~3.4× |
210
- | cleanliness Δ (single − two admitted) | | | +1.56, 95% CI [0.33, 2.67] |
210
+ | cleanliness Δ (single − two admitted) | n/a | n/a | +1.56, 95% CI [0.33, 2.67] |
211
211
 
212
212
  The verifier buys ~1.5–2.7 fewer junk sources for roughly **5× the dollars, 9× the
213
213
  tokens, and 3× the latency**. Since the cleanliness gain is de-dup-dominated
214
- (§4.1), the honest production move is a deterministic content-hash / canonical-URL
214
+ (§4.1), the production move is a deterministic content-hash / canonical-URL
215
215
  dedup, which captures most of the cleanliness at ~none of this premium, reserving
216
216
  an LLM check only for the off-scope tail. This is the cost half the "equal passes"
217
- framing left out and the rest of the paper is what we built once we saw it.
217
+ framing left out, and the rest of the paper is what we built once we saw it.
218
218
 
219
- ## 5. Result 3 the two bands where an LLM verifier does, and doesn't, earn its dollar
219
+ ## 5. Result 3: the two bands where an LLM verifier does, and doesn't, earn its dollar
220
220
 
221
221
  If de-dup is free and dominates the win, when is the LLM verifier worth its 5×? We
222
222
  found two bands, and they cut in opposite directions.
223
223
 
224
- ### 5.1 Misattributed citations the cheap check beats the expensive judge
224
+ ### 5.1 Misattributed citations: the cheap check beats the expensive judge
225
225
 
226
226
  `docs/results/claim-grounding.md`. A source can be on-topic, unique, and real, yet
227
- the cited *claim* never appears in the page the LLM wrote a plausible sentence and
227
+ the cited *claim* never appears in the page, the LLM wrote a plausible sentence and
228
228
  hung a real URL off it. De-dup passes it (unique). A relevance judge passes it (the
229
- page is on-topic). Only checking the claim against the fetched text catches it and
229
+ page is on-topic). Only checking the claim against the fetched text catches it, and
230
230
  that check is **deterministic text presence, $0 inference**.
231
231
 
232
232
  Each proposed source now carries the claim it is cited for (`withCitedClaim` →
233
233
  `metadata.citedClaim`). The claim-grounding verifier (`createClaimGroundingVerifier`,
234
234
  `src/claim-grounding.ts`) runs `groundClaimInText(claim, pageText)` over the
235
- `htmlToText` output of the page the worker actually fetched verbatim, normalized
235
+ `htmlToText` output of the page the worker actually fetched, verbatim, normalized
236
236
  (punctuation/whitespace-insensitive), or a ≥70% content-word overlap close
237
237
  paraphrase. A claim that isn't present is rejected as misattributed. The oracle is
238
238
  text presence, not a model call, so it composes with the LLM relevance verifier or
239
239
  runs alone at zero cost.
240
240
 
241
- Live A/B (glm-5.2, real web fetch, one planted misattribution per topic a real
242
- fetched page plus a deliberately-wrong claim over three verifier arms on the same
241
+ Live A/B (glm-5.2, real web fetch, one planted misattribution per topic, a real
242
+ fetched page plus a deliberately-wrong claim, over three verifier arms on the same
243
243
  proposals):
244
244
 
245
245
  | n=5 topics | misattributions caught | marginal $ | per-$ caught |
246
246
  |---|---|---|---|
247
- | no-verifier | 0 / 5 | $0.0000 | |
247
+ | no-verifier | 0 / 5 | $0.0000 | n/a |
248
248
  | relevance (LLM judge) | 4 / 5 | $0.0157 | 254 |
249
249
  | claim-grounding (text) | **5 / 5** | **$0.0000** | ∞ |
250
250
 
251
- The relevance judge catches one only by accident when the fabricated claim also
251
+ The relevance judge catches one only by accident, when the fabricated claim also
252
252
  makes the page read off-topic (a "12-billion-parameter draft transformer" claim on a
253
253
  rotary-embeddings page). When the fabrication stays on-topic (the KV-cache case), the
254
254
  judge waves it through, because the relevance verifier only ever sees the page text,
255
- never the cited claim it is **structurally blind** to misattribution. On this band
255
+ never the cited claim, it is **structurally blind** to misattribution. On this band
256
256
  the verifier-per-dollar comparison inverts §4.2: the cheap, deterministic check
257
257
  catches strictly more (5/5 vs 4/5) at strictly less ($0 vs $0.0157). The offline
258
258
  floor confirms the wiring: on a controlled 4-source pool (2 grounded, 2
259
259
  misattributed), claim-grounding admits **0/2** misattributions and keeps **2/2**
260
260
  grounded, while relevance and no-verifier both admit **2/2**.
261
261
 
262
- ### 5.2 Adaptive topology pay the LLM only on the ambiguous tail
262
+ ### 5.2 Adaptive topology: pay the LLM only on the ambiguous tail
263
263
 
264
264
  `docs/results/adaptive.md`. The deployable shape §4.2 implied: do the free
265
265
  deterministic work first, reserve the LLM for what the cheap signals can't decide.
@@ -275,7 +275,7 @@ decides:
275
275
  github, …) with a substantial body is **kept**; an obvious spam/listicle title
276
276
  or a too-thin body is **dropped**; everything else is **ambiguous**.
277
277
  3. **LLM escalation ($).** Only ambiguous survivors reach the shipped LLM relevance
278
- verifier one call each.
278
+ verifier, one call each.
279
279
 
280
280
  Live frontier, n=5 topics, glm-5.2, same fetched proposals gated through all three
281
281
  drivers (plus one planted tracking-decorated mirror of the first source, so the
@@ -291,12 +291,12 @@ dedup stage has a real duplicate to catch). Total spend $0.033:
291
291
  | **total** | **25** | **25** | **12 / 25 / $0.0261** | **20 / 6 / $0.0068** |
292
292
 
293
293
  Adaptive cuts LLM verifier calls **76%** (25 → 6) and dollars **74%** ($0.0261 →
294
- $0.0068). On 3 of the 5 topics it spent **zero** LLM calls every unique survivor
294
+ $0.0068). On 3 of the 5 topics it spent **zero** LLM calls, every unique survivor
295
295
  was on an authoritative host, so the $0 stages decided everything.
296
296
 
297
297
  It is a frontier point, not a free lunch. Admitted counts (lower = cleaner): single
298
298
  25, **adaptive 20**, full-LLM 12. Adaptive removes the 5 real duplicates the $0 dedup
299
- catches exactly the de-dup-dominated win but keeps the 8 sources full-LLM rejects
299
+ catches, exactly the de-dup-dominated win, but keeps the 8 sources full-LLM rejects
300
300
  on relevance, because on this authoritative-host-heavy set the heuristic resolved
301
301
  every non-duplicate survivor without ever asking the LLM, and the host prior is
302
302
  coarser than the relevance judge. So adaptive **recovers the deterministic de-dup
@@ -304,26 +304,26 @@ half of full-LLM's cleanliness for ~26% of its dollars, and gives up the
304
304
  relevance-judgment half**. The escalation count is the diagnostic: on the 3 topics
305
305
  where it was zero, adaptive *is* a pure host/title/length rule and the LLM
306
306
  contributes nothing by construction; on the 2 topics with unknown-host survivors
307
- (grouped-query attention, LoRA) it escalated 3 calls each the off-scope tail the
307
+ (grouped-query attention, LoRA) it escalated 3 calls each, the off-scope tail the
308
308
  verifier is actually for.
309
309
 
310
310
  ## 6. Discussion
311
311
 
312
312
  The three results compose into one rule. The LLM verifier's headline cleanliness win
313
313
  is real (§3) but **de-dup-dominated** (§4.1) and **expensive** (§4.2, ~5×/9×/3×), so
314
- spending an LLM call on every source is the wrong default a free content hash buys
314
+ spending an LLM call on every source is the wrong default, a free content hash buys
315
315
  most of it. The verifier earns its 5× exactly where the cheap signals are blind: on
316
316
  **misattribution** (§5.1), where a $0 text-presence check beats the LLM judge
317
317
  outright because the judge never sees the claim; and on the **off-scope tail** (§5.2),
318
318
  where a page looks on-topic, is unique, and isn't fabricated, so only a relevance
319
319
  judgment can settle it. The deployable loop therefore stratifies by cost: free dedup,
320
- free claim-grounding, free heuristic triage, then an LLM call only on what survives
320
+ free claim-grounding, free heuristic triage, then an LLM call only on what survives:
321
321
  which is what the adaptive driver ships.
322
322
 
323
323
  Two cross-cutting lessons. First, **the accounting unit decides the verdict**:
324
324
  charging the verify step as one pass made the topology look near-free; pricing it per
325
325
  LLM call (§4.2) is what surfaced the 5× and motivated everything after it. Second,
326
- **the same verifier inverts in value across bands** on de-dup the LLM is expensive
326
+ **the same verifier inverts in value across bands**, on de-dup the LLM is expensive
327
327
  for what a hash does; on misattribution a deterministic check is free for what the LLM
328
328
  can't do; on the off-scope tail the LLM is the only thing that works. "Add a verifier"
329
329
  is not a setting; it is a cost-stratified decision per error type.
@@ -344,7 +344,7 @@ is not a setting; it is a cost-stratified decision per error type.
344
344
  - **Planted error bands.** The misattributions (§5.1) and the adaptive duplicate
345
345
  (§5.2) are injected so the band is measurable. They model the real LLM
346
346
  citation-fabrication and mirror-host failures but do not measure their base rate in
347
- the wild that needs a hand-checked corpus of model-written citations.
347
+ the wild, that needs a hand-checked corpus of model-written citations.
348
348
  - **Adaptive's quality is host-prior-bound.** On an authoritative-host-heavy source
349
349
  pool the heuristic resolves everything and the LLM's relevance judgment contributes
350
350
  nothing; a richer worker (good sources on unknown hosts, junk on on-topic-looking
@@ -356,20 +356,20 @@ is not a setting; it is a cost-stratified decision per error type.
356
356
  - **High web variance.** One live run per topic per result; numbers move with what
357
357
  search returns.
358
358
 
359
- ## 8. A simpler loop built, not deferred
359
+ ## 8. A simpler loop: built, not deferred
360
360
 
361
361
  The original write-up named two simplifications as future work. Both are now built and
362
362
  measured; this is what changed.
363
363
 
364
- 1. **Deterministic dedup before the LLM, LLM only on the tail shipped.** The
364
+ 1. **Deterministic dedup before the LLM, LLM only on the tail, shipped.** The
365
365
  adaptive driver (`src/adaptive-driver.ts`, §5.2) does exactly this: free
366
366
  canonical-URL / content-hash dedup, free host/title/length triage, LLM relevance
367
367
  only on the ambiguous survivors. Measured: **76% fewer LLM calls, 74% cheaper**,
368
368
  recovering the de-dup half of the verifier's cleanliness. The remaining gap to
369
- full-LLM is the relevance-judgment half, kept honest in §5.2 adaptive is a
369
+ full-LLM is the relevance-judgment half, measured separately in §5.2, adaptive is a
370
370
  frontier point you choose by how much a kept-but-marginal source costs you, not a
371
371
  strict improvement.
372
- 2. **A free check the LLM judge can't replicate shipped.** Claim-grounding
372
+ 2. **A free check the LLM judge can't replicate, shipped.** Claim-grounding
373
373
  (`src/claim-grounding.ts`, §5.1) adds the one verification an LLM relevance judge is
374
374
  structurally blind to: does the cited claim actually appear in the page? It catches
375
375
  5/5 planted misattributions at **$0**, vs the judge's 4/5 at ~$0.003/topic.
@@ -377,19 +377,19 @@ measured; this is what changed.
377
377
  What is still **not** built remains the worker: the live worker is a ~500-line
378
378
  hand-wired pipeline (query-gen, search, fetch, propose) against the router directly,
379
379
  where the runtime integration's pattern is to author an agent profile
380
- and run it on a harness with a web-search tool reusable and harness-agnostic. The
380
+ and run it on a harness with a web-search tool, reusable and harness-agnostic. The
381
381
  direct pipeline is cheaper to run today (no harness, no creds beyond the router) but it
382
382
  is the loop's main remaining piece of duplication, and the obvious next step if this
383
383
  loop graduates from experiment to production.
384
384
 
385
- ## 9. From hygiene to depth a research-DRIVING loop, measured on held-out deep questions
385
+ ## 9. From hygiene to depth: a research-DRIVING loop, measured on held-out deep questions
386
386
 
387
- Everything above measures one thing: **source hygiene** how *few* sources a verifier
387
+ Everything above measures one thing: **source hygiene**, how *few* sources a verifier
388
388
  admits at equal coverage. That is the right metric for a verifier whose only job is to
389
389
  filter, and it is why the win turned out to be de-duplication (§4.1): the most a
390
390
  filter-only verifier can do is reject. By construction it cannot make the knowledge base
391
391
  *answer more*; it can only make it *carry less*. So "the verifier mostly deduplicates" is
392
- not a disappointing finding about *this* verifier it is the ceiling of what *any*
392
+ not a disappointing finding about *this* verifier, it is the ceiling of what *any*
393
393
  admit-or-reject step can do. To ask whether a second agent can improve the research
394
394
  itself, you have to change both the agent and the metric.
395
395
 
@@ -398,17 +398,17 @@ So we built the opposite agent and gave it the opposite metric. The **driving dr
398
398
  extracts each fetched source's claims, demands a second independent source for every
399
399
  claim, generates comparative / mechanism / contradiction sub-questions, and steers the
400
400
  worker to chase them in the next round. Its thesis is that *driving the research deeper*
401
- not pruning it builds a knowledge base that answers harder questions. We measure it
402
- not on admitted-count (which would score its whole point as a regression it admits
401
+ - not pruning it, builds a knowledge base that answers harder questions. We measure it
402
+ not on admitted-count (which would score its whole point as a regression, it admits
403
403
  *more*) but on a **firewalled exam of 20 deep questions across 5 ML topics**
404
404
  (`tests/loops/held-out-exam.ts`), graded with a $0 deterministic substring grader the
405
- loop never sees. The questions are depth questions by construction the grader scores
405
+ loop never sees. The questions are depth questions by construction, the grader scores
406
406
  **0/20** on a one-line topic definition and **20/20** on a mechanism-rich paragraph, so
407
407
  a high score is reachable only by depth, not by grader slack. All three arms run the
408
408
  same real web worker and differ only in the driver: (A) plain collection, (B)
409
409
  verify/dedup, (C) driving.
410
410
 
411
- **The honest verdict: driving does NOT reliably beat plain collection, and costs
411
+ **Result: driving does NOT reliably beat plain collection, and costs
412
412
  ~12–16× more.** The tell is that the winner flips with the compute budget, on the same
413
413
  exam:
414
414
 
@@ -420,55 +420,55 @@ exam:
420
420
 
421
421
  Driving "wins" at B=4 (16 > 15 > 13) and "loses" at B=6 (13 < 15), while the
422
422
  single-agent arm itself swings 15→13 across the two budgets. At n=5 topics a ±1–3
423
- question difference is inside the run-to-run web variance the **within-arm swing is as
423
+ question difference is inside the run-to-run web variance, the **within-arm swing is as
424
424
  large as the between-arm gap**, which is the signature of a null. What is stable and
425
425
  large is the cost: an order of magnitude more dollars and ~24× the tokens, for the
426
426
  claim-extraction LLM call driving runs on every fetched source.
427
427
 
428
428
  The autopsy explains it: every arm finished in **one effective round**
429
- (`passes=2` on every topic at every budget). The generic readiness gate "one source
430
- closes the gap" is met by the first fetch, so the loop stops *before* the driving
429
+ (`passes=2` on every topic at every budget). The generic readiness gate, "one source
430
+ closes the gap", is met by the first fetch, so the loop stops *before* the driving
431
431
  driver ever steers a second round, and its entire mechanism is multi-round. So we gave
432
- it its fairest test: a controlled probe that *forces* three rounds so the driver
433
- actually steers. It **still ties** a blind worker that just re-searches the same gaps
434
- **8/12 vs 8/12, at ~9× the cost**. Driving was better on RLHF (3 vs 1 chasing
432
+ it a controlled test: a probe that *forces* three rounds so the driver
433
+ actually steers. It **still ties** a blind worker that just re-searches the same gaps:
434
+ **8/12 vs 8/12, at ~9× the cost**. Driving was better on RLHF (3 vs 1, chasing
435
435
  corroboration reached a page blind search missed) and worse on speculative decoding (2
436
- vs 4 steering pulled the worker *off* the pages that answered the exam); the two
436
+ vs 4, steering pulled the worker *off* the pages that answered the exam); the two
437
437
  cancel. The null survives the fix, so it is not an artifact of a permissive gate.
438
438
 
439
- The durable output is the apparatus, not the agent: a firewalled deep-question exam with
439
+ The durable output is the evaluation method, not the agent: a firewalled deep-question exam with
440
440
  a $0 grader that can tell depth from surface, reusable for any future research-quality
441
441
  claim. Full result, per-topic tables, and the probe: [`docs/results/research-driving.md`](results/research-driving.md).
442
442
  The two findings compose into one rule for "should I add a second research agent?":
443
443
  a **filter** agent measured on hygiene buys de-dup cleanliness you can get cheaper from a
444
444
  hash (§3–§4); a **driver** agent measured on depth buys nothing reliable over plain
445
445
  collection at this n and worker, for 9–16× the cost (§9). Neither earns a blanket "yes";
446
- both earn a narrow, cost-stratified one the verifier on misattribution and the
446
+ both earn a narrow, cost-stratified one, the verifier on misattribution and the
447
447
  off-scope tail (§5), the driver only where a richer worker makes "go corroborate this"
448
448
  reach a page collection can't.
449
449
 
450
- ### 9.1 The domain was too easy re-running the A/B where one search is not enough
450
+ ### 9.1 The domain was too easy: re-running the A/B where one search is not enough
451
451
 
452
452
  The §9 null has a structural cause, not a measurement one: **on an ML topic a single
453
453
  good search already collects the answer.** Every arm finished in one effective round
454
- because the first fetch met the readiness gate, so the driving driver whose mechanism
455
- is steering a *second* round never acted. When one search suffices, there is no
454
+ because the first fetch met the readiness gate, so the driving driver, whose mechanism
455
+ is steering a *second* round, never acted. When one search suffices, there is no
456
456
  investigation for a smarter coordinator to do, and the metric can only reward
457
457
  collection. To ask whether topology *can ever* beat blind collection, you have to move
458
458
  to a domain where the answer is buried and a single fetch provably cannot surface it.
459
459
 
460
- So we did. We ported the whole apparatus firewalled checklist, `$0` model-free
461
- grader, matched-compute 3-arm A/B onto **investment research**: give a loop a company
460
+ So we did. We ported the full method, firewalled checklist, `$0` model-free
461
+ grader, matched-compute 3-arm A/B, onto **investment research**: give a loop a company
462
462
  + ticker + an as-of cutoff and grade the thesis on the buried, material 10-K-footnote
463
463
  facts a ticker search misses (an HTM mark the size of a bank's equity, a 97%-uninsured
464
464
  deposit base, a negative per-unit margin). First we *calibrated* the new metric and
465
- proved it discriminates depth on this harder domain a shallow ticker summary scores
465
+ proved it discriminates depth on this harder domain, a shallow ticker summary scores
466
466
  **1/27 (4%)**, a deep filings-grounded thesis **27/27 (100%)**, a **+96-point** gap.
467
467
  Then the live 3-arm A/B over 5 held-out companies: **driving surfaced the most buried
468
- facts (16/27, 59%) vs blind collection (11/27, 41%)** for ~1.9× the cost the lift is
468
+ facts (16/27, 59%) vs blind collection (11/27, 41%)** for ~1.9× the cost, the lift is
469
469
  real and points the right way, but at n=5 the paired-bootstrap CI still crosses zero
470
470
  (P(Δ≤0)=0.08), and verify did not beat collection (10/27). So the verdict survives the
471
- domain change: **no topology *significantly* beats collection but on a domain where
471
+ domain change: **no topology *significantly* beats collection, but on a domain where
472
472
  the answer must be investigated for, driving is the only arm that even leans positive,
473
473
  and it does so suggestively, not significantly.** Full reframe, calibration, and
474
474
  per-company A/B: [`docs/results/investment-thesis.md`](results/investment-thesis.md).
@@ -484,7 +484,7 @@ multi-topic burn.
484
484
  git clone https://github.com/tangle-network/agent-knowledge
485
485
  cd agent-knowledge && pnpm install
486
486
 
487
- # offline A/B deterministic, no credentials (a controlled lower bound that
487
+ # offline A/B: deterministic, no credentials (a controlled lower bound that
488
488
  # exercises the same harness against a planted source pool)
489
489
  pnpm exec vitest run tests/loops/research-loop-equal-compute.test.ts
490
490
 
@@ -492,29 +492,29 @@ pnpm exec vitest run tests/loops/research-loop-equal-compute.test.ts
492
492
  pnpm exec vitest run tests/loops/claim-grounding-ab.test.ts -t "offline"
493
493
  pnpm exec vitest run tests/loops/adaptive-ab.test.ts
494
494
 
495
- # the live cleanliness sweep real web search + a real glm-5.2 verifier, with
495
+ # the live cleanliness sweep: real web search + a real glm-5.2 verifier, with
496
496
  # per-arm cost reported (~$0.20 for 9 topics)
497
497
  export TANGLE_API_KEY=<router key with glm-5.2 credits>
498
498
  AGENT_KNOWLEDGE_LIVE=1 \
499
499
  AGENT_KNOWLEDGE_LIVE_GOALS="self-speculative decoding|grouped-query attention|rotary position embeddings|KV-cache quantization|LoRA|ring attention|constitutional AI|the transformer architecture|gradient descent" \
500
500
  pnpm exec vitest run tests/loops/research-loop-equal-compute.test.ts
501
501
 
502
- # live misattribution band three verifier arms over the same proposals
502
+ # live misattribution band: three verifier arms over the same proposals
503
503
  AGENT_KNOWLEDGE_LIVE=1 TANGLE_API_KEY=<…> \
504
504
  CLAIM_GROUNDING_LIVE_GOALS='self-speculative decoding|rotary position embeddings|grouped-query attention|KV-cache quantization|LoRA' \
505
505
  pnpm exec vitest run tests/loops/claim-grounding-ab.test.ts -t "three verifier arms"
506
506
 
507
- # live adaptive frontier single / full-LLM / adaptive on the same fetched proposals
507
+ # live adaptive frontier: single / full-LLM / adaptive on the same fetched proposals
508
508
  AGENT_KNOWLEDGE_LIVE=1 TANGLE_API_KEY=<…> \
509
509
  ADAPTIVE_LIVE_GOALS="self-speculative decoding|rotary position embeddings|grouped-query attention|KV-cache quantization|LoRA fine-tuning" \
510
510
  pnpm exec vitest run tests/loops/adaptive-ab.test.ts -t "three-topology"
511
511
 
512
- # the research-DRIVING 3-arm A/B (§9) collect / verify / drive, graded on the
512
+ # the research-DRIVING 3-arm A/B (§9): collect / verify / drive, graded on the
513
513
  # held-out deep-question exam; re-run at RQ_LIVE_BUDGET=6 to see the verdict flip
514
514
  AGENT_KNOWLEDGE_LIVE=1 RQ_LIVE_BUDGET=4 TANGLE_API_KEY=<…> \
515
515
  pnpm exec vitest run tests/loops/research-driving-ab.test.ts -t "3-arm A/B"
516
516
 
517
- # the controlled multi-round probe forces 3 rounds so the driver actually steers
517
+ # the controlled multi-round probe: forces 3 rounds so the driver actually steers
518
518
  AGENT_KNOWLEDGE_LIVE=1 RQ_PROBE=1 RQ_PROBE_ROUNDS=3 TANGLE_API_KEY=<…> \
519
519
  pnpm exec vitest run tests/loops/research-driving-ab.test.ts -t "multi-round probe"
520
520
  ```
@@ -523,17 +523,17 @@ AGENT_KNOWLEDGE_LIVE=1 RQ_PROBE=1 RQ_PROBE_ROUNDS=3 TANGLE_API_KEY=<…> \
523
523
  topic list; the live arms run the loops on each at equal compute and report the paired
524
524
  bootstrap and per-arm cost.
525
525
 
526
- **Source:** the loop [`src/two-agent-research-loop.ts`](../src/two-agent-research-loop.ts);
527
- the live worker + verifier + cost instrumentation [`src/web-research-worker.ts`](../src/web-research-worker.ts);
528
- the misattribution check [`src/claim-grounding.ts`](../src/claim-grounding.ts);
529
- the adaptive driver [`src/adaptive-driver.ts`](../src/adaptive-driver.ts);
530
- the driving driver [`src/research-driving-driver.ts`](../src/research-driving-driver.ts);
531
- the held-out exam + $0 grader [`tests/loops/held-out-exam.ts`](../tests/loops/held-out-exam.ts);
532
- the A/B harnesses [`tests/loops/`](../tests/loops/).
526
+ **Source:** the loop, [`src/two-agent-research-loop.ts`](../src/two-agent-research-loop.ts);
527
+ the live worker + verifier + cost instrumentation, [`src/web-research-worker.ts`](../src/web-research-worker.ts);
528
+ the misattribution check, [`src/claim-grounding.ts`](../src/claim-grounding.ts);
529
+ the adaptive driver, [`src/adaptive-driver.ts`](../src/adaptive-driver.ts);
530
+ the driving driver, [`src/research-driving-driver.ts`](../src/research-driving-driver.ts);
531
+ the held-out exam + $0 grader, [`tests/loops/held-out-exam.ts`](../tests/loops/held-out-exam.ts);
532
+ the A/B harnesses, [`tests/loops/`](../tests/loops/).
533
533
  Per-result detail: [`docs/results/cost-quality.md`](results/cost-quality.md),
534
534
  [`docs/results/claim-grounding.md`](results/claim-grounding.md),
535
535
  [`docs/results/adaptive.md`](results/adaptive.md),
536
536
  [`docs/results/research-driving.md`](results/research-driving.md),
537
- [`docs/results/investment-thesis.md`](results/investment-thesis.md) (§9.1 the domain reframe + calibration + 3-arm A/B).
537
+ [`docs/results/investment-thesis.md`](results/investment-thesis.md) (§9.1, the domain reframe + calibration + 3-arm A/B).
538
538
  </content>
539
539
  </invoke>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-knowledge",
3
- "version": "4.0.0",
3
+ "version": "4.1.0",
4
4
  "description": "Source-grounded, eval-gated knowledge growth primitives for agents.",
5
5
  "homepage": "https://github.com/tangle-network/agent-knowledge#readme",
6
6
  "repository": {
@@ -78,21 +78,18 @@
78
78
  "devDependencies": {
79
79
  "@biomejs/biome": "^2.5.4",
80
80
  "@neo4j-labs/agent-memory": "0.4.0",
81
- "@tangle-network/sandbox": "^0.9.7",
82
- "@types/node": "^25.6.0",
81
+ "@types/node": "^26.1.1",
83
82
  "@types/proper-lockfile": "4.1.4",
84
83
  "mem0ai": "3.1.0",
85
84
  "tsup": "^8.0.0",
86
- "tsx": "^4.23.1",
87
85
  "typescript": "^5.7.0",
88
- "vitest": "^3.0.0"
86
+ "vitest": "^4.1.10"
89
87
  },
90
88
  "pnpm": {
91
89
  "minimumReleaseAge": 4320,
92
90
  "minimumReleaseAgeExclude": [
93
91
  "@tangle-network/agent-eval",
94
- "@tangle-network/agent-interface",
95
- "@tangle-network/sandbox"
92
+ "@tangle-network/agent-interface"
96
93
  ],
97
94
  "overrides": {
98
95
  "hono": "4.12.30",