Skip to content

Run agent-assisted Next.js security upgrades - #98562

Draft
devjiwonchoi wants to merge 5 commits into
jiwon/agent-upgrade/docsfrom
jiwon/agent-upgrade/setup
Draft

Run agent-assisted Next.js security upgrades#98562
devjiwonchoi wants to merge 5 commits into
jiwon/agent-upgrade/docsfrom
jiwon/agent-upgrade/setup

Conversation

@devjiwonchoi

@devjiwonchoi devjiwonchoi commented Sep 11, 2026

Copy link
Copy Markdown
Member

Stacked on #98565.

Why?

Fixing a vulnerable Next.js app can require application-specific migration work beyond installing a patched version. The upgrade command needs to select a safe target and give a coding agent the evidence and guidance needed to complete that work.

How?

Add next upgrade --experimental-agent for apps that enable experimental.agenticAutoUpgrade: 'security'. Check the selected app and its installed version, fetch reviewed GitHub advisories with npm fallback, select a supported safe stable release, and verify its Node.js requirement. Disabled, unaffected or blocked apps exit before agent handoff.

Prepare an exact codemod command with --yes --skip-adoption. Retain the resolved inputs, advisory evidence, bundled workflow instructions and relevant migration guides outside app dependencies so they survive the upgrade. Canonical guides come from GitHub canary; the bundled workflow matches the installed CLI.

Continue in an existing Codex or Claude session, or let a terminal user select an installed agent and launch it in the background. New sessions use Luna for Codex and Haiku for Claude. Receipts provide session, log, stop and continuation information; Codex resume requires its background process to finish or stop. Existing sessions retain their model and permissions.

The workflow directs the agent to check for existing upgrade PRs, run codemods, complete contextual repairs, verify behavior and create commits. --experimental-agent-dry-run, used with --experimental-agent, stops at local commits without pushing or opening a PR. Publication otherwise follows the session's existing permissions.

Preserve the caller's environment for child commands, support Windows process launching, and exclude upgrade tooling from production traces. Include focused unit coverage for security-target selection.

@devjiwonchoi
devjiwonchoi added this pull request to stack #98564 September 11, 2026 13:22
@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Failing test suites

Commit: 167d186 | About building and testing Next.js

pnpm test-dev test/development/app-dir/instant-navs-devtools/instant-navs-devtools.test.ts (job)

  • instant-nav-panel > SPA captures > should capture when CookieStore writes are not reflected in document.cookie (DD)
Expand output

● instant-nav-panel › SPA captures › should capture when CookieStore writes are not reflected in document.cookie

locator.waitFor: Timeout 60000ms exceeded.
Call log:
  - waiting for locator('[data-testid="dynamic-skeleton"]') to be visible

  278 |     await browser
  279 |       .locator('[data-testid="dynamic-skeleton"]')
> 280 |       .waitFor({ state: 'visible' })
      |        ^
  281 |     await browser
  282 |       .locator('[data-testid="param-skeleton"]')
  283 |       .waitFor({ state: 'visible' })

  at waitFor (development/app-dir/instant-navs-devtools/instant-navs-devtools.test.ts:280:8)
  at Object.expectTargetPageSpaShell (development/app-dir/instant-navs-devtools/instant-navs-devtools.test.ts:607:13)

pnpm test-dev test/e2e/app-dir/instant-validation/suspense-boundaries.test.ts (job)

  • instant validation > dev - client navigation > invalid - loading.js covers page, but not layout at the same level (DD)
Expand output

● instant validation › dev - client navigation › invalid - loading.js covers page, but not layout at the same level

expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `instant validation dev - client navigation invalid - loading.js covers page, but not layout at the same level 1`

- Snapshot  - 24
+ Received  +  1

- {
-   "cause": [
-     {
-       "label": "Caused by: Instant Validation",
-       "source": "app/suspense-in-root/static/invalid-dynamic-layout-with-loading/layout.tsx (4:24) @ instant
- > 4 | export const instant = { level: 'experimental-error' }
-     |                        ^",
-       "stack": [
-         "instant app/suspense-in-root/static/invalid-dynamic-layout-with-loading/layout.tsx (4:24)",
-         "Set.forEach <anonymous>",
-       ],
-     },
-   ],
-   "description": "Next.js encountered uncached data during a navigation.",
-   "environmentLabel": "Server",
-   "label": "Instant",
-   "source": "app/suspense-in-root/static/invalid-dynamic-layout-with-loading/layout.tsx (24:19) @ Dynamic
- > 24 |   await connection()
-      |                   ^",
-   "stack": [
-     "Dynamic app/suspense-in-root/static/invalid-dynamic-layout-with-loading/layout.tsx (24:19)",
-     "Layout app/suspense-in-root/static/invalid-dynamic-layout-with-loading/layout.tsx (15:9)",
-   ],
- }
+ "Redbox did not open."

  1130 |         '/suspense-in-root/static/invalid-dynamic-layout-with-loading'
  1131 |       )
> 1132 |       await expect(browser).toDisplayCollapsedRedbox(`
       |                             ^
  1133 |        {
  1134 |          "cause": [
  1135 |            {

  at Object.toDisplayCollapsedRedbox (e2e/app-dir/instant-validation/suspense-boundaries.util.ts:1132:29)

pnpm test-start-turbo test/production/next-server-nft/next-server-nft.test.ts (turbopack) (job)

  • next-server-nft > with output:standalone > should not trace too many files in next-server.js.nft.json (DD)
Expand output

● next-server-nft › with output:standalone › should not trace too many files in next-server.js.nft.json

expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `next-server-nft with output:standalone should not trace too many files in next-server.js.nft.json 1`

- Snapshot  - 0
+ Received  + 2

@@ -227,10 +227,12 @@
    "/node_modules/next/dist/lib/typescript/runTypeCheckCli.js",
    "/node_modules/next/dist/lib/typescript/runTypeScriptCli.js",
    "/node_modules/next/dist/lib/typescript/type-paths.js",
    "/node_modules/next/dist/lib/typescript/writeAppTypeDeclarations.js",
    "/node_modules/next/dist/lib/typescript/writeConfigurationDefaults.js",
+   "/node_modules/next/dist/lib/upgrade/harness.js",
+   "/node_modules/next/dist/lib/upgrade/models.js",
    "/node_modules/next/dist/lib/url.js",
    "/node_modules/next/dist/lib/verify-partytown-setup.js",
    "/node_modules/next/dist/lib/verify-root-layout.js",
    "/node_modules/next/dist/lib/verify-typescript-setup.js",
    "/node_modules/next/dist/lib/wait.js",

  130 |         ]
  131 |
> 132 |         expect(traceGrouped).toMatchInlineSnapshot(`
      |                              ^
  133 |          [
  134 |            "/node_modules/@img/colour/*",
  135 |            "/node_modules/@img/sharp-<PLATFORM>-<ARCH>/*",

  at Object.toMatchInlineSnapshot (production/next-server-nft/next-server-nft.test.ts:132:30)

Other failing CI jobs

@devjiwonchoi
devjiwonchoi removed this pull request from stack #98564 September 11, 2026 13:31
@devjiwonchoi
devjiwonchoi changed the base branch from jiwon/agent-upgrade/codemods to jiwon/agent-upgrade/docs September 11, 2026 13:31
@devjiwonchoi
devjiwonchoi added this pull request to stack #98567 September 11, 2026 13:31
@devjiwonchoi devjiwonchoi changed the title jiwon/agent upgrade/setup Prepare security targets and migration guidance for upgrade agents Sep 11, 2026
@devjiwonchoi
devjiwonchoi force-pushed the jiwon/agent-upgrade/setup branch from 7e72fc9 to dd858a0 Compare September 11, 2026 14:16
@devjiwonchoi
devjiwonchoi removed this pull request from stack #98567 September 11, 2026 14:32
@devjiwonchoi
devjiwonchoi added this pull request to stack #98572 September 11, 2026 14:33
@devjiwonchoi
devjiwonchoi force-pushed the jiwon/agent-upgrade/setup branch from dd858a0 to a8faf6d Compare September 11, 2026 14:43
@devjiwonchoi
devjiwonchoi force-pushed the jiwon/agent-upgrade/setup branch 2 times, most recently from 64be173 to 02315c3 Compare September 11, 2026 15:02
@devjiwonchoi
devjiwonchoi force-pushed the jiwon/agent-upgrade/setup branch 2 times, most recently from 6c80ab4 to 8d37a7e Compare September 11, 2026 15:54
@devjiwonchoi
devjiwonchoi removed this pull request from stack #98572 September 11, 2026 15:54
@devjiwonchoi devjiwonchoi changed the title Prepare security targets and migration guidance for upgrade agents Run agent-assisted Next.js security upgrades Sep 11, 2026
@devjiwonchoi
devjiwonchoi added this pull request to stack #98574 September 11, 2026 15:55
@devjiwonchoi
devjiwonchoi force-pushed the jiwon/agent-upgrade/setup branch 7 times, most recently from 16c320d to 8a22f84 Compare September 11, 2026 21:41
@devjiwonchoi
devjiwonchoi force-pushed the jiwon/agent-upgrade/setup branch from 8a22f84 to 9d5c8f1 Compare September 11, 2026 23:14
A security upgrade must establish whether the app is affected and select an exact safe target before an agent edits it. Wire the experimental CLI option to the resolver so this checkpoint exposes its real caller.

Read the opt-in config and installed version, query reviewed advisories with npm fallback, select a supported safe release, and check its Node requirement. Reset loaded dotenv values before handoff and pin the codemod command without running a compatibility probe. Keep CLI-only upgrade files out of production traces. Retain deterministic security-target tests and preserve normal upgrade behavior.
Installing a safe version does not complete a migration, and replacing Next can erase its installed guides. Turn the resolved target into retained context and a handoff to the current agent.

Copy bundled workflow files and download relevant canonical guides, using Pages Router paths for versions through 13. Retain evidence outside app dependencies. The workflow requires codemods, contextual repairs, verification and commit checkpoints; experimental dry-run stops at local commits. Introduce the dry-run flag with its first execution consumer; terminal background launch follows in the next checkpoint.
Let developers interact with the upgrade agent in their current terminal. Offer installed agents, printed instructions, and cancellation; preserve existing-agent handoff and avoid launching a REPL without an interactive terminal.
@devjiwonchoi
devjiwonchoi force-pushed the jiwon/agent-upgrade/setup branch from 22b79bd to 4723ad0 Compare September 12, 2026 07:19
Keep the CLI focused on app scope, retained instructions and agent handoff so the coding agent can assess security eligibility and perform contextual repairs.

Replace the resolver and context file with bundled workflow guides, make dry-run enable agent mode, and support existing sessions, interactive launch and clipboard handoff.
Give agents explicit migration outcomes and common-issue guidance without duplicating the public upgrade explanations or changing rendered checklist content.

Add marked MDX comments for Next.js 15 and 16, have the workflow consume them, and explain how to verify image-quality behavior after upgrading.
@vercel-security-reviewer

Copy link
Copy Markdown

Security review details

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant