Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ updates:
# are `versions`, never `update-types`, which security updates do not read. A new
# floor fixture needs an entry here: __tests__/ci/ts-sdk-fixture-pins.test.ts
# fails without one.
#
# A range is only read for the package being updated, not for a parent moved on
# its behalf. #955 removed @ai-sdk/provider-utils 2.x from mastra-0 by running
# `npm install @mastra/core@1.80.0` with `@mastra/*` ignored below; the ignore only
# took those names out of the PR's description. So a transitive package with an
# accepted advisory needs a range of its own, which ends the update before it
# reaches the parent.
- package-ecosystem: npm
directory: /sdk/typescript/integration/fixtures/ai-4
schedule:
Expand All @@ -97,6 +104,9 @@ updates:
# ai@4.3.19 peers on zod ^3.23.8.
- dependency-name: zod
versions: [">=4.0.0"]
# ai@4.3.19 uses the 2.x API; the fix is in 3.x.
- dependency-name: "@ai-sdk/provider-utils"
versions: [">=3.0.0"]

- package-ecosystem: npm
directory: /sdk/typescript/integration/fixtures/langchain-0.3
Expand Down Expand Up @@ -138,6 +148,10 @@ updates:
# @mastra/core, and the @mastra/memory and @mastra/mcp releases paired with it.
- dependency-name: "@mastra/*"
versions: [">=1.0.0"]
# @mastra/core@0.24.9 requires ai@^4. This fixture's own zod is already 4.
# @mastra/core@0.24.9 requires ai@^4. This fixture's zod is already 4.
- dependency-name: ai
versions: [">=5.0.0"]
# The copies under ai@4.3.19 use the 2.x API; the fix is in 3.x. This is the
# package #955 moved @mastra/core to get rid of.
- dependency-name: "@ai-sdk/provider-utils"
versions: [">=3.0.0"]
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 1.0.14-beta.0 — 2026-11-02

### Dependencies

- Replace Dependabot's #965 and #955, neither of which could install, and clear every fixable Dependabot alert in the TypeScript SDK's integration fixtures. `mastra-1` takes `@mastra/mcp` 2.7.0 with the `@mastra/core` 1.81.0 and `@mastra/memory` 1.40.0 it needs, `mastra-0` stays on Mastra 0.x and clears `@hono/node-server`, `systeminformation`, `glob` and `minimatch`, `deepmerge` leaves three fixtures through `html-to-text` 10.0.1, and the nested zod 3 leaves two. None of these lockfiles ship in a published package (#966)
- Stop Dependabot moving `@mastra/core` off the `mastra-0` floor to remove `@ai-sdk/provider-utils`. `.github/dependabot.yml` gives that package its own `ignore` range on `ai-4` and `mastra-0`, because a range is read only for the package being updated, not for a parent moved on its behalf (#966)
Comment thread
NiveditJain marked this conversation as resolved.
Resolved

## 1.0.13 — 2026-11-02

The stable release of OpenClaw enforcement on OpenClaw 2026.9.6 and later, of daemon setup on Fedora, RHEL, Rocky and Alma, and of path policies on Antigravity's current file tools. Everything below in the `1.0.13-beta.*` sections ships here too.
Expand Down
23 changes: 19 additions & 4 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ That splits an alert in one of these lockfiles into two cases:
what makes the lockfiles reproducible and an override the only lever. **Never**
resolve one of these by moving the pinned framework — that deletes the fixture's
reason to exist and silently drops a supported release from the matrix.

When no release fixes the package, or the fix is a major its parent cannot take,
look one level up before accepting it. An override can move the *parent* to a
release that no longer needs the package, which takes it out of the tree:
`html-to-text@10` replaced `deepmerge`, which has no patched release, and `gaxios`
after 7.1.3 dropped `rimraf`, and with it the `glob` and `minimatch` that only a
major of each would have fixed. A nested copy whose consumers do not need that
major can go the same way: `mastra-0` and `langchain-dup-core` override their
nested zod 3 to their own zod 4, because `@mastra/mcp` and `@mastra/schema-compat`
call `zod-from-json-schema-v3` only under a zod 3 root, and
`@langchain/core@0.3.80` imports only `zod/v3` and `zod/v4/core`, which zod 4 also
ships.
2. **The advisory is against the pinned framework itself, or against a package whose
only fix is a major that framework cannot take.** There is no fix that keeps the
fixture, so record it in the table below rather than pretending it away. Unlike a
Expand All @@ -126,7 +138,10 @@ reach the fix by moving the framework, which is how #838, #931 and #935 happened
entry in [`.github/dependabot.yml`](.github/dependabot.yml)
(`open-pull-requests-limit: 0`) whose `ignore` ranges hold its framework on its
line, and zod on 3 where that framework requires it; a fix that stays on the line
still arrives. A new floor fixture needs its own entry, and
still arrives. A range is read only for the package being updated, not for a parent
moved on its behalf, so a transitive package with an accepted advisory needs a range
of its own: #955 moved `@mastra/core` to 1.80.0 to remove `@ai-sdk/provider-utils`
2.x, with `@mastra/*` ignored. A new floor fixture needs its own entry, and
`__tests__/ci/ts-sdk-fixture-pins.test.ts` fails without one. A Dependabot PR that
moves a pin anyway fails that same test: close it rather than merge it.

Expand All @@ -136,15 +151,15 @@ moves a pin anyway fails that same test: close it rather than merge it.
|---|---|---|---|
| [GHSA-rwvc-j5jr-mgvh](https://github.com/advisories/GHSA-rwvc-j5jr-mgvh) (low, CVSS 3.7) | `ai@4.3.19` | `ai-4`, `mastra-0` | A filetype-whitelist bypass on **file upload**. Fixed in `ai@5.0.52` — the major the `ai-4` fixture exists to stay below, and one `@mastra/core@0.24.9` cannot take either (it requires `ai@^4`). Neither fixture uploads a file or exposes an upload surface; each runs one scripted agent against an in-process model. |
| [GHSA-866g-f22w-33x8](https://github.com/advisories/GHSA-866g-f22w-33x8) (low, CVSS 4.3) | `@ai-sdk/provider-utils@2.2.8` | `ai-4`, `mastra-0` | Unbounded response-body reads in `createJsonResponseHandler` and its siblings. Fixed in `3.0.28`; `2.2.8` ships *inside* `ai@4.3.19`, which uses the v2 API, so the fix is the same blocked major as the row above. Exploiting it needs a hostile **model-provider HTTP response**; these fixtures never call one. |
| [GHSA-mrhx-c7xc-m3w5](https://github.com/advisories/GHSA-mrhx-c7xc-m3w5) (high, CVSS 7.5) | `zod@3.25.76` | `ai-4`, `langchain-0.3`, `llamaindex-0.11`; nested in `langchain-dup-core` and `mastra-0` | An array schema keeps every failing element's validation issues, uncapped, so one oversized input can exhaust memory. Fixed only in `4.6.6`: no zod 3 release carries the fix, and `3.25.76` is the newest. Each copy is held to `^3` by the release its fixture pins — `ai@4.3.19` and its `@ai-sdk/*` packages peer on `^3.23.8`, `@langchain/core@0.3.80` (in `langchain-dup-core`, the vendored provider's own copy) and `@langchain/langgraph@0.4.10` depend on `^3.25.32`, `@llamaindex/core@0.6.8` and `@llamaindex/workflow@1.1.5` need `^3.23.8`, and in `mastra-0`, `zod-from-json-schema-v3` (`zod-from-json-schema@0.0.5`, which builds zod 3 schemas for `@mastra/core` and `@mastra/mcp`) depends on `^3.24.2`. Exploiting it needs untrusted input validated against one of those schemas; each fixture validates only its own scripted tool arguments. |
| [GHSA-mrhx-c7xc-m3w5](https://github.com/advisories/GHSA-mrhx-c7xc-m3w5) (high, CVSS 7.5) | `zod@3.25.76` | `ai-4`, `langchain-0.3`, `llamaindex-0.11` | An array schema keeps every failing element's validation issues, uncapped, so one oversized input can exhaust memory. Fixed only in `4.6.6`: no zod 3 release carries the fix, and `3.25.76` is the newest. Each fixture's own zod is held to `^3` by the release it pins — `ai@4.3.19` and its `@ai-sdk/*` packages peer on `^3.23.8`, `@langchain/core@0.3.80` and `@langchain/langgraph@0.4.10` depend on `^3.25.32`, and `@llamaindex/core@0.6.8` and `@llamaindex/workflow@1.1.5` need `^3.23.8`. Exploiting it needs untrusted input validated against one of those schemas; each fixture validates only its own scripted tool arguments. |

Every row is bounded by the same facts: these are test fixtures — `"private": true`,
never published, installed with `--ignore-scripts`, and run only in CI against
scripted in-process models. Re-check them whenever the supported framework floor
moves. The first two rows retire once `ai` 4.x has left the matrix, which takes
`mastra-0` as well as `ai-4`, because `@mastra/core@0.24.9` requires `ai@^4`. The
zod row retires only once `ai` 4.x, LangChain 0.3, LlamaIndex 0.11 and Mastra 0.x
have all left it.
zod row retires only once `ai` 4.x, LangChain 0.3 and LlamaIndex 0.11 have all left
it.

## Maintainer setup (one-time)

Expand Down
63 changes: 63 additions & 0 deletions __tests__/ci/ts-sdk-fixture-pins.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ const readJson = (fixture: string, file: string) =>
packages?: Record<string, { version?: string }>;
};

/** Every version of `name` a fixture's lockfile installs, nested copies included. */
const lockedVersions = (fixture: string, name: string) =>
Object.entries(readJson(fixture, "package-lock.json").packages ?? {})
.filter(([path]) => path.endsWith(`node_modules/${name}`))
.map(([, entry]) => entry.version!);

/** Every `npm:<name>@<version>` a fixture's top-level programs import, once each. */
const NPM_SPECIFIER = /["']npm:((?:@[\w.-]+\/)?[\w.-]+)@([^"'/]+)/g;
const specifiers = fixtures.flatMap((fixture) =>
Expand Down Expand Up @@ -157,11 +163,68 @@ describe("Dependabot security updates on the supported floors", () => {
expect(holdsOnLine(entry, "zod", pinned, "3"), `${fixture}: ignore for zod`).toBe(true);
});

// #955 moved `@mastra/core` to 1.80.0 to remove `@ai-sdk/provider-utils` 2.x with
// `@mastra/*` ignored: a range is only read for the package being updated, so the
// framework's own range never came into it. The package needs a range of its own.
const providerUtils2 = floors
.map((f) => ({ ...f, pinned: lockedVersions(f.fixture, "@ai-sdk/provider-utils").find((v) => v.startsWith("2.")) }))
.filter((f) => f.pinned !== undefined);

it("finds the floors that install @ai-sdk/provider-utils 2", () => {
expect(providerUtils2.map((f) => f.fixture).sort()).toEqual(["ai-4", "mastra-0"]);
});

it.each(providerUtils2)(
"$fixture holds @ai-sdk/provider-utils on 2, so updating it cannot move $framework",
({ fixture, pinned }) => {
const entry = fixtureEntries.find((e) => e.fixture === fixture)!.update;
expect(holdsOnLine(entry, "@ai-sdk/provider-utils", pinned!, "2"), `${fixture}: ignore for @ai-sdk/provider-utils`).toBe(
true,
);
},
);

it("names only fixtures that exist", () => {
expect(fixtureEntries.map((e) => e.fixture).filter((f) => !fixtures.includes(f))).toEqual([]);
});
});

/**
* SECURITY.md accepts zod 3 in the floors that require it, and says which. Two more
* fixtures used to carry a nested copy whose consumers did not need that major; each
* now overrides it to its own zod 4. A copy arriving anywhere else is a new finding
* to fix or to write down, not one to inherit from the accepted row.
*/
describe("TS SDK integration fixtures that install zod 3", () => {
it("are the three SECURITY.md accepts", () => {
const withZod3 = fixtures.filter((fixture) => lockedVersions(fixture, "zod").some((v) => v.startsWith("3.")));
expect(withZod3.sort()).toEqual(["ai-4", "langchain-0.3", "llamaindex-0.11"]);
});
});

/**
* The `nextjs` fixture compares each route's trace with the same program's trace
* under plain Node, in the fixture its description names. Dependabot resolves one
* directory at a time, so nothing else keeps the two on one release: moving a twin
* alone would compare two different versions and still read as a parity result.
*/
describe("the nextjs fixture's framework pins", () => {
const nextjs = readJson("nextjs", "package.json").dependencies!;

it.each([
["@langchain/core", "langchain-1"],
["@langchain/langgraph", "langchain-1"],
["ai", "ai-7"],
["@mastra/core", "mastra-1"],
["llamaindex", "llamaindex-0.12"],
["@llamaindex/core", "llamaindex-0.12"],
["@llamaindex/workflow", "llamaindex-0.12"],
])("%s matches its twin in %s", (name, twin) => {
expect(nextjs[name], `nextjs: ${name}`).toBeDefined();
expect(nextjs[name], `nextjs: ${name}`).toBe(readJson(twin, "package.json").dependencies?.[name]);
});
});

describe("TS SDK integration fixtures' npm: specifiers", () => {
it("finds the Deno program's", () => {
expect(specifiers.map((s) => s.name)).toEqual(expect.arrayContaining(["ai", "zod"]));
Expand Down
53 changes: 48 additions & 5 deletions sdk/typescript/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,51 @@ section is missing or empty is refused before anything is built.

### Fixes

- **`mastra-1` tests the current Mastra 1.x, on the fixed MCP packages.**
`@mastra/core` 1.68.0 → 1.81.0, `@mastra/mcp` 2.0.0 → 2.7.0 and `@mastra/memory`
1.31.0 → 1.40.0. That takes `@modelcontextprotocol/node` to 2.1.2
(GHSA-f897-62hf-6gxq) and `@hono/node-server` to 2.1.6 (GHSA-rmxm-3fg6-px4f, and
the fixes 2.1.6 itself ships: GHSA-jpvv-r467-5p4w, GHSA-7v5p-43qr-wch5,
GHSA-qv5m-9pm6-hqp3). Dependabot's #965 moved `@mastra/mcp` alone, which peers on
`@mastra/core >=1.79.0`, so `npm ci` failed `ERESOLVE` and every shard that
installs the fixture failed with it. The `@modelcontextprotocol/client` and
`@modelcontextprotocol/server` overrides from #934 retire, because `@mastra/mcp`
2.7.0 pins fixed releases of both. The `argparse` override from #904 retires too:
`@mastra/core` no longer reaches `gray-matter`, so neither this fixture nor
`nextjs` installs `argparse` 1 or `sprintf-js`. `nextjs` moves `@mastra/core` to
1.81.0 with it, because it compares each route's trace with this fixture's;
`__tests__/ci/ts-sdk-fixture-pins.test.ts` now fails when any `nextjs` framework
pin leaves its twin. (#966)

- **`mastra-0` clears its transitive advisories and stays on Mastra 0.x.**
`@hono/node-server` 2.1.1 → 2.1.6 and `systeminformation` 5.33.13 → 5.33.19 are
in range (GHSA-rmxm-3fg6-px4f, GHSA-3f7j-7jwc-fxfj, GHSA-4vjg-vx72-qq4g). A
fixture-local override moves `gaxios` 7.1.3 → 7.3.1, which `gcp-metadata` pins
exactly and which no longer depends on `rimraf`, so `rimraf`, `glob`
(GHSA-3g3m-2fjr-6pw4), `minimatch` (GHSA-g3hv-75wg-m249) and 21 more packages leave
the tree. `@mastra/core`, `@mastra/mcp`, `@mastra/memory` and `ai` resolve exactly
as before. Dependabot's #955 reached the same alerts by moving `@mastra/core` to
1.80.0, off the floor this fixture holds, and `@mastra/mcp@0.14.5` cannot install
beside it. `.github/dependabot.yml` now gives `@ai-sdk/provider-utils`, the package
#955 was updating, its own range on `ai-4` and `mastra-0`: a range is read only for
the package being updated, so `@mastra/*` being ignored did not hold a parent moved
on its behalf. (#966)

- **`deepmerge` leaves `llamaindex-0.11`, `llamaindex-0.12` and `nextjs`.**
GHSA-gcqx-w48m-w2h4 has no patched release, so the fix is to take it out of the
tree. Each fixture reached it only through `@llamaindex/node-parser` →
`html-to-text@9.0.5`, and a fixture-local override moves `html-to-text` to 10.0.1,
which replaced it with `deepmerge-ts`. `@llamaindex/node-parser` imports only
`htmlToText`, which 10.x still exports, from an HTML parser no fixture runs. (#966)

- **`mastra-0` and `langchain-dup-core` drop their nested zod 3.** Both override zod
to their own zod 4 (GHSA-mrhx-c7xc-m3w5). `@mastra/mcp` and `@mastra/schema-compat`
call `zod-from-json-schema-v3` only when the root zod has no `toJSONSchema`, which
a zod 4 root does, and `@langchain/core@0.3.80` imports only `zod/v3` and
`zod/v4/core`, which zod 4 also ships. `langchain-dup-core` still nests its second
`@langchain/core`, which is what that fixture exists to test. `mastra-0` also moves
its own zod 4.6.6 → 4.6.7, the release every other fixture on zod 4 pins. (#966)

- **`nextjs` and `mastra-1` drop `sprintf-js`.** Every release through `1.1.3`
carries GHSA-hp3w-g68c-fv3c and none fixes it, so the fix is to take it out of
the tree. Both fixtures reached it only through `@mastra/core@1.68.0` →
Expand Down Expand Up @@ -66,12 +111,10 @@ section is missing or empty is refused before anything is built.
`2.2.0` override did. Each lockfile changes by those packages alone, and
`npm audit` reports no findings in `ai-5` or `mastra-1`. (#934)

- **zod GHSA-mrhx-c7xc-m3w5 stays in the five fixtures held to zod 3.** It is fixed
- **zod GHSA-mrhx-c7xc-m3w5 stays in the three fixtures held to zod 3.** It is fixed
only in `zod@4.6.6`, and no zod 3 release carries the fix. `ai-4`, `langchain-0.3`
and `llamaindex-0.11` pin `zod@3.25.76` beside frameworks that require `^3`, and
`langchain-dup-core` and `mastra-0` carry a nested copy that the vendored
provider's `@langchain/core@0.3.80` and `zod-from-json-schema@0.0.5` require.
`SECURITY.md` records it with the two `ai@4` advisories. (#934)
and `llamaindex-0.11` pin `zod@3.25.76` beside frameworks that require `^3`.
`SECURITY.md` records it with the two `ai@4` advisories. (#934, #966)

## 0.0.1-beta.1 — 2026-10-15

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"overrides": {
"langsmith": "0.10.5",
"uuid": "11.1.1"
"uuid": "11.1.1",
"zod": "$zod"
}
}
Loading
Loading