ralph-hero-knowledge-index 0.1.41 → 0.1.43

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 (42) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.mcp.json +1 -1
  3. package/README.md +42 -0
  4. package/coverage/coverage-summary.json +4 -5
  5. package/coverage/lcov-report/{src/chunker.ts.html → chunker.ts.html} +13 -13
  6. package/coverage/lcov-report/{src/config.ts.html → config.ts.html} +10 -10
  7. package/coverage/lcov-report/{src/db.ts.html → db.ts.html} +74 -74
  8. package/coverage/lcov-report/{src/embedder.ts.html → embedder.ts.html} +12 -12
  9. package/coverage/lcov-report/{src/file-scanner.ts.html → file-scanner.ts.html} +10 -10
  10. package/coverage/lcov-report/{src/format.ts.html → format.ts.html} +12 -12
  11. package/coverage/lcov-report/{src/generate-indexes.ts.html → generate-indexes.ts.html} +13 -13
  12. package/coverage/lcov-report/{src/graph-builder.ts.html → graph-builder.ts.html} +11 -11
  13. package/coverage/lcov-report/{src/graph-tools.ts.html → graph-tools.ts.html} +24 -24
  14. package/coverage/lcov-report/{src/hybrid-search.ts.html → hybrid-search.ts.html} +102 -102
  15. package/coverage/lcov-report/{src/ignore.ts.html → ignore.ts.html} +12 -12
  16. package/coverage/lcov-report/index.html +286 -31
  17. package/coverage/lcov-report/{src/index.ts.html → index.ts.html} +947 -62
  18. package/coverage/lcov-report/{src/llm-client.ts.html → llm-client.ts.html} +15 -15
  19. package/coverage/lcov-report/{src/parser.ts.html → parser.ts.html} +18 -18
  20. package/coverage/lcov-report/{src/reindex.ts.html → reindex.ts.html} +398 -23
  21. package/coverage/lcov-report/{src/reranker.ts.html → reranker.ts.html} +20 -20
  22. package/coverage/lcov-report/{src/search.ts.html → search.ts.html} +33 -33
  23. package/coverage/lcov-report/{src/traverse.ts.html → traverse.ts.html} +11 -11
  24. package/coverage/lcov-report/{src/vector-search.ts.html → vector-search.ts.html} +25 -25
  25. package/coverage/lcov.info +844 -712
  26. package/dist/index.d.ts +44 -0
  27. package/dist/index.js +229 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/reindex.d.ts +26 -0
  30. package/dist/reindex.js +104 -0
  31. package/dist/reindex.js.map +1 -1
  32. package/package.json +1 -1
  33. package/skills/setup/SKILL.md +42 -7
  34. package/src/__tests__/outcome-merge-ingest.test.ts +169 -0
  35. package/src/__tests__/recall.test.ts +562 -0
  36. package/src/__tests__/remember.test.ts +302 -0
  37. package/src/index.ts +296 -1
  38. package/src/reindex.ts +125 -0
  39. package/vitest.config.ts +9 -3
  40. package/coverage/lcov-report/src/index.html +0 -386
  41. package/coverage/lcov-report/src/scripts/index.html +0 -116
  42. package/coverage/lcov-report/src/scripts/verify-tiers.ts.html +0 -406
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ralph-knowledge",
3
- "version": "0.1.41",
3
+ "version": "0.1.43",
4
4
  "description": "Knowledge graph for ralph-hero: semantic search, relationship traversal, and document indexing across thoughts/ documents. Optional companion to ralph-hero.",
5
5
  "author": {
6
6
  "name": "Chad Dubiel",
package/.mcp.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "mcpServers": {
3
3
  "ralph-knowledge": {
4
4
  "command": "npx",
5
- "args": ["-y", "ralph-hero-knowledge-index@0.1.41"]
5
+ "args": ["-y", "ralph-hero-knowledge-index@0.1.43"]
6
6
  }
7
7
  }
8
8
  }
package/README.md CHANGED
@@ -100,6 +100,48 @@ Patterns behave exactly like `.gitignore`:
100
100
  Directories whose names start with `.` or `_` are also always skipped, as a
101
101
  fast-path before any matcher is consulted.
102
102
 
103
+ ## Choosing between `knowledge_search` and `knowledge_recall`
104
+
105
+ ralph-knowledge exposes two retrieval MCP tools that wrap the same underlying
106
+ hybrid search. They differ on **who decides the tier policy**:
107
+
108
+ | Tool | When to use | Tier handling |
109
+ |------|-------------|---------------|
110
+ | `knowledge_search` | Power-user / explicit path. You know the tier and want full control over `rerank`, `lambda`, `return_diagnostics`, chunk metadata, etc. | You pass `memory_tier` explicitly (`doc`, `raw`, `reflection`, `wiki`, or `any` — default `any`). |
111
+ | `knowledge_recall` | Default for agents and skills. You declare your role and the tool picks the right tiers. | A role-keyed policy fans out one rerank-enabled `hybrid.search()` per tier in the role's list, then merges and re-ranks. |
112
+
113
+ ### Role -> tier policy
114
+
115
+ `knowledge_recall(query, role, ...)` follows this fixed policy map:
116
+
117
+ | Role | Tiers (priority order) | Intent |
118
+ |------|------------------------|--------|
119
+ | `researcher` | `raw`, `reflection`, `doc` | Recovery of unfiltered observations + synthesized insights + curated research. Excludes wiki (we are looking for things the wiki does not already cover). |
120
+ | `planner` | `reflection`, `wiki`, `doc` | Bias toward synthesized insights + canonical curated knowledge; excludes raw observations to keep the planning frame stable. |
121
+ | `implementer` | `wiki`, `doc` | Only canonical references — never raw memory or speculative reflections. Keeps implementations grounded in agreed-upon truth. |
122
+ | `reviewer` | `wiki`, `doc` | Same constraints as implementer — review against the canonical surface, not the raw or speculative tiers. |
123
+ | `triager` | `doc`, `wiki` | Doc-first for issue context, wiki as fallback. |
124
+
125
+ ### Cost notes
126
+
127
+ - `knowledge_recall` always runs the cross-encoder reranker (`rerank=true`)
128
+ because role-aware retrieval is the most context-sensitive call path in the
129
+ surface. Expect a one-time ~0.5-1 s cold-start (ONNX model load on the first
130
+ call after process boot) and ~25-45 ms per (query, doc) pair on warm calls.
131
+ - Each tier sub-query targets <50 ms; a 3-tier fanout totals <150 ms before
132
+ reranking.
133
+ - If a tier sub-query throws (e.g., transient DB lock), `knowledge_recall`
134
+ logs the error to stderr and continues with the remaining tiers — degraded
135
+ results rather than a hard failure.
136
+
137
+ ### Power-user override
138
+
139
+ Skills can mix both tools. For example, `/ralph-hero:plan` calls
140
+ `knowledge_recall(role="planner", ...)` for the default tier-balanced context
141
+ gather, and ALSO calls `knowledge_search(type="research", ...)` for an explicit
142
+ artifact lookup where it needs a precise type filter. Keeping both tools in a
143
+ skill's allowlist is the recommended pattern.
144
+
103
145
  ## Environment variables
104
146
 
105
147
  | Variable | Purpose |
@@ -1,7 +1,7 @@
1
- {"total": {"lines":{"total":1403,"covered":1275,"skipped":0,"pct":90.87},"statements":{"total":1534,"covered":1381,"skipped":0,"pct":90.02},"functions":{"total":208,"covered":191,"skipped":0,"pct":91.82},"branches":{"total":901,"covered":734,"skipped":0,"pct":81.46},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
1
+ {"total": {"lines":{"total":1489,"covered":1346,"skipped":0,"pct":90.39},"statements":{"total":1623,"covered":1453,"skipped":0,"pct":89.52},"functions":{"total":218,"covered":200,"skipped":0,"pct":91.74},"branches":{"total":936,"covered":762,"skipped":0,"pct":81.41},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":"Unknown"}}
2
2
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/chunker.ts": {"lines":{"total":91,"covered":85,"skipped":0,"pct":93.4},"functions":{"total":6,"covered":6,"skipped":0,"pct":100},"statements":{"total":94,"covered":88,"skipped":0,"pct":93.61},"branches":{"total":45,"covered":39,"skipped":0,"pct":86.66}}
3
3
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/config.ts": {"lines":{"total":34,"covered":32,"skipped":0,"pct":94.11},"functions":{"total":5,"covered":5,"skipped":0,"pct":100},"statements":{"total":36,"covered":34,"skipped":0,"pct":94.44},"branches":{"total":31,"covered":31,"skipped":0,"pct":100}}
4
- ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/db.ts": {"lines":{"total":119,"covered":117,"skipped":0,"pct":98.31},"functions":{"total":31,"covered":31,"skipped":0,"pct":100},"statements":{"total":125,"covered":122,"skipped":0,"pct":97.6},"branches":{"total":78,"covered":68,"skipped":0,"pct":87.17}}
4
+ ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/db.ts": {"lines":{"total":119,"covered":117,"skipped":0,"pct":98.31},"functions":{"total":31,"covered":31,"skipped":0,"pct":100},"statements":{"total":125,"covered":122,"skipped":0,"pct":97.6},"branches":{"total":78,"covered":69,"skipped":0,"pct":88.46}}
5
5
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/embedder.ts": {"lines":{"total":55,"covered":52,"skipped":0,"pct":94.54},"functions":{"total":8,"covered":8,"skipped":0,"pct":100},"statements":{"total":60,"covered":57,"skipped":0,"pct":95},"branches":{"total":38,"covered":30,"skipped":0,"pct":78.94}}
6
6
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/file-scanner.ts": {"lines":{"total":16,"covered":16,"skipped":0,"pct":100},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":19,"covered":19,"skipped":0,"pct":100},"branches":{"total":21,"covered":21,"skipped":0,"pct":100}}
7
7
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/format.ts": {"lines":{"total":6,"covered":6,"skipped":0,"pct":100},"functions":{"total":4,"covered":4,"skipped":0,"pct":100},"statements":{"total":8,"covered":8,"skipped":0,"pct":100},"branches":{"total":6,"covered":6,"skipped":0,"pct":100}}
@@ -10,13 +10,12 @@
10
10
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/graph-tools.ts": {"lines":{"total":242,"covered":230,"skipped":0,"pct":95.04},"functions":{"total":34,"covered":32,"skipped":0,"pct":94.11},"statements":{"total":257,"covered":243,"skipped":0,"pct":94.55},"branches":{"total":151,"covered":120,"skipped":0,"pct":79.47}}
11
11
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/hybrid-search.ts": {"lines":{"total":174,"covered":173,"skipped":0,"pct":99.42},"functions":{"total":19,"covered":19,"skipped":0,"pct":100},"statements":{"total":203,"covered":195,"skipped":0,"pct":96.05},"branches":{"total":129,"covered":110,"skipped":0,"pct":85.27}}
12
12
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/ignore.ts": {"lines":{"total":17,"covered":16,"skipped":0,"pct":94.11},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":19,"covered":18,"skipped":0,"pct":94.73},"branches":{"total":12,"covered":11,"skipped":0,"pct":91.66}}
13
- ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/index.ts": {"lines":{"total":112,"covered":91,"skipped":0,"pct":81.25},"functions":{"total":16,"covered":13,"skipped":0,"pct":81.25},"statements":{"total":128,"covered":105,"skipped":0,"pct":82.03},"branches":{"total":83,"covered":57,"skipped":0,"pct":68.67}}
13
+ ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/index.ts": {"lines":{"total":183,"covered":162,"skipped":0,"pct":88.52},"functions":{"total":26,"covered":22,"skipped":0,"pct":84.61},"statements":{"total":202,"covered":177,"skipped":0,"pct":87.62},"branches":{"total":122,"covered":84,"skipped":0,"pct":68.85}}
14
14
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/llm-client.ts": {"lines":{"total":31,"covered":31,"skipped":0,"pct":100},"functions":{"total":6,"covered":5,"skipped":0,"pct":83.33},"statements":{"total":33,"covered":32,"skipped":0,"pct":96.96},"branches":{"total":13,"covered":13,"skipped":0,"pct":100}}
15
15
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/parser.ts": {"lines":{"total":49,"covered":49,"skipped":0,"pct":100},"functions":{"total":5,"covered":5,"skipped":0,"pct":100},"statements":{"total":53,"covered":53,"skipped":0,"pct":100},"branches":{"total":46,"covered":41,"skipped":0,"pct":89.13}}
16
- ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/reindex.ts": {"lines":{"total":194,"covered":157,"skipped":0,"pct":80.92},"functions":{"total":15,"covered":9,"skipped":0,"pct":60},"statements":{"total":209,"covered":164,"skipped":0,"pct":78.46},"branches":{"total":104,"covered":74,"skipped":0,"pct":71.15}}
16
+ ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/reindex.ts": {"lines":{"total":241,"covered":157,"skipped":0,"pct":65.14},"functions":{"total":18,"covered":9,"skipped":0,"pct":50},"statements":{"total":258,"covered":164,"skipped":0,"pct":63.56},"branches":{"total":114,"covered":74,"skipped":0,"pct":64.91}}
17
17
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/reranker.ts": {"lines":{"total":42,"covered":37,"skipped":0,"pct":88.09},"functions":{"total":7,"covered":6,"skipped":0,"pct":85.71},"statements":{"total":44,"covered":39,"skipped":0,"pct":88.63},"branches":{"total":22,"covered":18,"skipped":0,"pct":81.81}}
18
18
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/search.ts": {"lines":{"total":40,"covered":40,"skipped":0,"pct":100},"functions":{"total":12,"covered":12,"skipped":0,"pct":100},"statements":{"total":47,"covered":46,"skipped":0,"pct":97.87},"branches":{"total":24,"covered":23,"skipped":0,"pct":95.83}}
19
19
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/traverse.ts": {"lines":{"total":15,"covered":15,"skipped":0,"pct":100},"functions":{"total":5,"covered":5,"skipped":0,"pct":100},"statements":{"total":19,"covered":18,"skipped":0,"pct":94.73},"branches":{"total":16,"covered":12,"skipped":0,"pct":75}}
20
20
  ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/vector-search.ts": {"lines":{"total":25,"covered":24,"skipped":0,"pct":96},"functions":{"total":10,"covered":9,"skipped":0,"pct":90},"statements":{"total":26,"covered":25,"skipped":0,"pct":96.15},"branches":{"total":5,"covered":5,"skipped":0,"pct":100}}
21
- ,"/home/runner/work/ralph-hero/ralph-hero/plugin/ralph-knowledge/src/scripts/verify-tiers.ts": {"lines":{"total":32,"covered":0,"skipped":0,"pct":0},"functions":{"total":3,"covered":0,"skipped":0,"pct":0},"statements":{"total":34,"covered":0,"skipped":0,"pct":0},"branches":{"total":14,"covered":0,"skipped":0,"pct":0}}
22
21
  }
@@ -3,15 +3,15 @@
3
3
  <html lang="en">
4
4
 
5
5
  <head>
6
- <title>Code coverage report for src/chunker.ts</title>
6
+ <title>Code coverage report for chunker.ts</title>
7
7
  <meta charset="utf-8" />
8
- <link rel="stylesheet" href="../prettify.css" />
9
- <link rel="stylesheet" href="../base.css" />
10
- <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
8
+ <link rel="stylesheet" href="prettify.css" />
9
+ <link rel="stylesheet" href="base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
11
11
  <meta name="viewport" content="width=device-width, initial-scale=1" />
12
12
  <style type='text/css'>
13
13
  .coverage-summary .sorter {
14
- background-image: url(../sort-arrow-sprite.png);
14
+ background-image: url(sort-arrow-sprite.png);
15
15
  }
16
16
  </style>
17
17
  </head>
@@ -19,7 +19,7 @@
19
19
  <body>
20
20
  <div class='wrapper'>
21
21
  <div class='pad1'>
22
- <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> chunker.ts</h1>
22
+ <h1><a href="index.html">All files</a> chunker.ts</h1>
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
@@ -379,9 +379,9 @@
379
379
  <span class="cline-any cline-neutral">&nbsp;</span>
380
380
  <span class="cline-any cline-neutral">&nbsp;</span>
381
381
  <span class="cline-any cline-neutral">&nbsp;</span>
382
- <span class="cline-any cline-yes">5x</span>
383
- <span class="cline-any cline-yes">5x</span>
384
- <span class="cline-any cline-yes">5x</span>
382
+ <span class="cline-any cline-yes">8x</span>
383
+ <span class="cline-any cline-yes">8x</span>
384
+ <span class="cline-any cline-yes">8x</span>
385
385
  <span class="cline-any cline-neutral">&nbsp;</span>
386
386
  <span class="cline-any cline-neutral">&nbsp;</span>
387
387
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -940,16 +940,16 @@ export function chunkText(text: string, opts: ChunkerOptions = {}): Chunk[] {
940
940
  <div class='footer quiet pad2 space-top1 center small'>
941
941
  Code coverage generated by
942
942
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
943
- at 2026-05-13T01:40:01.638Z
943
+ at 2026-05-17T00:34:55.475Z
944
944
  </div>
945
- <script src="../prettify.js"></script>
945
+ <script src="prettify.js"></script>
946
946
  <script>
947
947
  window.onload = function () {
948
948
  prettyPrint();
949
949
  };
950
950
  </script>
951
- <script src="../sorter.js"></script>
952
- <script src="../block-navigation.js"></script>
951
+ <script src="sorter.js"></script>
952
+ <script src="block-navigation.js"></script>
953
953
  </body>
954
954
  </html>
955
955
 
@@ -3,15 +3,15 @@
3
3
  <html lang="en">
4
4
 
5
5
  <head>
6
- <title>Code coverage report for src/config.ts</title>
6
+ <title>Code coverage report for config.ts</title>
7
7
  <meta charset="utf-8" />
8
- <link rel="stylesheet" href="../prettify.css" />
9
- <link rel="stylesheet" href="../base.css" />
10
- <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
8
+ <link rel="stylesheet" href="prettify.css" />
9
+ <link rel="stylesheet" href="base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
11
11
  <meta name="viewport" content="width=device-width, initial-scale=1" />
12
12
  <style type='text/css'>
13
13
  .coverage-summary .sorter {
14
- background-image: url(../sort-arrow-sprite.png);
14
+ background-image: url(sort-arrow-sprite.png);
15
15
  }
16
16
  </style>
17
17
  </head>
@@ -19,7 +19,7 @@
19
19
  <body>
20
20
  <div class='wrapper'>
21
21
  <div class='pad1'>
22
- <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> config.ts</h1>
22
+ <h1><a href="index.html">All files</a> config.ts</h1>
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
@@ -385,16 +385,16 @@ export function loadConfig(): KnowledgeConfig {
385
385
  <div class='footer quiet pad2 space-top1 center small'>
386
386
  Code coverage generated by
387
387
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
388
- at 2026-05-13T01:40:01.638Z
388
+ at 2026-05-17T00:34:55.475Z
389
389
  </div>
390
- <script src="../prettify.js"></script>
390
+ <script src="prettify.js"></script>
391
391
  <script>
392
392
  window.onload = function () {
393
393
  prettyPrint();
394
394
  };
395
395
  </script>
396
- <script src="../sorter.js"></script>
397
- <script src="../block-navigation.js"></script>
396
+ <script src="sorter.js"></script>
397
+ <script src="block-navigation.js"></script>
398
398
  </body>
399
399
  </html>
400
400
 
@@ -3,15 +3,15 @@
3
3
  <html lang="en">
4
4
 
5
5
  <head>
6
- <title>Code coverage report for src/db.ts</title>
6
+ <title>Code coverage report for db.ts</title>
7
7
  <meta charset="utf-8" />
8
- <link rel="stylesheet" href="../prettify.css" />
9
- <link rel="stylesheet" href="../base.css" />
10
- <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
8
+ <link rel="stylesheet" href="prettify.css" />
9
+ <link rel="stylesheet" href="base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
11
11
  <meta name="viewport" content="width=device-width, initial-scale=1" />
12
12
  <style type='text/css'>
13
13
  .coverage-summary .sorter {
14
- background-image: url(../sort-arrow-sprite.png);
14
+ background-image: url(sort-arrow-sprite.png);
15
15
  }
16
16
  </style>
17
17
  </head>
@@ -19,7 +19,7 @@
19
19
  <body>
20
20
  <div class='wrapper'>
21
21
  <div class='pad1'>
22
- <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> db.ts</h1>
22
+ <h1><a href="index.html">All files</a> db.ts</h1>
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
@@ -30,9 +30,9 @@
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">87.17% </span>
33
+ <span class="strong">88.46% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>68/78</span>
35
+ <span class='fraction'>69/78</span>
36
36
  </div>
37
37
 
38
38
 
@@ -705,14 +705,14 @@
705
705
  <span class="cline-any cline-neutral">&nbsp;</span>
706
706
  <span class="cline-any cline-neutral">&nbsp;</span>
707
707
  <span class="cline-any cline-neutral">&nbsp;</span>
708
- <span class="cline-any cline-yes">362x</span>
709
- <span class="cline-any cline-yes">362x</span>
710
- <span class="cline-any cline-yes">362x</span>
711
- <span class="cline-any cline-yes">362x</span>
708
+ <span class="cline-any cline-yes">387x</span>
709
+ <span class="cline-any cline-yes">387x</span>
710
+ <span class="cline-any cline-yes">387x</span>
711
+ <span class="cline-any cline-yes">387x</span>
712
712
  <span class="cline-any cline-neutral">&nbsp;</span>
713
713
  <span class="cline-any cline-neutral">&nbsp;</span>
714
714
  <span class="cline-any cline-neutral">&nbsp;</span>
715
- <span class="cline-any cline-yes">362x</span>
715
+ <span class="cline-any cline-yes">387x</span>
716
716
  <span class="cline-any cline-neutral">&nbsp;</span>
717
717
  <span class="cline-any cline-neutral">&nbsp;</span>
718
718
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -789,8 +789,8 @@
789
789
  <span class="cline-any cline-neutral">&nbsp;</span>
790
790
  <span class="cline-any cline-neutral">&nbsp;</span>
791
791
  <span class="cline-any cline-neutral">&nbsp;</span>
792
- <span class="cline-any cline-yes">362x</span>
793
- <span class="cline-any cline-yes">362x</span>
792
+ <span class="cline-any cline-yes">387x</span>
793
+ <span class="cline-any cline-yes">387x</span>
794
794
  <span class="cline-any cline-neutral">&nbsp;</span>
795
795
  <span class="cline-any cline-neutral">&nbsp;</span>
796
796
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -799,14 +799,14 @@
799
799
  <span class="cline-any cline-neutral">&nbsp;</span>
800
800
  <span class="cline-any cline-neutral">&nbsp;</span>
801
801
  <span class="cline-any cline-neutral">&nbsp;</span>
802
- <span class="cline-any cline-yes">362x</span>
803
- <span class="cline-any cline-yes">362x</span>
802
+ <span class="cline-any cline-yes">387x</span>
803
+ <span class="cline-any cline-yes">387x</span>
804
804
  <span class="cline-any cline-neutral">&nbsp;</span>
805
805
  <span class="cline-any cline-neutral">&nbsp;</span>
806
806
  <span class="cline-any cline-neutral">&nbsp;</span>
807
807
  <span class="cline-any cline-neutral">&nbsp;</span>
808
808
  <span class="cline-any cline-neutral">&nbsp;</span>
809
- <span class="cline-any cline-yes">362x</span>
809
+ <span class="cline-any cline-yes">387x</span>
810
810
  <span class="cline-any cline-neutral">&nbsp;</span>
811
811
  <span class="cline-any cline-neutral">&nbsp;</span>
812
812
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -815,11 +815,11 @@
815
815
  <span class="cline-any cline-neutral">&nbsp;</span>
816
816
  <span class="cline-any cline-neutral">&nbsp;</span>
817
817
  <span class="cline-any cline-neutral">&nbsp;</span>
818
- <span class="cline-any cline-yes">362x</span>
819
- <span class="cline-any cline-yes">362x</span>
818
+ <span class="cline-any cline-yes">387x</span>
819
+ <span class="cline-any cline-yes">387x</span>
820
820
  <span class="cline-any cline-neutral">&nbsp;</span>
821
821
  <span class="cline-any cline-neutral">&nbsp;</span>
822
- <span class="cline-any cline-yes">362x</span>
822
+ <span class="cline-any cline-yes">387x</span>
823
823
  <span class="cline-any cline-yes">1x</span>
824
824
  <span class="cline-any cline-neutral">&nbsp;</span>
825
825
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -847,8 +847,8 @@
847
847
  <span class="cline-any cline-neutral">&nbsp;</span>
848
848
  <span class="cline-any cline-neutral">&nbsp;</span>
849
849
  <span class="cline-any cline-neutral">&nbsp;</span>
850
- <span class="cline-any cline-yes">362x</span>
851
- <span class="cline-any cline-yes">362x</span>
850
+ <span class="cline-any cline-yes">387x</span>
851
+ <span class="cline-any cline-yes">387x</span>
852
852
  <span class="cline-any cline-neutral">&nbsp;</span>
853
853
  <span class="cline-any cline-yes">2x</span>
854
854
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -875,11 +875,11 @@
875
875
  <span class="cline-any cline-neutral">&nbsp;</span>
876
876
  <span class="cline-any cline-neutral">&nbsp;</span>
877
877
  <span class="cline-any cline-neutral">&nbsp;</span>
878
- <span class="cline-any cline-yes">938x</span>
878
+ <span class="cline-any cline-yes">968x</span>
879
879
  <span class="cline-any cline-neutral">&nbsp;</span>
880
880
  <span class="cline-any cline-neutral">&nbsp;</span>
881
881
  <span class="cline-any cline-neutral">&nbsp;</span>
882
- <span class="cline-any cline-yes">938x</span>
882
+ <span class="cline-any cline-yes">968x</span>
883
883
  <span class="cline-any cline-neutral">&nbsp;</span>
884
884
  <span class="cline-any cline-neutral">&nbsp;</span>
885
885
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -901,19 +901,19 @@
901
901
  <span class="cline-any cline-neutral">&nbsp;</span>
902
902
  <span class="cline-any cline-neutral">&nbsp;</span>
903
903
  <span class="cline-any cline-neutral">&nbsp;</span>
904
- <span class="cline-any cline-yes">152x</span>
904
+ <span class="cline-any cline-yes">216x</span>
905
905
  <span class="cline-any cline-neutral">&nbsp;</span>
906
906
  <span class="cline-any cline-neutral">&nbsp;</span>
907
907
  <span class="cline-any cline-neutral">&nbsp;</span>
908
908
  <span class="cline-any cline-neutral">&nbsp;</span>
909
909
  <span class="cline-any cline-neutral">&nbsp;</span>
910
- <span class="cline-any cline-yes">170x</span>
911
- <span class="cline-any cline-yes">170x</span>
912
- <span class="cline-any cline-yes">298x</span>
910
+ <span class="cline-any cline-yes">171x</span>
911
+ <span class="cline-any cline-yes">171x</span>
912
+ <span class="cline-any cline-yes">300x</span>
913
913
  <span class="cline-any cline-neutral">&nbsp;</span>
914
914
  <span class="cline-any cline-neutral">&nbsp;</span>
915
915
  <span class="cline-any cline-neutral">&nbsp;</span>
916
- <span class="cline-any cline-yes">113x</span>
916
+ <span class="cline-any cline-yes">132x</span>
917
917
  <span class="cline-any cline-neutral">&nbsp;</span>
918
918
  <span class="cline-any cline-neutral">&nbsp;</span>
919
919
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -929,11 +929,11 @@
929
929
  <span class="cline-any cline-neutral">&nbsp;</span>
930
930
  <span class="cline-any cline-neutral">&nbsp;</span>
931
931
  <span class="cline-any cline-neutral">&nbsp;</span>
932
- <span class="cline-any cline-yes">23x</span>
933
- <span class="cline-any cline-yes">23x</span>
934
- <span class="cline-any cline-yes">23x</span>
932
+ <span class="cline-any cline-yes">28x</span>
933
+ <span class="cline-any cline-yes">28x</span>
934
+ <span class="cline-any cline-yes">28x</span>
935
935
  <span class="cline-any cline-neutral">&nbsp;</span>
936
- <span class="cline-any cline-yes">23x</span>
936
+ <span class="cline-any cline-yes">28x</span>
937
937
  <span class="cline-any cline-neutral">&nbsp;</span>
938
938
  <span class="cline-any cline-neutral">&nbsp;</span>
939
939
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -953,46 +953,46 @@
953
953
  <span class="cline-any cline-neutral">&nbsp;</span>
954
954
  <span class="cline-any cline-neutral">&nbsp;</span>
955
955
  <span class="cline-any cline-neutral">&nbsp;</span>
956
- <span class="cline-any cline-yes">23x</span>
956
+ <span class="cline-any cline-yes">28x</span>
957
957
  <span class="cline-any cline-neutral">&nbsp;</span>
958
958
  <span class="cline-any cline-neutral">&nbsp;</span>
959
959
  <span class="cline-any cline-neutral">&nbsp;</span>
960
- <span class="cline-any cline-yes">15x</span>
961
- <span class="cline-any cline-yes">15x</span>
960
+ <span class="cline-any cline-yes">18x</span>
961
+ <span class="cline-any cline-yes">18x</span>
962
962
  <span class="cline-any cline-neutral">&nbsp;</span>
963
- <span class="cline-any cline-yes">15x</span>
964
- <span class="cline-any cline-yes">6x</span>
965
- <span class="cline-any cline-yes">6x</span>
963
+ <span class="cline-any cline-yes">18x</span>
964
+ <span class="cline-any cline-yes">9x</span>
965
+ <span class="cline-any cline-yes">9x</span>
966
966
  <span class="cline-any cline-neutral">&nbsp;</span>
967
- <span class="cline-any cline-yes">15x</span>
967
+ <span class="cline-any cline-yes">18x</span>
968
968
  <span class="cline-any cline-yes">2x</span>
969
969
  <span class="cline-any cline-yes">2x</span>
970
970
  <span class="cline-any cline-neutral">&nbsp;</span>
971
- <span class="cline-any cline-yes">15x</span>
971
+ <span class="cline-any cline-yes">18x</span>
972
972
  <span class="cline-any cline-yes">2x</span>
973
973
  <span class="cline-any cline-yes">2x</span>
974
974
  <span class="cline-any cline-neutral">&nbsp;</span>
975
- <span class="cline-any cline-yes">15x</span>
975
+ <span class="cline-any cline-yes">18x</span>
976
976
  <span class="cline-any cline-yes">1x</span>
977
977
  <span class="cline-any cline-yes">1x</span>
978
978
  <span class="cline-any cline-neutral">&nbsp;</span>
979
- <span class="cline-any cline-yes">15x</span>
979
+ <span class="cline-any cline-yes">18x</span>
980
980
  <span class="cline-any cline-yes">1x</span>
981
981
  <span class="cline-any cline-yes">1x</span>
982
982
  <span class="cline-any cline-neutral">&nbsp;</span>
983
- <span class="cline-any cline-yes">15x</span>
983
+ <span class="cline-any cline-yes">18x</span>
984
984
  <span class="cline-any cline-no">&nbsp;</span>
985
985
  <span class="cline-any cline-no">&nbsp;</span>
986
986
  <span class="cline-any cline-neutral">&nbsp;</span>
987
- <span class="cline-any cline-yes">15x</span>
987
+ <span class="cline-any cline-yes">18x</span>
988
988
  <span class="cline-any cline-yes">2x</span>
989
989
  <span class="cline-any cline-yes">2x</span>
990
990
  <span class="cline-any cline-neutral">&nbsp;</span>
991
991
  <span class="cline-any cline-neutral">&nbsp;</span>
992
- <span class="cline-any cline-yes">15x</span>
993
- <span class="cline-any cline-yes">15x</span>
992
+ <span class="cline-any cline-yes">18x</span>
993
+ <span class="cline-any cline-yes">18x</span>
994
994
  <span class="cline-any cline-neutral">&nbsp;</span>
995
- <span class="cline-any cline-yes">15x</span>
995
+ <span class="cline-any cline-yes">18x</span>
996
996
  <span class="cline-any cline-neutral">&nbsp;</span>
997
997
  <span class="cline-any cline-neutral">&nbsp;</span>
998
998
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1002,7 +1002,7 @@
1002
1002
  <span class="cline-any cline-neutral">&nbsp;</span>
1003
1003
  <span class="cline-any cline-neutral">&nbsp;</span>
1004
1004
  <span class="cline-any cline-neutral">&nbsp;</span>
1005
- <span class="cline-any cline-yes">15x</span>
1005
+ <span class="cline-any cline-yes">18x</span>
1006
1006
  <span class="cline-any cline-neutral">&nbsp;</span>
1007
1007
  <span class="cline-any cline-neutral">&nbsp;</span>
1008
1008
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1051,33 +1051,33 @@
1051
1051
  <span class="cline-any cline-neutral">&nbsp;</span>
1052
1052
  <span class="cline-any cline-neutral">&nbsp;</span>
1053
1053
  <span class="cline-any cline-neutral">&nbsp;</span>
1054
+ <span class="cline-any cline-yes">3x</span>
1055
+ <span class="cline-any cline-yes">3x</span>
1056
+ <span class="cline-any cline-neutral">&nbsp;</span>
1057
+ <span class="cline-any cline-yes">2x</span>
1058
+ <span class="cline-any cline-yes">2x</span>
1054
1059
  <span class="cline-any cline-yes">2x</span>
1055
1060
  <span class="cline-any cline-yes">2x</span>
1056
1061
  <span class="cline-any cline-neutral">&nbsp;</span>
1057
- <span class="cline-any cline-yes">1x</span>
1058
- <span class="cline-any cline-yes">1x</span>
1059
- <span class="cline-any cline-yes">1x</span>
1060
- <span class="cline-any cline-yes">1x</span>
1061
- <span class="cline-any cline-neutral">&nbsp;</span>
1062
- <span class="cline-any cline-yes">1x</span>
1063
- <span class="cline-any cline-yes">3x</span>
1064
- <span class="cline-any cline-yes">3x</span>
1062
+ <span class="cline-any cline-yes">2x</span>
1063
+ <span class="cline-any cline-yes">4x</span>
1064
+ <span class="cline-any cline-yes">4x</span>
1065
1065
  <span class="cline-any cline-yes">3x</span>
1066
1066
  <span class="cline-any cline-neutral">&nbsp;</span>
1067
- <span class="cline-any cline-yes">3x</span>
1067
+ <span class="cline-any cline-yes">4x</span>
1068
1068
  <span class="cline-any cline-yes">1x</span>
1069
1069
  <span class="cline-any cline-neutral">&nbsp;</span>
1070
1070
  <span class="cline-any cline-neutral">&nbsp;</span>
1071
1071
  <span class="cline-any cline-neutral">&nbsp;</span>
1072
1072
  <span class="cline-any cline-neutral">&nbsp;</span>
1073
- <span class="cline-any cline-yes">1x</span>
1074
- <span class="cline-any cline-yes">1x</span>
1075
- <span class="cline-any cline-yes">1x</span>
1076
- <span class="cline-any cline-yes">1x</span>
1073
+ <span class="cline-any cline-yes">2x</span>
1074
+ <span class="cline-any cline-yes">2x</span>
1075
+ <span class="cline-any cline-yes">2x</span>
1076
+ <span class="cline-any cline-yes">2x</span>
1077
1077
  <span class="cline-any cline-neutral">&nbsp;</span>
1078
1078
  <span class="cline-any cline-neutral">&nbsp;</span>
1079
1079
  <span class="cline-any cline-neutral">&nbsp;</span>
1080
- <span class="cline-any cline-yes">1x</span>
1080
+ <span class="cline-any cline-yes">2x</span>
1081
1081
  <span class="cline-any cline-neutral">&nbsp;</span>
1082
1082
  <span class="cline-any cline-neutral">&nbsp;</span>
1083
1083
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1134,14 +1134,14 @@
1134
1134
  <span class="cline-any cline-neutral">&nbsp;</span>
1135
1135
  <span class="cline-any cline-neutral">&nbsp;</span>
1136
1136
  <span class="cline-any cline-neutral">&nbsp;</span>
1137
- <span class="cline-any cline-yes">18x</span>
1137
+ <span class="cline-any cline-yes">84x</span>
1138
1138
  <span class="cline-any cline-neutral">&nbsp;</span>
1139
1139
  <span class="cline-any cline-neutral">&nbsp;</span>
1140
- <span class="cline-any cline-yes">180x</span>
1141
- <span class="cline-any cline-yes">18x</span>
1140
+ <span class="cline-any cline-yes">840x</span>
1141
+ <span class="cline-any cline-yes">84x</span>
1142
1142
  <span class="cline-any cline-neutral">&nbsp;</span>
1143
1143
  <span class="cline-any cline-neutral">&nbsp;</span>
1144
- <span class="cline-any cline-yes">18x</span>
1144
+ <span class="cline-any cline-yes">84x</span>
1145
1145
  <span class="cline-any cline-neutral">&nbsp;</span>
1146
1146
  <span class="cline-any cline-neutral">&nbsp;</span>
1147
1147
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -1154,7 +1154,7 @@
1154
1154
  <span class="cline-any cline-neutral">&nbsp;</span>
1155
1155
  <span class="cline-any cline-neutral">&nbsp;</span>
1156
1156
  <span class="cline-any cline-neutral">&nbsp;</span>
1157
- <span class="cline-any cline-yes">97x</span>
1157
+ <span class="cline-any cline-yes">98x</span>
1158
1158
  <span class="cline-any cline-neutral">&nbsp;</span>
1159
1159
  <span class="cline-any cline-neutral">&nbsp;</span>
1160
1160
  <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import Database from "better-sqlite3";
@@ -1608,7 +1608,7 @@ export class KnowledgeDB {
1608
1608
  &nbsp;
1609
1609
  for (const row of rows) {
1610
1610
  eventsByType[row.eventType] = (eventsByType[row.eventType] ?? 0) + 1;
1611
- <span class="missing-if-branch" title="else path not taken" >E</span>if (row.driftCount !== null) {
1611
+ if (row.driftCount !== null) {
1612
1612
  driftCount += row.driftCount;
1613
1613
  }
1614
1614
  if (row.eventType === "blocker_recorded") {
@@ -1711,16 +1711,16 @@ export class KnowledgeDB {
1711
1711
  <div class='footer quiet pad2 space-top1 center small'>
1712
1712
  Code coverage generated by
1713
1713
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1714
- at 2026-05-13T01:40:01.638Z
1714
+ at 2026-05-17T00:34:55.475Z
1715
1715
  </div>
1716
- <script src="../prettify.js"></script>
1716
+ <script src="prettify.js"></script>
1717
1717
  <script>
1718
1718
  window.onload = function () {
1719
1719
  prettyPrint();
1720
1720
  };
1721
1721
  </script>
1722
- <script src="../sorter.js"></script>
1723
- <script src="../block-navigation.js"></script>
1722
+ <script src="sorter.js"></script>
1723
+ <script src="block-navigation.js"></script>
1724
1724
  </body>
1725
1725
  </html>
1726
1726