Skip to content

Commit c74ee64

Browse files
NiveditJainclaude
andauthored
[failproofai-legion-934] Clear the fixable Dependabot alerts and restore the fixture pins #931 moved (#934)
* [failproofai-legion-934] Clear the fixable Dependabot alerts and restore the fixture pins #931 moved Dependabot's grouped security update #931 reached the zod fix (GHSA-mrhx-c7xc-m3w5) in three integration fixtures by moving the very release each one exists to hold, the pin move SECURITY.md rules out: ai-4 ai 4.3.19 -> 7.0.152 langchain-0.3 @langchain/core 0.3.80 -> 1.3.0, @langchain/langgraph 0.4.10 -> 1.5.2 llamaindex-0.11 llamaindex 0.11.4 -> 0.12.1 each with zod 3.25.76 -> 4.6.7. ai-4 and langchain-0.3 kept installing and passing against a different major, so two supported floors left the matrix silently. llamaindex-0.11 stopped installing: @llamaindex/workflow@1.1.5 peers on zod@^3.23.8, so `npm ci` fails ERESOLVE (reproduced on node 24 against #931's manifests), and because global setup installs every fixture before any test runs, the frameworks shards (node 20, 24) and the runtimes shard went red on main. vite's module runner then masks the real error as `code.charCodeAt is not a function`. #931 also moved the runtimes fixture to zod 4.6.7 while deno-npm.ts still imported npm:zod@4.6.5, which Deno resolves against the fixture's node_modules and can no longer find; that fails the two "Deno with npm: specifiers" cases on its own. All three fixtures are back on their pre-#931 package.json and lockfile, and deno-npm.ts imports the zod the runtimes fixture installs. __tests__/ci/ts-sdk-fixture-pins.test.ts is the tripwire for both moves: a fixture named for a release line must pin its framework exactly, on that line, in package.json and the lockfile; and every npm: specifier a fixture imports must name the version its lockfile installs. Checked to fail on #931's manifests (ai-4, langchain-0.3, llamaindex-0.11) and on the old specifier. The fixable advisories still open after #931 are cleared with fixture-local overrides (SECURITY.md case 1), re-resolved with `npm install --package-lock-only --ignore-scripts`; each lockfile moves by exactly those packages: ai-5 undici 7.29.1 -> 7.30.1 (3 advisories) llamaindex-0.11 fast-uri 3.1.8 -> 3.1.9 (4 advisories; back with 0.11.4) mastra-1 @modelcontextprotocol/server 2.0.0 -> 2.3.0 and @modelcontextprotocol/client 2.2.0 -> 2.3.0 (4 advisories), both pinned exactly by @mastra/mcp@2.0.0; each brings its own @modelcontextprotocol/core@2.3.0 nested under it, as the client's 2.2.0 override did in #901 `npm audit` now reports nothing in 10 of the 15 fixtures. What remains is zod GHSA-mrhx-c7xc-m3w5 in the five held to zod 3 (ai-4, langchain-0.3, llamaindex-0.11, and nested in langchain-dup-core and mastra-0), plus the two ai@4 advisories SECURITY.md already accepts. zod's only fix is 4.6.6, no zod 3 release carries it, and every copy is required at ^3 by the framework release its fixture pins; `npm audit fix` in mastra-0 changes nothing. SECURITY.md case 2: recorded in its table. Locally, in node:20 and node:24 containers mirroring the CI job: frameworks (node 20 and 24) 1036 passed / 4 skipped each, runtimes 1132 passed, nextjs 60 passed. Root: lint clean, tsc clean, e2e 358 passed / 7 skipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R83BsnFfqDkiHDyhGCnprq * [failproofai-legion-934] Require every framework floor in the pin test, and name mastra-0 in the ai@4 retirement Review on #934 (CodeRabbit): - The pin test's discovery check required ai-4, langchain-0.3 and mastra-0 but not llamaindex-0.11, so deleting that fixture would drop its case with every assertion still passing. It now requires all four supported floors. - SECURITY.md said dropping ai 4.x retires the two ai@4 rows. Both also cover mastra-0, whose @mastra/core@0.24.9 requires ai@^4, so the ai-4 fixture leaving is not enough; the text now says mastra-0 must go too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R83BsnFfqDkiHDyhGCnprq --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent a509c04 commit c74ee64

15 files changed

Lines changed: 648 additions & 345 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 1.0.13-beta.0 — 2026-10-25
4+
5+
### Dependencies
6+
7+
- Restore the `ai-4`, `langchain-0.3` and `llamaindex-0.11` SDK integration fixtures to the releases they exist to test: `ai@4.3.19`, `@langchain/core@0.3.80` with `@langchain/langgraph@0.4.10`, and `llamaindex@0.11.4`, each with `zod@3.25.76`. Dependabot's grouped security update (#931) reached the zod fix by moving them to `ai@7.0.152`, `@langchain/core@1.3.0` and `llamaindex@0.12.1`, the pin move `SECURITY.md` rules out, so the matrix silently stopped testing three supported floors. `llamaindex-0.11` then stopped installing (`@llamaindex/workflow@1.1.5` peers on `zod@^3.23.8`, so `npm ci` failed `ERESOLVE`), and because global setup installs every fixture first, the `frameworks` and `runtimes` integration shards failed on `main`. #931 also moved the `runtimes` fixture to `zod@4.6.7` while its Deno program still imported `npm:zod@4.6.5`, which Deno could no longer find; it now imports the installed version. `__tests__/ci/ts-sdk-fixture-pins.test.ts` fails on either move before anything installs (#934)
8+
- Patch the fixable SDK integration fixture advisories with fixture-local `overrides`, moving no pin: `undici` 7.29.1 → 7.30.1 in `ai-5` (GHSA-xjj6-f33q-929c, GHSA-4qv8-2p9j-2685, GHSA-f72v-6w45-q472); `fast-uri` 3.1.8 → 3.1.9 in `llamaindex-0.11` (GHSA-w74x-v6f9-j3xg, GHSA-wjr9-j795-jxcr, GHSA-xhq7-xmqj-769h, GHSA-333x-w4r6-6crp); and in `mastra-1`, `@modelcontextprotocol/server` 2.0.0 → 2.3.0 and `@modelcontextprotocol/client` 2.2.0 → 2.3.0 (GHSA-jm63-cq47-j5jp, GHSA-46jr-4wx8-v453, GHSA-rvq5-wwqv-78pq, GHSA-6prh-2h8m-c8cw), both pinned exactly by `@mastra/mcp@2.0.0`, each now with its own `@modelcontextprotocol/core@2.3.0` nested under it (#934)
9+
- `SECURITY.md` accepts zod GHSA-mrhx-c7xc-m3w5 in the five fixtures held to zod 3: `ai-4`, `langchain-0.3` and `llamaindex-0.11`, and the nested copies in `langchain-dup-core` and `mastra-0`. It is fixed only in zod 4.6.6, no zod 3 release carries the fix, and every copy is required at `^3` by the framework release its fixture pins (#934)
10+
311
## 1.0.12 — 2026-10-23
412

513
The stable release of logging in to FailproofAI Cloud from `config` in your browser, and of Cloud-managed Jev and hybrid policies scoped to agents. Everything below in the `1.0.12-beta.*` sections ships here too.

‎SECURITY.md‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,15 @@ That splits an alert in one of these lockfiles into two cases:
124124
|---|---|---|---|
125125
| [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. |
126126
| [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. |
127+
| [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. |
127128

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

133137
## Maintainer setup (one-time)
134138

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { readFileSync, readdirSync } from "node:fs";
2+
import { join } from "node:path";
3+
4+
import { describe, expect, it } from "vitest";
5+
6+
/**
7+
* A TypeScript SDK integration fixture named for a release line — `ai-4`,
8+
* `langchain-0.3`, `mastra-0` — exists to hold its framework on that line: the
9+
* pinned release is the subject of the test (SECURITY.md, "Triaging a Dependabot
10+
* alert in an integration fixture"). A move off it still installs and still
11+
* passes, against a different major, so the matrix loses a supported floor with
12+
* every check green. Dependabot security updates have made that move twice
13+
* (#838, #931), both times to reach a fix the fixture could not take. This fails
14+
* on the manifest, before anything installs.
15+
*
16+
* #931 also moved the `runtimes` fixture's zod without the `npm:zod@…` specifier
17+
* its Deno program imports, which Deno resolves against the fixture's
18+
* `node_modules` and so could no longer find. That half is checked here too.
19+
*/
20+
21+
const fixturesDir = join(__dirname, "..", "..", "sdk", "typescript", "integration", "fixtures");
22+
23+
/** The package each fixture-name prefix pins. */
24+
const FRAMEWORK: Record<string, string> = {
25+
ai: "ai",
26+
langchain: "@langchain/core",
27+
llamaindex: "llamaindex",
28+
mastra: "@mastra/core",
29+
};
30+
31+
const fixtures = readdirSync(fixturesDir, { withFileTypes: true })
32+
.filter((entry) => entry.isDirectory())
33+
.map((entry) => entry.name);
34+
35+
const named = fixtures
36+
.map((name) => /^([a-z]+)-(\d+(?:\.\d+)?)$/.exec(name))
37+
.filter((match): match is RegExpExecArray => match !== null)
38+
.map(([fixture, prefix, line]) => ({ fixture: fixture!, framework: FRAMEWORK[prefix!], line: line! }));
39+
40+
const readJson = (fixture: string, file: string) =>
41+
JSON.parse(readFileSync(join(fixturesDir, fixture, file), "utf8")) as {
42+
dependencies?: Record<string, string>;
43+
packages?: Record<string, { version?: string }>;
44+
};
45+
46+
/** Every `npm:<name>@<version>` a fixture's top-level programs import, once each. */
47+
const NPM_SPECIFIER = /["']npm:((?:@[\w.-]+\/)?[\w.-]+)@([^"'/]+)/g;
48+
const specifiers = fixtures.flatMap((fixture) =>
49+
readdirSync(join(fixturesDir, fixture))
50+
.filter((file) => file.endsWith(".ts"))
51+
.flatMap((file) => {
52+
const source = readFileSync(join(fixturesDir, fixture, file), "utf8");
53+
const found = new Set([...source.matchAll(NPM_SPECIFIER)].map(([, name, version]) => `${name}@${version}`));
54+
return [...found].map((spec) => {
55+
const at = spec.lastIndexOf("@");
56+
return { fixture, file, name: spec.slice(0, at), version: spec.slice(at + 1) };
57+
});
58+
}),
59+
);
60+
61+
describe("TS SDK integration fixtures named for a release line", () => {
62+
it("finds them, every framework's supported floor among them", () => {
63+
expect(named.map((f) => f.fixture)).toEqual(
64+
expect.arrayContaining(["ai-4", "langchain-0.3", "llamaindex-0.11", "mastra-0"]),
65+
);
66+
});
67+
68+
it("know which framework each name pins", () => {
69+
expect(named.filter((f) => f.framework === undefined).map((f) => f.fixture)).toEqual([]);
70+
});
71+
72+
it.each(named)("$fixture pins $framework exactly, on $line", ({ fixture, framework, line }) => {
73+
const pinned = readJson(fixture, "package.json").dependencies?.[framework!];
74+
expect(pinned, `${fixture}: ${framework} in package.json`).toMatch(/^\d+\.\d+\.\d+$/);
75+
expect(pinned!.startsWith(`${line}.`), `${fixture} pins ${framework}@${pinned}`).toBe(true);
76+
const locked = readJson(fixture, "package-lock.json").packages?.[`node_modules/${framework}`]?.version;
77+
expect(locked, `${fixture}: ${framework} in package-lock.json`).toBe(pinned);
78+
});
79+
});
80+
81+
describe("TS SDK integration fixtures' npm: specifiers", () => {
82+
it("finds the Deno program's", () => {
83+
expect(specifiers.map((s) => s.name)).toEqual(expect.arrayContaining(["ai", "zod"]));
84+
});
85+
86+
it.each(specifiers)("$fixture/$file imports npm:$name@$version, the version it installs", (spec) => {
87+
const { fixture, name, version } = spec;
88+
const locked = readJson(fixture, "package-lock.json").packages?.[`node_modules/${name}`]?.version;
89+
expect(locked, `${fixture}: ${name} in package-lock.json`).toBe(version);
90+
});
91+
});

‎sdk/typescript/CHANGELOG.md‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,43 @@ section is missing or empty is refused before anything is built.
2121
dependencies. Each lockfile changes by those two packages and nothing else, and
2222
`npm audit` on both now reports no findings. (#904)
2323

24+
- **`ai-4`, `langchain-0.3` and `llamaindex-0.11` test their own releases again.**
25+
Dependabot's grouped security update (#931) reached the zod fix by moving all
26+
three off the release they exist to hold: `ai@4.3.19` → `7.0.152`,
27+
`@langchain/core@0.3.80` → `1.3.0` (with `@langchain/langgraph@0.4.10` →
28+
`1.5.2`) and `llamaindex@0.11.4` → `0.12.1`, each with `zod@3.25.76` → `4.6.7`.
29+
`ai-4` and `langchain-0.3` still installed and passed while testing a
30+
different major, so the matrix silently lost two supported floors. `llamaindex-0.11`
31+
did not install: `@llamaindex/workflow@1.1.5` peers on `zod@^3.23.8`, so
32+
`npm ci` failed `ERESOLVE`, and because the global setup installs every fixture
33+
before any test runs, the `frameworks` and `runtimes` shards failed on `main`.
34+
All three are back on their pre-#931 manifests and lockfiles. #931 also moved
35+
the `runtimes` fixture to `zod@4.6.7` while `deno-npm.ts` still imported
36+
`npm:zod@4.6.5`, which Deno resolves against the fixture's `node_modules` and
37+
could no longer find; it imports `4.6.7` now. A root CI test,
38+
`__tests__/ci/ts-sdk-fixture-pins.test.ts`, fails on either move: a fixture named
39+
for a release line pinning its framework off that line, or an `npm:` specifier
40+
naming a version the fixture does not install. (#934)
41+
42+
- **The remaining fixable fixture advisories clear, each with an override.** `ai-5`
43+
moves `undici` 7.29.1 → 7.30.1 (GHSA-xjj6-f33q-929c, GHSA-4qv8-2p9j-2685,
44+
GHSA-f72v-6w45-q472) and `llamaindex-0.11` moves `fast-uri` 3.1.8 → 3.1.9
45+
(GHSA-w74x-v6f9-j3xg, GHSA-wjr9-j795-jxcr, GHSA-xhq7-xmqj-769h,
46+
GHSA-333x-w4r6-6crp). In `mastra-1`, `@mastra/mcp@2.0.0` pins
47+
`@modelcontextprotocol/server` and `@modelcontextprotocol/client` exactly, so the
48+
fixture overrides both to `2.3.0` (GHSA-jm63-cq47-j5jp, GHSA-46jr-4wx8-v453,
49+
GHSA-rvq5-wwqv-78pq, GHSA-6prh-2h8m-c8cw); each brings its own
50+
`@modelcontextprotocol/core@2.3.0` nested under it, as the client's earlier
51+
`2.2.0` override did. Each lockfile changes by those packages alone, and
52+
`npm audit` reports no findings in `ai-5` or `mastra-1`. (#934)
53+
54+
- **zod GHSA-mrhx-c7xc-m3w5 stays in the five fixtures held to zod 3.** It is fixed
55+
only in `zod@4.6.6`, and no zod 3 release carries the fix. `ai-4`, `langchain-0.3`
56+
and `llamaindex-0.11` pin `zod@3.25.76` beside frameworks that require `^3`, and
57+
`langchain-dup-core` and `mastra-0` carry a nested copy that the vendored
58+
provider's `@langchain/core@0.3.80` and `zod-from-json-schema@0.0.5` require.
59+
`SECURITY.md` records it with the two `ai@4` advisories. (#934)
60+
2461
## 0.0.1-beta.1 — 2026-10-15
2562

2663
### Features

0 commit comments

Comments
 (0)