@bleedingdev/modern-js-ultramodern-create 3.9.0-ultramodern.13 → 3.9.0-ultramodern.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -99,15 +99,6 @@ const __rspack_default_export = [
99
99
  repository: true,
100
100
  workspace: null,
101
101
  reason: 'Build router params without string code generation in CSP/Worker bundles.'
102
- },
103
- {
104
- packageName: 'zod',
105
- version: '4.6.5',
106
- path: 'patches/zod@4.6.5.patch',
107
- sha256: '7640b49bb7addea5feff95947618c322ddb94b0bc834b4eb3ad349cff6fbf73b',
108
- repository: true,
109
- workspace: null,
110
- reason: 'Disable code-generation capability probing in CSP/Worker bundles.'
111
102
  }
112
103
  ];
113
104
  __webpack_require__.d(__webpack_exports__, {}, {
@@ -70,15 +70,6 @@ const patch_inventory = [
70
70
  repository: true,
71
71
  workspace: null,
72
72
  reason: 'Build router params without string code generation in CSP/Worker bundles.'
73
- },
74
- {
75
- packageName: 'zod',
76
- version: '4.6.5',
77
- path: 'patches/zod@4.6.5.patch',
78
- sha256: '7640b49bb7addea5feff95947618c322ddb94b0bc834b4eb3ad349cff6fbf73b',
79
- repository: true,
80
- workspace: null,
81
- reason: 'Disable code-generation capability probing in CSP/Worker bundles.'
82
73
  }
83
74
  ];
84
75
  export default patch_inventory;
@@ -71,15 +71,6 @@ const patch_inventory = [
71
71
  repository: true,
72
72
  workspace: null,
73
73
  reason: 'Build router params without string code generation in CSP/Worker bundles.'
74
- },
75
- {
76
- packageName: 'zod',
77
- version: '4.6.5',
78
- path: 'patches/zod@4.6.5.patch',
79
- sha256: '7640b49bb7addea5feff95947618c322ddb94b0bc834b4eb3ad349cff6fbf73b',
80
- repository: true,
81
- workspace: null,
82
- reason: 'Disable code-generation capability probing in CSP/Worker bundles.'
83
74
  }
84
75
  ];
85
76
  export default patch_inventory;
package/package.json CHANGED
@@ -26,7 +26,7 @@
26
26
  "engines": {
27
27
  "node": ">=26.7.0"
28
28
  },
29
- "version": "3.9.0-ultramodern.13",
29
+ "version": "3.9.0-ultramodern.14",
30
30
  "types": "./dist/types/index.d.ts",
31
31
  "main": "./dist/esm-node/index.js",
32
32
  "bin": {
@@ -83,11 +83,11 @@
83
83
  ],
84
84
  "dependencies": {
85
85
  "@babel/parser": "^8.0.6",
86
- "@modern-js/app-tools-extensions": "npm:@bleedingdev/modern-js-app-tools-extensions@3.9.0-ultramodern.13",
87
- "@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.0-ultramodern.13",
86
+ "@modern-js/app-tools-extensions": "npm:@bleedingdev/modern-js-app-tools-extensions@3.9.0-ultramodern.14",
87
+ "@modern-js/backend-federation-contracts": "npm:@bleedingdev/modern-js-backend-federation-contracts@3.9.0-ultramodern.14",
88
88
  "@modern-js/codesmith": "2.6.9",
89
- "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.9.0-ultramodern.13",
90
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.13",
89
+ "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.9.0-ultramodern.14",
90
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.14",
91
91
  "esbuild": "^0.28.2",
92
92
  "miniflare": "5.20260921.0-alpha",
93
93
  "oxfmt": "0.66.0",
@@ -95,9 +95,9 @@
95
95
  "ultracite": "7.12.0"
96
96
  },
97
97
  "devDependencies": {
98
- "@modern-js/i18n-integration": "npm:@bleedingdev/modern-js-i18n-integration@3.9.0-ultramodern.13",
99
- "@modern-js/i18n-runtime-extensions": "npm:@bleedingdev/modern-js-i18n-runtime-extensions@3.9.0-ultramodern.13",
100
- "@modern-js/plugin-bff-build-extensions": "npm:@bleedingdev/modern-js-plugin-bff-build-extensions@3.9.0-ultramodern.13",
98
+ "@modern-js/i18n-integration": "npm:@bleedingdev/modern-js-i18n-integration@3.9.0-ultramodern.14",
99
+ "@modern-js/i18n-runtime-extensions": "npm:@bleedingdev/modern-js-i18n-runtime-extensions@3.9.0-ultramodern.14",
100
+ "@modern-js/plugin-bff-build-extensions": "npm:@bleedingdev/modern-js-plugin-bff-build-extensions@3.9.0-ultramodern.14",
101
101
  "@rslib/core": "1.0.2",
102
102
  "@scripts/rstest-config": "2.66.0",
103
103
  "@types/node": "^26.6.2",
@@ -118,6 +118,6 @@
118
118
  "type-check": "tsgo --noEmit -p tsconfig.json"
119
119
  },
120
120
  "ultramodern": {
121
- "frameworkVersion": "3.9.0-ultramodern.13"
121
+ "frameworkVersion": "3.9.0-ultramodern.14"
122
122
  }
123
123
  }
@@ -51,242 +51,242 @@
51
51
  {
52
52
  "sourceName": "@modern-js/adapter-rstest",
53
53
  "targetName": "@bleedingdev/modern-js-adapter-rstest",
54
- "version": "3.9.0-ultramodern.13"
54
+ "version": "3.9.0-ultramodern.14"
55
55
  },
56
56
  {
57
57
  "sourceName": "@modern-js/app-tools",
58
58
  "targetName": "@bleedingdev/modern-js-app-tools",
59
- "version": "3.9.0-ultramodern.13"
59
+ "version": "3.9.0-ultramodern.14"
60
60
  },
61
61
  {
62
62
  "sourceName": "@modern-js/app-tools-extensions",
63
63
  "targetName": "@bleedingdev/modern-js-app-tools-extensions",
64
- "version": "3.9.0-ultramodern.13"
64
+ "version": "3.9.0-ultramodern.14"
65
65
  },
66
66
  {
67
67
  "sourceName": "@modern-js/backend-federation-contracts",
68
68
  "targetName": "@bleedingdev/modern-js-backend-federation-contracts",
69
- "version": "3.9.0-ultramodern.13"
69
+ "version": "3.9.0-ultramodern.14"
70
70
  },
71
71
  {
72
72
  "sourceName": "@modern-js/bff-core",
73
73
  "targetName": "@bleedingdev/modern-js-bff-core",
74
- "version": "3.9.0-ultramodern.13"
74
+ "version": "3.9.0-ultramodern.14"
75
75
  },
76
76
  {
77
77
  "sourceName": "@modern-js/bff-effect",
78
78
  "targetName": "@bleedingdev/modern-js-bff-effect",
79
- "version": "3.9.0-ultramodern.13"
79
+ "version": "3.9.0-ultramodern.14"
80
80
  },
81
81
  {
82
82
  "sourceName": "@modern-js/bff-runtime",
83
83
  "targetName": "@bleedingdev/modern-js-bff-runtime",
84
- "version": "3.9.0-ultramodern.13"
84
+ "version": "3.9.0-ultramodern.14"
85
85
  },
86
86
  {
87
87
  "sourceName": "@modern-js/boundary-debugger",
88
88
  "targetName": "@bleedingdev/modern-js-boundary-debugger",
89
- "version": "3.9.0-ultramodern.13"
89
+ "version": "3.9.0-ultramodern.14"
90
90
  },
91
91
  {
92
92
  "sourceName": "@modern-js/builder",
93
93
  "targetName": "@bleedingdev/modern-js-builder",
94
- "version": "3.9.0-ultramodern.13"
94
+ "version": "3.9.0-ultramodern.14"
95
95
  },
96
96
  {
97
97
  "sourceName": "@modern-js/code-tools",
98
98
  "targetName": "@bleedingdev/modern-js-code-tools",
99
- "version": "3.9.0-ultramodern.13"
99
+ "version": "3.9.0-ultramodern.14"
100
100
  },
101
101
  {
102
102
  "sourceName": "@modern-js/create-request",
103
103
  "targetName": "@bleedingdev/modern-js-create-request",
104
- "version": "3.9.0-ultramodern.13"
104
+ "version": "3.9.0-ultramodern.14"
105
105
  },
106
106
  {
107
107
  "sourceName": "@modern-js/federation-runtime",
108
108
  "targetName": "@bleedingdev/modern-js-federation-runtime",
109
- "version": "3.9.0-ultramodern.13"
109
+ "version": "3.9.0-ultramodern.14"
110
110
  },
111
111
  {
112
112
  "sourceName": "@modern-js/i18n-integration",
113
113
  "targetName": "@bleedingdev/modern-js-i18n-integration",
114
- "version": "3.9.0-ultramodern.13"
114
+ "version": "3.9.0-ultramodern.14"
115
115
  },
116
116
  {
117
117
  "sourceName": "@modern-js/i18n-runtime-extensions",
118
118
  "targetName": "@bleedingdev/modern-js-i18n-runtime-extensions",
119
- "version": "3.9.0-ultramodern.13"
119
+ "version": "3.9.0-ultramodern.14"
120
120
  },
121
121
  {
122
122
  "sourceName": "@modern-js/i18n-utils",
123
123
  "targetName": "@bleedingdev/modern-js-i18n-utils",
124
- "version": "3.9.0-ultramodern.13"
124
+ "version": "3.9.0-ultramodern.14"
125
125
  },
126
126
  {
127
127
  "sourceName": "@modern-js/image",
128
128
  "targetName": "@bleedingdev/modern-js-image",
129
- "version": "3.9.0-ultramodern.13"
129
+ "version": "3.9.0-ultramodern.14"
130
130
  },
131
131
  {
132
132
  "sourceName": "@modern-js/main-doc",
133
133
  "targetName": "@bleedingdev/modern-js-main-doc",
134
- "version": "3.9.0-ultramodern.13"
134
+ "version": "3.9.0-ultramodern.14"
135
135
  },
136
136
  {
137
137
  "sourceName": "@modern-js/plugin",
138
138
  "targetName": "@bleedingdev/modern-js-plugin",
139
- "version": "3.9.0-ultramodern.13"
139
+ "version": "3.9.0-ultramodern.14"
140
140
  },
141
141
  {
142
142
  "sourceName": "@modern-js/plugin-bff",
143
143
  "targetName": "@bleedingdev/modern-js-plugin-bff",
144
- "version": "3.9.0-ultramodern.13"
144
+ "version": "3.9.0-ultramodern.14"
145
145
  },
146
146
  {
147
147
  "sourceName": "@modern-js/plugin-bff-build-extensions",
148
148
  "targetName": "@bleedingdev/modern-js-plugin-bff-build-extensions",
149
- "version": "3.9.0-ultramodern.13"
149
+ "version": "3.9.0-ultramodern.14"
150
150
  },
151
151
  {
152
152
  "sourceName": "@modern-js/plugin-bff-extensions",
153
153
  "targetName": "@bleedingdev/modern-js-plugin-bff-extensions",
154
- "version": "3.9.0-ultramodern.13"
154
+ "version": "3.9.0-ultramodern.14"
155
155
  },
156
156
  {
157
157
  "sourceName": "@modern-js/plugin-data-loader",
158
158
  "targetName": "@bleedingdev/modern-js-plugin-data-loader",
159
- "version": "3.9.0-ultramodern.13"
159
+ "version": "3.9.0-ultramodern.14"
160
160
  },
161
161
  {
162
162
  "sourceName": "@modern-js/plugin-i18n",
163
163
  "targetName": "@bleedingdev/modern-js-plugin-i18n",
164
- "version": "3.9.0-ultramodern.13"
164
+ "version": "3.9.0-ultramodern.14"
165
165
  },
166
166
  {
167
167
  "sourceName": "@modern-js/plugin-polyfill",
168
168
  "targetName": "@bleedingdev/modern-js-plugin-polyfill",
169
- "version": "3.9.0-ultramodern.13"
169
+ "version": "3.9.0-ultramodern.14"
170
170
  },
171
171
  {
172
172
  "sourceName": "@modern-js/plugin-ssg",
173
173
  "targetName": "@bleedingdev/modern-js-plugin-ssg",
174
- "version": "3.9.0-ultramodern.13"
174
+ "version": "3.9.0-ultramodern.14"
175
175
  },
176
176
  {
177
177
  "sourceName": "@modern-js/plugin-styled-components",
178
178
  "targetName": "@bleedingdev/modern-js-plugin-styled-components",
179
- "version": "3.9.0-ultramodern.13"
179
+ "version": "3.9.0-ultramodern.14"
180
180
  },
181
181
  {
182
182
  "sourceName": "@modern-js/plugin-tanstack",
183
183
  "targetName": "@bleedingdev/modern-js-plugin-tanstack",
184
- "version": "3.9.0-ultramodern.13"
184
+ "version": "3.9.0-ultramodern.14"
185
185
  },
186
186
  {
187
187
  "sourceName": "@modern-js/prod-server",
188
188
  "targetName": "@bleedingdev/modern-js-prod-server",
189
- "version": "3.9.0-ultramodern.13"
189
+ "version": "3.9.0-ultramodern.14"
190
190
  },
191
191
  {
192
192
  "sourceName": "@modern-js/render",
193
193
  "targetName": "@bleedingdev/modern-js-render",
194
- "version": "3.9.0-ultramodern.13"
194
+ "version": "3.9.0-ultramodern.14"
195
195
  },
196
196
  {
197
197
  "sourceName": "@modern-js/runtime",
198
198
  "targetName": "@bleedingdev/modern-js-runtime",
199
- "version": "3.9.0-ultramodern.13"
199
+ "version": "3.9.0-ultramodern.14"
200
200
  },
201
201
  {
202
202
  "sourceName": "@modern-js/runtime-extensions",
203
203
  "targetName": "@bleedingdev/modern-js-runtime-extensions",
204
- "version": "3.9.0-ultramodern.13"
204
+ "version": "3.9.0-ultramodern.14"
205
205
  },
206
206
  {
207
207
  "sourceName": "@modern-js/runtime-renderer-extensions",
208
208
  "targetName": "@bleedingdev/modern-js-runtime-renderer-extensions",
209
- "version": "3.9.0-ultramodern.13"
209
+ "version": "3.9.0-ultramodern.14"
210
210
  },
211
211
  {
212
212
  "sourceName": "@modern-js/runtime-utils",
213
213
  "targetName": "@bleedingdev/modern-js-runtime-utils",
214
- "version": "3.9.0-ultramodern.13"
214
+ "version": "3.9.0-ultramodern.14"
215
215
  },
216
216
  {
217
217
  "sourceName": "@modern-js/sandpack-react",
218
218
  "targetName": "@bleedingdev/modern-js-sandpack-react",
219
- "version": "3.9.0-ultramodern.13"
219
+ "version": "3.9.0-ultramodern.14"
220
220
  },
221
221
  {
222
222
  "sourceName": "@modern-js/server",
223
223
  "targetName": "@bleedingdev/modern-js-server",
224
- "version": "3.9.0-ultramodern.13"
224
+ "version": "3.9.0-ultramodern.14"
225
225
  },
226
226
  {
227
227
  "sourceName": "@modern-js/server-core",
228
228
  "targetName": "@bleedingdev/modern-js-server-core",
229
- "version": "3.9.0-ultramodern.13"
229
+ "version": "3.9.0-ultramodern.14"
230
230
  },
231
231
  {
232
232
  "sourceName": "@modern-js/server-runtime",
233
233
  "targetName": "@bleedingdev/modern-js-server-runtime",
234
- "version": "3.9.0-ultramodern.13"
234
+ "version": "3.9.0-ultramodern.14"
235
235
  },
236
236
  {
237
237
  "sourceName": "@modern-js/server-runtime-extensions",
238
238
  "targetName": "@bleedingdev/modern-js-server-runtime-extensions",
239
- "version": "3.9.0-ultramodern.13"
239
+ "version": "3.9.0-ultramodern.14"
240
240
  },
241
241
  {
242
242
  "sourceName": "@modern-js/server-utils",
243
243
  "targetName": "@bleedingdev/modern-js-server-utils",
244
- "version": "3.9.0-ultramodern.13"
244
+ "version": "3.9.0-ultramodern.14"
245
245
  },
246
246
  {
247
247
  "sourceName": "@modern-js/surface-resolution",
248
248
  "targetName": "@bleedingdev/modern-js-surface-resolution",
249
- "version": "3.9.0-ultramodern.13"
249
+ "version": "3.9.0-ultramodern.14"
250
250
  },
251
251
  {
252
252
  "sourceName": "@modern-js/tsconfig",
253
253
  "targetName": "@bleedingdev/modern-js-tsconfig",
254
- "version": "3.9.0-ultramodern.13"
254
+ "version": "3.9.0-ultramodern.14"
255
255
  },
256
256
  {
257
257
  "sourceName": "@modern-js/types",
258
258
  "targetName": "@bleedingdev/modern-js-types",
259
- "version": "3.9.0-ultramodern.13"
259
+ "version": "3.9.0-ultramodern.14"
260
260
  },
261
261
  {
262
262
  "sourceName": "@modern-js/ultramodern-app-tools",
263
263
  "targetName": "@bleedingdev/modern-js-ultramodern-app-tools",
264
- "version": "3.9.0-ultramodern.13"
264
+ "version": "3.9.0-ultramodern.14"
265
265
  },
266
266
  {
267
267
  "sourceName": "@modern-js/ultramodern-create",
268
268
  "targetName": "@bleedingdev/modern-js-ultramodern-create",
269
- "version": "3.9.0-ultramodern.13"
269
+ "version": "3.9.0-ultramodern.14"
270
270
  },
271
271
  {
272
272
  "sourceName": "@modern-js/ultramodern-sandpack-profile",
273
273
  "targetName": "@bleedingdev/modern-js-ultramodern-sandpack-profile",
274
- "version": "3.9.0-ultramodern.13"
274
+ "version": "3.9.0-ultramodern.14"
275
275
  },
276
276
  {
277
277
  "sourceName": "@modern-js/utils",
278
278
  "targetName": "@bleedingdev/modern-js-utils",
279
- "version": "3.9.0-ultramodern.13"
279
+ "version": "3.9.0-ultramodern.14"
280
280
  }
281
281
  ],
282
282
  "release": {
283
283
  "tag": "latest",
284
- "version": "3.9.0-ultramodern.13"
284
+ "version": "3.9.0-ultramodern.14"
285
285
  },
286
286
  "schema": "bleedingdev.ultramodern.release-cohort",
287
287
  "schemaVersion": 1,
288
288
  "source": {
289
- "commit": "cefd1b52b8f5e40bc63f0cead60dc210aab51bbc",
289
+ "commit": "eefd9e53bda3bcd1651864c1da0658c56cd7eade",
290
290
  "repository": "BleedingDev/ultramodern.js"
291
291
  }
292
292
  }
@@ -3,14 +3,12 @@ import crypto from "node:crypto";
3
3
  import fs from "node:fs";
4
4
  import http from "node:http";
5
5
  import path from "node:path";
6
+ import { parseEnv } from "node:util";
6
7
  import { convertV4MiniflareOptions, Log, LogLevel, Miniflare } from "miniflare";
7
8
 
8
- const workspaceRoot = path.resolve(process.env.ULTRAMODERN_WORKSPACE_ROOT ?? process.cwd());
9
- const defaultProofRoutes = ["/en"];
10
- const reportPath = path.join(
11
- workspaceRoot,
12
- ".codex/reports/cloudflare-workerd-ssr/composition-proof.json",
13
- );
9
+ const reportRelativePath = ".codex/reports/cloudflare-workerd-ssr/composition-proof.json";
10
+ // Mirrors the public website quality gate default for server-rendered HTML.
11
+ const defaultSsrHtmlMaxBytes = 250_000;
14
12
 
15
13
  const assert = (condition, message) => {
16
14
  if (!condition) {
@@ -120,86 +118,164 @@ const bindExecutedModule = (app, envelope, module) => {
120
118
  };
121
119
  };
122
120
 
123
- const topology = readJson(path.join(workspaceRoot, "topology/reference-topology.json"));
124
- const overlay = readJson(path.join(workspaceRoot, "topology/local-overlays/development.json"));
125
- assert(topology.schemaVersion === 1 && topology.shell && Array.isArray(topology.verticals), "Invalid topology/reference-topology.json");
126
- const apps = [topology.shell, ...topology.verticals, ...(topology.shells ?? [])].map((rawApp) => {
127
- const kind = rawApp.kind === "vertical" ? "vertical" : "shell";
128
- const hasApiSurface = kind === "vertical" && rawApp.surfaceProfile !== "ui-only";
129
- const appPath = rawApp.path;
130
- assert(typeof appPath === "string" && appPath.length > 0, `${rawApp.id} topology path is missing`);
131
- const moduleFederation =
132
- rawApp.moduleFederation && typeof rawApp.moduleFederation === "object"
133
- ? rawApp.moduleFederation
134
- : {};
135
- const configuredProofRoutes = rawApp.cloudflare?.distributedSsrProofRoutes;
136
- const proofRoutes = Array.isArray(configuredProofRoutes)
137
- ? [...new Set(configuredProofRoutes.filter(
138
- (route) => typeof route === "string" && route.startsWith("/"),
139
- ))]
140
- : [];
141
- const outputRoot = path.join(workspaceRoot, appPath, ".output");
142
- const wranglerPath = path.join(outputRoot, "wrangler.json");
121
+ const normalizeRoutes = (routes) => [
122
+ ...new Set(
123
+ (Array.isArray(routes) ? routes : []).filter(
124
+ (route) => typeof route === "string" && route.startsWith("/"),
125
+ ),
126
+ ),
127
+ ];
128
+
129
+ // The generator's distributed SSR contract: every expose except the page
130
+ // route is a fragment a host can server-render (see distributedSsrExposes).
131
+ const declaresDistributedSsrExpose = (rawApp) =>
132
+ Array.isArray(rawApp?.moduleFederation?.exposes) &&
133
+ rawApp.moduleFederation.exposes.some(
134
+ (expose) => typeof expose === "string" && expose !== "./Route",
135
+ );
136
+
137
+ /**
138
+ * Derive what the proof must execute from topology/reference-topology.json.
139
+ *
140
+ * - `ssrRoutes`: every route the app itself must server-render on its own
141
+ * Worker (`cloudflare.routes.ssr` plus `cloudflare.distributedSsrProofRoutes`).
142
+ * - `serverRenderedRoutes`: shell routes that must compose distributed SSR
143
+ * boundaries. `cloudflare.distributedSsrProofRoutes` declares them; without
144
+ * it the shell's `cloudflare.routes.ssr` is the composition route. An empty
145
+ * array declares a shell whose MicroVerticals load on the client only.
146
+ * - `serverRenderedRemoteIds`: shell `verticalRefs` whose topology declares a
147
+ * distributed SSR expose, i.e. the boundaries the shell must server-render.
148
+ */
149
+ export const planWorkerdSsrProof = (topology) => {
143
150
  assert(
144
- fs.existsSync(wranglerPath),
145
- `${rawApp.id} Cloudflare output is missing; run pnpm cloudflare:build first`,
146
- );
147
- const wrangler = readJson(wranglerPath);
148
- const executedEnvelope =
149
- hasApiSurface
150
- ? readExecutionEnvelope(
151
- String(rawApp.id),
152
- outputRoot,
153
- rawApp.deliveryUnit?.unitId,
154
- )
155
- : {};
156
- const domain = rawApp.domain ?? rawApp.id;
157
- const portEnv = rawApp.portEnv ??
158
- (kind === "vertical"
159
- ? `VERTICAL_${String(domain).replace(/[^a-zA-Z0-9]/gu, "_").toUpperCase()}_PORT`
160
- : undefined);
161
- assert(typeof portEnv === "string" && portEnv.length > 0, `${rawApp.id} has no declared port environment name`);
162
- const configuredPort = process.env[portEnv];
163
- const port = configuredPort === undefined
164
- ? Number(overlay.ports?.[rawApp.id])
165
- : Number(configuredPort);
151
+ topology?.schemaVersion === 1 && topology.shell && Array.isArray(topology.verticals),
152
+ "Invalid topology/reference-topology.json",
153
+ );
154
+ const rawApps = [topology.shell, ...topology.verticals, ...(topology.shells ?? [])];
155
+ const rawAppsById = new Map(rawApps.map((rawApp) => [String(rawApp.id), rawApp]));
156
+ const plans = rawApps.map((rawApp) => {
157
+ const id = String(rawApp.id);
158
+ const kind = rawApp.kind === "vertical" ? "vertical" : "shell";
159
+ const cloudflare = rawApp.cloudflare ?? {};
160
+ const declaredServerRenderedRoutes = cloudflare.distributedSsrProofRoutes;
161
+ const rawVerticalRefs = rawApp.verticalRefs ?? rawApp.moduleFederation?.verticalRefs;
162
+ const verticalRefs = Array.isArray(rawVerticalRefs)
163
+ ? rawVerticalRefs.filter((ref) => typeof ref === "string")
164
+ : [];
165
+ for (const ref of verticalRefs) {
166
+ assert(rawAppsById.has(ref), `${id} references missing MicroVertical ${ref}`);
167
+ }
168
+ const serverRenderedRemoteIds =
169
+ kind === "shell"
170
+ ? verticalRefs.filter((ref) => declaresDistributedSsrExpose(rawAppsById.get(ref)))
171
+ : [];
172
+ assert(
173
+ declaredServerRenderedRoutes === undefined ||
174
+ (Array.isArray(declaredServerRenderedRoutes) &&
175
+ normalizeRoutes(declaredServerRenderedRoutes).length ===
176
+ declaredServerRenderedRoutes.length),
177
+ `${id} cloudflare.distributedSsrProofRoutes must list unique absolute routes`,
178
+ );
179
+ const serverRenderedRoutes =
180
+ kind !== "shell"
181
+ ? []
182
+ : Array.isArray(declaredServerRenderedRoutes)
183
+ ? normalizeRoutes(declaredServerRenderedRoutes)
184
+ : normalizeRoutes([cloudflare.routes?.ssr]);
185
+ const ssrRoutes = normalizeRoutes([
186
+ ...(Array.isArray(declaredServerRenderedRoutes) ? declaredServerRenderedRoutes : []),
187
+ cloudflare.routes?.ssr,
188
+ ]);
189
+ const apiOnly = rawApp.surfaceProfile === "api-only";
190
+ assert(
191
+ apiOnly || normalizeRoutes([cloudflare.routes?.ssr]).length === 1,
192
+ `${id} declares no cloudflare.routes.ssr to prove on its own Worker`,
193
+ );
194
+ return {
195
+ apiOnly,
196
+ id,
197
+ kind,
198
+ serverRenderedRemoteIds:
199
+ serverRenderedRoutes.length > 0 ? serverRenderedRemoteIds : [],
200
+ serverRenderedRoutes,
201
+ ssrRoutes,
202
+ verticalRefs,
203
+ };
204
+ });
166
205
  assert(
167
- Number.isInteger(port) && port > 0 && port <= 65535,
168
- `${rawApp.id} has an invalid local proof port from ${portEnv}`,
206
+ plans.some((plan) => plan.kind === "shell"),
207
+ "Workerd SSR proof requires at least one shell",
169
208
  );
209
+ assert(
210
+ plans.some((plan) => plan.kind === "vertical"),
211
+ "Workerd SSR proof requires at least one MicroVertical or headless API",
212
+ );
213
+ return { plans, rawApps };
214
+ };
170
215
 
171
- return {
172
- id: String(rawApp.id),
173
- kind,
174
- hasApiSurface,
175
- apiOnly: rawApp.surfaceProfile === "api-only",
176
- path: appPath,
177
- mfName: typeof moduleFederation.name === "string" ? moduleFederation.name : String(rawApp.id),
178
- verticalRefs: Array.isArray(rawApp.verticalRefs ?? moduleFederation.verticalRefs)
179
- ? (rawApp.verticalRefs ?? moduleFederation.verticalRefs).filter((ref) => typeof ref === "string")
180
- : [],
181
- apiPrefix:
182
- typeof rawApp.api?.bff?.prefix === "string"
183
- ? rawApp.api.bff.prefix.replace(/\/+$/u, "")
184
- : undefined,
185
- apiProtocol: rawApp.api?.protocol ?? "rest",
186
- rpcRoute: rawApp.api?.protocol === "rpc" ? rawApp.cloudflare?.routes?.rpc : undefined,
187
- proofRoutes: proofRoutes.length > 0 ? proofRoutes : defaultProofRoutes,
188
- jsonSmokeChecks: Array.isArray(rawApp.cloudflare?.jsonSmokeChecks)
189
- ? rawApp.cloudflare.jsonSmokeChecks
190
- : [],
191
- ...executedEnvelope,
192
- outputRoot,
193
- port,
194
- wrangler,
195
- };
196
- });
216
+ const readDevVars = (outputRoot) => {
217
+ // Wrangler's local-secret convention: `.dev.vars` beside the executed config.
218
+ const devVarsPath = path.join(outputRoot, ".dev.vars");
219
+ return fs.existsSync(devVarsPath) ? parseEnv(fs.readFileSync(devVarsPath, "utf8")) : {};
220
+ };
197
221
 
198
- const shells = apps.filter((app) => app.kind === "shell");
199
- assert(shells.length > 0, "Workerd SSR proof requires at least one shell");
200
- if (process.env.ULTRAMODERN_KEEP_WORKERD === "1") {
201
- assert(shells.length === 1, "Browser workerd proof requires exactly one shell");
202
- }
222
+ const loadApps = (workspaceRoot, topology, overlay) => {
223
+ const { plans, rawApps } = planWorkerdSsrProof(topology);
224
+ return rawApps.map((rawApp, index) => {
225
+ const plan = plans[index];
226
+ const hasApiSurface = plan.kind === "vertical" && rawApp.surfaceProfile !== "ui-only";
227
+ const appPath = rawApp.path;
228
+ assert(typeof appPath === "string" && appPath.length > 0, `${plan.id} topology path is missing`);
229
+ const outputRoot = path.join(workspaceRoot, appPath, ".output");
230
+ const wranglerPath = path.join(outputRoot, "wrangler.json");
231
+ assert(
232
+ fs.existsSync(wranglerPath),
233
+ `${plan.id} Cloudflare output is missing; run pnpm cloudflare:build first`,
234
+ );
235
+ const wrangler = readJson(wranglerPath);
236
+ const executedEnvelope = hasApiSurface
237
+ ? readExecutionEnvelope(plan.id, outputRoot, rawApp.deliveryUnit?.unitId)
238
+ : {};
239
+ const domain = rawApp.domain ?? rawApp.id;
240
+ const portEnv = rawApp.portEnv ??
241
+ (plan.kind === "vertical"
242
+ ? `VERTICAL_${String(domain).replace(/[^a-zA-Z0-9]/gu, "_").toUpperCase()}_PORT`
243
+ : undefined);
244
+ assert(typeof portEnv === "string" && portEnv.length > 0, `${plan.id} has no declared port environment name`);
245
+ const configuredPort = process.env[portEnv];
246
+ const port = configuredPort === undefined
247
+ ? Number(overlay.ports?.[plan.id])
248
+ : Number(configuredPort);
249
+ assert(
250
+ Number.isInteger(port) && port > 0 && port <= 65535,
251
+ `${plan.id} has an invalid local proof port from ${portEnv}`,
252
+ );
253
+
254
+ return {
255
+ ...plan,
256
+ hasApiSurface,
257
+ path: appPath,
258
+ apiPrefix:
259
+ typeof rawApp.api?.bff?.prefix === "string"
260
+ ? rawApp.api.bff.prefix.replace(/\/+$/u, "")
261
+ : undefined,
262
+ apiProtocol: rawApp.api?.protocol ?? "rest",
263
+ rpcRoute: rawApp.api?.protocol === "rpc" ? rawApp.cloudflare?.routes?.rpc : undefined,
264
+ ssrHtmlMaxBytes: Number(
265
+ rawApp.cloudflare?.qualityGates?.budgets?.ssrHtmlMaxBytes ??
266
+ defaultSsrHtmlMaxBytes,
267
+ ),
268
+ jsonSmokeChecks: Array.isArray(rawApp.cloudflare?.jsonSmokeChecks)
269
+ ? rawApp.cloudflare.jsonSmokeChecks
270
+ : [],
271
+ ...executedEnvelope,
272
+ devVars: readDevVars(outputRoot),
273
+ outputRoot,
274
+ port,
275
+ wrangler,
276
+ };
277
+ });
278
+ };
203
279
 
204
280
  const workerName = (app) => {
205
281
  assert(
@@ -209,7 +285,7 @@ const workerName = (app) => {
209
285
  return app.wrangler.name;
210
286
  };
211
287
 
212
- const createWorkerOptions = (app, extra = {}) => {
288
+ const createWorkerOptions = (app, workspaceRoot, extra = {}) => {
213
289
  const main = typeof app.wrangler.main === "string" ? app.wrangler.main : "server/index.mjs";
214
290
  const assets =
215
291
  app.wrangler.assets && typeof app.wrangler.assets === "object" ? app.wrangler.assets : {};
@@ -279,6 +355,7 @@ const createWorkerOptions = (app, extra = {}) => {
279
355
  modulesRoot: app.outputRoot,
280
356
  compatibilityDate: app.wrangler.compatibility_date,
281
357
  compatibilityFlags: app.wrangler.compatibility_flags,
358
+ bindings: { ...app.wrangler.vars, ...app.devVars },
282
359
  assets: {
283
360
  binding: typeof assets.binding === "string" ? assets.binding : "ASSETS",
284
361
  directory: path.resolve(app.outputRoot, directory),
@@ -387,7 +464,7 @@ const resolveApiSmokeChecks = (app, shell) => {
387
464
  return [...uniqueChecks.values()];
388
465
  };
389
466
 
390
- const runApiProofs = async (miniflare, shell, executionByAppId) => {
467
+ const runApiProofs = async (apps, miniflare, shell, executionByAppId) => {
391
468
  const results = [];
392
469
  for (const app of apps.filter((candidate) => candidate.hasApiSurface)) {
393
470
  const jsonSmokeChecks = resolveApiSmokeChecks(app, shell);
@@ -477,6 +554,7 @@ const closeServer = (server) =>
477
554
  });
478
555
 
479
556
  const startWorkerdTargetServers = async (
557
+ apps,
480
558
  miniflare,
481
559
  failedServices,
482
560
  workerConfigurations,
@@ -490,18 +568,9 @@ const startWorkerdTargetServers = async (
490
568
  Number.isInteger(app.port) && app.port > 0,
491
569
  `${app.id} requires a configured local port for all-workerd browser proof`,
492
570
  );
493
- // Miniflare assigns one shared assets storage service inside
494
- // a multi-worker instance. Keep the shell composition runtime intact,
495
- // but give every directly browsed MicroVertical its own runtime so its
496
- // static assets and MF manifest cannot resolve from a sibling Worker.
497
571
  const runtime =
498
572
  app.kind === "vertical"
499
- ? new Miniflare(
500
- convertV4MiniflareOptions({
501
- log: new Log(LogLevel.ERROR),
502
- workers: [workerConfigurations[index]],
503
- }),
504
- )
573
+ ? createIsolatedRuntime(workerConfigurations[index])
505
574
  : miniflare;
506
575
  if (runtime !== miniflare) {
507
576
  isolatedVerticalRuntimes.push(runtime);
@@ -649,9 +718,22 @@ const decodeDistributedSsrFragmentRequest = (request) => {
649
718
  };
650
719
  };
651
720
 
721
+ // Miniflare assigns one shared assets storage service inside a multi-worker
722
+ // instance. Keep the shell composition runtime intact, but give every directly
723
+ // requested MicroVertical its own runtime so its static assets and MF manifest
724
+ // cannot resolve from a sibling Worker. Its service bindings still resolve
725
+ // through the shared composition runtime.
726
+ const createIsolatedRuntime = (workerOptions) =>
727
+ new Miniflare(
728
+ convertV4MiniflareOptions({
729
+ log: new Log(LogLevel.ERROR),
730
+ workers: [workerOptions],
731
+ }),
732
+ );
733
+
652
734
  const createServiceBindings = (
653
735
  caller,
654
- { apiBindingRequests, failedServices, fragmentBindingRequests },
736
+ { apiBindingRequests, composition, failedServices, fragmentBindingRequests },
655
737
  ) => {
656
738
  const services = Array.isArray(caller.wrangler.services) ? caller.wrangler.services : [];
657
739
  return Object.fromEntries(
@@ -662,7 +744,7 @@ const createServiceBindings = (
662
744
  );
663
745
  return [
664
746
  service.binding,
665
- async (request, miniflare) => {
747
+ async (request) => {
666
748
  if (failedServices.has(service.service)) {
667
749
  throw new Error(
668
750
  `Injected unavailable service binding ${service.binding} -> ${service.service}`,
@@ -699,7 +781,7 @@ const createServiceBindings = (
699
781
  };
700
782
  apiBindingRequests.push(apiBindingRequest);
701
783
  }
702
- const target = await miniflare.getWorker(service.service);
784
+ const target = await composition.miniflare.getWorker(service.service);
703
785
  const response = await target.fetch(request);
704
786
  if (apiBindingRequest !== undefined) {
705
787
  apiBindingRequest.response = {
@@ -714,11 +796,96 @@ const createServiceBindings = (
714
796
  );
715
797
  };
716
798
 
717
- const proofs = [];
718
- const apiProofs = [];
719
- let executions = [];
799
+ const proveRoute = async (app, route, fetchRoute, apps, recorders) => {
800
+ const apiBindingRequestStart = recorders.apiBindingRequests.length;
801
+ const fragmentBindingRequestStart = recorders.fragmentBindingRequests.length;
802
+ const outboundRequestStart = recorders.outboundRequests.length;
803
+ const response = await fetchRoute(`https://${workerName(app)}.invalid${route}`, {
804
+ headers: { accept: "text/html" },
805
+ });
806
+ const html = await response.text();
807
+ const htmlBytes = Buffer.byteLength(html);
808
+ const routeOutboundRequests = recorders.outboundRequests.slice(outboundRequestStart);
809
+ assert(
810
+ response.status === 200,
811
+ `${app.id} returned HTTP ${response.status} for ${route} in workerd; outbound requests: ${JSON.stringify(routeOutboundRequests)}; response: ${html.slice(0, 500)}`,
812
+ );
813
+ assert(
814
+ response.headers.get("content-type")?.includes("text/html") === true,
815
+ `${app.id} did not return HTML for ${route} in workerd`,
816
+ );
817
+ // Runaway server rendering (for example a worker re-rendering its own
818
+ // route data requests) can still end in an oversized document.
819
+ assert(
820
+ htmlBytes <= app.ssrHtmlMaxBytes,
821
+ `${app.id} rendered ${htmlBytes} bytes for ${route} in workerd, over the ${app.ssrHtmlMaxBytes} byte ssrHtmlMaxBytes budget`,
822
+ );
823
+ assert(
824
+ !html.includes('data-modern-distributed-ssr-status="degraded"'),
825
+ `${app.id} rendered a degraded MicroVertical fallback for ${route} in workerd`,
826
+ );
827
+
828
+ const boundaries = collectDistributedBoundaries(html);
829
+ const routeApiBindingRequests = recorders.apiBindingRequests.slice(apiBindingRequestStart);
830
+ const routeFragmentBindingRequests = recorders.fragmentBindingRequests.slice(
831
+ fragmentBindingRequestStart,
832
+ );
833
+ for (const boundary of boundaries) {
834
+ assert(
835
+ boundary.status === "ready",
836
+ `${app.id} did not mark ${boundary.key} as ready for ${route}`,
837
+ );
838
+ assert(
839
+ typeof boundary.buildMarker === "string" && boundary.buildMarker.length > 0,
840
+ `${app.id} ${boundary.key} is missing immutable build provenance`,
841
+ );
842
+ assert(
843
+ /^[a-f\d]{64}$/u.test(boundary.digest ?? ""),
844
+ `${app.id} ${boundary.key} is missing a verified SHA-256 digest`,
845
+ );
846
+ const remote = apps.find((candidate) => candidate.id === boundary.remote);
847
+ assert(remote, `${app.id} rendered unknown remote ${boundary.remote}`);
848
+ const requests = routeFragmentBindingRequests.filter(
849
+ (request) =>
850
+ request.service === workerName(remote) &&
851
+ request.remote === boundary.remote &&
852
+ request.expose === boundary.expose,
853
+ );
854
+ const renderedCount = boundaries.filter(
855
+ (candidate) => candidate.key === boundary.key,
856
+ ).length;
857
+ assert(
858
+ requests.length === renderedCount &&
859
+ requests.every((request) => request.pathname.includes("/_mf/fragment/")),
860
+ `${app.id} must compose each ${boundary.key} occurrence through its remote service binding`,
861
+ );
862
+ }
863
+
864
+ const stylesheetHrefs = collectStylesheetHrefs(html);
865
+ assert(
866
+ new Set(stylesheetHrefs).size === stylesheetHrefs.length,
867
+ `${app.id} rendered duplicate distributed SSR stylesheets for ${route}`,
868
+ );
869
+ assert(
870
+ !routeOutboundRequests.some(({ url }) => /(?:remoteEntry|\.m?js(?:\?|$))/u.test(url)),
871
+ `${app.id} attempted to fetch remote JavaScript during ${route} server rendering`,
872
+ );
873
+
874
+ return {
875
+ worker: workerName(app),
876
+ route,
877
+ status: response.status,
878
+ htmlBytes,
879
+ boundaries,
880
+ fragmentBindingRequests: routeFragmentBindingRequests,
881
+ apiBindingRequests: routeApiBindingRequests,
882
+ outboundRequests: routeOutboundRequests,
883
+ stylesheetHrefs,
884
+ degradedBoundaryCount: count(html, 'data-modern-distributed-ssr-status="degraded"'),
885
+ };
886
+ };
720
887
 
721
- const writeReport = () => {
888
+ const writeReport = (reportPath, report) => {
722
889
  fs.mkdirSync(path.dirname(reportPath), { recursive: true });
723
890
  fs.writeFileSync(
724
891
  reportPath,
@@ -726,10 +893,8 @@ const writeReport = () => {
726
893
  {
727
894
  schemaVersion: 3,
728
895
  runtime: "workerd",
729
- routes: [...new Set(proofs.map((proof) => proof.route))],
730
- executions,
731
- apiProofs,
732
- proofs,
896
+ routes: [...new Set(report.proofs.map((proof) => proof.route))],
897
+ ...report,
733
898
  },
734
899
  null,
735
900
  2,
@@ -737,42 +902,39 @@ const writeReport = () => {
737
902
  );
738
903
  };
739
904
 
740
- for (const shell of shells) {
741
- const expectedRemotes = shell.verticalRefs.map((ref) => {
742
- const remote = apps.find((app) => app.id === ref);
743
- assert(remote, `${shell.id} references missing MicroVertical ${ref}`);
744
- return remote;
745
- });
746
- const headlessApiVerticals = apps.filter((app) => app.kind === "vertical" && app.apiOnly);
747
- assert(
748
- expectedRemotes.length > 0 || headlessApiVerticals.length > 0,
749
- `${shell.id} has no UI MicroVerticals or headless APIs to prove`,
905
+ const main = async () => {
906
+ const workspaceRoot = path.resolve(process.env.ULTRAMODERN_WORKSPACE_ROOT ?? process.cwd());
907
+ const reportPath = path.join(workspaceRoot, reportRelativePath);
908
+ const keepWorkerd = process.env.ULTRAMODERN_KEEP_WORKERD === "1";
909
+ const apps = loadApps(
910
+ workspaceRoot,
911
+ readJson(path.join(workspaceRoot, "topology/reference-topology.json")),
912
+ readJson(path.join(workspaceRoot, "topology/local-overlays/development.json")),
750
913
  );
914
+ const shells = apps.filter((app) => app.kind === "shell");
915
+ assert(!keepWorkerd || shells.length === 1, "Browser workerd proof requires exactly one shell");
751
916
 
752
- const apiBindingRequests = [];
917
+ const recorders = {
918
+ apiBindingRequests: [],
919
+ fragmentBindingRequests: [],
920
+ outboundRequests: [],
921
+ };
753
922
  const failedServices = new Set();
754
- const fragmentBindingRequests = [];
755
- const outboundRequests = [];
923
+ const composition = {};
756
924
  const workerConfigurations = apps.map((app) =>
757
- createWorkerOptions(app, {
758
- serviceBindings: createServiceBindings(app, {
759
- apiBindingRequests,
760
- failedServices,
761
- fragmentBindingRequests,
762
- }),
925
+ createWorkerOptions(app, workspaceRoot, {
926
+ serviceBindings: createServiceBindings(app, { ...recorders, composition, failedServices }),
763
927
  async outboundService(request) {
764
928
  const requestUrl = new URL(request.url);
765
- outboundRequests.push({ callerId: app.id, url: requestUrl.href });
929
+ recorders.outboundRequests.push({ callerId: app.id, url: requestUrl.href });
766
930
  return new Response("External network disabled by SSR proof", {
767
931
  status: 502,
768
932
  });
769
933
  },
770
934
  }),
771
935
  );
772
- executions = workerConfigurations.map((configuration) => configuration.executionEvidence);
773
- const executionByAppId = new Map(
774
- apps.map((app, index) => [app.id, executions[index]]),
775
- );
936
+ const executions = workerConfigurations.map((configuration) => configuration.executionEvidence);
937
+ const executionByAppId = new Map(apps.map((app, index) => [app.id, executions[index]]));
776
938
  const workers = workerConfigurations.map(
777
939
  ({ executionEvidence: _executionEvidence, ...configuration }) => configuration,
778
940
  );
@@ -782,113 +944,83 @@ for (const shell of shells) {
782
944
  workers,
783
945
  }),
784
946
  );
785
- const renderedRemoteIds = new Set();
947
+ composition.miniflare = miniflare;
948
+ const report = { executions, apiProofs: [], proofs: [], verticalProofs: [] };
786
949
 
787
950
  try {
788
- for (const route of shell.proofRoutes) {
789
- const apiBindingRequestStart = apiBindingRequests.length;
790
- const fragmentBindingRequestStart = fragmentBindingRequests.length;
791
- const outboundRequestStart = outboundRequests.length;
792
- const response = await miniflare.dispatchFetch(
793
- `https://${workerName(shell)}.invalid${route}`,
794
- { headers: { accept: "text/html" } },
795
- );
796
- const html = await response.text();
797
- assert(
798
- response.status === 200,
799
- `${shell.id} returned HTTP ${response.status} for ${route} in workerd`,
800
- );
801
- assert(
802
- !html.includes('data-modern-distributed-ssr-status="degraded"'),
803
- `${shell.id} rendered a degraded MicroVertical fallback for ${route} in workerd`,
804
- );
805
-
806
- const boundaries = collectDistributedBoundaries(html);
807
- assert(
808
- expectedRemotes.length > 0 ? boundaries.length > 0 : boundaries.length === 0,
809
- expectedRemotes.length > 0
810
- ? `${shell.id} rendered no distributed SSR boundaries for ${route}`
811
- : `${shell.id} rendered unexpected distributed SSR boundaries for ${route}`,
812
- );
813
- const routeApiBindingRequests = apiBindingRequests.slice(
814
- apiBindingRequestStart,
815
- );
816
- const routeFragmentBindingRequests = fragmentBindingRequests.slice(
817
- fragmentBindingRequestStart,
818
- );
819
- const routeOutboundRequests = outboundRequests.slice(outboundRequestStart);
820
- for (const boundary of boundaries) {
821
- renderedRemoteIds.add(boundary.remote);
822
- assert(
823
- boundary.status === "ready",
824
- `${shell.id} did not mark ${boundary.key} as ready for ${route}`,
825
- );
826
- assert(
827
- typeof boundary.buildMarker === "string" && boundary.buildMarker.length > 0,
828
- `${shell.id} ${boundary.key} is missing immutable build provenance`,
951
+ for (const shell of shells) {
952
+ // Shell routes compose declared server-rendered boundaries through the
953
+ // shell's entry Worker exactly as a browser request would.
954
+ const renderedRemoteIds = new Set();
955
+ for (const route of shell.ssrRoutes) {
956
+ const proof = await proveRoute(
957
+ shell,
958
+ route,
959
+ (url, init) => miniflare.dispatchFetch(url, init),
960
+ apps,
961
+ recorders,
829
962
  );
830
963
  assert(
831
- /^[a-f\d]{64}$/u.test(boundary.digest ?? ""),
832
- `${shell.id} ${boundary.key} is missing a verified SHA-256 digest`,
964
+ shell.serverRenderedRoutes.length > 0 || proof.boundaries.length === 0,
965
+ `${shell.id} declares client composition but rendered distributed SSR boundaries for ${route}`,
833
966
  );
834
- const remote = apps.find((app) => app.id === boundary.remote);
835
- assert(remote, `${shell.id} rendered unknown remote ${boundary.remote}`);
836
- const requests = routeFragmentBindingRequests.filter(
837
- (request) =>
838
- request.service === workerName(remote) &&
839
- request.remote === boundary.remote &&
840
- request.expose === boundary.expose,
841
- );
842
- const renderedCount = boundaries.filter(
843
- (candidate) => candidate.key === boundary.key,
844
- ).length;
967
+ if (shell.serverRenderedRoutes.includes(route)) {
968
+ assert(
969
+ shell.serverRenderedRemoteIds.length === 0 || proof.boundaries.length > 0,
970
+ `${shell.id} rendered no distributed SSR boundaries for ${route}`,
971
+ );
972
+ for (const boundary of proof.boundaries) {
973
+ renderedRemoteIds.add(boundary.remote);
974
+ }
975
+ }
976
+ report.proofs.push({ shellId: shell.id, ...proof });
977
+ }
978
+ for (const remoteId of shell.serverRenderedRemoteIds) {
845
979
  assert(
846
- requests.length === renderedCount &&
847
- requests.every((request) => request.pathname.includes("/_mf/fragment/")),
848
- `${shell.id} must compose each ${boundary.key} occurrence through its remote service binding`,
980
+ renderedRemoteIds.has(remoteId),
981
+ `${shell.id} proof routes are missing independently rendered ${remoteId} content`,
849
982
  );
850
983
  }
851
-
852
- const stylesheetHrefs = collectStylesheetHrefs(html);
853
- assert(
854
- new Set(stylesheetHrefs).size === stylesheetHrefs.length,
855
- `${shell.id} rendered duplicate distributed SSR stylesheets for ${route}`,
984
+ report.apiProofs.push(
985
+ ...(await runApiProofs(apps, miniflare, shell, executionByAppId)),
856
986
  );
857
- assert(
858
- !routeOutboundRequests.some(({ url }) => /(?:remoteEntry|\.m?js(?:\?|$))/u.test(url)),
859
- `${shell.id} attempted to fetch remote JavaScript during ${route} server composition`,
860
- );
861
-
862
- proofs.push({
863
- shellId: shell.id,
864
- worker: workerName(shell),
865
- route,
866
- status: response.status,
867
- boundaries,
868
- fragmentBindingRequests: routeFragmentBindingRequests,
869
- apiBindingRequests: routeApiBindingRequests,
870
- outboundRequests: routeOutboundRequests,
871
- stylesheetHrefs,
872
- degradedBoundaryCount: count(html, 'data-modern-distributed-ssr-status="degraded"'),
873
- });
874
987
  }
875
988
 
876
- for (const remote of expectedRemotes) {
877
- assert(
878
- renderedRemoteIds.has(remote.id),
879
- `${shell.id} proof routes are missing independently rendered ${remote.id} content`,
880
- );
989
+ // Every UI MicroVertical proves its own Worker at its declared SSR routes,
990
+ // whether or not a shell also composes it on the server.
991
+ for (const [index, vertical] of apps.entries()) {
992
+ if (vertical.kind !== "vertical" || vertical.ssrRoutes.length === 0) {
993
+ continue;
994
+ }
995
+ const runtime = createIsolatedRuntime(workers[index]);
996
+ try {
997
+ for (const route of vertical.ssrRoutes) {
998
+ report.verticalProofs.push({
999
+ appId: vertical.id,
1000
+ ...(await proveRoute(
1001
+ vertical,
1002
+ route,
1003
+ (url, init) => runtime.dispatchFetch(url, init),
1004
+ apps,
1005
+ recorders,
1006
+ )),
1007
+ });
1008
+ }
1009
+ } finally {
1010
+ await runtime.dispose();
1011
+ }
881
1012
  }
882
- apiProofs.push(...(await runApiProofs(miniflare, shell, executionByAppId)));
883
- if (process.env.ULTRAMODERN_KEEP_WORKERD === "1") {
884
- writeReport();
1013
+
1014
+ writeReport(reportPath, report);
1015
+ if (keepWorkerd) {
885
1016
  const targetServers = await startWorkerdTargetServers(
1017
+ apps,
886
1018
  miniflare,
887
1019
  failedServices,
888
1020
  workers,
889
1021
  );
890
1022
  console.log(`WORKERD_TARGET_URLS=${JSON.stringify(targetServers.targetUrls)}`);
891
- console.log(`WORKERD_URL=${targetServers.targetUrls[shell.id]}`);
1023
+ console.log(`WORKERD_URL=${targetServers.targetUrls[shells[0].id]}`);
892
1024
  try {
893
1025
  await new Promise((resolve) => {
894
1026
  process.once("SIGINT", resolve);
@@ -901,7 +1033,10 @@ for (const shell of shells) {
901
1033
  } finally {
902
1034
  await miniflare.dispose();
903
1035
  }
904
- }
905
1036
 
906
- writeReport();
907
- console.log(`Workerd SSR composition proof passed for ${shells.length} shell(s): ${reportPath}`);
1037
+ console.log(`Workerd SSR composition proof passed for ${shells.length} shell(s): ${reportPath}`);
1038
+ };
1039
+
1040
+ if (import.meta.main) {
1041
+ await main();
1042
+ }