Skip to content

fix(deps): take the fix for the seven OSV advisories turning Validate Package Dependencies red - #20564

Merged
hotlong merged 3 commits into
mainfrom
claude/objectstack-release-steps-ynhz3j-osv
Sep 29, 2026
Merged

hotlong merged 3 commits into
mainfrom
claude/objectstack-release-steps-ynhz3j-osv

Conversation

@hotlong

@hotlong hotlong commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Fixes #20561

Summary

Validate Package Dependencies runs OSV-Scanner against pnpm-lock.yaml. It is red on seven Medium advisories that were published on 2026-09-28. Run 36510180397 on the Version Packages PR reported them, and the same lockfile entries sit on main. I reproduced all seven locally against origin/main at b0574343, using OSV-Scanner v2.3.8 (the version the workflow pins) with its offline npm database. Every advisory names a published fix, so this PR takes the fix. That is the path the osv-scanner.toml header prescribes. The ledger keeps zero exemptions and is not changed, and neither is .github/workflows/validate-deps.yml.

Clause-②: no

Advisory → action

Advisory CVSS Package Resolved on main Fixed in Action Resolved after
GHSA-2vr4-cq9g-pvrc 6.9 ip-address 10.4.0 + 10.5.0 10.5.1 new override 'ip-address@<11.0.0': '^10.5.1' 10.7.2 (one copy)
GHSA-rpw4-54j3-4h4q 6.3 ip-address 10.4.0 + 10.5.0 10.5.1 same override 10.7.2 (one copy)
GHSA-6vj9-mwq6-2f5v 5.9 nodemailer 9.1.1 10.0.2 @objectstack/plugin-email declares ^10.0.2 (was ^9.1.1), a major 10.0.12
GHSA-3wwx-pv8p-q78v 5.9 undici 7.29.0 7.29.1 target-only lift of the existing 'undici@>=7.23.0 <8.0.0' pin, ^7.29.0 → ^7.29.1 7.30.0
GHSA-3wwx-pv8p-q78v 5.9 undici 8.9.0 8.10.2 new override 'undici@>=8.1.0 <9.0.0': '^8.10.2' 8.11.2
  • ip-address is transitive-only. One copy comes through @modelcontextprotocol/sdk → express-rate-limit@8.6.1, which declares ^10.2.0. The other comes through mongodb → socks@2.8.9, which declares ^10.1.1. Both ranges already admit 10.5.1, so the override is a dedupe onto the patched line and does not force either dependent past its own range. GHSA-rpw4's affected range starts at 0, so the selector states only the major-boundary upper bound, following the dompurify precedent.
  • undici is transitive-only and dev-only. The 7.x copy comes from ai → @ai-sdk/provider-utils, which declares ^7.28.0. It was already inside the existing selector, so only that selector's target moves. The 8.x copy comes from jsdom@30.0.1, which declares ^8.9.0. It sat outside every selector, and the header note at the top of pnpm-workspace.yaml described it as an unaffected major, so it gets its own entry. That entry is floored at the advisory's 8.1.0 and bounded at 9.0.0, the shape the overrides header prescribes. No 6.x copy resolves anywhere.
  • nodemailer is the one direct dependency, and the prior sweep deliberately did not take the 10.x major. The advisory covers every release from 5.0.0 through 10.0.1, so 9.x has no patched release and the major is the only fix.

nodemailer 9 → 10 migration notes

The breaking changes in nodemailer's 10.0.0 changelog are that it now requires Node.js 20 or newer, and that it was rewritten in TypeScript with ES module and CommonJS builds and bundled declarations. What that means here:

  • Node floor: no change for us. @objectstack/core, which plugin-email depends on, already declares node >= 22.0.0.
  • Module shape: no code change. SmtpTransport (packages/plugins/plugin-email/src/transports/smtp.ts) loads nodemailer lazily with await import('nodemailer') and reads createTransport from the namespace or its default, through a structural NodemailerLike interface. I measured 10.0.2, 10.0.10, 10.0.11 and 10.0.12, and both the ESM and CJS entries expose createTransport in both places. The built dist/index.js (CJS) and dist/index.mjs (ESM) both load 10.0.12 and get a createTransport function.
  • Types: the @types/nodemailer devDependency is removed. tsc --traceResolution in plugin-email resolves nodemailer to nodemailer/dist/esm/nodemailer.d.ts@10.0.12, the package's own declarations, so the DefinitelyTyped package was already shadowed and served no purpose. typecheck, including check:test-typecheck, is green without it.
  • Operator-visible corner: from nodemailer 10.0.12, requireTLS wins over ignoreTLS / opportunisticTLS. On a non-465 port with TLS on, SmtpTransport sets requireTLS. If an operator also passed transportOptions: { ignoreTLS: true } through the escape hatch, nodemailer 9 ran that session in cleartext. It now does the STARTTLS upgrade the secure: true option already documents, or fails the send. The changeset records this, and secure: false remains the explicit way to connect in the clear. No option key, payload key or accept/reject verdict of ours changes.
  • Files that use nodemailer, all read and none needing an edit: src/transports/smtp.ts; smtp.test.ts and email-plugin.mail-settings.test.ts, which mock nodemailer; smtp.wire.test.ts and sys-email-payload.wire.test.ts, which run the real nodemailer against an in-process fake SMTP server through fake-smtp.testkit.ts; and smtp-port-contract.ts. No other package in the repository imports nodemailer. The mentions in docs and ADRs are prose.

Lockfile

I regenerated the lockfile with a plain pnpm install from origin/main's lockfile and did not edit it by hand. The only inputs were the declared range and the three override lines. It moves exactly the flagged families plus the dropped @types/nodemailer, and the scanned package count goes from 1371 to 1369: the two ip-address copies collapse into one, and @types/nodemailer@8.0.1 leaves. Nothing unrelated moves.

What I ran

All of these ran in a dedicated worktree on this branch.

Check Result
osv-scanner scan --offline-vulnerabilities --lockfile=pnpm-lock.yaml (v2.3.8, SHA-256 verified against the release's checksum file) on origin/main exit 1, the seven findings above
The same scan on this branch exit 0, No issues found
pnpm install --frozen-lockfile --prefer-offline pass
node scripts/check-changeset-fixed.mjs pass (69 public packages)
pnpm check:override-consistency (self-test + check) pass. Neither new entry shows up in the idle or self-expiring reports
pnpm check:vendor-export-contract-resolve pass
node scripts/check-osv-exemptions.mjs --self-test and node scripts/check-osv-exemptions.mjs pass, zero exemptions
@objectstack/plugin-email build pass
@objectstack/plugin-email typecheck (tsc --noEmit + check:test-typecheck) pass
@objectstack/plugin-email test 31 files / 510 tests pass, the same count as the pre-change baseline on 9.1.1
plugin-email's real-nodemailer wire tests (smtp.wire.test.ts, sys-email-payload.wire.test.ts) against the declared floor, 10.0.2, via a throwaway alias config 7/7 pass. The negative control, with the alias pointing at a missing copy, fails all 7 at smtp.ts's import
turbo run test for the packages whose resolved transitive deps moved: client-react (jsdom → undici 8), mcp and connector-mcp (MCP SDK → ip-address), driver-mongodb and plugin-auth (mongodb → socks → ip-address), plus plugin-email. The run built their whole closure first 41/41 tasks pass. client-react 34, mcp 344, connector-mcp 23, plugin-auth 2464, plugin-email 510, driver-mongodb 656 passed + 167 skipped. The skipped tests are the opt-in live-mongod suites (OS_TEST_MONGODB_MEMORY_SERVER_ENABLED), which the ordinary lanes skip too
@objectstack/spec src/contracts/llm-adapter.test.ts + ai-service.test.ts, the only consumers of ai (→ @ai-sdk/provider-utils → undici 7), which import it as types only 29/29 pass
check-empty-changeset.mjs, check-adr-0087-registration.mjs, check-changeset-no-major.mjs (self-test + this body as the event payload) against the merge base pass. The level axis reads Clause-②: no with no direction arm
eslint (the pnpm lint command) on packages/plugins/plugin-email pass. eslint does not lint the other changed files (package.json, pnpm-workspace.yaml, the changeset), because no config covers them
Repo gates check:undeclared-dep-imports, published-files, lean-entry-closure, doc-authoring, issue-citations, workspace-manifest-cycles, vendor-version-stamps, merge-driver, nul-bytes, prerelease-pins, lockstep-package-count, pnpm-filter-targets, manifest-repository-directory, pm-changeset-deadline-census, type-check-coverage, node-version, pm-governed-prose all pass
Full pnpm build 72/72 tasks pass
After the full build: check:dual-build-cjs-loads, check:dts-closure, check:type-check-debt all pass. Before the build they exited 3 (PREREQUISITE NOT MET) because dist/ was missing

Changeset

.changeset/osv-advisory-bumps-2026-09-29.md bumps @objectstack/plugin-email as a patch with Clause-②: no. The only published change is a dependency-range floor, and no exported surface or accept set moves. The overrides do not ship, so the changeset names them only so that all seven findings can be read in one place.


Generated by Claude Code

… Package Dependencies red

OSV-Scanner v2.3.8 against origin/main's pnpm-lock.yaml (b057434) reports
seven Medium findings across three packages. It is the same set run
36510180397 reported on the Version Packages PR. Every finding names a
published fix version, so this takes the fix, the path osv-scanner.toml's
header prescribes. That ledger keeps its zero entries, and
validate-deps.yml is not changed.

  GHSA-2vr4-cq9g-pvrc  6.9  ip-address  10.4.0 + 10.5.0  -> 10.7.2
  GHSA-rpw4-54j3-4h4q  6.3  ip-address  10.4.0 + 10.5.0  -> 10.7.2
  GHSA-6vj9-mwq6-2f5v  5.9  nodemailer  9.1.1            -> 10.0.12
  GHSA-3wwx-pv8p-q78v  5.9  undici      7.29.0           -> 7.30.0
  GHSA-3wwx-pv8p-q78v  5.9  undici      8.9.0            -> 8.11.2

nodemailer is the one direct dependency. plugin-email's declared range
moves from ^9.1.1 to ^10.0.2, a major, because the advisory covers every
release up to 10.0.1 and 9.x has no patched release. The transport reads
nodemailer structurally and loads it lazily. Measured on 10.0.2 through
10.0.12, both the ESM and the CJS entry expose createTransport on the
namespace and on default, so no source changes. nodemailer 10 ships its
own declarations and tsc resolves nodemailer to dist/esm/nodemailer.d.ts,
which leaves @types/nodemailer dead. This commit drops it.

ip-address and undici are transitive-only, so each is a workspace override
in the shape the overrides header prescribes: the selector is bounded at
the major and the target is floored at the fix. Every dependent's declared
range already admits the fixed version, so each is a dedupe onto the
patched line and not a forced upgrade.
- ip-address: new `<11.0.0 -> ^10.5.1`. Its two copies collapse into one.
- undici 7.x: the existing selector already covers 7.29.0, so only the
  target lifts, from ^7.29.0 to ^7.29.1.
- undici 8.x: jsdom's copy sat outside every selector, so it gets a new
  `>=8.1.0 <9.0.0 -> ^8.10.2` entry, floored at the advisory's affected
  lower bound.

The lockfile was regenerated with a plain `pnpm install` from origin/main's
lockfile, so the only inputs are the declared range and the three override
lines. It moves exactly the flagged families plus the dropped
@types/nodemailer (registry tuples 1371 -> 1369). OSV-Scanner on the
result reports "No issues found".

Claude-Session: https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL
Co-authored-by: Claude <noreply@anthropic.com>
…undici range claims as measured

The ip-address note said check-override-consistency lists the entry as one
it cannot cross-check. The check prints no such list. It holds declared
ranges against override targets and says nothing about an override that
nothing publishable declares, so the note now says that. The undici
affected lines are spelled as the advisory's half-open ranges.

Claude-Session: https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL
Co-authored-by: Claude <noreply@anthropic.com>
The seven advisories this branch clears are filed on #20561. The override
note now names that card beside the scan run, the same way its neighbouring
notes name theirs. It is a comment-only change: the lockfile still matches
(`pnpm install --frozen-lockfile` passes).

Claude-Session: https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation tooling labels Sep 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 1 changed file(s) yielded no anchor (packages/plugins/plugin-email/package.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/plugins/plugin-email/package.json) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 5 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 487a7846df13847124434f641756092991bd48a4 → packageMentionDocs.

@hotlong
hotlong marked this pull request as ready for review September 29, 2026 03:36
@hotlong
hotlong enabled auto-merge September 29, 2026 03:36
@hotlong
hotlong added this pull request to the merge queue Sep 29, 2026
Merged via the queue into main with commit f572a7e Sep 29, 2026
38 of 39 checks passed
@hotlong
hotlong deleted the claude/objectstack-release-steps-ynhz3j-osv branch September 29, 2026 04:10
veigajoao pushed a commit to veigajoao/objectstack that referenced this pull request Sep 29, 2026
…ai#20623)

## What this is

The release-time half of the 17.5.0 release notes. The page
`content/docs/releases/v17/17-5.mdx` landed before the cut (objectstack-ai#20396) with
a `RELEASE-TIME TODO` comment listing four edits to make once 17.5.0 was
on npm. 17.5.0 was published on 2026-09-29 (`@objectstack/cli@17.5.0` at
07:58Z, the last package, `@objectstack/spec`, at 08:09Z). This PR makes
those edits, deletes both TODO comments, and updates
`content/docs/releases/v17/index.mdx`.

Docs-only: two files under `content/docs/releases/`, which is
release-owned, so this is the dedicated docs-only PR `AGENTS.md`
sanctions for that tree. It publishes nothing from any package, hence
`skip-changeset`.

## What changed

**`17-5.mdx`**

- **Publish date.** "What's new" now opens: 17.5.0 was published to the
`latest` tag on 2026-09-29, 20 days after 17.4.0.
- **Count.** The draft said it was compiled from "868 changesets pending
on `main` at `ab6fb027`". The version commit `8c87d26a` (objectstack-ai#17076)
actually consumed **958** changesets (the `.changeset/*.md` files it
deletes, README excluded). The page now states 958 as its measure and
cross-checks it against the CHANGELOGs: the 69 package `CHANGELOG.md`
files that carry a 17.5.0 section at `8c87d26a` list **1,372 per-package
entries** (703 minor, 669 patch, 0 major) in 56 of those files, and
those entries de-duplicate to exactly the same 958.
- **The 90 changesets the draft never read**, the ones consumed by
`8c87d26a` but not pending at `ab6fb027`, were each read in full and
folded in:
- **Breaking changes & migration: 45.** Two new subsections: *Written
values are held to the field's declared type* (date and datetime ISO
spellings on a real day, the year range 0001–9999, the numeric string
grammar, `precision`, `progress` bounds, `/import` thousands commas,
with a Migration table) and *An edge-branched decision takes its first
matching branch* (objectstack-ai#20344, with the stored-row caveat). The rest joined
existing subsections: RLS cross-class comparisons; org-less grants; cube
`public`; number comparands, `having` placeholders and double
accumulation; flow node config, `connector_action`, `api` flow secrets
and the connector resilience keys; list-view `tabs`, action `aria` and
view round-trip keys; `/diff` `/history` `/audit` as authoring doors and
OpenAPI `info`; remote Turso and unbuildable indexes; the one stack
authoring shape and new lint positions; QA `requires`, narrowed
published types and `retiredAfter`.
- **New capabilities: 11.** Studio form rows for 27 structured keys, the
staged `$empty` operator, the new `ComponentPropsMap` rows, and email
verification under `open`.
- **Notable fixes: 15.** Dispatcher-only hosts, `/diff` default range,
plain-text email faces, auth-settings sibling isolation, SQLite
`reclaimSpace()`, zh-CN/ja-JP/es-ES object labels, aggregate `search`,
and the OSV sweep.
- **New in Console: 2.** The fourth objectui pin move and the `trash-2`
→ `trash` icon.
- **Judged too minor to surface: 17.** Each is text only, with no
behaviour change an app or operator can reach: describe, docblock and
comment rewrites, `os migrate meta` guidance text, liveness-ledger data
and layout, a form row's declared language, a test-only import change in
`plugin-dev`, and the successor `Link` header of the deprecated
`?layers=true` flag on the environment-scoped mount.
- **Highlights** gain three bullets drawn from the above (decision
first-match, written values, the stack authoring shape). The "running
deployment" warning list gains five lines.
- Every breaking entry that needs an operator action has an
upgrade-checklist line, marked *Not exercised* unless the HotCRM upgrade
below exercised it.
- **Console.** Four pin moves now, not three: `f8a9d0fb0596 →
dd3f7e1be356` (`3cf6449`, objectstack-ai#20436) carries 325 releasing objectui
changesets, 41 of them declared breaking upstream. The Highlights,
"What's new" and Console sections all say four.
- **Dependencies.** `nodemailer` is `^10.0.2`, not `^9.1.1`. That is a
major bump for GHSA-6vj9-mwq6-2f5v, which has no 9.x fix. The line also
carries the operator-visible note from objectstack-ai#20564's changeset: from
nodemailer 10.0.12, `requireTLS` wins over `ignoreTLS`, so a
`transportOptions: { ignoreTLS: true }` override on a port other than
465 now upgrades to STARTTLS or fails the send, and `secure: false` is
the way to connect in the clear.
- **New subsection "Also shipped in 17.5.0 — not in its CHANGELOG".**
The publish ran from `main` at `0f6dcac5` (Release run 36536081716), 8
first-parent commits after the version commit, so the npm packages also
contain `6e3aa75e a093ce3 92fe081 3a89d45 7001918 c96beb2 ba4648d
0f6dcac`. Their changesets are still unconsumed in `.changeset/`. The
subsection gives one line per commit and says they will be listed again
in 17.6.0's CHANGELOG and that the cause is tracked in objectstack-ai#20613. The
breaking `92fe0814` (objectstack-ai#20458, cube member inner `name` retired) gets a
Migration note taken from its own changeset and a checklist entry, and
the checklist preface says where that note lives.

**`v17/index.mdx`** (following the 17.4.0 curation precedent `b11bfb9a`)

- frontmatter description: "17.0.0 through 17.5.0";
- status blockquote: 17.5.0 is released and current, published
2026-09-29, taking over from 17.4.0; a plain install resolves 17.5.0;
the minors warning names 17.5.0;
- a "17.5.0 stays in that register" paragraph drawn from the page's
Highlights, linking `#breaking-changes--migration-in-1750` and
`#upgrade-checklist`;
- the per-release list marks 17.5.0 current and 17.4.0 no longer
current;
- the checklist callout records that 17.4.0 → 17.5.0 has been exercised
only in part (seven lines, on HotCRM), and the per-release checklist
links lead with 17.5.0.

## Findings from a HotCRM 17.4.0 → 17.5.0 upgrade

These were folded in at the coordinator's request; the parent session
verified them.

- **Decision-mode flip** (objectstack-ai#20344): now a 17.4.0 → 17.5.0 table, a
standing warning that flows stored in `sys_metadata` take the new
meaning without being rewritten, and a checklist line. The line says to
review each `mode: 'inclusive'` that `os migrate meta --from 17` offers,
deleting it where the conditions partition, because applied blindly it
draws `flow-decision-inclusive-overlap`. It then says to review the
`--stored` list.
- **`specVersion` / `engines.protocol`**: the checklist now says what an
app does after a 17.x minor, from the code. `PROTOCOL_VERSION` is still
`17.0.0`, and the handshake compares only the major, so
`engines.protocol: '^17'` stays, a `^17.0.0` `specVersion` admits
17.5.0, and a `^18` range is refused `OS_PROTOCOL_INCOMPATIBLE`.
"Protocol 18" is the migration registry's next major; the 17.5.0 schemas
already refuse its shapes, which is why `os migrate meta --from 17` runs
to 18. The Breaking-changes intro carries the same sentence.
- **Seven checklist lines** are marked *Exercised on HotCRM (a 17.4.0
app with a 17.4.0-created SQLite DB), 2026-09-29* with the observed
result: `os doctor` scheduled-work reading, the `account-issuer`
pre-flight, `os migrate meta --from 17` (41 refusals in 874 lines, 240
of them generic protocol-18 notices, so filter the output), the decision
review with `--stored` (0 rows), `page.assignedProfiles`, lookup screen
field `reference`, and `chartConfig` (34 sites). Every other line stays
*Not exercised*, and the preface and the v17 index callout say the hop
was exercised only in part.

## Citations

Every added `#N` was resolved on the board: 144 candidate numbers from
the 90 commits and the 8 post-version commits, all resolving, and objectstack-ai#20613
is open. SHAs are 7-character short SHAs, and each was verified to
resolve unambiguously.

## Gates run (workspace installed)

The full sweep ran on `2b3b323b`. The head `664854a4` changes one phrase
in one checklist line, and on it the MDX parse, `check:doc-anchors`,
`check:role-word`, `check:issue-citations --base origin/main`, the
audit-scope gate and the release-page gates were re-run, all green.

Named in the task, all exit 0:

- `pnpm check:doc-anchors`: 391 internal fragment links, all resolve.
- `node scripts/check-issue-citations.mjs --base origin/main`: 119
citations judged (104 resolve as pull requests, 1 as an issue, 14
cross-repo `objectui#N` unjudged); every added citation resolves.
- `pnpm check:role-word`: no new occurrences.
- `node scripts/docs-audit/check-audit-scope.mjs`: in sync, and
release-owned pages are review-only.
- `check-release-page-status`, `check-release-section-coverage` (plain
and `--strict`) and `check-release-notes`: all OK.
- MDX parse: both pages compile with `@mdx-js/mdx` 3 + `remark-gfm`, and
all 7 tables on `17-5.mdx` parse with no ragged rows.

Derived with `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands`: 47 commands, **all 47 exit 0**.
The first sweep hit 5 prerequisite refusals (exit 3, or `check:docs` on
the missing gitignored `json-schema` tree) from unbuilt
`@objectstack/spec`, `@objectstack/formula`, `@objectstack/lint` and
`@objectstack/client-react`. None was a finding. Those packages were
built and the whole list was re-run. Among the 47:
`check:doc-authoring`, `check:docs-single-h1`, `check:docs-redirects`,
`check:corpus-claim-drift`, `check:docs-transcript-drift`,
`@objectstack/spec check:docs` / `check:skill-examples` /
`check:liveness`, `@objectstack/lint check:doc-formula-expressions` /
`check:doc-security-posture`, `check-doc-frontmatter`,
`check-docs-section-name`, `check-section-landing-index` and
`check:nul-bytes`.

The diff was also re-read by hand; the fixes from that pass are the
second commit (`da443bdb`).

## Not in this PR

`content/docs/upgrading.mdx`'s per-release table still reads "v17.4.0 —
⛔ checklist not written; machine-draft notes only" and has no 17.5.0
row. It is a hand-written tree outside `content/docs/releases/`, so it
is left for a separate change.


---
_Generated by [Claude
Code](https://claude.ai/code/session_014VGCS11YUtYAiinRcdqQwL)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Oct 7, 2026
…r OSV advisories (objectstack-ai#20774)

Fixes objectstack-ai#20769

Clause-②: no

## Summary

`Validate Package Dependencies` (OSV-Scanner against `pnpm-lock.yaml`)
flags two transitive copies that `origin/main` locks:

| Advisory | CVSS | Package | Locked on main | Fixed in |
|---|---|---|---|---|
| GHSA-6j4f-fj2g-mc7p | 7.5 | brace-expansion | 5.0.9 | 5.0.10 |
| GHSA-qhr7-859c-m2p7 | 7.5 | brace-expansion | 5.0.9 | 5.0.11 |
| GHSA-q2hr-2g5m-vwhr | 5.3 | brace-expansion | 5.0.9 | 5.0.12 |
| GHSA-hrr3-gc8f-f4qj | 4.8 | fast-uri | 3.1.7 | 3.1.8 |

Both fix versions are published (`npm view brace-expansion@5.0.12
version` returns 5.0.12, `npm view fast-uri@3.1.8 version` returns
3.1.8). This is the take-the-fix path: `osv-scanner.toml` is untouched
and still holds zero exemptions.

## Change

Two override targets are raised in `pnpm-workspace.yaml`, selectors
unchanged (both already sit on their major boundary):

- `'brace-expansion@>=5.0.0 <6.0.0'`: `^5.0.9` to `^5.0.12`
- `'fast-uri@<4.0.0'`: `^3.1.6` to `^3.1.8`

Each advisory-history comment is extended in the file's existing style
and names the new GHSA ids and objectstack-ai#20769. The floor keeps this workspace's
own resolution from ever re-locking a vulnerable copy. Workspace
overrides do not reach downstream installs, so this PR does not claim to
fix a consumer's own copy.

## Lockfile

Regenerated with `pnpm install --lockfile-only` (pnpm 10.31.0, the
`packageManager` version), never hand-edited. The diff is 11 lines
changed on each side (22 total) and names only these entries: the two
override specifiers, `brace-expansion` 5.0.9 to 5.0.12 (package and
snapshot entries, plus the two `brace-expansion:` dependents' edges),
and `fast-uri` 3.1.7 to 3.1.8 (package and snapshot entries, plus the
one `fast-uri:` dependent's edge). Nothing unrelated moves, and the
scanned package count stays 1369. `pnpm install --frozen-lockfile`
passes on the result.

Other copies: none. Each package appears exactly once in the lockfile,
at the vulnerable version on main and at the fixed version on this
branch.

## Changeset decision

No changeset. A workspace-override raise plus a lockfile move publishes
nothing: no package's `files[]` content or declared range changes. The
precedent is the devalue override PR (objectstack-ai#18942, commit `5e0a1b9e02`),
which touched exactly `pnpm-workspace.yaml` and `pnpm-lock.yaml` and
added no changeset. The two other OSV precedents (objectstack-ai#20719, objectstack-ai#20564) each
changed a published package's declared range, so they carried changesets
and are not the shape here. No empty changeset is added. `Check
Changeset` may stay red on this PR until a maintainer applies
`skip-changeset`; the author seat does not apply labels.

## What I ran

| Check | Result |
|---|---|
| OSV-Scanner v2.3.8 (SHA-256 verified against the release checksum
file), `--offline-vulnerabilities`, on `origin/main`'s lockfile | exit
1, exactly the four GHSAs above |
| The same scan on this branch's lockfile | exit 0, `No issues found`
(1369 packages) |
| `pnpm install --frozen-lockfile` | pass |
| `node scripts/pm/dispatch-gates.mjs --commands`, every derived command
run, then `--ran` | 21 derived, 21 run, 0 NOT-MEASURED, 0 UNRUN |
| Full `pnpm build` (under the shared verify lock, `--concurrency=2`) |
72/72 tasks pass |
| After the build: `check:dts-closure`, `check:dual-build-cjs-loads`,
`check:lean-entry-closure`, `check:sourcemap-no-sources-content` | all
exit 0 |
| `check:override-consistency`, `check:vendor-export-contract-resolve`,
`check:workspace-manifest-cycles`, `check:nul-bytes`,
`check-osv-exemptions` and the rest of the derived list | all exit 0 |

Not run: the per-package test suites of `minimatch` and `ajv` consumers.
The gate derivation selects none for a two-path lockfile and
workspace-yaml diff, and both bumps are patch-line moves inside the
ranges the dependents already declare. CI's shards cover them.

## Acceptance notes

None.

---
🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/s tooling

Projects

None yet

2 participants