[PR #1062] [MERGED] feat(app-router): add artifact compatibility metadata #1062

Closed
opened 2026-05-06 13:11:48 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/1062
Author: @NathanDrake2406
Created: 5/5/2026
Status: Merged
Merged: 5/6/2026
Merged by: @james-elicx

Base: mainHead: nathan/726-compat-01-envelope


📝 Commits (5)

  • b56b041 feat(app-router): add artifact compatibility envelope
  • 7d9ac6d test(app-router): cover future artifact schema rejection
  • 01751af feat(app-router): attach artifact compatibility metadata
  • 6284368 Merge remote-tracking branch 'upstream/main' into nathan/726-compat-01-envelope
  • d2ec7c2 fix(app-router): tolerate unused compatibility metadata parse failures

📊 Changes

6 files changed (+556 additions, -3 deletions)

View changed files

📝 packages/vinext/src/server/app-elements-wire.ts (+35 -2)
📝 packages/vinext/src/server/app-elements.ts (+1 -0)
📝 packages/vinext/src/server/app-page-render.ts (+35 -1)
packages/vinext/src/server/artifact-compatibility.ts (+202 -0)
📝 tests/app-elements.test.ts (+240 -0)
📝 tests/app-page-render.test.ts (+43 -0)

📄 Description

What this changes

Implements #726-COMPAT-01 plus #726-COMPAT-02/03 from #726.

This PR adds the App Router artifact compatibility envelope, attaches concrete render-boundary metadata to outgoing record payloads, and defines a conservative compatibility evaluator for future cache/skip callers.

Why

Issue #726 requires every reusable or skippable artifact to carry compatibility proof before cache reuse or skip transport can depend on it. The rule for this slice is deliberately strict: no proof, no reuse. Unknown compatibility is represented as a render-fresh fallback, never as positive compatibility proof.

Approach

  • Add packages/vinext/src/server/artifact-compatibility.ts with schema constants, ArtifactCompatibilityEnvelope, constructor/parser helpers, a route/root graph fingerprint helper, and evaluateArtifactCompatibility().
  • Keep legacy/malformed wire parsing fail-closed: missing legacy metadata defaults to an unknown-proof envelope; malformed or future-schema metadata is rejected.
  • Attach compatibility metadata in renderAppPageLifecycle when the outgoing App Router payload is a record:
    • graph metadata from route pattern plus root boundary fingerprint
    • deployment metadata from process.env.__VINEXT_BUILD_ID
    • schema metadata from the envelope constants
    • rootBoundaryId from __rootLayout when available
    • renderEpoch: null until a real epoch owner exists
  • Preserve current semantics: no cache reuse, no skip transport, and no rolling-deploy protocol completeness in this PR.

Correctness oracle

Vinext internal invariant from #726: no reusable or skippable artifact should gain implicit compatibility proof from cache presence, artifact presence, or wire shape. Unknown graph/deployment/root/epoch compatibility must return a render-fresh fallback, and only fully known matching metadata can produce compatible.

A focused Next.js source/test search for artifact compatibility, compatibility envelope, renderEpoch, deploymentVersion, and graphVersion found no public Next.js behavior to port for this internal Vinext protocol. This PR does not claim public Next.js behavior parity for rolling deploys.

Validation

  • vp test run tests/app-elements.test.ts tests/app-page-render.test.ts
  • vp check packages/vinext/src/server/artifact-compatibility.ts packages/vinext/src/server/app-elements.ts packages/vinext/src/server/app-page-render.ts tests/app-elements.test.ts tests/app-page-render.test.ts
  • vp run vinext#build

Risks / follow-ups

  • The graphVersion helper is a narrow route/root fingerprint until the RouteManifest graphVersion from GRAPH-02/03 exists.
  • renderEpoch is carried but remains null, so current artifacts cannot become positive reuse proof solely from matching graph/deployment/root metadata.
  • #726-COMPAT-04/05 should add old-client/new-server coverage and hard-navigation loop prevention before any broader deployment fallback behavior depends on this envelope.

Refs #726


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/1062 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 5/5/2026 **Status:** ✅ Merged **Merged:** 5/6/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `nathan/726-compat-01-envelope` --- ### 📝 Commits (5) - [`b56b041`](https://github.com/cloudflare/vinext/commit/b56b04194bc70f050027789304cbcbb6b2dd4220) feat(app-router): add artifact compatibility envelope - [`7d9ac6d`](https://github.com/cloudflare/vinext/commit/7d9ac6d2f001b776dbf9d423ef98f96cac3794d4) test(app-router): cover future artifact schema rejection - [`01751af`](https://github.com/cloudflare/vinext/commit/01751af7b6eb496df3726c93f7c53a18dcbab4c9) feat(app-router): attach artifact compatibility metadata - [`6284368`](https://github.com/cloudflare/vinext/commit/62843683f61d84621faea4f7cbf6e49f0c74712b) Merge remote-tracking branch 'upstream/main' into nathan/726-compat-01-envelope - [`d2ec7c2`](https://github.com/cloudflare/vinext/commit/d2ec7c28099d65d42bdda5395b8de5c0852a392b) fix(app-router): tolerate unused compatibility metadata parse failures ### 📊 Changes **6 files changed** (+556 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/server/app-elements-wire.ts` (+35 -2) 📝 `packages/vinext/src/server/app-elements.ts` (+1 -0) 📝 `packages/vinext/src/server/app-page-render.ts` (+35 -1) ➕ `packages/vinext/src/server/artifact-compatibility.ts` (+202 -0) 📝 `tests/app-elements.test.ts` (+240 -0) 📝 `tests/app-page-render.test.ts` (+43 -0) </details> ### 📄 Description ## What this changes Implements `#726-COMPAT-01` plus `#726-COMPAT-02/03` from #726. This PR adds the App Router artifact compatibility envelope, attaches concrete render-boundary metadata to outgoing record payloads, and defines a conservative compatibility evaluator for future cache/skip callers. ## Why Issue #726 requires every reusable or skippable artifact to carry compatibility proof before cache reuse or skip transport can depend on it. The rule for this slice is deliberately strict: no proof, no reuse. Unknown compatibility is represented as a render-fresh fallback, never as positive compatibility proof. ## Approach - Add `packages/vinext/src/server/artifact-compatibility.ts` with schema constants, `ArtifactCompatibilityEnvelope`, constructor/parser helpers, a route/root graph fingerprint helper, and `evaluateArtifactCompatibility()`. - Keep legacy/malformed wire parsing fail-closed: missing legacy metadata defaults to an unknown-proof envelope; malformed or future-schema metadata is rejected. - Attach compatibility metadata in `renderAppPageLifecycle` when the outgoing App Router payload is a record: - graph metadata from route pattern plus root boundary fingerprint - deployment metadata from `process.env.__VINEXT_BUILD_ID` - schema metadata from the envelope constants - `rootBoundaryId` from `__rootLayout` when available - `renderEpoch: null` until a real epoch owner exists - Preserve current semantics: no cache reuse, no skip transport, and no rolling-deploy protocol completeness in this PR. ## Correctness oracle Vinext internal invariant from #726: no reusable or skippable artifact should gain implicit compatibility proof from cache presence, artifact presence, or wire shape. Unknown graph/deployment/root/epoch compatibility must return a render-fresh fallback, and only fully known matching metadata can produce `compatible`. A focused Next.js source/test search for `artifact compatibility`, `compatibility envelope`, `renderEpoch`, `deploymentVersion`, and `graphVersion` found no public Next.js behavior to port for this internal Vinext protocol. This PR does not claim public Next.js behavior parity for rolling deploys. ## Validation - `vp test run tests/app-elements.test.ts tests/app-page-render.test.ts` - `vp check packages/vinext/src/server/artifact-compatibility.ts packages/vinext/src/server/app-elements.ts packages/vinext/src/server/app-page-render.ts tests/app-elements.test.ts tests/app-page-render.test.ts` - `vp run vinext#build` ## Risks / follow-ups - The `graphVersion` helper is a narrow route/root fingerprint until the RouteManifest graphVersion from GRAPH-02/03 exists. - `renderEpoch` is carried but remains `null`, so current artifacts cannot become positive reuse proof solely from matching graph/deployment/root metadata. - `#726-COMPAT-04/05` should add old-client/new-server coverage and hard-navigation loop prevention before any broader deployment fallback behavior depends on this envelope. Refs #726 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:11:48 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#1062
No description provided.