@4da/mcp-server 5.0.4 → 6.0.1

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