penthera 1.7.0 → 1.8.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 (163) hide show
  1. package/CHANGELOG.md +315 -0
  2. package/README.md +139 -76
  3. package/SECURITY.md +8 -6
  4. package/docs/examples/pr-dependency-review.yml +1 -1
  5. package/lib/adaptive-probes.js +3 -3
  6. package/lib/advisories/evidence.js +248 -0
  7. package/lib/advisories/index.js +228 -0
  8. package/lib/advisories/products.js +83 -0
  9. package/lib/advisories/versions.js +65 -0
  10. package/lib/agents/hidden-content.js +122 -11
  11. package/lib/agents/index.js +26 -6
  12. package/lib/agents/lock.js +33 -5
  13. package/lib/agents/rules.js +33 -4
  14. package/lib/compliance/index.js +4 -4
  15. package/lib/crawler.js +12 -15
  16. package/lib/deps/capabilities.js +21 -5
  17. package/lib/deps/findings.js +309 -0
  18. package/lib/deps/index.js +13 -272
  19. package/lib/deps/iocs.js +74 -0
  20. package/lib/deps/lockfile.js +3 -8
  21. package/lib/deps/online.js +8 -3
  22. package/lib/deps/popular-packages.json.gz +0 -0
  23. package/lib/deps/popular-pypi.json.gz +0 -0
  24. package/lib/deps/python/capabilities.js +16 -3
  25. package/lib/deps/python/index.js +5 -1
  26. package/lib/deps/python/lockfiles.js +11 -5
  27. package/lib/deps/python/source.js +75 -26
  28. package/lib/deps/python/toml.js +15 -3
  29. package/lib/deps/source.js +28 -9
  30. package/lib/deps/typosquat.js +30 -5
  31. package/lib/fix/apply.js +253 -34
  32. package/lib/fix/index.js +7 -4
  33. package/lib/fix/model.js +25 -5
  34. package/lib/fix/util.js +6 -2
  35. package/lib/fuzzer.js +3 -3
  36. package/lib/git.js +65 -0
  37. package/lib/hook/index.js +157 -73
  38. package/lib/hook/policy.js +10 -4
  39. package/lib/install/index.js +4 -7
  40. package/lib/machine.js +0 -13
  41. package/lib/memory/store.js +11 -4
  42. package/lib/nuclei-loader.js +0 -25
  43. package/lib/owasp-wstg.js +4 -0
  44. package/lib/plugins.js +1 -1
  45. package/lib/provenance.js +1 -0
  46. package/lib/recon.js +12 -31
  47. package/lib/references.json +224 -0
  48. package/lib/retirejs.js +4 -4
  49. package/lib/rules/advisories/advisories.json +186 -0
  50. package/lib/rules/advisories/eol.json +413 -0
  51. package/lib/rules/advisories/pack.json +20 -0
  52. package/lib/rules/advisories/pack.json.sig +6 -0
  53. package/lib/rules/allowed_signers +13 -0
  54. package/lib/rules/core/agent-exec.json +29 -0
  55. package/lib/rules/core/agent-instructions.json +17 -0
  56. package/lib/rules/core/pack.json +30 -0
  57. package/lib/rules/core/pack.json.sig +6 -0
  58. package/lib/rules/core/secrets.json +161 -0
  59. package/lib/rules/core/templates.json +52 -0
  60. package/lib/rules/index.js +107 -0
  61. package/lib/rules/ioc-2025-2026/files.json +43 -0
  62. package/lib/rules/ioc-2025-2026/hosts.json +35 -0
  63. package/lib/rules/ioc-2025-2026/pack.json +25 -0
  64. package/lib/rules/ioc-2025-2026/pack.json.sig +6 -0
  65. package/lib/rules/ioc-2025-2026/packages.json +1048 -0
  66. package/lib/rules/pack.js +452 -0
  67. package/lib/rules/regex-guard.js +81 -9
  68. package/lib/rules/sshsig.js +205 -0
  69. package/lib/templates.js +24 -20
  70. package/lib/tmp.js +21 -0
  71. package/lib/whitebox/frameworks.js +1 -1
  72. package/lib/whitebox/secrets.js +117 -41
  73. package/package.json +12 -4
  74. package/scripts/rules/build-pack.mjs +80 -0
  75. package/scripts/rules/check-bundled.mjs +30 -0
  76. package/scripts/rules/sign-pack.sh +32 -0
  77. package/skills/penthera/SKILL.md +16 -15
  78. package/src/agent/git.js +147 -14
  79. package/src/agent/loop.js +165 -46
  80. package/src/cli/agent.js +11 -5
  81. package/src/cli/deps.js +0 -2
  82. package/src/cli/detect.js +14 -7
  83. package/src/cli/fix.js +26 -8
  84. package/src/cli/hook.js +2 -1
  85. package/src/cli/onboarding.js +14 -6
  86. package/src/cli/report-outputs.js +1 -0
  87. package/src/cli/rules.js +144 -0
  88. package/src/cli/ui.js +43 -10
  89. package/src/cli.js +24 -1
  90. package/src/report/evidence.js +105 -21
  91. package/src/report/footer.js +1 -1
  92. package/src/report/md-escape.js +8 -0
  93. package/src/scan-repo.js +6 -0
  94. package/src/scan-url.js +11 -3
  95. package/src/ui/api/data.js +39 -6
  96. package/src/ui/api/routes.js +44 -11
  97. package/src/ui/api/runs.js +32 -7
  98. package/src/ui/security.js +20 -23
  99. package/src/ui/server.js +52 -27
  100. package/src/ui/static/app.css +583 -213
  101. package/src/ui/static/favicon.svg +1 -1
  102. package/src/ui/static/fonts/DepartureMono-LICENSE.txt +93 -0
  103. package/src/ui/static/fonts/DepartureMono-Regular.woff2 +0 -0
  104. package/src/ui/static/index.html +5 -4
  105. package/src/ui/static/js/api.js +114 -6
  106. package/src/ui/static/js/app.js +81 -42
  107. package/src/ui/static/js/center.js +246 -133
  108. package/src/ui/static/js/charts.js +99 -18
  109. package/src/ui/static/js/copy.js +68 -9
  110. package/src/ui/static/js/dialog.js +152 -0
  111. package/src/ui/static/js/left.js +23 -60
  112. package/src/ui/static/js/menubar.js +170 -0
  113. package/src/ui/static/js/onboarding.js +104 -0
  114. package/src/ui/static/js/panels.js +186 -0
  115. package/src/ui/static/js/right.js +69 -188
  116. package/src/ui/static/js/state.js +36 -5
  117. package/src/ui/static/logo.svg +10 -0
  118. package/src/ui/static/mark.svg +3 -0
  119. package/src/utils/http.js +162 -13
  120. package/docs/METHODOLOGY.md +0 -375
  121. package/docs/commands/README.md +0 -24
  122. package/docs/commands/action.md +0 -21
  123. package/docs/commands/agents.md +0 -38
  124. package/docs/commands/deps.md +0 -115
  125. package/docs/commands/fix.md +0 -53
  126. package/docs/commands/hook.md +0 -69
  127. package/docs/commands/init.md +0 -114
  128. package/docs/commands/install.md +0 -53
  129. package/docs/commands/scan.md +0 -100
  130. package/docs/commands/skill.md +0 -58
  131. package/docs/compare/README.md +0 -25
  132. package/docs/compare/github.md +0 -60
  133. package/docs/compare/semgrep.md +0 -54
  134. package/docs/compare/snyk.md +0 -62
  135. package/docs/compare/socket.md +0 -78
  136. package/docs/compare/zap.md +0 -59
  137. package/docs/compliance-cra.md +0 -141
  138. package/docs/compliance-nis2.md +0 -168
  139. package/docs/dashboard.md +0 -187
  140. package/docs/evidence.md +0 -162
  141. package/docs/funding/due-diligence-checklist.md +0 -79
  142. package/docs/funding/nlnet-ngi-zero-draft.md +0 -273
  143. package/docs/funding/partner-one-pager.md +0 -84
  144. package/docs/funding/sponsor-tiers.md +0 -81
  145. package/docs/index.md +0 -81
  146. package/docs/internal-audit.md +0 -83
  147. package/docs/local-loop.md +0 -276
  148. package/docs/marketing.md +0 -151
  149. package/docs/owasp-wstg-coverage.md +0 -79
  150. package/docs/plan.md +0 -102
  151. package/docs/privacy.md +0 -38
  152. package/docs/references.bib +0 -559
  153. package/docs/references.md +0 -119
  154. package/docs/release-plan.md +0 -228
  155. package/docs/research/socket-positioning-notes.md +0 -183
  156. package/docs/use-cases/README.md +0 -14
  157. package/docs/use-cases/agencies.md +0 -71
  158. package/docs/use-cases/ai-coding-teams.md +0 -81
  159. package/docs/use-cases/eu-sme-compliance.md +0 -68
  160. package/docs/use-cases/open-source-maintainers.md +0 -75
  161. package/docs/use-cases/solo-founder.md +0 -65
  162. package/lib/deps/popular-packages.json +0 -1
  163. package/lib/deps/popular-pypi.json +0 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,289 @@ All notable changes to Penthera are documented here. Versioning follows [SemVer]
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [1.8.0] - 2026-10-21
8
+
9
+ 1.8.0 is 1.8.0-rc.1 plus the changes below; there was no separate rc.2
10
+ release. Highlights across both: fixes from a second independent security
11
+ review, a fix loop that cannot edit the tests that judge it, the redesigned
12
+ dashboard (Simple and Advanced mode), release checks on Linux, macOS and
13
+ Windows, and now runtime advisories, starting with PHP's critical security
14
+ release of 21 October 2026, in a new signed `advisories` rule pack (1.8.0-rc.1
15
+ cannot load it). The benchmark gained two PHP cases: precision 0.88 (95% CI
16
+ 0.69 to 0.96) and recall 0.91 (0.73 to 0.98) on 24 scored findings.
17
+
18
+ ### Added
19
+
20
+ - **Runtime advisories: is the PHP, Apache, nginx, Node.js, Python or OpenSSL
21
+ you run affected?** URL scans read `Server` and `X-Powered-By` banners, the
22
+ `PHPSESSID` cookie name and `.php` pages. Repo scans read Dockerfile and
23
+ compose images, `.tool-versions`, `.php-version`, `.nvmrc`,
24
+ `.python-version`, `runtime.txt` and `composer.json`. Each product and
25
+ version gets one answer: affected, end of life with no fix, check on server,
26
+ or has the fix (as advertised). A hidden version is never reported as safe.
27
+ A distribution build (`8.1.2-1ubuntu2.19`, or any version behind a `Server`
28
+ header that names a distribution) is never reported as affected, because
29
+ distributions backport fixes under the same version number. Advisories that
30
+ need more than a version (Windows, CGI) stay `potential`. See
31
+ [docs/runtime-advisories.md](docs/runtime-advisories.md).
32
+ - **Two rule-pack kinds, `runtime-advisory` and `runtime-eol`**, so a new
33
+ advisory ships as a signed data pack (`--rules`) the same day, without a
34
+ release. End of life is judged by the pack's date, not the scan's clock.
35
+ - **A bundled `advisories` pack** with the PHP security release of 21 October
36
+ 2026 (CVE-2026-109618 and CVE-2026-109619, both Critical, CVSS 4.0 9.2,
37
+ fixed in 8.2.35, 8.3.36, 8.4.27 and 8.5.12, from the php-src advisories),
38
+ vendor-checked worked examples (CVE-2024-4577 and CVE-2024-8926 for PHP-CGI on Windows, CVE-2021-41773 and
39
+ CVE-2021-42013 for Apache HTTP Server 2.4.49 and 2.4.50) and end-of-life
40
+ release lines. Benchmark cases for both URL and repo scans.
41
+
42
+ ### Site
43
+
44
+ - **A landing page in `site/`**, a static site for Vercel: the positioning,
45
+ `npx penthera`, prompts for Claude Code, Cursor and Codex, the hero loop and
46
+ the walkthrough, the limits and the research plan. No third-party scripts,
47
+ analytics or cookies; fonts are self-hosted or system fonts.
48
+ - **A check in the browser.** Drop or paste a `package.json`, `.mcp.json`,
49
+ `.claude/settings.json`, `CLAUDE.md` or `AGENTS.md` and Penthera's own
50
+ `lib/` code runs in the tab: the agent-config rules, the secret patterns,
51
+ install scripts, typosquats against the vendored popular list, and the
52
+ bundled IOC pack. `site/build.mjs` bundles `lib/` at build time, so the site
53
+ and the CLI run the same rules; `tests/site.test.js` holds the page to the
54
+ CLI on the agents and deps fixtures. The page is served with
55
+ `connect-src 'none'`, so it cannot send the files anywhere.
56
+ - **Runtime advisories in the browser check.** Drop a `Dockerfile`,
57
+ `compose.yaml`, `.php-version`, `.tool-versions` or `composer.json`, or
58
+ paste the response headers `curl -sI` printed for your site (the page never
59
+ contacts it), and `lib/advisories` runs on them: the same findings and
60
+ confidence as the CLI, with "check on the server: distributions backport
61
+ fixes" next to every version-only verdict. `tests/site.test.js` compares
62
+ pasted headers with a URL scan of a loopback server sending the same
63
+ headers, and runtime pins with `runtimeAdvisoriesForRepo`.
64
+ - `penthera deps` findings are built in `lib/deps/findings.js` (moved from
65
+ `lib/deps/index.js`, no behaviour change), so the browser check uses the
66
+ same wording.
67
+ - `scripts/docs-commands.mjs` also checks every command the site shows.
68
+
69
+ ### Docs
70
+
71
+ - **New title for the launch:** "Penthera: your open-source cyber security
72
+ agent", in the README, docs index, `penthera --help`, the GitHub Action name
73
+ (which renames its Marketplace listing), the dashboard and the report
74
+ footer.
75
+
76
+ - **README hero is a 12-second loop** of the terminal and the dashboard
77
+ (setup, an offline scan, Simple and Advanced mode, a fix approved), cut from
78
+ the walkthrough video by `scripts/media/hero-gif.sh`, and it loops without a
79
+ jump. The terminal-only scan clip is now `assets/demo-scan.gif`. The Demo
80
+ media workflow re-cuts the loop on every release.
81
+ - **The README diagram is back**, updated: what Penthera checks, where the
82
+ findings go, and that the fix loop asks first and cannot edit its own tests.
83
+
84
+ ## [1.8.0-rc.1] - 2026-10-20
85
+
86
+ Release candidate for 1.8.0, published on npm's `next` dist-tag
87
+ (`npm install penthera@next`). It becomes 1.8.0 on `latest` after it has run
88
+ on real projects without a blocking issue.
89
+
90
+ ### Security
91
+
92
+ Fixes from a second independent review. Most also apply to 1.7.0; upgrading
93
+ is recommended.
94
+
95
+ - **Dependency scans fail closed.** An npm or Python package that could not be
96
+ read in full (a code file over 64 MB, more files than the reader takes, an
97
+ archive with inconsistent sizes or other structural anomalies, a matched
98
+ artifact that cannot be opened) is now `unscanned`: a high "could not be
99
+ scanned" finding that `penthera install` always holds for approval. The
100
+ Python scanner gained this state. Wheels are capped on the bytes actually
101
+ inflated. Pax global headers that set a size or path are refused. Deeply
102
+ nested `uv.lock`/`poetry.lock` files are a parse error, not a crash.
103
+ - **The fix loop and `fix --apply` run git hardened.** Commit and tag signing,
104
+ signing programs, attribute files and every configured filter driver are
105
+ overridden on every call (`--attr-source` on git 2.40+). Pathspecs are
106
+ literal. Writes are refused when the repository's own config sets
107
+ `filter.*`, `gpg.*` or `include.*`, or on git older than 2.31; the loop then
108
+ does not start, and its one message names the key and how to go on.
109
+ - **The fix loop keeps your uncommitted work.** Dirty files are read with
110
+ `status -z` and re-checked right before every write and commit. Reverts
111
+ restore the exact bytes from before the fix, and only while the file still
112
+ holds what penthera wrote (otherwise the fix is a `conflict` and the file is
113
+ left alone). Commits use `--only`. Plans that touch untracked or ignored
114
+ files are skipped, and every revert step runs even when one fails.
115
+ - **`applyDiff` is all-or-nothing and writes only regular files in the repo.**
116
+ Duplicate and nested paths are refused, a failed apply puts back what it
117
+ wrote, files are replaced through a temp file (never written through a hard
118
+ link), NTFS stream names and 8.3 aliases are refused, and added lines may not
119
+ contain control characters. Approval prompts show control characters as
120
+ escapes.
121
+ - **The pre-commit hook checks everything it should.** Staged content is read
122
+ by object id from NUL-separated output, type changes are included, files
123
+ with NUL bytes are scanned, and a staged file over 16 MB blocks the commit
124
+ (or warns, with `"largeFiles": "warn"`). `hook install` no longer writes
125
+ through a symlinked `pre-commit`.
126
+ - **Secret scanning checks every match.** A placeholder no longer hides a real
127
+ secret of the same rule later in the file. Only regular files are read, with
128
+ a per-file size cap.
129
+ - **Dashboard sessions are bound to the page.** The one-time token travels in
130
+ the URL fragment and is exchanged for a per-tab session sent as an
131
+ `Authorization` header; no cookie is set or accepted. Approvals carry the
132
+ sha256 of the diff shown, and a cut diff says so and needs an explicit
133
+ acknowledgement. A symlinked default `reports/` is refused and every write
134
+ re-checks the folder. Event ids keep counting past the buffer; requests,
135
+ bodies (413), finished runs and open streams are bounded. `--open` no
136
+ longer puts the token on a command line.
137
+ - **Evidence bundles** are built in a private folder and renamed into place,
138
+ and verification never follows a symlinked folder and caps what it reads.
139
+ - **HTTP responses are bounded.** Every body is read with a size cap (counted
140
+ after decompression) and a deadline that covers the body, not just the
141
+ headers. `--offline` compares host and port, and cross-origin redirects drop
142
+ credentials and do not replay request bodies.
143
+ - **Linear-time matching on untrusted text.** Agent-config exec patterns and
144
+ other agent and hook checks no longer backtrack on long input. The rule-pack
145
+ regex guard refuses ambiguous alternation and optional items inside repeated
146
+ groups and end-anchored rescans; community templates use the same guard.
147
+ - **Hostile repos no longer hang or crash scans**: a FIFO is never read, and
148
+ deeply nested JSON is handled; one unreadable agent config becomes a finding
149
+ instead of aborting the run.
150
+ - `--fix-model` never sends a file from outside the repo as context.
151
+ - Installing the hook through pre-commit.com no longer runs the test suite:
152
+ the `prepack` script is gone (publishing still runs `npm test`).
153
+ - Workflows that push or only read no longer keep credentials in the checkout.
154
+ - **The fix loop cannot game its own checker.** A fix diff, from a local
155
+ model or a recipe, may not edit tests, test runner config or the test
156
+ script, Penthera's policy, suppressions, baseline, lock or memory, CI
157
+ workflows, git hooks or lockfiles; `applyDiff` refuses it with `PROTECTED`
158
+ and says to make that change by hand. The loop verifies only against the
159
+ checker the run began with. "Could not fix" is now a recorded outcome
160
+ (`gave_up` in memory, `loopRun.gaveUp`, a summary line): the finding is not
161
+ retried in that run, and a give-up never counts against a recipe. Older
162
+ Penthera versions report a memory chain with `gave_up` events as malformed.
163
+
164
+ ### Added
165
+
166
+ - Release checks in CI (`.github/workflows/install-matrix.yml`): the packed
167
+ tarball is installed into an empty project and run with `npx penthera` on
168
+ Linux, macOS and Windows with Node 22 and 24 (setup wizard dry run, deps,
169
+ agents, repo scan, the pre-commit hook on a real commit, the dashboard's
170
+ token check, bundled rule pack signatures). An upgrade job installs 1.7.0
171
+ from npm, writes memory and dashboard state, upgrades to the tarball and
172
+ checks the old memory chain still verifies and grows. All of it runs under a
173
+ network guard that fails on anything past loopback.
174
+ - Docs as tests: `scripts/docs-commands.mjs` checks every command in the
175
+ README, `docs/` and the skill against `--help` and runs the offline ones on a
176
+ fixture, in `npm test` and against the installed package.
177
+ - Provenance check in CI (`scripts/ci/provenance.mjs`): every commit in a pull
178
+ request that names an AI co-author must carry an `AI-Assisted` line, and the
179
+ other way round.
180
+
181
+ ### Fixed
182
+
183
+ - Windows: `npx penthera` / `penthera init` in a git repository failed with
184
+ "Refusing to write outside the project" for its own `reports/` folder, because
185
+ git prints the repo root with forward slashes. Git roots are now native paths.
186
+ Found by the new Windows install checks.
187
+ - `penthera --help` lists `--rules-signers` and `--allow-unsigned-rules`. Both
188
+ worked and were documented in `docs/rule-packs.md`, but the help left them
189
+ out.
190
+ - `penthera ui`, Advanced mode: a run's transcript no longer shows a stray
191
+ "null" under its title.
192
+
193
+ ### Changed
194
+
195
+ - **`penthera ui` redesigned for people who are not programmers.** A first
196
+ visit runs a three-screen setup (what Penthera does, Simple or Advanced, the
197
+ project and a first check). Simple mode, the default, leads every project
198
+ with a one-sentence verdict ("Not ready to ship: 1 critical problem to fix
199
+ first."), lists problems in plain words, explains each one as what is wrong,
200
+ how sure and what to do, and tells a run as one sentence. Advanced keeps
201
+ everything, now as project tabs (Findings, Dependencies, AI tooling, History,
202
+ Proof) with a severity by confidence triage matrix. A menu bar replaces the
203
+ prompt bar and carries every action with its shortcut and the run status;
204
+ runs start from a New scan window; every change waits in its own window
205
+ (`y`, `n`, `q`). New look: a 1-bit "System" register of tiled windows, dither
206
+ patterns instead of greys, `#0000ed` as the one accent, Departure Mono (OFL,
207
+ self-hosted) for chrome, the serif Penthera wordmark, and a halftone field
208
+ whose density is the open risk. Both themes pass WCAG AA in every state.
209
+ `scripts/dashboard-screenshots.mjs` regenerates the docs screenshots.
210
+ - Smaller npm package: 797 kB to 657 kB packed, 2.3 MB to 1.7 MB unpacked. The
211
+ package ships only `docs/examples/` (the documentation lives on GitHub, and
212
+ README links resolve there), and the popular-package lists for the typosquat
213
+ check are stored gzipped. No behaviour change.
214
+ - Code cleanup, no behaviour change: one git runner (`lib/git.js`), one
215
+ temp-folder helper, one Markdown table-cell escape and one JSON fetch
216
+ helper replace their copies; unused exports and helpers are gone. CI now
217
+ runs `npm run lint` (ESLint, dev-only, minimal rules). Still one runtime
218
+ dependency.
219
+
220
+ ### Docs
221
+
222
+ - **Penthera is described as an open R&D project with a usable tool:** "an
223
+ open-source cyber security agent you can use today, and verify yourself."
224
+ The README, `docs/index.md`, `package.json`, the plugin and marketplace
225
+ manifests, the Agent Skill (trigger phrases kept), the GitHub Action and the
226
+ repository description carry the approved wording. The README has a "How it
227
+ is measured" section (method, evidence, tool) with Wilson intervals next to
228
+ the benchmark numbers, and stays under 14 KB.
229
+ - **One roadmap, one research plan.** `ROADMAP.md` now says what ships next,
230
+ starting with the 1.8.0 feature freeze. `docs/vision-2.0.md` is the research
231
+ plan and holds the quality gates from `docs/plan.md`. `docs/plan.md`,
232
+ `docs/release-plan.md` (v1.2 to v1.4) and the Socket positioning notes moved
233
+ to `docs/archive/`.
234
+ - **Every user-facing page names the question it answers**, for a starter ("is
235
+ my app safe to ship?") or a pro ("how do I put it in CI?"), and
236
+ `docs/index.md` has a Start here path from starter to pro.
237
+ - **Voice guide** (`docs/voice.md`): plain words, short sentences, numbers with
238
+ intervals over adjectives, limits next to claims, no hype. Every user-facing
239
+ page was edited against it.
240
+ - **Release cadence** in CONTRIBUTING: at most one minor release every 2 to 4
241
+ weeks, always through an `-rc.N` on npm's `next` tag, patches for fixes only,
242
+ and a feature freeze before each minor. Current freeze: 1.8.0 = main + #63.
243
+ - Fixed stale facts: SECURITY.md's supported versions (1.2.x to 1.7.x), README
244
+ anchors that no longer existed, Agent Skill links into `docs/` that broke in
245
+ the npm package since the docs stopped shipping there, and the partner brief
246
+ and due diligence notes that still called shipped features "in review".
247
+ - Limitations stated in full: the methodology's "Known limitations" now covers
248
+ every module (deps, AI tooling, fix loop), the evidence (small sample, wide
249
+ intervals, same-team benchmark, single labeller, uncalibrated confidence
250
+ labels), reproducibility, AI-assisted development, and compliance output. The
251
+ 2.0 research program adds "Threats to validity".
252
+ - GenAI disclosure: `docs/genai.md` states how Penthera is built with
253
+ generative AI (models, scale, review gates, licensing, logs), the README has a
254
+ short "How Penthera is built" section (107 of 117 non-merge commits up to
255
+ v1.7.0 written with Claude), and CONTRIBUTING requires an
256
+ `AI-Assisted` trailer on AI-assisted commits. Follows NLnet's generative AI
257
+ policy.
258
+ - `docs/MANIFESTO.md`: what Penthera is today (and is not), seven design
259
+ decisions with their costs and what would change them, and an FAQ. Written to
260
+ be challenged in Discussions.
261
+ - **After the 2026 agent incidents:** `docs/research/agent-incidents-2026.md`
262
+ says what the OpenAI–Hugging Face and Anthropic evaluation incidents mean
263
+ for Penthera, with sources and caveats. `docs/agents-safely.md` is a
264
+ one-page checklist for running AI agents. `docs/research/spec-harness-rules.md`
265
+ specifies planned `harness-*`, `sandbox-*` and `scorer-*` rules (not built
266
+ yet), and the research plan adds E7 and a draft pre-registration for E8
267
+ (do harness guardrails reduce judge tampering?).
268
+ - README: a "Building in public" section linking the CHANGELOG, the freeze, the
269
+ research in progress and the roadmap. Counts refreshed (57 references);
270
+ `npm run docs:numbers` now also counts the secret patterns in the core rule
271
+ pack (20, as the README says, not 8).
272
+ - `docs/genai.md` covers commits since v1.7.0 and how the agents that build
273
+ Penthera are contained; the manifesto says the fix loop cannot edit what
274
+ judges it.
275
+ - `docs/vision-2.0.md`: the plan for 2.0, covering the biggest gaps, an AI roadmap
276
+ (models propose, deterministic checks decide; local models first) and a
277
+ pre-registered research program with sample sizes and safety rules.
278
+ - **An 80-second walkthrough video** (`assets/walkthrough.mp4`, with a poster
279
+ and `walkthrough.vtt` captions) shows `npx penthera`, an offline scan of the
280
+ mock server, `penthera ui --demo` in Simple and Advanced mode, one fix
281
+ approved and the owner report. It is linked from the README and
282
+ `docs/index.md`. `scripts/media/walkthrough.mjs` renders it from demo data
283
+ only, and the Demo media workflow re-renders it on every release.
284
+ - **The terminal GIFs are re-rendered** in the dashboard's black and white
285
+ look. `scan.tape` now writes the README hero (`assets/demo.gif`) directly
286
+ and scans with `--offline`. The `agents` and `deps --diff` tapes rendered a
287
+ "Cannot find module" error, because they ran `bin/penthera.js` by a
288
+ relative path after changing folder; they use an absolute path now.
289
+
7
290
  ## [1.7.0] - 2026-10-19
8
291
 
9
292
  One view and one command. `npx penthera` now sets Penthera up in a project:
@@ -140,6 +423,38 @@ reproduced; each fix has a regression test that fails without it.
140
423
 
141
424
  ### Added
142
425
 
426
+ - **Signed rule packs** (`lib/rules/`, [docs/rule-packs.md](docs/rule-packs.md)):
427
+ detection data (secret formats, hidden-instruction and exec patterns, IOC
428
+ lists, typosquat targets, Nuclei-compatible templates) ships as versioned
429
+ directories. Each pack has a `pack.json` index of SHA-256 hashes, signed
430
+ with `ssh-keygen -Y sign -n penthera-rules`. Penthera verifies the signature
431
+ (in Node; ssh-keygen is not needed at run time), then every hash, the schema
432
+ and every regex, before it loads anything. Packs arrive bundled in a release,
433
+ or by path with `--rules <dir>` (plus `--rules-signers <file>` for your own
434
+ keys). Unsigned packs are refused unless `--allow-unsigned-rules`, which
435
+ warns loudly. Nothing is ever fetched
436
+ - `penthera rules list` and `penthera rules verify <dir>`; tooling in
437
+ `scripts/rules/` (`build-pack.mjs`, maintainer-only `sign-pack.sh`,
438
+ `check-bundled.mjs`). The publish workflow now refuses to stage a release
439
+ whose bundled packs are not signed by a key in `lib/rules/allowed_signers`
440
+ - ReDoS guard for data-supplied regexes (`lib/rules/regex-guard.js`): length
441
+ cap, no backreferences or lookaround, no nested quantifiers, no alternation
442
+ under unbounded repeats, no unbounded quantifier that every start position
443
+ can rescan, and a backtracking budget for overlapping quantifier chains.
444
+ Fuzz-tested: everything it accepts runs in milliseconds on adversarial
445
+ input. The v1.1.1 template guard moved here too, rewritten from a regex
446
+ (itself polynomial on hostile pattern strings, flagged by CodeQL) into a
447
+ linear scan that also catches deeper nesting
448
+ - Bundled `core` pack: 12 AI-provider key formats, the credential-path
449
+ instruction pattern, two exec patterns and the `.env` template moved out of
450
+ code. Behaviour is identical; a test compares against a snapshot of the old
451
+ built-ins
452
+ - Bundled `ioc-2025-2026` pack (**unsigned in this PR; the maintainer signs it
453
+ before release**): s1ngularity/nx versions (GHSA-cxm3-wv7p-598c), Shai-Hulud
454
+ (StepSecurity's list, exfil URL, `bundle.js` by hash), Shai-Hulud 2.0 (Wiz
455
+ Research's CSV, loader file names) and postmark-mcp 1.0.16 to 1.0.18 with its
456
+ exfil domain. `penthera deps` reports hits as critical `deps-ioc` findings
457
+ that cite the source, wherever the package sits in the tree, installed or not
143
458
  - **Internal testing audit** (`npm run audit:internal`), the release gate:
144
459
  tests, benchmark drift, a self-scan against `audit/baseline.json`, a CLI
145
460
  smoke matrix, package contents and size, zero third-party egress offline,
package/README.md CHANGED
@@ -1,10 +1,12 @@
1
1
  <div align="center">
2
2
 
3
- <img src="assets/penthera-social.jpg" alt="Penthera: Cyber Security Agent" width="840">
3
+ <img src="assets/penthera-social.jpg" alt="Penthera: your open-source cyber security agent" width="840">
4
4
 
5
5
  <br/><br/>
6
6
 
7
- **Penthera: Cyber Security Agent. Open-source security for the apps and AI systems you ship.**
7
+ **Penthera: your open-source cyber security agent**
8
+
9
+ The security review you never had time for. Offline, rule-based, and you can verify every finding yourself.
8
10
 
9
11
  <br/>
10
12
 
@@ -16,27 +18,37 @@
16
18
 
17
19
  <br/>
18
20
 
19
- <img src="assets/demo.gif" alt="Penthera running an interactive security scan in the terminal" width="760">
21
+ <img src="assets/demo.gif" alt="A 12-second loop: npx penthera sets up a project, an offline scan runs in the terminal, the dashboard shows the verdict in Simple mode and the triage matrix in Advanced mode, and a fix is approved" width="760">
20
22
 
21
23
  <br/><br/>
22
24
 
23
- | `penthera ui`, dark | `penthera ui`, light |
25
+ | `penthera ui`, Simple, dark | `penthera ui`, Advanced, light |
24
26
  |---|---|
25
- | ![The dashboard in the dark theme: projects, findings, and a finding's detail](assets/dashboard/ui-dark.jpg) | ![The dashboard in the light theme: all projects and the side cards](assets/dashboard/ui-light.jpg) |
27
+ | ![The dashboard in Simple mode, dark: the verdict, problems in plain words and one problem open](assets/dashboard/ui-dark.jpg) | ![The dashboard in Advanced mode, light: a project's tabs, the triage matrix and a finding open](assets/dashboard/ui-light.jpg) |
28
+
29
+ <a href="assets/walkthrough.mp4"><img src="assets/walkthrough-poster.jpg" alt="Walkthrough video: setup, a scan, the dashboard in Simple and Advanced mode, one fix approved, the report" width="760"></a>
30
+
31
+ [Watch the 80-second walkthrough](assets/walkthrough.mp4): setup, a scan, the dashboard, a fix approved, the report. Demo data, no sound, captions in the video.
26
32
 
27
33
  </div>
28
34
 
29
35
  ---
30
36
 
31
- ## The problem
37
+ ## What Penthera is
38
+
39
+ Teams ship apps and AI agents faster than anyone can check them, and most
40
+ security scanners offer no evidence of how well they actually work. Penthera is
41
+ an open-source R&D project that tackles both.
42
+
43
+ **Use it today.** A cyber security agent for your coding tools that runs
44
+ offline on your own machine: it checks your app, its dependencies and your AI
45
+ tooling, and fixes what it can with your approval, through a dashboard that
46
+ works for first-timers and pros alike.
32
47
 
33
- Teams now ship apps and AI agents faster than anyone can secure them. AI writes
34
- much of the code and pulls in the packages, MCP servers, and skills, and on most
35
- teams nobody works on security full time. Attackers have adapted: 2025 and 2026
36
- brought self-spreading npm worms that hijacked AI coding tools, malicious MCP
37
- servers, poisoned agent skills, and leaked AI provider keys. Penthera does the
38
- repeatable security work on your own machine, with rules you can read, so the
39
- people you have can spend their time on judgement.
48
+ **Trust it because it's measured.** Every check is tested in public,
49
+ pre-registered experiments, and the results are published, good or bad. What
50
+ holds up ships in the next release, so Penthera keeps pace with new attacks and
51
+ with EU rules such as NIS2 and the Cyber Resilience Act.
40
52
 
41
53
  ## Get started
42
54
 
@@ -79,6 +91,29 @@ Penthera needs Node.js 22 or later. To run it in a container:
79
91
 
80
92
  ## What it does
81
93
 
94
+ ```mermaid
95
+ flowchart LR
96
+ U["You or your AI agent"] --> P(("Penthera<br/>on your machine"))
97
+
98
+ P --> APP["Your app<br/>URL scan, repo scan"]
99
+ P --> DEP["Your dependencies<br/>capabilities, install firewall<br/>typosquats, upgrade diff"]
100
+ P --> AI["Your AI tooling<br/>skills, MCP, hooks<br/>plugins, rule files"]
101
+
102
+ APP --> F[["Findings<br/>severity, confidence<br/>evidence at file:line"]]
103
+ DEP --> F
104
+ AI --> F
105
+
106
+ F --> FIX["Fix loop<br/>asks first, local branch<br/>cannot edit its own tests"]
107
+ FIX -. "re-scan proves it" .-> F
108
+ F --> R["Reports and dashboard<br/>terminal, Markdown, SARIF<br/>penthera ui"]
109
+ F --> E["Evidence<br/>signed bundle<br/>NIS2 and CRA drafts"]
110
+
111
+ classDef core fill:#0000ed,stroke:#0000ed,color:#ffffff
112
+ classDef box fill:#ffffff,stroke:#000000,color:#000000
113
+ class P core
114
+ class U,APP,DEP,AI,F,FIX,R,E box
115
+ ```
116
+
82
117
  ### Before you deploy
83
118
 
84
119
  | Job | What Penthera does | Command |
@@ -101,7 +136,7 @@ Penthera needs Node.js 22 or later. To run it in a container:
101
136
  | Job | What Penthera does | Command |
102
137
  |---|---|---|
103
138
  | Report and prove | Writes reports for developers, owners, and auditors; a hashed, signable evidence bundle; NIS2 and CRA readiness reports and drafts | [`penthera <url> --audience auditor --evidence out/`](docs/evidence.md) |
104
- | See it all | A local dashboard on 127.0.0.1: one view with your projects, findings in plain words, history, side panels for dependencies, AI tooling and evidence, and the fix loop with Apply, Skip, and Stop per diff | [`penthera ui`](docs/dashboard.md) |
139
+ | See it all | A local dashboard on 127.0.0.1 with a Simple mode for non-programmers: a one-sentence verdict, problems in plain words, a guided setup, and the fix loop with Apply, Skip, and Stop per change. Advanced adds dependencies, AI tooling, history and evidence | [`penthera ui`](docs/dashboard.md) |
105
140
  | Keep watching | Scheduled checks of your production for drift: certificates, headers, new endpoints, keys in bundles, new CVEs in your SBOM | on the [roadmap](ROADMAP.md) |
106
141
 
107
142
  Every finding carries a severity, a confidence label (`confirmed`, `likely`,
@@ -110,60 +145,69 @@ Reports come out as Markdown, JSON, and SARIF for GitHub code scanning. Exit
110
145
  code `1` means critical or high findings. Every command and flag is in
111
146
  [docs/commands/](docs/commands/README.md).
112
147
 
113
- Penthera is not a human pentester, a 24/7 SOC, or incident response. It does
114
- the checks that can be automated reliably and says plainly which ones need a
115
- person.
148
+ ## How it is measured
149
+
150
+ Each feature goes through the same path: **method → evidence → tool.**
151
+
152
+ - **Method.** The [methodology](docs/METHODOLOGY.md) states the threat model,
153
+ what black-box (HTTP) and white-box (source) analysis can and cannot see, the
154
+ confidence model, and the false-positive controls on each probe. Each design
155
+ choice cites the research or standard it rests on: 92 verified references, in
156
+ APA style, in [docs/references.md](docs/references.md).
157
+ - **Evidence.** A benchmark runs on every release, and the release gate fails
158
+ if precision or recall drops by more than 0.02. Experiments that decide what
159
+ ships next are pre-registered in [docs/research/prereg/](docs/research/prereg/)
160
+ before any data is collected, and the results are published either way.
161
+ - **Tool.** What holds up ships in a reviewed, signed release. What does not
162
+ hold up is dropped, and the rules stay.
163
+
164
+ | Measure | Result today |
165
+ |---|---|
166
+ | Precision on the bundled benchmark | 0.88, 95% CI 0.69 to 0.96 (21 true positives, 3 false positives) |
167
+ | Recall on the bundled benchmark | 0.91, 95% CI 0.73 to 0.98 (2 misses, [each one explained](bench/RESULTS.md)) |
168
+ | Requests to non-loopback hosts during the benchmark | 0 |
169
+ | Detection rules, all readable | 14 URL scan templates, 20 secret and AI-key patterns, 15 dependency capabilities, 39 AI-tooling rules, 5 fix recipes |
170
+
171
+ These numbers come from 24 findings in small labs that we wrote ourselves, so
172
+ they catch regressions; they do not measure real-world accuracy. Measuring that
173
+ on real projects is experiment E1, the first step of the
174
+ [research plan](docs/vision-2.0.md). Intervals are Wilson. What Penthera cannot
175
+ see is listed under [Known limitations](docs/METHODOLOGY.md#known-limitations).
176
+ Counts as of 2026-10-21; refresh them with `npm run docs:numbers` and
177
+ `npm run bench`.
178
+
179
+ **Cite this repository** with the button on GitHub or
180
+ [CITATION.cff](CITATION.cff). APA and BibTeX forms are in the
181
+ [methodology](docs/METHODOLOGY.md#how-to-cite).
116
182
 
117
183
  ## Why you can trust it
118
184
 
119
185
  - **Local and offline.** No account, no telemetry, no cloud. `--offline` limits
120
186
  network traffic to the target you named, and every report lists the hosts it
121
- contacted.
122
- - **Deterministic.** Rules you can read, with `file:line` evidence. No model
123
- decides what is malicious.
187
+ contacted ([network use](docs/privacy.md)).
188
+ - **Deterministic.** Rules you can read, with `file:line` evidence. A local
189
+ model may propose a fix; a deterministic re-scan and your tests decide.
124
190
  - **Non-destructive by default.** The default scan sends only requests a
125
191
  browser would send. Payload testing (`--deep`, `--fuzz`, `--all`) is opt-in
126
192
  and asks for confirmation.
127
- - **Never acts behind your back.** The fix loop works on a local branch, asks
128
- before every change by default, and never pushes or opens pull requests.
193
+ - **Asks before it changes anything.** The fix loop works on a local branch,
194
+ asks before every change by default, and never pushes or opens pull requests.
129
195
  - **No update channel to hijack.** Detection rules ship inside reviewed
130
- releases. Nothing is downloaded and executed at run time.
196
+ releases as signed, versioned [rule packs](docs/rule-packs.md). You can add
197
+ your own by path (`--rules <dir>`). Nothing is downloaded and run at run time.
131
198
  - **Releases you can verify.** npm provenance through trusted publishing, a
132
199
  maintainer approval with 2FA for every version, SHA-pinned CI, CodeQL, and
133
200
  OpenSSF Scorecard. Every release passes an
134
201
  [internal audit](docs/internal-audit.md) of eight gates
135
202
  ([latest report](audit/REPORT.md)).
136
203
 
137
- ## Research and methodology
138
-
139
- Penthera's method is written down and tied to the literature. The
140
- [methodology](docs/METHODOLOGY.md) states the threat model, separates what
141
- black-box (HTTP) and white-box (source) analysis can and cannot observe, and
142
- defines a confidence model that keeps heuristics from posing as facts. Each
143
- probe has explicit false-positive controls, such as randomized canaries and
144
- repeated timing measurement, and each design choice cites the research or
145
- standard it rests on: 49 verified references, listed in APA style in
146
- [docs/references.md](docs/references.md).
147
-
148
- | Measure | Result |
149
- |---|---|
150
- | Precision on the bundled benchmark | 0.86 (19 true positives, 3 false positives) |
151
- | Recall on the bundled benchmark | 0.90 (2 misses, [each one explained](bench/RESULTS.md)) |
152
- | Requests to non-loopback hosts during the benchmark | 0 |
153
- | Detection rules, all readable | 14 URL scan templates, 20 secret and AI-key patterns, 15 dependency capabilities, 39 AI-tooling rules, 5 fix recipes |
154
-
155
- The benchmark targets are small and were written by the same people as the
156
- scanner, so the numbers catch regressions rather than measure real-world
157
- accuracy ([limits](bench/RESULTS.md#limits-of-these-numbers)). Counts as of
158
- 2026-10-19; refresh them with `npm run docs:numbers` and `npm run bench`.
159
-
160
- **Cite this repository.** Use the button on GitHub, or the metadata in
161
- [CITATION.cff](CITATION.cff). The APA and BibTeX forms are in the
162
- [methodology](docs/METHODOLOGY.md#how-to-cite).
204
+ Penthera finds known classes of problems, not novel ones, and it does not
205
+ replace a human pentester or incident response. The decisions behind it, its
206
+ limits, and how to challenge them are in the [manifesto and FAQ](docs/MANIFESTO.md).
163
207
 
164
208
  ## How it fits with other tools
165
209
 
166
- Penthera works next to the tools you already use. Its SARIF output goes
210
+ Penthera works next to the tools you already use; its SARIF output goes
167
211
  straight into GitHub code scanning, for example. Each comparison page says where
168
212
  the other tool goes further and how to run the two together.
169
213
 
@@ -176,29 +220,19 @@ the other tool goes further and how to run the two together.
176
220
  | [OWASP ZAP](docs/compare/zap.md) | Dynamic testing of web apps | Your machine or CI | Active and passive scan rules |
177
221
  | [Semgrep](docs/compare/semgrep.md) | Static analysis of your own code | Your machine, CI, cloud platform | Pattern rules, plus a paid cross-file engine |
178
222
 
179
- All comparisons: [docs/compare/](docs/compare/README.md). Corrections are
180
- welcome by pull request.
181
-
182
- ## Use cases
223
+ ## Start here
183
224
 
184
- | You are | Start here |
225
+ | You want to know | Read |
185
226
  |---|---|
186
- | A solo founder or vibecoder about to launch | [Before launch](docs/use-cases/solo-founder.md) |
187
- | A team adopting Claude Code or Cursor | [The AI-tooling supply chain](docs/use-cases/ai-coding-teams.md) |
188
- | An open-source maintainer | [For maintainers](docs/use-cases/open-source-maintainers.md) |
189
- | An EU SME with NIS2 or CRA duties | [Evidence for NIS2 and the CRA](docs/use-cases/eu-sme-compliance.md) ([NIS2 guide](docs/compliance-nis2.md), [CRA guide](docs/compliance-cra.md)) |
190
- | An agency shipping client apps | [A repeatable handover check](docs/use-cases/agencies.md) |
227
+ | Is my app safe to ship? | [Before launch](docs/use-cases/solo-founder.md), then [scan](docs/commands/scan.md) |
228
+ | Is this package or MCP server safe? | [deps](docs/commands/deps.md), [install](docs/commands/install.md), [agents](docs/commands/agents.md) |
229
+ | How do I put it in CI? | [The GitHub Action](docs/commands/action.md), [scan in CI](docs/commands/scan.md#ci-integration) |
230
+ | What do I give my auditor? | [Evidence bundles](docs/evidence.md), [NIS2](docs/compliance-nis2.md), [CRA](docs/compliance-cra.md) |
231
+ | How do I run the fix loop? | [Fix and verify](docs/commands/fix.md), [the local loop](docs/local-loop.md) |
191
232
 
192
- Compliance output is readiness tooling. It is not a certification and not
193
- legal advice.
194
-
195
- ## Privacy
196
-
197
- Penthera has no telemetry and does not phone home. Scan traffic goes to the
198
- target you name, reports stay on your machine, and every scan lists any
199
- third-party host it contacted. With `--offline`, the HTTP client refuses every
200
- host except the target. Which hosts a normal scan may contact, and why, is in
201
- [docs/privacy.md](docs/privacy.md).
233
+ The full map, by situation and from first scan to pro use, is in
234
+ [docs/index.md](docs/index.md). Compliance output is readiness tooling. It is
235
+ not a certification and not legal advice.
202
236
 
203
237
  ## Ethics and authorization
204
238
 
@@ -210,17 +244,46 @@ or harm anyone. Unauthorized testing may break computer-misuse laws such as the
210
244
  US CFAA, the UK Computer Misuse Act, and their EU equivalents. When in doubt, do
211
245
  not scan.
212
246
 
213
- The software is provided "as is", without warranty, for defensive testing of
214
- systems you own or are authorized to test. The author accepts no liability for
215
- misuse, and you are responsible for making sure every scan you run is lawful.
247
+ The software is provided "as is", without warranty. The author accepts no
248
+ liability for misuse, and you are responsible for making sure every scan you
249
+ run is lawful.
250
+
251
+ ## How Penthera is built
252
+
253
+ Penthera is developed with substantial help from generative AI: 91% of the
254
+ commits up to v1.7.0 were written with Claude (Anthropic) through Claude Code,
255
+ directed and reviewed by the maintainer, and marked with a co-author trailer.
256
+ Generated code passes the same gates as any change: tests, CodeQL, an
257
+ independent review, the internal audit, and a 2FA-approved release. Inside the
258
+ product, models only ever propose; deterministic checks decide. The full
259
+ disclosure, and the rules for AI-assisted contributions, are in
260
+ [docs/genai.md](docs/genai.md).
261
+
262
+ ## Building in public
263
+
264
+ What changed, what we are measuring, and what comes next, in one place.
265
+
266
+ | | Where it stands | Read more |
267
+ |---|---|---|
268
+ | **Latest release** | 1.8.0 (2026-10-21): runtime advisories starting with PHP's critical release, fixes from a second security review, a fix loop that cannot edit its own tests, the redesigned dashboard | [CHANGELOG](CHANGELOG.md) |
269
+ | **On main, unreleased** | Whatever lands after 1.8.0 | [Unreleased](CHANGELOG.md#unreleased) |
270
+ | **Now** | Toward 1.9: accuracy on real code (E1) and an MCP server, so coding agents can call Penthera | [Roadmap](ROADMAP.md#next) |
271
+ | **Research** | E1, accuracy on real code, is pre-registered; the benchmark tooling is in review. After the 2026 agent incidents: a checklist for running agents safely and a draft experiment (E8) | [E1 pre-registration](docs/research/prereg/E1-real-world-accuracy.md), [agents safely](docs/agents-safely.md), [what the incidents mean](docs/research/agent-incidents-2026.md) |
272
+ | **Next** | Real-world precision and recall with intervals, published whatever the result | [Roadmap: next](ROADMAP.md#next), [research plan](docs/vision-2.0.md) |
273
+
274
+ Releases are deliberately slow: a feature freeze, an independent review, the
275
+ release checks, and a release candidate before any new minor version. To
276
+ follow along, watch the repository for releases or join the
277
+ [Discussions](https://github.com/danoszz/penthera/discussions).
216
278
 
217
279
  ## Contributing and support
218
280
 
219
281
  Clone the repository and run `npm install`, then `npm test` for the suite and
220
282
  `npm run bench` for precision and recall.
221
- [CONTRIBUTING.md](CONTRIBUTING.md) covers the project layout and the release
222
- checklist, and the [roadmap](ROADMAP.md) shows what is next. Issues and pull
223
- requests are welcome.
283
+ [CONTRIBUTING.md](CONTRIBUTING.md) covers the project layout, the release
284
+ cadence and the release checklist. The [roadmap](ROADMAP.md) shows what ships
285
+ next, and the [research plan](docs/vision-2.0.md) what we measure. Issues and
286
+ pull requests are welcome.
224
287
 
225
288
  Penthera is free. If it caught something before you shipped it, you can
226
289
  [sponsor its maintenance](https://github.com/sponsors/danoszz). Sponsorship pays