Repository navigation
Commit 289ff6d
fix(deps): take the fixes for sharp and shell-quote that turn main's OSV scan red (#22016)
Fixes #22013
Clause-②: no
## What this does
`Validate Package Dependencies` runs OSV-Scanner against
`pnpm-lock.yaml`. Two advisories published on 2026-10-06 match `main`'s
lockfile, so every PR that touches a `package.json` inherits a red that
is not its own (PR #22002, run 37483796939, is the first measured), and
the next scheduled scan will be red too. Both advisories name a fixed
version, so this PR takes both fixes. There is no exemption:
`osv-scanner.toml` is untouched, because it is for advisories with no
fixed release.
PR #22002 is not touched here. Its `update-branch` after this lands is
the PM's pointer to its holder.
## OSV reading: before and after
Measured locally with OSV-Scanner **v2.3.8**, the version
`validate-deps.yml` pins, in offline mode (`--offline-vulnerabilities
--download-offline-databases`). The OSV npm database was downloaded on
2026-10-06 at 16:36 UTC, after both advisories were published (13:40 and
13:43 UTC).
`main` at `803764a3` (exit 1). These are the two rows the card names:
```text
| https://osv.dev/GHSA-wq5f-xc86-pv6w | 8.9 | npm | sharp | 0.35.4 | 0.35.5 | pnpm-lock.yaml |
| https://osv.dev/GHSA-pqg4-j6r4-53mv | 9.2 | npm | shell-quote | 1.10.0 | 1.11.0 | pnpm-lock.yaml |
```
This PR at `d263b701` (exit 0): `No issues found`. One vulnerability is
filtered, the standing `sprintf-js` exemption, unchanged. The scanner
names nothing beyond these two advisories, so no third one has appeared
since the card was filed.
## Changes
### `sharp`: the override target lifts from `^0.35.4` to `^0.35.5`
- **Advisory:** GHSA-wq5f-xc86-pv6w (8.9 high). It is a memory bug in
the librsvg that sharp's prebuilt binaries bundle. The range is
introduced 0, fixed 0.35.5, read from the scanner's offline database.
- **Edit:** the target only, `'sharp@>=0.34.0 <0.36.0': '^0.35.5'`. The
selector already sits at the 0.x caret boundary, so it does not change.
This is the same shape as the #16999 lift on this entry.
- **Dedupe, not a forced upgrade:** `next@16.3.6` declares the optional
`sharp: ^0.35.4`, which already admits 0.35.5. 0.35.4 was the single
resolved copy.
- **What moves with it:** sharp pins its prebuilt `@img/sharp-*`
binaries exactly, so they move to 0.35.5, and the libvips binaries move
to 1.3.4.
- **Measured:** the installed sharp 0.35.5 loads on linux-x64. It
reports `rsvg 2.63.2`, the librsvg release the advisory names as fixed,
and it renders a PNG.
### `shell-quote`: a new override, `'shell-quote@>=1.8.4 <2.0.0':
'^1.11.0'`
- **Advisory:** GHSA-pqg4-j6r4-53mv (9.2 critical). In `quote()`, a line
terminator in a string after a `{ comment }` token ends the comment, and
the rest of that string runs as shell input. The range is introduced
1.8.4, fixed 1.11.0.
- **The one path:** `launch-editor@2.14.1`, then
`@changesets/cli@3.0.3`, then the root `package.json`'s
`devDependencies`. launch-editor declares `shell-quote: ^1.8.4`, which
admits the fix, so this is a dedupe onto the patched line. The copy sat
on 1.10.0 through lockfile inertia.
- **Selector shape:** the floor is the advisory's 1.8.4, and the bound
sits at the 2.0.0 major boundary, per the block header's rule. The bound
is never `<1.11.0`.
- **Resolution:** `^1.11.0` floats to **1.12.0**, the newest 1.x.
launch-editor calls shell-quote in one place, `parse()` on the editor
command (`guess.js`). 1.11.0 and 1.12.0 only teach `parse()` ANSI-C
quoting and more operators. Seven editor command strings (`code --wait`,
a quoted macOS path with `-w`, `emacsclient -t -a ''` and others) parse
identically under 1.10.0 and 1.12.0. The vulnerable `quote()` is never
called on this path. The fix is taken anyway, because the gate reads the
lockfile, not the call graph.
- **Note:** the entry carries a note in the block's style, at the foot
of `overrides:`.
### Why an override and not a `@changesets/cli` bump
No release on that path forces the fix (`npm view`, 2026-10-06):
- `@changesets/cli` 3.0.3 is npm `latest`, which is the version the root
already declares. Every 3.0.x declares `launch-editor: ^2.14.1`.
- launch-editor's latest, 2.14.2 (published today), declares
`shell-quote: ^1.10.0`, which still admits the flagged 1.10.0.
So the bump route does not exist, and a launch-editor bump would still
leave the floor to lockfile inertia. On the four axes:
- **Real need:** the measured need is a patched resolution and a green
gate. Only the override delivers both, because no upstream release
declares a range above 1.10.0.
- **Long-term soundness:** the entry follows the block header's selector
rule (bound at the major boundary), so a later advisory is a target-only
lift. It turns into a dedupe floor once launch-editor declares
`^1.11.0`. Its cost is one more ledgered entry.
- **Making AI mistakes harder:** a declared floor is audited by
`check:override-consistency`, and no re-lock can land below it. A bare
re-lock with no floor, like #21951's `proxy-addr` step, leaves nothing
to stop a later resolution from drifting back.
- **Startup scope:** this is the smallest change. It moves no
devDependency and adds no gate.
## Lockfile diff
`pnpm-lock.yaml` is **+126/−125**, re-locked by `pnpm install`, never by
hand. Every changed line falls into one of four kinds:
- a `sharp`, `@img/sharp-*` or `shell-quote` package or snapshot key;
- a dependency edge onto one of those packages;
- the integrity line under one of those keys;
- one of the two `overrides:` header lines, which are the sharp target
and the new shell-quote entry.
Nothing else moves. This was measured by attributing every changed line:
after dropping the lines that name sharp or shell-quote, and the
integrity lines under those keys, zero lines remain.
`pnpm-workspace.yaml` is **+39/−1**: the sharp target, its dated note,
and the shell-quote entry with its note.
`pnpm why`, before and after:
- `sharp` 0.35.4 becomes 0.35.5, one version in both cases. The tree
shape is byte-identical with the version masked: through `next@16.3.6`
under `@objectstack/docs` (and the fumadocs packages), and through
better-auth's `next` peer under `@objectstack/plugin-auth`.
- `shell-quote` 1.10.0 becomes 1.12.0, one version in both cases:
`launch-editor@2.14.1`, then `@changesets/cli@3.0.3`, then the root's
devDependencies.
## Changeset
`skip-changeset`. The diff touches `pnpm-lock.yaml` and
`pnpm-workspace.yaml`, both repo-root configuration, and neither is in
any package's `files[]`. sharp resolves under two importers:
- `@objectstack/docs`, which is private.
- `@objectstack/plugin-auth`, which is published. Its `files[]` is
`dist`, `README.md` and `CHANGELOG.md`, and its `package.json` does not
change. It declares no sharp range at all. sharp reaches it only through
better-auth 1.7.3's optional `next` peer, which this workspace
auto-installs (`auto-install-peers=true`), and next's own optional
`sharp` dependency.
Overrides do not reach downstream installs, so nothing published
changes. shell-quote is dev-only, under the private root.
## Local verification, at `d263b701`
- `pnpm install --frozen-lockfile --prefer-offline`: exit 0.
- The gates come from `node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack`, derived from the change set at this
head: 22 commands. The dispatch named 25 because it included
`package.json`, which this diff does not touch. The `--ran`
reconciliation is filled in below.
`--ran` reconciliation, with exit codes recorded before any pipe: **22
derived, 18 run, 4 NOT-MEASURED, 0 UNRUN**.
| Gate | Exit |
|---|---|
| `node scripts/check-changeset-fixed.mjs` | 0 |
| `node scripts/check-closing-keyword-parity.mjs` (+ `--self-test`) | 0
/ 0 |
| `node scripts/check-comment-mask-corpus.mjs` | 0 |
| `node scripts/check-dts-emitted.mjs --self-test` | 0 |
| `node scripts/check-osv-exemptions.mjs` (+ `--self-test`) | 0 / 0 |
| `node scripts/check-prerelease-pin-watch.mjs --self-test` ;
`--verbose` | 0 / 0 |
| `pnpm --filter @objectstack/spec run check:llms-txt` | 0 |
| `pnpm check:driver-memory-census` · `check:gitlink-declared` ·
`check:nul-bytes` · `check:override-consistency` ·
`check:refd-timer-probe` · `check:vendor-export-contract-resolve` ·
`check:watch-hint-literal` · `check:workspace-manifest-cycles` | 0 each
|
| `pnpm check:dts-closure` · `check:dual-build-cjs-loads` ·
`check:lean-entry-closure` · `check:sourcemap-no-sources-content` | **3,
PREREQUISITE NOT MET** |
- **`check:override-consistency`:** the census now counts 38 overrides,
up from 37. shell-quote appears in neither report: it has a consumer,
and its bound clears the target floor.
- **NOT MEASURED (four gates):** they read every package's built
`dist/`. This diff touches no package source, so the local scope builds
no package, and the build these four need is the full `pnpm build`. CI's
`Build Core` and `Lint & Repo Gates` measure them on the built tree.
This narrowing is declared here, and none of the four is counted as a
pass.
- **Not run locally, CI's:** the path-scheduled jobs that
`dispatch-gates` lists (`Test Core`, `Temporal Conformance`, `Dogfood
Regression Gate`, `Dogfood Verify CLI`, `Build Core`, `Build Docs`) and
the type-check lanes.
## Acceptance notes
- `pnpm install` prints `ioredis-mock 8.13.1: unmet peer ioredis@^5:
found 6.0.0`. That warning is already on `main` and is not from this
diff.
- The sharp selector's floor is 0.34.0, while the new advisory's range
starts at 0. No sharp copy below 0.34 resolves anywhere, and the card
rules the selector untouched, so the floor stays where it is.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01VF48aw8RPG6wzDnMgp6rtw)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent 8601526 commit 289ff6d
2 files changed
Lines changed: 165 additions & 126 deletions
0 commit comments