Commit 5b6620e
authored
fix(security): clear the dependency advisories and gate them in CI (#153)
## Related Issue
No issue — this came from the Dependabot alerts on `main`. GitHub
currently reports **83 vulnerabilities** there (2 critical, 33 high, 41
moderate, 7 low).
## Problem
A full-workspace audit returned 88 advisory records across 78 unique
advisories. Several land in code that actually runs: the WebSocket
server, the protobuf decoder, the router, and the Markdown/diagram
renderers inside the web UI that the CLI ships prebuilt as `dist-web`.
An unreachable advisory is still a valid finding — reachability changes
urgency and test scope, not whether the dependency is vulnerable.
The second problem is that nothing was watching. Fixing 78 advisories
once and having them drift back is the default outcome without a gate.
## What changed
**Advisory floors.** The lockfile now resolves clean at every severity.
| Area | Moves |
|---|---|
| Runtime | `ws` → 8.21.3, `react-router` → 7.18.2, plus `protobufjs`,
`@protobufjs/utf8`, `find-my-way`, `ip-address`, `fast-uri` |
| Browser | `mermaid` → 11.17.0, `dompurify` → patched, Monaco via patch
(below) |
| Tooling | `vite` → 6.4.3, plus `esbuild`, `postcss`, `nanoid`,
`brace-expansion`, `js-yaml`, `linkify-it`, `qs`, `body-parser` |
`tar` is dropped outright rather than bumped — nothing has imported it
since the hosted ripgrep bootstrap was removed.
**Monaco has no release carrying the fix**, so
`patches/monaco-editor@0.55.1.patch` pins its bundled DOMPurify. A patch
that only applies on some build paths is worse than no patch, so
`flake.nix` adds `./patches` to the fileset — without it the Nix build
would install an unpatched Monaco while every other path got the patched
one — and `scripts/security/check-artifacts.mjs` asserts the patch
survived install rather than trusting that it did.
**`dist-web` is rebuilt** in the same commit. The CLI ships the bundle
prebuilt, so patched `mermaid`/`dompurify`/Monaco only reach users once
the committed bundle is rebuilt against them. The staleness gate
enforces this.
**The guards**, so this does not have to be redone:
- `dependabot.yml` for the update stream.
- `codeql.yml` for source analysis.
- `security.yml`, which packs the CLI tarball and the VSIX and audits
**what those artifacts actually ship**. A clean lockfile says nothing
about what ends up inside a published package — the two can disagree,
and the artifact is what users install.
`docs/security/dependency-remediation-2026-08.md` records the evidence
and the ownership split behind each floor, including the rule that
discovery sources can corroborate a version but never establish a safe
floor on their own.
## Verification
Run locally against this branch:
| Gate | Result |
|---|---|
| `pnpm run typecheck` | pass |
| `pnpm run lint` | 0 errors (3224 pre-existing warnings) |
| `pnpm run test` | 20318 passed; the one failure was
`sessionIndex.test.ts` under concurrent load and passes 39/39 isolated |
| `pnpm run check:security-artifacts` | every version floor asserted;
Monaco patch confirmed present in the installed tree |
| `node scripts/check-nix-workspace.mjs` | 18/18 workspace deps present
|
| `nix build .#pythinker-code` | builds; refreshed `pnpmDeps` hash
verified, no mismatch |
| pre-push suite | all checks passed in 296s |
`check:security-artifacts` additionally needs
`.tmp/security-artifacts/{cli,vsix}` populated, which `security.yml`
does by packing first — that part is exercised by CI on this PR, not
locally.
## Checklist
- [x] I have read the CONTRIBUTING document.
- [ ] I have linked a related issue — none; this came from the
Dependabot alert list.
- [x] I have added tests that prove my feature works —
`scripts/security/check-artifacts.mjs` and `check-built-browser.mjs` are
the tests: they assert the floors and the Monaco patch against the
packed artifacts, so a regression fails CI rather than reappearing as an
alert.
- [x] Ran `gen-changesets` skill — `patch` on `@pymodel/pythinker-code`:
"Update the bundled dependencies to releases that carry the current
security fixes." The CI and tooling parts carry no changeset; users
cannot perceive them.
- [x] Ran `gen-docs` skill, or this PR needs no doc update — no
user-facing CLI behavior changed.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Expanded diagram rendering support, including flowcharts, state
diagrams, timelines, mind maps, radar charts, treemaps, Sankey charts,
Venn diagrams, and more.
* Added editor language support and syntax highlighting for Python,
JavaScript, TypeScript, HTML, JSON, YAML, XML, MDX, Razor, Liquid,
Handlebars, FreeMarker, and CSS.
* Added improved code, math, Mermaid, D2, and infographic block
rendering.
* **Bug Fixes**
* Strengthened content sanitization and security validation.
* Improved diagram rendering reliability and layout behavior.
* Addressed dependency vulnerabilities and removed unused packaged
assets.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->1 parent 35c89a7 commit 5b6620e
246 files changed
Lines changed: 7677 additions & 5013 deletions
File tree
- .changeset
- .github
- workflows
- apps
- desktop/scripts
- pythinker-code/dist-web
- assets
- pythinker-inspect
- pythinker-web
- vis/web
- vscode
- docs
- security
- packages
- agent-core-v2
- agent-core
- agent-gateway
- klient
- patches
- scripts/security
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
16 | 10 | | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
30 | 40 | | |
31 | 41 | | |
32 | 42 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
| 115 | + | |
115 | 116 | | |
116 | 117 | | |
117 | 118 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
| 2 | + | |
3 | 3 | | |
4 | 4 | | |
0 commit comments