@4da/mcp-server 5.0.4 → 6.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.
Files changed (172) hide show
  1. package/CHANGELOG.md +667 -0
  2. package/README.md +66 -35
  3. package/dist/build-staleness.d.ts +35 -0
  4. package/dist/build-staleness.js +95 -0
  5. package/dist/db.d.ts +53 -2
  6. package/dist/db.js +233 -37
  7. package/dist/doctor.js +27 -7
  8. package/dist/embeddings.js +7 -1
  9. package/dist/freshness-markers.d.ts +34 -0
  10. package/dist/freshness-markers.js +74 -0
  11. package/dist/gitignore.d.ts +37 -0
  12. package/dist/gitignore.js +130 -0
  13. package/dist/index.js +127 -44
  14. package/dist/live/bun-lockfile.d.ts +26 -0
  15. package/dist/live/bun-lockfile.js +123 -0
  16. package/dist/live/cargo-platform.d.ts +38 -0
  17. package/dist/live/cargo-platform.js +178 -0
  18. package/dist/live/changelog-classify.d.ts +41 -0
  19. package/dist/live/changelog-classify.js +207 -0
  20. package/dist/live/changelog.d.ts +64 -0
  21. package/dist/live/changelog.js +318 -0
  22. package/dist/live/crates-registry.js +3 -1
  23. package/dist/live/crates-versions.d.ts +47 -0
  24. package/dist/live/crates-versions.js +201 -0
  25. package/dist/live/dependency-set.d.ts +13 -0
  26. package/dist/live/dependency-set.js +95 -0
  27. package/dist/live/dev-scope.d.ts +32 -0
  28. package/dist/live/dev-scope.js +102 -0
  29. package/dist/live/file-signature.d.ts +18 -0
  30. package/dist/live/file-signature.js +43 -0
  31. package/dist/live/go-registry.js +3 -1
  32. package/dist/live/hn-fetcher.js +9 -3
  33. package/dist/live/index.d.ts +105 -2
  34. package/dist/live/index.js +266 -139
  35. package/dist/live/install-state.d.ts +43 -0
  36. package/dist/live/install-state.js +150 -0
  37. package/dist/live/js-lockfile-readers.d.ts +46 -0
  38. package/dist/live/js-lockfile-readers.js +181 -0
  39. package/dist/live/lockfile-parsers-pygo.d.ts +60 -0
  40. package/dist/live/lockfile-parsers-pygo.js +274 -0
  41. package/dist/live/lockfile-parsers.d.ts +69 -0
  42. package/dist/live/lockfile-parsers.js +311 -0
  43. package/dist/live/lockfile-types.d.ts +34 -0
  44. package/dist/live/lockfile-types.js +42 -0
  45. package/dist/live/maintenance.d.ts +33 -0
  46. package/dist/live/maintenance.js +37 -0
  47. package/dist/live/npm-packument.d.ts +47 -0
  48. package/dist/live/npm-packument.js +150 -0
  49. package/dist/live/npm-registry.js +67 -53
  50. package/dist/live/osv-scanner.d.ts +12 -1
  51. package/dist/live/osv-scanner.js +50 -15
  52. package/dist/live/package-archive.d.ts +49 -0
  53. package/dist/live/package-archive.js +186 -0
  54. package/dist/live/pypi-registry.js +3 -1
  55. package/dist/live/registry-health.d.ts +16 -0
  56. package/dist/live/registry-health.js +74 -0
  57. package/dist/live/release-metadata.d.ts +67 -0
  58. package/dist/live/release-metadata.js +16 -0
  59. package/dist/live/resolution.d.ts +43 -0
  60. package/dist/live/resolution.js +62 -0
  61. package/dist/live/semver-precedence.d.ts +30 -0
  62. package/dist/live/semver-precedence.js +83 -0
  63. package/dist/live/severity-scope.d.ts +57 -0
  64. package/dist/live/severity-scope.js +89 -0
  65. package/dist/live/types.d.ts +83 -0
  66. package/dist/live/upgrade-sources.d.ts +71 -0
  67. package/dist/live/upgrade-sources.js +198 -0
  68. package/dist/live/version-compare.d.ts +39 -0
  69. package/dist/live/version-compare.js +130 -0
  70. package/dist/live/version-resolver.d.ts +14 -1
  71. package/dist/live/version-resolver.js +93 -303
  72. package/dist/native-bindings.d.ts +19 -0
  73. package/dist/native-bindings.js +39 -0
  74. package/dist/project-manifests.d.ts +40 -0
  75. package/dist/project-manifests.js +193 -0
  76. package/dist/project-scanner.js +38 -48
  77. package/dist/project-tree.d.ts +41 -0
  78. package/dist/project-tree.js +110 -0
  79. package/dist/prompts.d.ts +28 -0
  80. package/dist/prompts.js +54 -0
  81. package/dist/schema-registry.d.ts +41 -29
  82. package/dist/schema-registry.js +98 -105
  83. package/dist/server-instructions.d.ts +11 -0
  84. package/dist/server-instructions.js +36 -0
  85. package/dist/tool-args.d.ts +28 -0
  86. package/dist/tool-args.js +93 -0
  87. package/dist/tool-dispatch.d.ts +1 -1
  88. package/dist/tool-dispatch.js +42 -8
  89. package/dist/tools/app-plan.d.ts +92 -0
  90. package/dist/tools/app-plan.js +155 -0
  91. package/dist/tools/briefing-stored-advisories.d.ts +20 -0
  92. package/dist/tools/briefing-stored-advisories.js +58 -0
  93. package/dist/tools/briefing-task-scope.d.ts +73 -0
  94. package/dist/tools/briefing-task-scope.js +197 -0
  95. package/dist/tools/briefing-wisdom.d.ts +31 -0
  96. package/dist/tools/briefing-wisdom.js +148 -0
  97. package/dist/tools/decision-enforcement.d.ts +0 -5
  98. package/dist/tools/decision-enforcement.js +0 -4
  99. package/dist/tools/decision-memory.js +18 -66
  100. package/dist/tools/dependency-check-signals.d.ts +74 -0
  101. package/dist/tools/dependency-check-signals.js +264 -0
  102. package/dist/tools/dependency-check.d.ts +98 -0
  103. package/dist/tools/dependency-check.js +295 -0
  104. package/dist/tools/dependency-health.js +74 -21
  105. package/dist/tools/developer-dna.d.ts +3 -0
  106. package/dist/tools/developer-dna.js +16 -15
  107. package/dist/tools/ecosystem-pulse.d.ts +6 -2
  108. package/dist/tools/ecosystem-pulse.js +53 -14
  109. package/dist/tools/get-actionable-signals.d.ts +26 -4
  110. package/dist/tools/get-actionable-signals.js +214 -251
  111. package/dist/tools/get-context.d.ts +2 -0
  112. package/dist/tools/get-context.js +9 -1
  113. package/dist/tools/get-relevant-content.d.ts +3 -1
  114. package/dist/tools/get-relevant-content.js +34 -3
  115. package/dist/tools/index.d.ts +4 -2
  116. package/dist/tools/index.js +4 -2
  117. package/dist/tools/install-drift-notes.d.ts +51 -0
  118. package/dist/tools/install-drift-notes.js +172 -0
  119. package/dist/tools/knowledge-gap-citations.d.ts +55 -0
  120. package/dist/tools/knowledge-gap-citations.js +132 -0
  121. package/dist/tools/knowledge-gap-exposure.d.ts +72 -0
  122. package/dist/tools/knowledge-gap-exposure.js +160 -0
  123. package/dist/tools/knowledge-gap-grading.d.ts +91 -0
  124. package/dist/tools/knowledge-gap-grading.js +157 -0
  125. package/dist/tools/knowledge-gap-installs.d.ts +65 -0
  126. package/dist/tools/knowledge-gap-installs.js +134 -0
  127. package/dist/tools/knowledge-gap-ranges.d.ts +51 -0
  128. package/dist/tools/knowledge-gap-ranges.js +146 -0
  129. package/dist/tools/knowledge-gap-scope.d.ts +63 -0
  130. package/dist/tools/knowledge-gap-scope.js +118 -0
  131. package/dist/tools/knowledge-gaps.d.ts +12 -3
  132. package/dist/tools/knowledge-gaps.js +172 -121
  133. package/dist/tools/package-presence.d.ts +24 -0
  134. package/dist/tools/package-presence.js +35 -0
  135. package/dist/tools/record-feedback.d.ts +0 -1
  136. package/dist/tools/record-feedback.js +7 -8
  137. package/dist/tools/signal-classifier.d.ts +25 -0
  138. package/dist/tools/signal-classifier.js +40 -0
  139. package/dist/tools/upgrade-impact-callsites.d.ts +52 -0
  140. package/dist/tools/upgrade-impact-callsites.js +226 -0
  141. package/dist/tools/upgrade-impact-literals.d.ts +45 -0
  142. package/dist/tools/upgrade-impact-literals.js +118 -0
  143. package/dist/tools/upgrade-impact-report.d.ts +80 -0
  144. package/dist/tools/upgrade-impact-report.js +178 -0
  145. package/dist/tools/upgrade-impact.d.ts +84 -0
  146. package/dist/tools/upgrade-impact.js +305 -0
  147. package/dist/tools/upgrade-planner.d.ts +41 -8
  148. package/dist/tools/upgrade-planner.js +201 -53
  149. package/dist/tools/vulnerability-scan-concise.d.ts +72 -0
  150. package/dist/tools/vulnerability-scan-concise.js +97 -0
  151. package/dist/tools/vulnerability-scan-format.d.ts +137 -0
  152. package/dist/tools/vulnerability-scan-format.js +276 -0
  153. package/dist/tools/vulnerability-scan.d.ts +338 -18
  154. package/dist/tools/vulnerability-scan.js +84 -125
  155. package/dist/tools/what-should-i-know.d.ts +86 -19
  156. package/dist/tools/what-should-i-know.js +277 -283
  157. package/dist/types.d.ts +4 -1
  158. package/package.json +27 -30
  159. package/dist/schemas/agent-memory.json +0 -49
  160. package/dist/schemas/decision-enforcement.json +0 -22
  161. package/dist/schemas/decision-memory.json +0 -54
  162. package/dist/schemas/dependency-health.json +0 -27
  163. package/dist/schemas/developer-dna.json +0 -219
  164. package/dist/schemas/ecosystem-pulse.json +0 -17
  165. package/dist/schemas/get-actionable-signals.json +0 -29
  166. package/dist/schemas/get-context.json +0 -17
  167. package/dist/schemas/get-relevant-content.json +0 -26
  168. package/dist/schemas/knowledge-gaps.json +0 -14
  169. package/dist/schemas/record-feedback.json +0 -24
  170. package/dist/schemas/upgrade-planner.json +0 -22
  171. package/dist/schemas/vulnerability-scan.json +0 -26
  172. package/dist/schemas/what-should-i-know.json +0 -19
package/CHANGELOG.md ADDED
@@ -0,0 +1,667 @@
1
+ # Changelog
2
+
3
+ ## 6.0.0 — 2026-10-02
4
+
5
+ ### New: `upgrade_impact`
6
+
7
+ What changes between the version you run and the one you want, for one npm
8
+ or crates.io dependency: the releases in between (publish dates, npm
9
+ deprecations, crates yanks), the changelog shipped inside the target
10
+ version's own registry archive with every entry classified breaking /
11
+ deprecation / security, the breaking entries that mention symbols your code
12
+ imports from the package (`touches_your_code`), the files that import it, and
13
+ the advisories the upgrade fixes or leaves. Only the package's registry and
14
+ OSV.dev are contacted; when the archive ships no changelog (fastembed, vite and
15
+ zod do not) the answer says so and gives the release-notes URL instead of
16
+ guessing.
17
+
18
+ Breaking changes in string literals are found too: the old syntax a breaking
19
+ entry names (axum 0.8's `/:single` -> `/{single}`) is matched in the
20
+ importing files' route and pattern strings, with file and line
21
+ (`matched_literals`).
22
+
23
+ Every entry carries the heading or parent bullet it sits under (`under`):
24
+ "`rt::{Arbiter}` re-exports." means nothing until you see it sits under
25
+ "Removed". Concise output keeps up to 20 plain changes per release under API
26
+ or neutral headings ("Changed", "Methods", "Types") and 3 under additive ones,
27
+ and says how many it left out.
28
+
29
+ How far the "breaking" flags go, measured: five corpora of real upgrades,
30
+ each rated blind by three independent raters. The last, 47 upgrades never
31
+ used to build the rules, rated by raters who saw each entry's heading
32
+ (Fleiss kappa 0.982), is the release measurement: 98.6% of entries flagged
33
+ breaking were breaking (95% CI 94.9-99.6%) and about 65% of breaking entries
34
+ were flagged. Earlier fresh corpora, before the last parser fixes, measured
35
+ 73-87%, so the summary says "flagged", every answer states the measurement in
36
+ `_meta.classification`, and the agent is told to read every entry of a major
37
+ upgrade. Counts are `null` when the changelog has no entry for the releases
38
+ crossed, and labelled lower bounds when it covers only some. Changelog formats
39
+ read: keep-a-changelog and changesets headings, category headings at the
40
+ release's own level (date-fns), plain and bold label lines, releases as
41
+ bullets (indexmap), History.md label lists (express), day-first dates (knex),
42
+ RELEASE-NOTES.md (base64); layout markup (`<details>`) is skipped.
43
+
44
+ ### New: `dependency_check` — a verdict before you add or bump a dependency
45
+
46
+ An agent calls it with up to 25 `{ ecosystem, package, to, from? }` items (npm
47
+ and crates.io) before it edits a manifest; `to: "latest"` checks the newest
48
+ stable release and reports which version that was (`to_requested`). Each item gets `proceed`, `wait`,
49
+ `review`, `avoid` or `unknown`, a one-line reason, and the signals behind it,
50
+ each with evidence: known OSV advisories on the target (and the ones the change
51
+ fixes), release age (under 3 days is `wait`, unless the release fixes an
52
+ advisory affecting the installed version), a drop in publish trust (trusted
53
+ publisher > provenance attestation > neither), npm install scripts the target
54
+ adds, runtime dependencies the target adds that were themselves first published
55
+ under 30 days earlier, yanked / deprecated / unpublished targets, and the
56
+ upgrade type. Against the axios 1.14.0 -> 1.14.1 compromise shape (token
57
+ publish replacing a trusted publisher, plus a dependency created the day
58
+ before) it answers `review` on both counts. A registry or OSV that cannot be
59
+ reached gives `unknown`, never `proceed`; a name missing from the public
60
+ registry says it may be private, misspelled or hallucinated.
61
+
62
+ Registry requests carry the package name only. The installed and target
63
+ versions are picked out of the full release list locally: npm's full packument
64
+ (cached on disk with its ETag and revalidated with `If-None-Match`) and the
65
+ crates.io versions API (spaced one request per second, with a descriptive
66
+ User-Agent) plus the sparse index for per-version dependencies.
67
+
68
+ ### New: the `deps` prompt
69
+
70
+ The server now declares the MCP `prompts` capability. `deps` is a user-invoked
71
+ workflow: plan with `upgrade_planner`, vet each bump with `dependency_check`,
72
+ apply only `proceed` items in small batches with the project's tests after
73
+ each, report everything else with its evidence, and re-run
74
+ `vulnerability_scan` at the end.
75
+
76
+ ### New: a Claude Code plugin, with a hook on dependency edits
77
+
78
+ Install with `claude plugin marketplace add 4DA-Systems/4DA --sparse
79
+ .claude-plugin mcp-4da-server` and `claude plugin install 4da@4da` (the
80
+ repository now carries the marketplace manifest the plugin needed to be
81
+ installable at all). After an Edit or MultiEdit that changes a dependency's
82
+ version in `package.json`, `Cargo.toml`, `pyproject.toml`, `requirements.txt`
83
+ or `go.mod`, the agent is told which packages moved and given the exact
84
+ `dependency_check` and `upgrade_impact` calls. A tool is called when the agent
85
+ thinks to; a hook fires on the edit itself. Plain Node, no network, silent for
86
+ every other edit, and it can never fail the edit. Verified end to end in a real
87
+ Claude Code session: the hook's context reaches the agent on the edit.
88
+
89
+ ### Fixed: the vulnerability scan read lockfiles losslessly
90
+
91
+ Measured against osv-scanner on 12 projects, the matching was exact but the
92
+ lockfile reading lost findings (precision 0.74, recall 0.48 per advisory). Now
93
+ precision 1.00, recall 0.995:
94
+ - every installed copy is scanned, not one version per package name (nested
95
+ npm copies, two versions of a crate: 4DA's own `rsa 0.9.10` was missed);
96
+ - npm/pnpm/Pipfile/poetry dev flags make a transitive's dev scope known;
97
+ - Go: full pseudo-versions and `+incompatible`, `replace` directives, Go's build
98
+ list from `go.mod` (and `go.sum` before go 1.17);
99
+ - `requirements.txt` extras, dotted names, markers, comments and `--hash`
100
+ options; `poetry.lock` of any vintage, `uv.lock`, Poetry and PEP 621 manifests;
101
+ - Cargo virtual workspaces, and standalone mode scans every independently
102
+ locked project under the root, honouring `.gitignore`;
103
+ - `bun.lock` (Bun 1.2+), with dev scope from the workspaces;
104
+ - PEP 440 version order and PEP 503 names when choosing the fix version.
105
+
106
+ Before release the scan was re-run, from the packed tarball installed fresh,
107
+ on those 12 projects and on 11 more never used to build the readers (npm,
108
+ yarn v1, pnpm, bun, Cargo, Go, uv, Pipfile, Poetry): every project matches
109
+ osv-scanner or an independent oracle (OSV queried directly; Go's own
110
+ `go list -m all` build list, where the server reports modules osv-scanner
111
+ misses). The only misses are transitives of a `requirements.txt` without a
112
+ lockfile, documented below. Eight projects locked at current releases report
113
+ zero findings.
114
+
115
+ ### Changed: answers only confirmed evidence can raise
116
+
117
+ - `what_should_i_know` is built from the task: the dependencies it names,
118
+ their installed versions, version-confirmed vulnerabilities, majors crossed.
119
+ Feed headlines no longer drive the delegation verdict (a security keyword
120
+ in an arXiv paper or in OpenAI company news forced `human_only` for any task).
121
+ - `get_actionable_signals` no longer classifies items by keyword; it shows the
122
+ desktop app's classifications only when its relevance judge accepted the item,
123
+ and a headline is never above medium unless it comes from an advisory database.
124
+ - `get_relevant_content` and `knowledge_gaps` leave out judge-rejected items.
125
+ - `upgrade_planner` targets the smallest version that fixes the advisories, not
126
+ the newest major; unmaintained-package notices are not counted as CVEs. It
127
+ and `dependency_health` run the OSV scan themselves when none has run (they
128
+ answered "run vulnerability_scan first", leaving the first answer of a
129
+ session CVE-blind),
130
+ and `package` finds a vulnerable transitive instead of calling it "not a
131
+ dependency".
132
+ - `vulnerability_scan` takes `package`: one dependency's findings across every
133
+ installed copy, with a `package_note` saying what the lockfiles hold for it.
134
+ An agent asked about one transitive otherwise read the whole report.
135
+ - A scan that finishes late no longer replaces a newer one: the startup scan
136
+ (devDependencies left out) could overwrite an agent's `include_dev` scan, and
137
+ the planner then sent the devDependency node-fetch 2.6.0 to the ESM-only 3.3.2
138
+ with no advisories (2 runs in 6). A plan or briefing that needs
139
+ devDependencies covered scans at that scope instead of reading a narrower scan.
140
+ - Desktop mode finds the app's database on Linux (`$XDG_DATA_HOME/4da/data`, as
141
+ the app writes it) and honours the app's `FOURDA_DATA_DIR`.
142
+
143
+ ### Changed: the protocol surface
144
+
145
+ - Every tool now lists all its parameters in `tools/list` (most were hidden).
146
+ - Server `instructions` for hosts with tool search; argument errors come back as
147
+ `isError` with the fix; `structuredContent` beside the text; compact JSON;
148
+ invisible and control characters stripped from third-party text.
149
+ - `tools/list` no longer waits for the project scan (6.6 s measured).
150
+ - `agent_memory` and `decision_memory` match their published schemas (recall
151
+ takes `query`, store takes `subject`; the old schema could not be followed).
152
+
153
+ ### Breaking
154
+
155
+ - Node.js 22 or later. better-sqlite3 publishes no Node 20 binary from 12.10,
156
+ so a Node 20 install compiled from source and failed on any machine without
157
+ Python and a C++ toolchain (every slim container); Node 20 reached end of
158
+ life in April 2026. Verified installs: Node 20 (with a toolchain), 22 and 24
159
+ on Windows; Node 22 on Debian and Alpine Linux; Node 24 on Debian.
160
+ - npm 12 blocks dependency install scripts unless allowed, so better-sqlite3
161
+ is left unbuilt by both `npx` and `npm install`. `--doctor` now opens a
162
+ database instead of trusting the import; it had reported the bindings as
163
+ loaded while every tool failed with "Could not locate the bindings file".
164
+ That error now carries the fix: `npm config set
165
+ allow-scripts=better-sqlite3 --location=user` and `npx clear-npx-cache`, or
166
+ `npm install-scripts approve better-sqlite3` and `npm rebuild
167
+ better-sqlite3`. Each was verified on npm 12.2.0. npm 10 and 11, which every
168
+ current Node release ships, are not affected.
169
+ - `upgrade_impact`'s summary says "N entries flagged breaking", not "N
170
+ breaking changes": the flags are a pre-sort, and every entry now carries its
171
+ heading (`under`).
172
+ - `vulnerability_scan` answers in a concise form by default: `vulnerable_packages`
173
+ has one row per vulnerable package version (worst severity, the version that
174
+ fixes all its advisories, advisory count and first ids), the 40 most severe,
175
+ with 25 recommendations and a count of anything left out. `by_severity` still
176
+ counts every advisory. Pass `response_format: "detailed"` for the previous
177
+ full report, one row per advisory. One row per advisory came to about 25k
178
+ tokens on large projects, the size at which Claude Code cuts a tool answer
179
+ off.
180
+ - `get_actionable_signals` returns fewer items: unclassified and judge-rejected
181
+ ones are gone by design.
182
+ - Tool schemas are no longer separate JSON files (`dist/schemas/`); the
183
+ `4da://schema/<tool>` resources serve them from the tool definitions.
184
+ - A standalone database is created in the user data folder, not in
185
+ `<cwd>/data/4da.db`. An existing one there is still found and used.
186
+ - Hacker News is contacted only when `ecosystem_pulse` is called, never at startup.
187
+
188
+ ### Changed: `upgrade_planner` returns the 4DA app's plan when there is one
189
+
190
+ The tool used to compute its own plan from the lockfiles in the current
191
+ directory, even on a machine where the 4DA app had already computed one. An
192
+ agent could be told a different target than the app showed for the same
193
+ install. When the app's database holds its persisted Upgrade Plan (schema 4),
194
+ the tool now returns that plan's work order with `provenance.mode: "app_plan"`:
195
+ one step per package, keyed by the app's item id, with the ecosystem, each
196
+ installed version and its minimum clean target, the upgrade type
197
+ (patch/minor/major), the projects holding it (direct or transitive, dev or
198
+ not) and the mechanism. `manifest_bump` means edit the manifest;
199
+ `lockfile_or_parent_update` means the package is only transitive, so update its
200
+ parent or refresh the lockfile rather than adding it as a direct dependency.
201
+ Past the plan's `expires_at` the result says `stale: true` and is still the
202
+ app's plan. Without a usable plan (no app database, nothing computed yet, or a
203
+ snapshot from another app version) the tool runs the standalone heuristic as
204
+ before and says why in `appPlanUnavailable`. The server reads the plan; it
205
+ does not reimplement the app's matching. `package` narrows either plan to one
206
+ package.
207
+
208
+ ## 5.1.0 — 2026-09-11
209
+
210
+ ### Fixed: scoped packages in pnpm and yarn lockfiles were never scanned
211
+
212
+ `vulnerability_scan` asked OSV about `'@humanfs/node`, with a leading quote,
213
+ instead of `@humanfs/node`. So GHSA-p498-v437-472g never appeared, although it
214
+ was open as Dependabot alert 340 on this repository and the app showed it. The
215
+ pnpm reader matched package keys with a pattern whose `\s` crossed the blank
216
+ line pnpm writes between entries, and so kept the next key's quote. Every
217
+ scoped package outside the importer blocks was affected: 525 names across five
218
+ lockfiles in this repository (measured 2026-09-11). The test fixture had no
219
+ blank lines, so it passed. The reader now matches keys by column on whole
220
+ lines, reads pnpm lockfile v5, v6 and v9, and drops keys that pin no registry
221
+ version (git, tarball, file) instead of querying them as names. The yarn
222
+ reader could not match a header that starts with `@`, so it dropped every
223
+ scoped package, and it never read yarn berry's `version: x` lines. Both are
224
+ fixed. Expect more findings on a pnpm or yarn project after upgrading; they
225
+ were always there.
226
+
227
+ ### Fixed: a patched lockfile no longer hides a vulnerable node_modules
228
+
229
+ `mcp-4da-server/pnpm-lock.yaml` pinned hono 4.13.5 (the fix for
230
+ CVE-2026-84363/-84364/-84365) while `mcp-4da-server/node_modules` held 4.13.1
231
+ for 25 days, because activation ran `pnpm install` only at the repo root.
232
+ Every 4DA surface reads the lockfile, so every surface reported hono fixed
233
+ while the vulnerable copy was the one that ran (measured 2026-09-10). For npm
234
+ direct dependencies resolved from a lockfile, the server now reads
235
+ `node_modules/<name>/package.json` (scoped names included; hoisted workspaces
236
+ by walking up to the repository root, at most six levels). A directory with
237
+ no `node_modules` of its own is skipped, and a manifest-only resolution is
238
+ never compared, because a specifier floor is not a pin. When the installed
239
+ version differs, OSV is asked about the installed version too, so the answer
240
+ is OSV's, not a guess.
241
+
242
+ `vulnerability_scan` gains `install_drift: [{ package, dir, lockfile_version,
243
+ installed_version, vulnerable_installed, lockfile_version_vulnerable, fix,
244
+ note }]`, where `fix` is `pnpm install`, `npm ci` or `yarn install` according
245
+ to the lockfile that pinned the version. Each affected vulnerability carries
246
+ `installed_version`, `lockfile_version` and an `install_note` ("the lockfile
247
+ is patched but node_modules still has 4.13.1 — run `pnpm install`"), and the
248
+ recommendation is the reinstall, not an upgrade the lockfile is already past.
249
+ `what_should_i_know` names a vulnerable installed copy with its reinstall
250
+ command whatever the task, so the verdict is at least `review_needed` and
251
+ never clean. That advisory is graded the way the app grades its install-drift
252
+ row: high when the reinstall clears an advisory the running copy has (the
253
+ hono case, though its three advisories are medium on their own), medium when
254
+ the lockfile's pinned version is exposed too. `dependency_health` and `upgrade_planner` show `installedVersion`
255
+ beside `currentVersion`, and `upgrade_planner` turns a drift-only row into a
256
+ `reinstall` step. Expect `install_drift: []` on a healthy checkout.
257
+
258
+ ### Fixed: a long-running server answered for the dependency set it saw at startup
259
+
260
+ Three server processes were live on the founder machine. Two had started
261
+ before the pull that brought hono 4.13.5, and `vulnerability_scan` from one
262
+ of them reported hono 4.13.3 (the lockfile at its start) with
263
+ `_meta.cached: false`: versions were resolved once at init and never again,
264
+ and `cached` only ever described the OSV lookup. Each resolution group now
265
+ records the files it read as stat signatures (every lockfile candidate,
266
+ present or absent; the manifest when the resolver fell back to it; for npm,
267
+ the node_modules install state). `vulnerability_scan`, `what_should_i_know`,
268
+ `dependency_health`, `upgrade_planner` and the briefing's scan wait re-run the
269
+ same resolution when one changes, and drop the stored scan and the warmup so
270
+ no answer describes a dependency set that no longer exists. Stat calls only:
271
+ no timers, no watchers. The cargo host-platform memo is keyed on
272
+ `Cargo.lock`/`Cargo.toml` too, so a re-resolution cannot mark newly added
273
+ crates as not built on this host.
274
+
275
+ ### Added: resolution provenance
276
+
277
+ `vulnerability_scan`'s `_meta` gains `resolution: { resolved_at, lockfiles:
278
+ [{ path, kind, mtime }], re_resolved_this_call, note }` and `osv_cached` (the
279
+ same value as `cached`, which stays for compatibility). The tool description
280
+ now says that `cached` refers to the OSV advisory lookup, not to dependency
281
+ resolution. `what_should_i_know` gains a `scan` block (`status`,
282
+ `scanned_at`, `resolved_at`, `re_resolved_this_call`); `scan_status` stays.
283
+
284
+ ### Changed: one severity rule with the desktop app (AD-046)
285
+
286
+ `vulnerability_scan` graded `sandbox@3.1.2`, a transitive of paddle-webhook
287
+ whose dev/runtime scope is unknown, critical (`by_severity.critical: 1`; the
288
+ briefing said "CRITICAL: Sandbox Breakout"), while the app graded the same
289
+ advisory High. Every surface now presents one grade, the rule the app uses
290
+ (`osv::identity::scope_adjusted_urgency`): a transitive-only dependency caps
291
+ critical at high, then a dev-only dependency drops one level (critical to
292
+ high, high to medium, medium to low; low and unknown stay). Unknown dev scope
293
+ gets no discount. Applied in `vulnerability_scan`, `what_should_i_know` and
294
+ `get_actionable_signals`; `severity_filter` and sorting use the presented
295
+ grade. Nothing is hidden: every entry keeps the advisory's own tier as
296
+ `advisory_severity` (with a `severity_note` when the two differ),
297
+ `by_severity` counts the presented grade, and the new `advisory_by_severity`
298
+ counts the raw tiers.
299
+
300
+ In full-database mode a transitive's dev scope comes from the app's
301
+ `dependency_instances` table. Only a real determination counts (`is_dev = 1`,
302
+ or a `scope` of runtime, dev or build); the app's placeholder rows
303
+ (`is_dev = 0, scope = 'unknown'`) stay unknown. Without `include_dev`, only
304
+ direct devDependencies are left out of the scan: a transitive of known dev
305
+ scope is graded down, not dropped, and one of unknown scope is no longer
306
+ hidden because a direct devDependency shares its name.
307
+
308
+ ### Added: the database-recovery voice in data_freshness
309
+
310
+ When the headless refresh engine restores `4da.db` from a backup, or
311
+ quarantines it and starts a fresh empty one, it leaves `data/.db-recovered`
312
+ beside it. A fresh database looks fresh by every other freshness field.
313
+ `data_freshness` now surfaces the marker the way it surfaces `.engine-blocked`:
314
+ `db_recovered_at`, `db_recovery_kind`, `db_recovery_detail`, and a note ("The
315
+ database was restored from a backup / replaced with a fresh empty database by
316
+ the background refresh at … — results may be incomplete or empty; the
317
+ preserved file is …"). Read-only: the desktop app shows the marker once and
318
+ deletes it.
319
+
320
+ ### Changed: ranked reads break ties by id
321
+
322
+ `get_relevant_content` orders by `COALESCE(rank_score, relevance_score) DESC,
323
+ id DESC`, mirroring the app's `RANKED_ORDER_EXPR`. 100 of 651 surfaced items
324
+ sat at exactly 0.5000 (a hard score cap), and their order was whatever SQLite
325
+ emitted.
326
+
327
+ ### Changed: dependency_health says when it has no CVE data
328
+
329
+ `dependency_health` no longer says "all healthy" without a vulnerability scan
330
+ behind it, and says so when CVE data is not loaded (no scan yet, or the
331
+ dependencies changed since the last one).
332
+
333
+ ### Fixed: the briefing never answers "safe" without a vulnerability scan
334
+
335
+ `what_should_i_know` awaited nothing. In full-database mode the live layer was
336
+ initialised without a vulnerability scan, so the first call after start read
337
+ an empty cache and reported `safe_to_delegate` for a task that named a package
338
+ with an open advisory (verified live 2026-09-07: 0 advisories at t+0, 11 at
339
+ t+7 min). The scan now warms at server start, the briefing awaits it (bounded,
340
+ 8 s), and the result carries `scan_status` (`ready` | `unavailable` |
341
+ `disabled`). Without a ready scan the delegation level is the new `"unknown"`
342
+ — treat the task as unreviewed, never as safe; `safe_to_delegate` is only
343
+ emitted over a ready scan. Existing `human_only` evidence still wins.
344
+
345
+ Security signals now also come through a 30-day feed pass (`since_hours` max
346
+ raised from 168 to 720; windows past 7 days keep the current-pipeline-version
347
+ guard), so a three-day-old advisory is no longer cut by the 72-hour window. A
348
+ relevant security or breaking-change advisory yields at least `review_needed`.
349
+
350
+ ### Fixed: one signal per vulnerability
351
+
352
+ `get_actionable_signals` injected one live signal per OSV record, so a
353
+ GHSA/RUSTSEC pair for one bug read as two problems. Alias-connected records
354
+ are clustered (union-find, scoped to package + version) and emitted once,
355
+ every id in `triggers`. Platform-inactive advisories and maintenance notices
356
+ drop to `low` with an explanatory action, and the briefing does not read them.
357
+
358
+ A `signal_type` filter is now pushed into the database read: the general read
359
+ is capped at the top 200 ranked items across every type, and on the live
360
+ corpus that cap starved a security-only pass (both in-window stored security
361
+ alerts ranked 299th and 582nd). The pipeline's stored priority vocabulary
362
+ (`critical` / `alert` / `advisory` / `watch`) is mapped onto the tool's tiers
363
+ instead of cast through unchanged — 92 of 93 stamped rows carried a priority
364
+ no filter, sort, or briefing rule recognised.
365
+
366
+ ### Fixed: knowledge_gaps coverage and grading
367
+
368
+ - Every direct dependency is scanned (a `LIMIT 100` left 43 of 143 live
369
+ dependencies unexamined); candidate items are loaded once.
370
+ - Registry rows (`crates_io`, `npm_registry`, `pypi`, `go_modules`) are version
371
+ updates and grade `medium` regardless of title words — when the row is newer
372
+ than the installed version (the row for the version you run is not a gap).
373
+ - An advisory names a dependency when the dependency is its subject package
374
+ (`[ID] package: …`), not when the title merely contains the word: `url` was
375
+ graded critical on a SurrealDB advisory ("via URL path"), `hmac` on a
376
+ Phalcon one.
377
+ - An advisory the installed version is positively inside survives the 90-day
378
+ publish-date cut; unknown exposure does not exempt.
379
+ - `osv_advisories` is consulted for the dependency's own ecosystem (the npm
380
+ and crates.io `jsonwebtoken` were being conflated).
381
+
382
+ ### Fixed: dependency_health counts vulnerable packages the way vulnerability_scan does
383
+
384
+ `vulnerableCount` is the actionable set (built on this host, not a maintenance
385
+ notice); `advisoryCount` reports every row so nothing is hidden. The health
386
+ penalty and severity breakdown follow the same set.
387
+
388
+ ## 5.0.4 (2026-08-24)
389
+
390
+ ### Fixed: vulnerability_scan could recommend a downgrade
391
+
392
+ `fixed_version` selection took the first OSV range's fix regardless of which
393
+ range contains the installed version — live consequence: "Upgrade undici to
394
+ 6.28.0" while on 7.28.0. Selection is now branch-aware (the fix comes from the
395
+ range containing the installed version), with a hard guard that a
396
+ recommendation is never below the installed version — if no fix at or above it
397
+ exists, the honest "no fix version published" line is emitted instead.
398
+
399
+ ### Changed: ranked reads follow the app's evidence/rank split
400
+
401
+ `get_relevant_content` orders by `COALESCE(rank_score, relevance_score)`
402
+ (schema 110, guarded for older databases); membership thresholds stay on the
403
+ evidence score.
404
+
405
+ ## 5.0.3 (2026-08-23)
406
+
407
+ ### Fixed: standalone mode broke on its second session (critical)
408
+
409
+ The minimal standalone schema created `dependencies` without the `is_direct`
410
+ column, while the live-intelligence init queried it. Session 1 of a standalone
411
+ install worked (fresh scan); session 2+ threw on init, the error was swallowed,
412
+ and `vulnerability_scan` / `dependency_health` / `upgrade_planner` silently
413
+ reported "no project detected" — blaming the user's setup. The column is now in
414
+ the minimal schema and an `ensureColumn` upgrade heals existing standalone DBs
415
+ on open.
416
+
417
+ ### Fixed: grounded tool output
418
+
419
+ - `knowledge_gaps`: word-boundary matching with relevance/recency guards and
420
+ honest severity (previously substring matches like "invite" → vite, and
421
+ everything reported "critical").
422
+ - `ecosystem_pulse`: returns headlines again (dependency prefetch + on-demand
423
+ fetch + 14-day recency window; previously reproducibly empty).
424
+ - `what_should_i_know`: the decision-windows section was dead (ordered by a
425
+ column that does not exist on that table — `created_at` vs `opened_at`).
426
+ - Version logic: no more prerelease "upgrades" (rsa 0.10.0-rc downgrade) or
427
+ phantom stable versions (React "19.0.8") — stable-semver comparison
428
+ throughout.
429
+ - `dependency_health`: healthScore is proportional instead of collapsing to
430
+ 0/100; feed output deduplicated (title similarity).
431
+
432
+ ### Changed: tools/list serves real schemas for required-param tools (AD-032)
433
+
434
+ Tools whose schema declares required parameters (`record_feedback`,
435
+ `decision_memory`, `agent_memory`, `check_decision_alignment`,
436
+ `what_should_i_know`) now serve their real `inputSchema` in `tools/list` —
437
+ the slim `{"type":"object"}` made them uncallable for clients that never read
438
+ MCP Resources. All-optional tools stay slim; full schemas remain available at
439
+ `4da://schema/{tool}`.
440
+
441
+ ## 5.0.2 (2026-08-17)
442
+
443
+ ### Docs: republish so npm serves the corrected README
444
+
445
+ No code changes. 5.0.1 was published to npm on 2026-08-16 minutes before the
446
+ AD-030 copy retirement (#469) landed the corrected README, so the npm package
447
+ page still described "Compound intelligence (learns over time)" and content that "compounds over time" — claims the product retired. <!-- retired-ok: quotes the retired claims verbatim to document exactly what this republish removed from npm -->
448
+ This release exists to put the current README (and the corrected app-vs-MCP
449
+ comparison) on npm.
450
+
451
+ ## 5.0.1 (2026-08-16)
452
+
453
+ ### Security: HTTP transport accepted forged authentication tokens
454
+
455
+ **Affects `--http` only. The default stdio transport was never exposed.**
456
+
457
+ `extractAuthClaims` decoded the JWT payload and validated the claims inside it
458
+ but never read the signature segment — no HMAC was ever computed, despite the
459
+ function's own docstring claiming "HMAC-SHA256 verification against the shared
460
+ relay secret". Any request could present
461
+ `Authorization: Bearer x.<base64url({"team_id":"x","client_id":"y","role":"admin","exp":9999999999})>.x`
462
+ and be accepted as a team admin.
463
+
464
+ Three defects compounded it:
465
+
466
+ - The transport's header claimed "Binds to 127.0.0.1 only", but `--host`
467
+ accepted any address, so `--http --host 0.0.0.0` served all 14 tools to the
468
+ network.
469
+ - The DNS rebinding guard was written as `if (origin) { ...check... }`, so a
470
+ request with **no** `Origin` header — every non-browser client, and any
471
+ attacker — skipped it entirely.
472
+ - `hasPermission()` existed but was never called, so even legitimate tokens got
473
+ no role enforcement: a `viewer` could invoke every write tool.
474
+
475
+ Fixed:
476
+
477
+ - **Real signature verification.** HMAC-SHA256 over
478
+ `base64url(header).base64url(payload)`, constant-time compared
479
+ (`crypto.timingSafeEqual`) against the shared secret, **before** any claim is
480
+ read. The algorithm is pinned to `HS256`, so `alg: none`, other HMAC widths,
481
+ and asymmetric-algorithm confusion are all refused. `exp` is now mandatory
482
+ (a signed token with no expiry is a permanent credential) and `nbf` is
483
+ honoured, both with the issuer's 60s leeway. No new dependency — Node's
484
+ built-in `node:crypto`.
485
+ - **Fail closed.** With no secret configured (`MCP_AUTH_SECRET`, falling back
486
+ to `JWT_SECRET` for parity with a co-deployed relay), *every* token is
487
+ rejected. A server that cannot verify a signature must not trust claims.
488
+ - **Host-header DNS rebinding guard on every request**, using the SDK's
489
+ `validateHostHeader`/`validateOriginHeader`. `Host` is mandatory, so the
490
+ check can no longer be skipped by omitting a header; a foreign `Origin` is
491
+ still refused when present.
492
+ - **Safe `--host`.** 127.0.0.1 remains the default. A non-loopback bind is
493
+ **refused at startup** unless a secret is configured, prints a warning
494
+ banner, and forces authentication on for every request regardless of
495
+ `MCP_AUTH_REQUIRED`.
496
+ - **Role enforcement wired up.** Every tool call is checked against the
497
+ verified role via the registry's existing `readOnlyHint` annotation:
498
+ `viewer` = read-only, `member`/`admin` = read + write. Unknown tools fail
499
+ closed as writes.
500
+ - Removed `isNetworkTierAllowed()` — dead code with no tier data anywhere in
501
+ this package.
502
+
503
+ **Behaviour change:** an existing `--http --host 0.0.0.0` deployment will now
504
+ refuse to start until `MCP_AUTH_SECRET` is set, and only accepts localhost-class
505
+ `Host` headers unless `MCP_ALLOWED_HOSTS` names the address clients use. This is
506
+ deliberate: that deployment was previously reachable by anyone with forgeable
507
+ admin credentials.
508
+
509
+ ## 5.0.0 (2026-08-11)
510
+
511
+ ### Breaking: Node.js 20+ required
512
+
513
+ The server now requires Node.js >= 20 (previously >= 18; Node 18 has been EOL
514
+ since April 2025). No tool behavior changes.
515
+
516
+ ### Changed: migrated to MCP TypeScript SDK v2 + 2026-07-28 protocol support
517
+
518
+ Replaced the discontinued `@modelcontextprotocol/sdk` v1 with the v2 packages
519
+ (`@modelcontextprotocol/server` + `@modelcontextprotocol/node`) and moved both
520
+ transports onto the v2 serving entries:
521
+
522
+ - **stdio** now goes through `serveStdio`, which negotiates the protocol era
523
+ per connection: 2025-era hosts (Claude Code, Claude Desktop, Cursor — the
524
+ classic `initialize` handshake) are served exactly as before, and hosts
525
+ speaking the new stateless 2026-07-28 revision (`server/discover`) are now
526
+ supported on the same endpoint.
527
+ - **--http** now goes through `createMcpHandler` + `toNodeHandler`: stateless
528
+ serving for both eras from one factory — the previous per-request transport
529
+ wiring is gone. Health endpoint, localhost binding, Origin-header DNS
530
+ rebinding protection, and the optional JWT auth gate are unchanged.
531
+
532
+ Existing clients need no changes — protocol version negotiation is untouched
533
+ for 2025-era hosts and verified against a v1-SDK client.
534
+
535
+ ### Fixed: startup log reported a stale version
536
+
537
+ The stdio startup line hardcoded "v4.6.3" regardless of the installed version;
538
+ it now derives from package.json like `--version` and `serverInfo`.
539
+
540
+ ## 4.6.2 (2026-06-17)
541
+
542
+ ### Fixed: vulnerability_scan returned empty severity, fix versions, and summaries
543
+
544
+ The scanner enumerated advisories via OSV's `/v1/querybatch` endpoint, which returns
545
+ only `{ id, modified }` per vulnerability — but it then mapped that index-only object
546
+ as if it were the full record. Every rich field collapsed to a default: `summary`
547
+ became the bare advisory ID, `fixed_version` was always `null` (so every
548
+ recommendation read "no fix version published"), `references` was always empty,
549
+ `published` actually carried the *modified* timestamp, and severity was hardcoded
550
+ (`medium` for any GHSA, `unknown` for anything else) rather than derived.
551
+
552
+ The scanner now hydrates each matched advisory via `/v1/vulns/{id}` (cache-first,
553
+ 24h TTL, bounded concurrency over the vulnerable subset only) and derives severity
554
+ honestly: a CVSS base score — computed from the vector string when OSV provides one
555
+ (new `cvss.ts`, CVSS v3.0/3.1) — wins, then the GitHub-advisory severity label, then
556
+ `unknown`. No more fabricated default buckets. Real fix versions, CVE aliases,
557
+ summaries, and reference links now flow through.
558
+
559
+ ## 4.6.1 (2026-06-11)
560
+
561
+ ### Improved: prescriptive tool descriptions
562
+
563
+ All 14 tool descriptions now state WHEN to call the tool, not just what it does
564
+ (e.g. "Call when the user asks about security, vulnerabilities, or CVEs"). Both the
565
+ slim tool list and the full schemas carry explicit triggers, so calling models select
566
+ the right tool more reliably. A regression test enforces this going forward.
567
+
568
+ ### Changed: license
569
+
570
+ Relicensed to Apache-2.0 (from MIT). The 4DA desktop app remains under
571
+ FSL-1.1-Apache-2.0; this MCP connector is intentionally permissive to maximize adoption.
572
+
573
+ ## 4.6.0 (2026-04-24)
574
+
575
+ ### Breaking: Tool consolidation — 39 → 14 tools
576
+
577
+ Removed 25 tools that returned empty, broken, or low-value data through MCP.
578
+ Every remaining tool reliably returns useful, actionable information.
579
+
580
+ **Kept (14):**
581
+ - `vulnerability_scan` — live CVE scanning (standalone)
582
+ - `dependency_health` — health score + version freshness (standalone)
583
+ - `upgrade_planner` — ranked upgrade recommendations (standalone)
584
+ - `what_should_i_know` — pre-task intelligence briefing (standalone)
585
+ - `ecosystem_pulse` — filtered ecosystem news (standalone)
586
+ - `get_context` — tech stack + interests (standalone)
587
+ - `get_relevant_content` — scored content feed (full mode)
588
+ - `get_actionable_signals` — classified alerts (full mode)
589
+ - `knowledge_gaps` — dependency blind spots (full mode)
590
+ <!-- retired-ok: historical release notes — describes that release's tool list verbatim -->
591
+ - `record_feedback` — save/dismiss to teach the system (full mode)
592
+ - `decision_memory` — persistent architectural decisions (standalone)
593
+ - `check_decision_alignment` — verify tech choices (standalone)
594
+ - `agent_memory` — cross-session persistent memory (standalone)
595
+ - `developer_dna` — tech identity profile (full mode)
596
+
597
+ **Removed:** explain_relevance, score_autopsy, trend_analysis, daily_briefing,
598
+ context_analysis, topic_connections, signal_chains, semantic_shifts,
599
+ attention_report, source_health, config_validator, llm_status,
600
+ export_context_packet, reverse_mentions, project_health, tech_radar,
601
+ agent_session_brief, delegation_score, autophagy_status, decision_windows,
602
+ compound_advantage, record_agent_feedback, get_agent_feedback_stats,
603
+ trust_summary, preemption_feed
604
+
605
+ **Fixed:**
606
+ - `get_relevant_content` now uses Rust-computed PASIFA scores when the desktop
607
+ app database is present, instead of the simplified TypeScript keyword scorer.
608
+ Results are dramatically more accurate.
609
+
610
+ ## 1.0.0 (2026-02-27)
611
+
612
+ Initial public release.
613
+
614
+ ### Tools (27)
615
+
616
+ **Content & Scoring**
617
+ - `get_relevant_content` — Query filtered content by relevance, source, time
618
+ - `explain_relevance` — Understand why an item scored the way it did
619
+ - `record_feedback` — Teach 4DA what you like/dislike (click, save, dismiss)
620
+ - `score_autopsy` — Deep forensic analysis of relevance scores
621
+
622
+ **Intelligence & Analysis**
623
+ - `daily_briefing` — Executive summary of discoveries
624
+ - `trend_analysis` — Statistical patterns, anomalies, and predictions
625
+ - `get_actionable_signals` — Classify content into actionable signals with priority levels
626
+ - `signal_chains` — Get causal signal chains connecting related events over time
627
+ - `semantic_shifts` — Detect narrative shifts in topics you follow
628
+ - `topic_connections` — Build knowledge graphs from content
629
+
630
+ **Developer Context**
631
+ - `get_context` — Get user's interests, tech stack, learned affinities
632
+ - `context_analysis` — Optimize your context for better relevance
633
+ - `knowledge_gaps` — Detect knowledge gaps in your project dependencies
634
+ - `project_health` — Project health radar for dependency freshness and security
635
+ - `reverse_mentions` — Find where your projects are mentioned in sources
636
+ - `attention_report` — Analyze attention allocation vs codebase needs
637
+ - `developer_dna` — Export your Developer DNA — tech identity, dependencies, engagement, blind spots
638
+
639
+ **Decision & Memory**
640
+ - `decision_memory` — Manage developer decisions (record, list, check, update, supersede)
641
+ - `tech_radar` — Generate tech radar from decisions and content signals
642
+ - `check_decision_alignment` — Check if a technology aligns with active decisions
643
+ - `decision_windows` — View time-bounded opportunities requiring attention
644
+ - `compound_advantage` — Measures intelligence leverage for decisions
645
+
646
+ **Agent Integration**
647
+ - `agent_memory` — Cross-agent persistent memory — store and recall across sessions
648
+ - `agent_session_brief` — Tailored session startup context for AI agents
649
+ - `delegation_score` — Should the agent proceed or ask the human?
650
+ - `export_context_packet` — Generate portable context packet for session handoff
651
+
652
+ **System**
653
+ - `source_health` — Diagnose source fetching and data quality issues
654
+ - `config_validator` — Validate configuration and detect issues
655
+ - `llm_status` — Check LLM/Ollama configuration and availability
656
+ - `autophagy_status` — Intelligence metabolism status — calibration accuracy, anti-patterns
657
+
658
+ ### Features
659
+
660
+ - 11 content sources: Hacker News, Reddit, Twitter/X, GitHub, RSS, YouTube, arXiv, Dev.to, Lobsters, Product Hunt, custom feeds
661
+ - PASIFA scoring algorithm — 5-axis codebase-aware relevance with confidence calibration
662
+ - Privacy-first — local SQLite reads; the only outbound call is vulnerability_scan (package names + versions to OSV.dev), zero telemetry
663
+ - BYOK — bring your own API keys, never stored remotely
664
+ - Works offline with Ollama fallback for embeddings
665
+ - Dual transport: stdio (default) and Streamable HTTP
666
+ - SQLite storage with automatic migrations
667
+ - Compatible with Claude Code, Cursor, Windsurf, VS Code Copilot, and any MCP client