@bleedingdev/modern-js-create 3.4.0-ultramodern.8 → 3.5.0-ultramodern.0

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.
Files changed (135) hide show
  1. package/README.md +25 -23
  2. package/dist/cjs/index.cjs +37 -4
  3. package/dist/cjs/locale/en.cjs +12 -2
  4. package/dist/cjs/locale/zh.cjs +12 -2
  5. package/dist/cjs/ultramodern-tooling/commands.cjs +185 -0
  6. package/dist/cjs/ultramodern-tooling/config.cjs +172 -0
  7. package/dist/cjs/ultramodern-workspace/add-vertical.cjs +87 -75
  8. package/dist/cjs/ultramodern-workspace/{effect-api.cjs → api.cjs} +207 -208
  9. package/dist/cjs/ultramodern-workspace/bridge-config.cjs +327 -0
  10. package/dist/cjs/ultramodern-workspace/codesmith.cjs +1 -0
  11. package/dist/cjs/ultramodern-workspace/contracts.cjs +127 -657
  12. package/dist/cjs/ultramodern-workspace/demo-components.cjs +12 -12
  13. package/dist/cjs/ultramodern-workspace/descriptors.cjs +25 -25
  14. package/dist/cjs/ultramodern-workspace/fs-io.cjs +117 -0
  15. package/dist/cjs/ultramodern-workspace/generation-result.cjs +5 -5
  16. package/dist/cjs/ultramodern-workspace/index.cjs +4 -0
  17. package/dist/cjs/ultramodern-workspace/mf-validation.cjs +571 -0
  18. package/dist/cjs/ultramodern-workspace/module-federation.cjs +33 -18
  19. package/dist/cjs/ultramodern-workspace/overlays.cjs +2 -2
  20. package/dist/cjs/ultramodern-workspace/package-json.cjs +57 -41
  21. package/dist/cjs/ultramodern-workspace/policy.cjs +4 -4
  22. package/dist/cjs/ultramodern-workspace/public-api.cjs +4 -0
  23. package/dist/cjs/ultramodern-workspace/public-surface.cjs +2 -2
  24. package/dist/cjs/ultramodern-workspace/versions.cjs +5 -0
  25. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +119 -50
  26. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +62 -21
  27. package/dist/esm/index.js +37 -4
  28. package/dist/esm/locale/en.js +12 -2
  29. package/dist/esm/locale/zh.js +12 -2
  30. package/dist/esm/ultramodern-tooling/commands.js +132 -0
  31. package/dist/esm/ultramodern-tooling/config.js +120 -0
  32. package/dist/esm/ultramodern-workspace/add-vertical.js +88 -79
  33. package/dist/esm/ultramodern-workspace/{effect-api.js → api.js} +146 -147
  34. package/dist/esm/ultramodern-workspace/bridge-config.js +270 -0
  35. package/dist/esm/ultramodern-workspace/codesmith.js +1 -0
  36. package/dist/esm/ultramodern-workspace/contracts.js +129 -611
  37. package/dist/esm/ultramodern-workspace/demo-components.js +13 -13
  38. package/dist/esm/ultramodern-workspace/descriptors.js +11 -11
  39. package/dist/esm/ultramodern-workspace/fs-io.js +116 -2
  40. package/dist/esm/ultramodern-workspace/generation-result.js +6 -6
  41. package/dist/esm/ultramodern-workspace/index.js +1 -0
  42. package/dist/esm/ultramodern-workspace/mf-validation.js +516 -0
  43. package/dist/esm/ultramodern-workspace/module-federation.js +34 -19
  44. package/dist/esm/ultramodern-workspace/overlays.js +2 -2
  45. package/dist/esm/ultramodern-workspace/package-json.js +56 -40
  46. package/dist/esm/ultramodern-workspace/policy.js +5 -5
  47. package/dist/esm/ultramodern-workspace/public-api.js +1 -0
  48. package/dist/esm/ultramodern-workspace/public-surface.js +2 -2
  49. package/dist/esm/ultramodern-workspace/versions.js +3 -1
  50. package/dist/esm/ultramodern-workspace/workspace-scripts.js +107 -34
  51. package/dist/esm/ultramodern-workspace/write-workspace.js +64 -26
  52. package/dist/esm-node/index.js +37 -4
  53. package/dist/esm-node/locale/en.js +12 -2
  54. package/dist/esm-node/locale/zh.js +12 -2
  55. package/dist/esm-node/ultramodern-tooling/commands.js +133 -0
  56. package/dist/esm-node/ultramodern-tooling/config.js +121 -0
  57. package/dist/esm-node/ultramodern-workspace/add-vertical.js +88 -79
  58. package/dist/esm-node/ultramodern-workspace/{effect-api.js → api.js} +146 -147
  59. package/dist/esm-node/ultramodern-workspace/bridge-config.js +271 -0
  60. package/dist/esm-node/ultramodern-workspace/codesmith.js +1 -0
  61. package/dist/esm-node/ultramodern-workspace/contracts.js +129 -611
  62. package/dist/esm-node/ultramodern-workspace/demo-components.js +13 -13
  63. package/dist/esm-node/ultramodern-workspace/descriptors.js +11 -11
  64. package/dist/esm-node/ultramodern-workspace/fs-io.js +116 -2
  65. package/dist/esm-node/ultramodern-workspace/generation-result.js +6 -6
  66. package/dist/esm-node/ultramodern-workspace/index.js +1 -0
  67. package/dist/esm-node/ultramodern-workspace/mf-validation.js +517 -0
  68. package/dist/esm-node/ultramodern-workspace/module-federation.js +34 -19
  69. package/dist/esm-node/ultramodern-workspace/overlays.js +2 -2
  70. package/dist/esm-node/ultramodern-workspace/package-json.js +56 -40
  71. package/dist/esm-node/ultramodern-workspace/policy.js +5 -5
  72. package/dist/esm-node/ultramodern-workspace/public-api.js +1 -0
  73. package/dist/esm-node/ultramodern-workspace/public-surface.js +2 -2
  74. package/dist/esm-node/ultramodern-workspace/versions.js +3 -1
  75. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +107 -34
  76. package/dist/esm-node/ultramodern-workspace/write-workspace.js +64 -26
  77. package/dist/types/locale/en.d.ts +10 -0
  78. package/dist/types/locale/index.d.ts +20 -0
  79. package/dist/types/locale/zh.d.ts +10 -0
  80. package/dist/types/ultramodern-tooling/commands.d.ts +1 -0
  81. package/dist/types/ultramodern-tooling/config.d.ts +43 -0
  82. package/dist/types/ultramodern-workspace/add-vertical.d.ts +5 -2
  83. package/dist/types/ultramodern-workspace/api.d.ts +73 -0
  84. package/dist/types/ultramodern-workspace/bridge-config.d.ts +64 -0
  85. package/dist/types/ultramodern-workspace/codesmith.d.ts +1 -0
  86. package/dist/types/ultramodern-workspace/contracts.d.ts +2 -17
  87. package/dist/types/ultramodern-workspace/descriptors.d.ts +10 -10
  88. package/dist/types/ultramodern-workspace/fs-io.d.ts +1 -0
  89. package/dist/types/ultramodern-workspace/index.d.ts +2 -0
  90. package/dist/types/ultramodern-workspace/mf-validation.d.ts +27 -0
  91. package/dist/types/ultramodern-workspace/package-json.d.ts +5 -4
  92. package/dist/types/ultramodern-workspace/public-api.d.ts +2 -0
  93. package/dist/types/ultramodern-workspace/types.d.ts +9 -7
  94. package/dist/types/ultramodern-workspace/versions.d.ts +2 -0
  95. package/dist/types/ultramodern-workspace/workspace-scripts.d.ts +2 -7
  96. package/dist/types/ultramodern-workspace/write-workspace.d.ts +4 -2
  97. package/package.json +5 -3
  98. package/template-workspace/{.agents → .codex}/skills-lock.json +12 -12
  99. package/template-workspace/.github/workflows/ultramodern-workspace-gates.yml.handlebars +2 -0
  100. package/template-workspace/.gitignore.handlebars +3 -0
  101. package/template-workspace/AGENTS.md.handlebars +11 -5
  102. package/template-workspace/README.md.handlebars +15 -12
  103. package/template-workspace/oxfmt.config.ts +1 -0
  104. package/template-workspace/oxlint.config.ts +1 -0
  105. package/template-workspace/patches/@tanstack__router-core@1.171.13.patch +51 -0
  106. package/template-workspace/pnpm-workspace.yaml.handlebars +4 -0
  107. package/template-workspace/scripts/bootstrap-agent-skills.mjs +77 -67
  108. package/templates/workspace-scripts/assert-mf-types.mjs.handlebars +51 -8
  109. package/templates/workspace-scripts/check-ultramodern-api-boundaries.mts +344 -0
  110. package/templates/workspace-scripts/{check-ultramodern-i18n-boundaries.mjs → check-ultramodern-i18n-boundaries.mts} +1 -1
  111. package/templates/workspace-scripts/generate-public-surface-assets.mjs +246 -9
  112. package/templates/workspace-scripts/proof-cloudflare-version.mjs +277 -9
  113. package/templates/workspace-scripts/ultramodern-cloudflare-proof.mjs +35 -10
  114. package/templates/workspace-scripts/ultramodern-performance-readiness.mjs +165 -2
  115. package/templates/workspace-scripts/ultramodern-typecheck.mjs +4 -2
  116. package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +840 -84
  117. package/dist/types/ultramodern-workspace/effect-api.d.ts +0 -73
  118. /package/template-workspace/{.agents → .codex}/rstackjs-agent-skills-LICENSE +0 -0
  119. /package/template-workspace/{.agents → .codex}/skills/rsbuild-best-practices/SKILL.md +0 -0
  120. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/SKILL.md +0 -0
  121. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/command-map.md +0 -0
  122. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/common-analysis-patterns.md +0 -0
  123. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +0 -0
  124. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +0 -0
  125. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +0 -0
  126. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/install-rsdoctor.md +0 -0
  127. /package/template-workspace/{.agents → .codex}/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +0 -0
  128. /package/template-workspace/{.agents → .codex}/skills/rslib-best-practices/SKILL.md +0 -0
  129. /package/template-workspace/{.agents → .codex}/skills/rslib-modern-package/SKILL.md +0 -0
  130. /package/template-workspace/{.agents → .codex}/skills/rspack-best-practices/SKILL.md +0 -0
  131. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/SKILL.md +0 -0
  132. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/references/bottlenecks.md +0 -0
  133. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/references/tracing-guide.md +0 -0
  134. /package/template-workspace/{.agents → .codex}/skills/rspack-tracing/scripts/analyze_trace.js +0 -0
  135. /package/template-workspace/{.agents → .codex}/skills/rstest-best-practices/SKILL.md +0 -0
@@ -1,4 +1,5 @@
1
1
  import { execFileSync } from 'node:child_process';
2
+ import crypto from 'node:crypto';
2
3
  import fs from 'node:fs';
3
4
  import path from 'node:path';
4
5
 
@@ -14,6 +15,21 @@ const expectedCloudflareBuildScript = {{expectedCloudflareBuildScriptJson}};
14
15
  const expectedCloudflareDeployScript = {{expectedCloudflareDeployScriptJson}};
15
16
  const expectedCloudflareSecurity = {{expectedCloudflareSecurityJson}};
16
17
  const publicSurfaceManagedSourceAssetPaths = {{publicSurfaceManagedSourceAssetPathsJson}};
18
+ const compactConfigPath = '.modernjs/ultramodern.json';
19
+ const retiredMetadataPaths = [
20
+ '.modernjs/ultramodern-generated-contract.json',
21
+ '.modernjs/ultramodern-package-source.json',
22
+ '.modernjs/ultramodern-workspace-template-manifest.json',
23
+ ];
24
+ const modernPackageCohort = [
25
+ '@modern-js/create',
26
+ '@modern-js/code-tools',
27
+ '@modern-js/app-tools',
28
+ '@modern-js/plugin-bff',
29
+ '@modern-js/plugin-i18n',
30
+ '@modern-js/plugin-tanstack',
31
+ '@modern-js/runtime',
32
+ ];
17
33
  const expectedModernPackageSpecifier = packageName => {
18
34
  if (packageSource.strategy === 'workspace') {
19
35
  return 'workspace:*';
@@ -70,6 +86,688 @@ const assertArray = (value, contract, fixArea) => {
70
86
  };
71
87
  const findById = (entries, id) =>
72
88
  Array.isArray(entries) ? entries.find(entry => entry?.id === id) : undefined;
89
+ const generatedContractLabel = compactConfigPath;
90
+ const toKebabCase = value =>
91
+ String(value)
92
+ .trim()
93
+ .replace(/([a-z0-9])([A-Z])/gu, '$1-$2')
94
+ .replace(/[^a-zA-Z0-9._-]+/gu, '-')
95
+ .replace(/[._]+/gu, '-')
96
+ .toLowerCase()
97
+ .replace(/-+/gu, '-')
98
+ .replace(/^-+|-+$/gu, '');
99
+ const toPascalCase = value =>
100
+ toKebabCase(value)
101
+ .split('-')
102
+ .filter(Boolean)
103
+ .map(part => part.charAt(0).toUpperCase() + part.slice(1))
104
+ .join('');
105
+ const toCamelCase = value => {
106
+ const pascal = toPascalCase(value);
107
+ return `${pascal.charAt(0).toLowerCase()}${pascal.slice(1)}`;
108
+ };
109
+ const toEnvSegment = value => toKebabCase(value).replace(/-/gu, '_').toUpperCase();
110
+ const packageNameFor = (scope, suffix) => `@${scope}/${suffix}`;
111
+ const normalizeRelativePath = value =>
112
+ String(value ?? '').replace(/\\/gu, '/').replace(/^\.\/+/u, '');
113
+ const appNamespace = app => (app.kind === 'shell' ? 'shell' : (app.domain ?? app.id));
114
+ const tailwindPrefixDigitWords = [
115
+ 'zero',
116
+ 'one',
117
+ 'two',
118
+ 'three',
119
+ 'four',
120
+ 'five',
121
+ 'six',
122
+ 'seven',
123
+ 'eight',
124
+ 'nine',
125
+ ];
126
+ const tailwindPrefixFor = app =>
127
+ app.kind === 'shell'
128
+ ? 'shell'
129
+ : String(app.domain ?? app.id)
130
+ .toLowerCase()
131
+ .replace(/[^a-z0-9]/gu, '')
132
+ .replace(/[0-9]/gu, digit => tailwindPrefixDigitWords[Number(digit)]);
133
+ const buildMarkerFor = app =>
134
+ crypto
135
+ .createHash('sha256')
136
+ .update(`${packageScope}:${app.packageSuffix}:${app.id}:0.1.0`)
137
+ .digest('hex')
138
+ .slice(0, 16);
139
+ const normalizeCompactApp = rawApp => {
140
+ const id = String(rawApp.id);
141
+ const kind = rawApp.kind === 'vertical' ? 'vertical' : 'shell';
142
+ const appPath =
143
+ typeof rawApp.path === 'string'
144
+ ? normalizeRelativePath(rawApp.path)
145
+ : kind === 'shell'
146
+ ? 'apps/shell-super-app'
147
+ : `verticals/${toKebabCase(id)}`;
148
+ const packageSuffix =
149
+ typeof rawApp.packageSuffix === 'string'
150
+ ? rawApp.packageSuffix
151
+ : appPath.split('/').at(-1) ?? id;
152
+ const domain =
153
+ typeof rawApp.domain === 'string'
154
+ ? rawApp.domain
155
+ : kind === 'vertical'
156
+ ? packageSuffix
157
+ : undefined;
158
+ const moduleFederation =
159
+ rawApp.moduleFederation && typeof rawApp.moduleFederation === 'object'
160
+ ? rawApp.moduleFederation
161
+ : {};
162
+ const api =
163
+ rawApp.api && typeof rawApp.api === 'object'
164
+ ? {
165
+ stem:
166
+ typeof rawApp.api.stem === 'string'
167
+ ? rawApp.api.stem
168
+ : domain ?? id,
169
+ prefix:
170
+ typeof rawApp.api.prefix === 'string'
171
+ ? rawApp.api.prefix
172
+ : `/${domain ?? id}-api`,
173
+ consumedBy: Array.isArray(rawApp.api.consumedBy)
174
+ ? rawApp.api.consumedBy.filter(
175
+ consumer => typeof consumer === 'string',
176
+ )
177
+ : ['shell-super-app', id],
178
+ }
179
+ : undefined;
180
+
181
+ return {
182
+ id,
183
+ kind,
184
+ path: appPath,
185
+ package: typeof rawApp.package === 'string' ? rawApp.package : undefined,
186
+ packageSuffix,
187
+ domain,
188
+ port:
189
+ typeof rawApp.port === 'number'
190
+ ? rawApp.port
191
+ : kind === 'shell'
192
+ ? 3020
193
+ : 3030,
194
+ portEnv:
195
+ typeof rawApp.portEnv === 'string'
196
+ ? rawApp.portEnv
197
+ : kind === 'shell'
198
+ ? 'SHELL_SUPER_APP_PORT'
199
+ : `VERTICAL_${toEnvSegment(domain ?? id)}_PORT`,
200
+ mfName:
201
+ typeof moduleFederation.name === 'string'
202
+ ? moduleFederation.name
203
+ : kind === 'shell'
204
+ ? 'shellSuperApp'
205
+ : `vertical${toPascalCase(domain ?? id)}`,
206
+ exposes: Array.isArray(moduleFederation.exposes)
207
+ ? moduleFederation.exposes.filter(expose => typeof expose === 'string')
208
+ : [],
209
+ moduleFederationSsr: moduleFederation.ssr !== false,
210
+ verticalRefs: Array.isArray(moduleFederation.verticalRefs)
211
+ ? moduleFederation.verticalRefs.filter(ref => typeof ref === 'string')
212
+ : [],
213
+ api,
214
+ };
215
+ };
216
+ const compactAppsFromConfig = config =>
217
+ Array.isArray(config.topology?.apps)
218
+ ? config.topology.apps.map(normalizeCompactApp)
219
+ : [];
220
+ const remoteDependencyAliasFor = app => toCamelCase(app.domain ?? app.id.replace(/^remote-/u, ''));
221
+ const remoteContractsFor = (app, apps) =>
222
+ (app.verticalRefs ?? [])
223
+ .map(ref => apps.find(candidate => candidate.id === ref))
224
+ .filter(Boolean)
225
+ .map(remote => ({
226
+ id: remote.id,
227
+ alias: remoteDependencyAliasFor(remote),
228
+ name: remote.mfName,
229
+ manifestEnv: `VERTICAL_${toEnvSegment(remote.domain ?? remote.id)}_MF_MANIFEST`,
230
+ manifestUrl: `http://localhost:${remote.port}/mf-manifest.json`,
231
+ }));
232
+ const createRouteOwnedEntries = app => {
233
+ const namespace = appNamespace(app);
234
+ const base = {
235
+ descriptionKey: `${namespace}.seo.description`,
236
+ mfBoundaryId: app.mfName,
237
+ namespace,
238
+ ownerAppId: app.id,
239
+ public: false,
240
+ indexable: false,
241
+ publicSurface: 'private-app-screen',
242
+ };
243
+
244
+ return [
245
+ {
246
+ ...base,
247
+ canonicalPath: '/',
248
+ id: app.kind === 'shell' ? 'shell-home' : `${app.id}-home`,
249
+ localisedPaths: {
250
+ cs: '/',
251
+ en: '/',
252
+ },
253
+ titleKey: app.kind === 'shell' ? 'shell.title' : `${namespace}.title`,
254
+ },
255
+ ];
256
+ };
257
+ const createPublicRoutes = app =>
258
+ createRouteOwnedEntries(app)
259
+ .filter(route => route.public && route.indexable)
260
+ .map(route => ({
261
+ canonicalPath: route.canonicalPath,
262
+ id: route.id,
263
+ localisedPaths: route.localisedPaths,
264
+ namespace: route.namespace,
265
+ ownerAppId: route.ownerAppId,
266
+ descriptionKey: route.descriptionKey,
267
+ titleKey: route.titleKey,
268
+ }));
269
+ const createLocalisedUrls = app =>
270
+ Object.fromEntries(
271
+ createRouteOwnedEntries(app).flatMap(route => {
272
+ if (route.canonicalPath === '/') {
273
+ return [];
274
+ }
275
+ return Array.from(
276
+ new Set([route.canonicalPath, ...Object.values(route.localisedPaths)]),
277
+ ).map(pathname => [pathname, route.localisedPaths]);
278
+ }),
279
+ );
280
+ const createPublicSurface = app => {
281
+ const publicRoutes = createPublicRoutes(app);
282
+ return {
283
+ authoring: 'colocated-route-meta',
284
+ artifactLifecycle: 'build-and-deploy-output',
285
+ generatedManifest: './src/routes/ultramodern-route-metadata',
286
+ source: 'route-owned-public-routes',
287
+ metadataExport: './src/routes/ultramodern-route-metadata',
288
+ generator: 'scripts/generate-public-surface-assets.mts',
289
+ outputRoot: 'dist/public',
290
+ cloudflareOutputRoot: '.output/public',
291
+ privateRoutePolicy: 'omit-from-generated-public-surface',
292
+ files:
293
+ publicRoutes.length > 0
294
+ ? ['robots.txt', 'sitemap.xml', 'site.webmanifest']
295
+ : ['robots.txt'],
296
+ omittedByDefault: ['api-catalog.json', 'llms.txt', 'security.txt'],
297
+ languages: ['en', 'cs'],
298
+ contentExpansion: {
299
+ authoring: 'route-owned-esm-provider',
300
+ defaultProviderFile: 'route.sitemap.mjs',
301
+ entryExport: 'default-or-entries',
302
+ paramsSource: 'params-or-localeParams',
303
+ draftPolicy: 'omit-draft-by-default',
304
+ indexablePolicy: 'omit-indexable-false',
305
+ lifecycle: 'executed-during-public-surface-generation',
306
+ },
307
+ contentSources: [],
308
+ publicRoutes,
309
+ routeEntries: [],
310
+ concreteUrlPaths: [],
311
+ };
312
+ };
313
+ const createPublicHead = () => ({
314
+ authoring: 'colocated-route-meta',
315
+ generator: './src/routes/ultramodern-route-head',
316
+ renderer: '@modern-js/runtime/head Helmet',
317
+ ssr: true,
318
+ title: {
319
+ required: true,
320
+ source: 'route.titleKey',
321
+ },
322
+ description: {
323
+ required: true,
324
+ source: 'route.descriptionKey',
325
+ },
326
+ canonical: {
327
+ publicIndexableOnly: true,
328
+ source: 'localized canonical route URL',
329
+ },
330
+ alternates: {
331
+ hreflang: ['en', 'cs'],
332
+ xDefault: 'en',
333
+ },
334
+ openGraph: {
335
+ publicIndexableOnly: true,
336
+ required: ['og:title', 'og:description', 'og:url', 'og:type'],
337
+ },
338
+ twitter: {
339
+ publicIndexableOnly: true,
340
+ required: ['twitter:card', 'twitter:title', 'twitter:description'],
341
+ },
342
+ structuredData: {
343
+ publicIndexableOnly: true,
344
+ optional: true,
345
+ source: 'route.jsonLd',
346
+ inference: false,
347
+ helperModule: './src/routes/ultramodern-jsonld',
348
+ helperTypes: [
349
+ 'WebPage',
350
+ 'WebApplication',
351
+ 'SoftwareApplication',
352
+ 'BreadcrumbList',
353
+ 'FAQPage',
354
+ 'Organization',
355
+ ],
356
+ sanitizesHtmlOpenBracket: true,
357
+ },
358
+ privateRouteRobots: 'noindex, nofollow',
359
+ });
360
+ const createQualityGates = () => ({
361
+ publicRoutes: {
362
+ requireSitemapWhenPresent: true,
363
+ requireRobotsSitemapConsistency: true,
364
+ requireWebManifestWhenPresent: true,
365
+ },
366
+ statusCodes: {
367
+ notFoundRoute: '/__ultramodern-smoke-missing/nope',
368
+ unknownRouteStatus: 404,
369
+ },
370
+ indexing: {
371
+ previewNoindex: true,
372
+ productionPublicRoutesIndexable: true,
373
+ },
374
+ assets: {
375
+ cssPreloadRequired: true,
376
+ cssResponseRequired: true,
377
+ cacheControlRequiredForCss: true,
378
+ sourcemapsPubliclyReferenced: false,
379
+ },
380
+ budgets: {
381
+ ssrHtmlMaxBytes: 250_000,
382
+ mfManifestMaxBytes: 500_000,
383
+ localeJsonMaxBytes: 100_000,
384
+ sitemapXmlMaxBytes: 500_000,
385
+ cssAssetMaxBytes: 750_000,
386
+ },
387
+ csp: {
388
+ finalMode: 'report-only-dogfood',
389
+ decision:
390
+ 'Report-only remains the generated final mode until public smoke proof records MF SSR script/style/connect compatibility for the deployed surface.',
391
+ },
392
+ });
393
+ const createCloudflareRoutes = app => ({
394
+ ssr: '/en',
395
+ mfManifest: '/mf-manifest.json',
396
+ locale: `/locales/en/${appNamespace(app)}.json`,
397
+ ...(app.api
398
+ ? {
399
+ apiReadiness: `${app.api.prefix}/${app.api.stem}/readiness`,
400
+ }
401
+ : {}),
402
+ });
403
+ const createCloudflareDeploy = app => ({
404
+ target: 'cloudflare',
405
+ workerName: expectedWorkerName(app.packageSuffix),
406
+ publicUrlEnv: `ULTRAMODERN_PUBLIC_URL_${toEnvSegment(app.id)}`,
407
+ compatibilityDate: '{{cloudflareCompatibilityDate}}',
408
+ compatibilityFlags: ['nodejs_compat', 'global_fetch_strictly_public'],
409
+ assetsBinding: 'ASSETS',
410
+ routes: createCloudflareRoutes(app),
411
+ security: expectedCloudflareSecurity,
412
+ qualityGates: createQualityGates(),
413
+ evidence: {
414
+ proofScript: 'scripts/proof-cloudflare-version.mts',
415
+ reportDefault:
416
+ '.codex/reports/cloudflare-version-proof/public-url-proof.json',
417
+ },
418
+ });
419
+ const createEffectReadiness = app => ({
420
+ endpoint: `/${app.api.stem}/readiness`,
421
+ marker: {
422
+ ui: 'ultramodernUiMarker',
423
+ api: 'ultramodernApiMarker',
424
+ skew: 'none',
425
+ },
426
+ checks: ['moduleFederation', 'ssr', 'translations', 'api'],
427
+ });
428
+ const createEffectRequestContext = () => ({
429
+ propagatedHeaders: [
430
+ 'accept-language',
431
+ 'authorization',
432
+ 'traceparent',
433
+ 'x-correlation-id',
434
+ 'x-tenant-id',
435
+ 'x-ultramodern-env',
436
+ 'x-vertical-version-id',
437
+ ],
438
+ source: 'shell-to-vertical-api-client',
439
+ });
440
+ const createEffectDomainOperations = app => {
441
+ const stem = app.api.stem;
442
+ const group = toCamelCase(stem);
443
+ const basePath = `/${stem}`;
444
+ return {
445
+ workspaceFeed: {
446
+ client: `list${toPascalCase(stem)}`,
447
+ method: 'GET',
448
+ path: basePath,
449
+ resource: 'workspace-items',
450
+ owner: app.id,
451
+ },
452
+ workspaceDetail: {
453
+ client: `get${toPascalCase(stem)}`,
454
+ method: 'GET',
455
+ path: `${basePath}/:id`,
456
+ resource: 'workspace-item',
457
+ owner: app.id,
458
+ },
459
+ workspaceCreate: {
460
+ client: `create${toPascalCase(stem)}`,
461
+ method: 'POST',
462
+ path: basePath,
463
+ resource: group,
464
+ owner: app.id,
465
+ },
466
+ };
467
+ };
468
+ const createEffectOperationContract = app => ({
469
+ group: toCamelCase(app.api.stem),
470
+ operations: {
471
+ readiness: {
472
+ method: 'GET',
473
+ path: `/${app.api.stem}/readiness`,
474
+ source: 'generated-client',
475
+ },
476
+ },
477
+ });
478
+ const createAppConfigContract = app => ({
479
+ preset: 'presetUltramodern',
480
+ plugins: [
481
+ 'appTools',
482
+ 'tanstackRouterPlugin',
483
+ 'i18nPlugin',
484
+ ...(app.api ? ['bffPlugin'] : []),
485
+ 'moduleFederationPlugin',
486
+ 'zephyrRspackPlugin',
487
+ ],
488
+ dev: {
489
+ assetPrefix: '/',
490
+ },
491
+ output: {
492
+ assetPrefix: {
493
+ envFallbackOrder: ['MODERN_ASSET_PREFIX', 'ULTRAMODERN_ASSET_PREFIX'],
494
+ default: app.kind === 'shell' ? '/' : 'app-public-origin',
495
+ },
496
+ disableTsChecker: false,
497
+ },
498
+ performance: {
499
+ readinessDiagnostics: {
500
+ default: 'enabled',
501
+ optOut: {
502
+ env: 'ULTRAMODERN_PERFORMANCE_READINESS_DIAGNOSTICS=false',
503
+ config: 'scripts/ultramodern-performance-readiness.config.mjs',
504
+ },
505
+ failOn: 'framework-invariant',
506
+ },
507
+ },
508
+ rspack: {
509
+ output: {
510
+ uniqueName: app.mfName,
511
+ chunkLoadingGlobal: expectedChunkLoadingGlobal(app.mfName),
512
+ },
513
+ },
514
+ source: {
515
+ siteUrl: {
516
+ envFallbackOrder: [
517
+ 'MODERN_PUBLIC_SITE_URL',
518
+ `ULTRAMODERN_PUBLIC_URL_${toEnvSegment(app.id)}`,
519
+ 'ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN',
520
+ app.portEnv,
521
+ ],
522
+ defaultLocalhostPort: app.port,
523
+ },
524
+ },
525
+ });
526
+ const cssDedupe = () => ({
527
+ strategy: 'shared-token-package-plus-css-content-hash',
528
+ sharedPackage: packageNameFor(packageScope, 'shared-design-tokens'),
529
+ sharedLayers: ['ultramodern-shared-tokens'],
530
+ runtimeLoad: 'once-per-content-hash',
531
+ duplicateBaseStylesAllowed: false,
532
+ });
533
+ const createStylingContract = app => {
534
+ const sharedTokenPackage = packageNameFor(packageScope, 'shared-design-tokens');
535
+ const ownedLayers =
536
+ app.kind === 'shell'
537
+ ? ['ultramodern-shell-base', 'ultramodern-shell-overlay']
538
+ : [`ultramodern-vertical-${app.domain ?? app.id}`];
539
+
540
+ return {
541
+ tailwind: tailwindEnabled,
542
+ federation: {
543
+ owner: {
544
+ id: app.id,
545
+ package: app.package ?? packageNameFor(packageScope, app.packageSuffix),
546
+ },
547
+ role: app.kind === 'shell' ? 'shell-base-overlay' : 'vertical-css',
548
+ rootSelector: `[data-app-id="${app.id}"]`,
549
+ classPrefix: `${tailwindPrefixFor(app)}:`,
550
+ layers: {
551
+ shared: ['ultramodern-shared-tokens'],
552
+ owned: ownedLayers,
553
+ },
554
+ entrypoints: {
555
+ layoutImport: 'src/routes/layout.tsx',
556
+ css: ['src/routes/index.css'],
557
+ ...(app.kind === 'shell'
558
+ ? {}
559
+ : { federationEntry: 'src/federation-entry.tsx' }),
560
+ },
561
+ assets: {
562
+ shared: [`${sharedTokenPackage}/tokens.css`],
563
+ owned: ['src/routes/index.css'],
564
+ },
565
+ dedupe: cssDedupe(),
566
+ ssr: {
567
+ cloudflare: true,
568
+ firstPaintRequired: true,
569
+ verticalCss:
570
+ app.kind === 'shell'
571
+ ? 'host-preloads-shell-and-shared-css'
572
+ : 'federated-manifest-owned-css',
573
+ },
574
+ },
575
+ };
576
+ };
577
+ const createAppContract = (app, apps) => ({
578
+ id: app.id,
579
+ package: app.package ?? packageNameFor(packageScope, app.packageSuffix),
580
+ path: app.path,
581
+ kind: app.kind,
582
+ config: createAppConfigContract(app),
583
+ styling: createStylingContract(app),
584
+ deploy: {
585
+ target: 'cloudflare',
586
+ cloudflare: createCloudflareDeploy(app),
587
+ worker: {
588
+ compatibilityDate: '{{cloudflareCompatibilityDate}}',
589
+ name: expectedWorkerName(app.packageSuffix),
590
+ security: expectedCloudflareSecurity,
591
+ ssr: true,
592
+ },
593
+ },
594
+ ssr: app.moduleFederationSsr
595
+ ? {
596
+ mode: 'string',
597
+ moduleFederationAppSSR: true,
598
+ }
599
+ : undefined,
600
+ i18n: {
601
+ languages: ['en', 'cs'],
602
+ namespace: appNamespace(app),
603
+ localisedUrls: createLocalisedUrls(app),
604
+ },
605
+ routes: {
606
+ source: 'route-owned',
607
+ metadataAuthoring: 'colocated-route-meta',
608
+ generatedManifest: true,
609
+ metadataExport: './src/routes/ultramodern-route-metadata',
610
+ localisedUrls: createLocalisedUrls(app),
611
+ owned: createRouteOwnedEntries(app),
612
+ publicRoutes: createPublicRoutes(app),
613
+ privateByDefault: true,
614
+ publicnessDefault: 'private-app-screen',
615
+ publicHead: createPublicHead(),
616
+ publicSurface: createPublicSurface(app),
617
+ },
618
+ moduleFederation: {
619
+ name: app.mfName,
620
+ ...(app.verticalRefs?.length
621
+ ? {
622
+ verticalRefs: app.verticalRefs,
623
+ remotes: remoteContractsFor(app, apps),
624
+ }
625
+ : {}),
626
+ exposes: app.exposes,
627
+ dts: {
628
+ compilerInstance: 'tsgo',
629
+ displayErrorInTerminal: true,
630
+ tsConfigPath: './tsconfig.mf-types.json',
631
+ },
632
+ browserSafeExposesOnly: true,
633
+ },
634
+ marker: {
635
+ appId: app.id,
636
+ packageName: app.package ?? packageNameFor(packageScope, app.packageSuffix),
637
+ version: '0.1.0',
638
+ build: buildMarkerFor(app),
639
+ deployProfile: 'cloudflare-ssr-mf-effect-v1',
640
+ uiSurface: 'ui',
641
+ ...(app.api ? { apiSurface: 'api' } : {}),
642
+ },
643
+ ...(app.api
644
+ ? {
645
+ api: {
646
+ runtime: 'effect',
647
+ import: '@modern-js/plugin-bff/effect-edge',
648
+ prefix: app.api.prefix,
649
+ openapi: '/openapi.json',
650
+ strictEffectApproach: true,
651
+ workerEntry: 'worker/__modern_bff_effect.js',
652
+ contract: './api',
653
+ client: './api/client',
654
+ readiness: createEffectReadiness(app),
655
+ requestContext: createEffectRequestContext(),
656
+ domainOperations: createEffectDomainOperations(app),
657
+ ...createEffectOperationContract(app),
658
+ },
659
+ }
660
+ : {}),
661
+ });
662
+ const createCssFederationContract = () => ({
663
+ sharedDesignTokens: {
664
+ owner: {
665
+ id: 'shared-design-tokens',
666
+ package: packageNameFor(packageScope, 'shared-design-tokens'),
667
+ },
668
+ role: 'shared-design-tokens',
669
+ rootSelector: ':root',
670
+ classPrefix: '--um-',
671
+ layers: {
672
+ owned: ['ultramodern-shared-tokens'],
673
+ },
674
+ entrypoints: {
675
+ css: ['packages/shared-design-tokens/src/tokens.css'],
676
+ },
677
+ assets: {
678
+ exports: ['./tokens.css'],
679
+ },
680
+ dedupe: cssDedupe(),
681
+ ssr: {
682
+ firstPaintRequired: true,
683
+ },
684
+ },
685
+ });
686
+ const createPerformanceReadinessContract = () => ({
687
+ default: 'enabled',
688
+ mode: 'diagnostic',
689
+ scope: 'ultramodern-generated-and-framework-owned',
690
+ report: {
691
+ script: 'scripts/ultramodern-performance-readiness.mts',
692
+ config: 'scripts/ultramodern-performance-readiness.config.mjs',
693
+ deterministic: true,
694
+ },
695
+ optOut: {
696
+ env: 'ULTRAMODERN_PERFORMANCE_READINESS_DIAGNOSTICS=false',
697
+ },
698
+ signals: [
699
+ 'bfcache',
700
+ 'core-web-vitals-rum',
701
+ 'duplicate-prefetch-warmup',
702
+ 'cache-policy-sanity',
703
+ 'save-data-behavior',
704
+ 'cloudflare-ssr-cache-hints',
705
+ ].map(id => ({ id })),
706
+ });
707
+ const createModernPackageAliases = packageSourceConfig => {
708
+ if (typeof packageSourceConfig?.aliasScope !== 'string') {
709
+ return undefined;
710
+ }
711
+ const scope = packageSourceConfig.aliasScope.replace(/^@/u, '');
712
+ const prefix =
713
+ typeof packageSourceConfig.aliasPackageNamePrefix === 'string'
714
+ ? packageSourceConfig.aliasPackageNamePrefix
715
+ : '';
716
+ return Object.fromEntries(
717
+ modernPackageCohort.map(packageName => [
718
+ packageName,
719
+ `@${scope}/${prefix}${packageName.split('/').at(-1)}`,
720
+ ]),
721
+ );
722
+ };
723
+ const synthesizePackageSourceFromCompact = config => {
724
+ const source = config.packageSource ?? {};
725
+ const strategy = source.strategy === 'install' ? 'install' : 'workspace';
726
+ const specifier =
727
+ strategy === 'install' && typeof source.modernPackageVersion === 'string'
728
+ ? source.modernPackageVersion
729
+ : 'workspace:*';
730
+ const aliases = createModernPackageAliases(source);
731
+ return {
732
+ schemaVersion: 1,
733
+ strategy,
734
+ modernPackages: {
735
+ packages: modernPackageCohort,
736
+ specifier,
737
+ ...(typeof source.registry === 'string'
738
+ ? { registry: source.registry }
739
+ : {}),
740
+ ...(aliases ? { aliases } : {}),
741
+ },
742
+ generatedWorkspacePackages: {
743
+ packages: [
744
+ packageNameFor(packageScope, 'shared-contracts'),
745
+ packageNameFor(packageScope, 'shared-design-tokens'),
746
+ ],
747
+ specifier: 'workspace:*',
748
+ },
749
+ };
750
+ };
751
+ const synthesizeGeneratedContractFromCompact = config => {
752
+ const apps = compactAppsFromConfig(config);
753
+ return {
754
+ schemaVersion: 1,
755
+ profile: config.profile ?? 'cloudflare-ssr-mf-effect-v1',
756
+ node: {
757
+ version: config.workspace?.node?.version ?? expectedNodeVersion,
758
+ engineRange: '>=26',
759
+ },
760
+ performanceReadiness: createPerformanceReadinessContract(),
761
+ cssFederation: createCssFederationContract(),
762
+ apps: apps.map(app => createAppContract(app, apps)),
763
+ };
764
+ };
765
+ const readPackageSourceView = config => {
766
+ return synthesizePackageSourceFromCompact(config);
767
+ };
768
+ const readGeneratedContractView = config => {
769
+ return synthesizeGeneratedContractFromCompact(config);
770
+ };
73
771
  const expectedManifestUrl = vertical =>
74
772
  `http://localhost:${vertical.port}/mf-manifest.json`;
75
773
  const expectedApiUrl = vertical =>
@@ -95,9 +793,9 @@ const requiredMicroVerticalPaths = vertical => [
95
793
  `${vertical.path}/tsconfig.mf-types.json`,
96
794
  `${vertical.path}/modern.config.ts`,
97
795
  `${vertical.path}/module-federation.config.ts`,
98
- `${vertical.path}/api/effect/index.ts`,
99
- `${vertical.path}/shared/effect/api.ts`,
100
- `${vertical.path}/src/effect/${vertical.stem}-client.ts`,
796
+ `${vertical.path}/api/index.ts`,
797
+ `${vertical.path}/shared/api.ts`,
798
+ `${vertical.path}/src/api/${vertical.stem}-client.ts`,
101
799
  `${vertical.path}/src/modern-app-env.d.ts`,
102
800
  `${vertical.path}/src/modern.runtime.ts`,
103
801
  `${vertical.path}/src/federation-entry.tsx`,
@@ -173,11 +871,11 @@ const assertMicroVerticalContractGraph = ({
173
871
  assertObject(
174
872
  overlay.apis,
175
873
  'topology/local-overlays/development.json apis',
176
- 'restore generated local Effect API overlays',
874
+ 'restore generated local API overlays',
177
875
  );
178
876
  assertArray(
179
877
  generatedContract.apps,
180
- '.modernjs/ultramodern-generated-contract.json apps',
878
+ `${generatedContractLabel} apps`,
181
879
  'regenerate the generated contract from the workspace topology',
182
880
  );
183
881
 
@@ -202,26 +900,26 @@ const assertMicroVerticalContractGraph = ({
202
900
  assertSameJson(
203
901
  generatedContract.apps.map(app => app?.id),
204
902
  expectedAppIds,
205
- '.modernjs/ultramodern-generated-contract.json apps',
903
+ `${generatedContractLabel} apps`,
206
904
  'regenerate the generated contract after topology changes',
207
905
  );
208
906
 
209
907
  const shellContract = findById(generatedContract.apps, 'shell-super-app');
210
908
  assertObject(
211
909
  shellContract,
212
- '.modernjs/ultramodern-generated-contract.json apps.shell-super-app',
910
+ `${generatedContractLabel} apps.shell-super-app`,
213
911
  'regenerate the generated shell contract entry',
214
912
  );
215
913
  assertSameJson(
216
914
  shellContract.moduleFederation?.verticalRefs ?? [],
217
915
  expectedVerticalIds,
218
- '.modernjs/ultramodern-generated-contract.json shell moduleFederation.verticalRefs',
916
+ `${generatedContractLabel} shell moduleFederation.verticalRefs`,
219
917
  'regenerate the generated shell Module Federation contract',
220
918
  );
221
919
  assertSameJson(
222
920
  (shellContract.moduleFederation?.remotes ?? []).map(remoteContractSubset),
223
921
  expectedShellRemotes,
224
- '.modernjs/ultramodern-generated-contract.json shell moduleFederation.remotes',
922
+ `${generatedContractLabel} shell moduleFederation.remotes`,
225
923
  'regenerate the generated shell Module Federation contract',
226
924
  );
227
925
  assertSameJson(
@@ -230,7 +928,7 @@ const assertMicroVerticalContractGraph = ({
230
928
  mode: 'string',
231
929
  moduleFederationAppSSR: true,
232
930
  },
233
- '.modernjs/ultramodern-generated-contract.json shell SSR contract',
931
+ `${generatedContractLabel} shell SSR contract`,
234
932
  'restore generated string SSR Module Federation settings',
235
933
  );
236
934
 
@@ -266,9 +964,9 @@ const assertMicroVerticalContractGraph = ({
266
964
  remoteContractSubset,
267
965
  ),
268
966
  },
269
- effect: {
270
- prefix: topologyEntry.api?.effect?.bff?.prefix,
271
- serverEntry: topologyEntry.api?.effect?.serverEntry,
967
+ api: {
968
+ prefix: topologyEntry.api?.bff?.prefix,
969
+ serverEntry: topologyEntry.api?.serverEntry,
272
970
  },
273
971
  },
274
972
  {
@@ -282,9 +980,9 @@ const assertMicroVerticalContractGraph = ({
282
980
  verticalRefs: expectedRefs,
283
981
  remotes: expectedRemoteSubsetsForRefs(expectedRefs),
284
982
  },
285
- effect: {
983
+ api: {
286
984
  prefix: vertical.apiPrefix,
287
- serverEntry: `${vertical.path}/api/effect/index.ts`,
985
+ serverEntry: `${vertical.path}/api/index.ts`,
288
986
  },
289
987
  },
290
988
  `topology/reference-topology.json verticals.${vertical.id}`,
@@ -325,14 +1023,14 @@ const assertMicroVerticalContractGraph = ({
325
1023
  overlay.apis[vertical.id],
326
1024
  expectedApiUrl(vertical),
327
1025
  `topology/local-overlays/development.json apis.${vertical.id}`,
328
- 'restore generated local Effect API overlay',
1026
+ 'restore generated local API overlay',
329
1027
  );
330
1028
 
331
1029
  assertSameJson(
332
1030
  shellPackage.dependencies?.[vertical.packageName],
333
1031
  'workspace:*',
334
1032
  `apps/shell-super-app/package.json dependencies.${vertical.packageName}`,
335
- 'restore shell dependency for the MicroVertical Effect API consumer',
1033
+ 'restore shell dependency for the MicroVertical API consumer',
336
1034
  );
337
1035
  assertSameJson(
338
1036
  shellPackage['zephyr:dependencies']?.[vertical.zephyrAlias],
@@ -343,7 +1041,7 @@ const assertMicroVerticalContractGraph = ({
343
1041
 
344
1042
  assertObject(
345
1043
  contractEntry,
346
- `.modernjs/ultramodern-generated-contract.json apps.${vertical.id}`,
1044
+ `${generatedContractLabel} apps.${vertical.id}`,
347
1045
  'regenerate the generated MicroVertical contract entry',
348
1046
  );
349
1047
  assertSameJson(
@@ -359,10 +1057,10 @@ const assertMicroVerticalContractGraph = ({
359
1057
  remoteContractSubset,
360
1058
  ),
361
1059
  },
362
- effect: {
363
- prefix: contractEntry.effect?.prefix,
364
- contract: contractEntry.effect?.contract,
365
- client: contractEntry.effect?.client,
1060
+ api: {
1061
+ prefix: contractEntry.api?.prefix,
1062
+ contract: contractEntry.api?.contract,
1063
+ client: contractEntry.api?.client,
366
1064
  },
367
1065
  ssr: contractEntry.ssr,
368
1066
  },
@@ -376,17 +1074,17 @@ const assertMicroVerticalContractGraph = ({
376
1074
  verticalRefs: expectedRefs,
377
1075
  remotes: expectedRemoteSubsetsForRefs(expectedRefs),
378
1076
  },
379
- effect: {
1077
+ api: {
380
1078
  prefix: vertical.apiPrefix,
381
- contract: './shared/effect/api',
382
- client: './effect/client',
1079
+ contract: './api',
1080
+ client: './api/client',
383
1081
  },
384
1082
  ssr: {
385
1083
  mode: 'string',
386
1084
  moduleFederationAppSSR: true,
387
1085
  },
388
1086
  },
389
- `.modernjs/ultramodern-generated-contract.json apps.${vertical.id}`,
1087
+ `${generatedContractLabel} apps.${vertical.id}`,
390
1088
  'regenerate the generated MicroVertical contract entry',
391
1089
  );
392
1090
  }
@@ -586,7 +1284,7 @@ const assertPublicSurfaceAssets = (appPath, publicRoutes) => {
586
1284
  };
587
1285
  const assertPublicSurfaceContract = (appId, publicSurface) => {
588
1286
  assert(publicSurface?.artifactLifecycle === 'build-and-deploy-output', `${appId} public surface artifacts must be build/deploy outputs`);
589
- assert(publicSurface?.generator === 'scripts/generate-public-surface-assets.mjs', `${appId} public surface generator script is incorrect`);
1287
+ assert(publicSurface?.generator === 'scripts/generate-public-surface-assets.mts', `${appId} public surface generator script is incorrect`);
590
1288
  assert(publicSurface?.outputRoot === 'dist/public', `${appId} public surface dist outputRoot is incorrect`);
591
1289
  assert(publicSurface?.cloudflareOutputRoot === '.output/public', `${appId} public surface Cloudflare outputRoot is incorrect`);
592
1290
  assert(!('staticRoot' in (publicSurface ?? {})), `${appId} public surface must not point at source config/public`);
@@ -770,24 +1468,23 @@ const requiredPaths = [
770
1468
  'oxfmt.config.ts',
771
1469
  '.github/renovate.json',
772
1470
  '.github/workflows/ultramodern-workspace-gates.yml',
773
- '.agents/skills-lock.json',
774
1471
  '.agents/agent-reference-repos.json',
775
- '.agents/rstackjs-agent-skills-LICENSE',
1472
+ '.codex/skills-lock.json',
1473
+ '.codex/rstackjs-agent-skills-LICENSE',
776
1474
  'topology/reference-topology.json',
777
1475
  'topology/ownership.json',
778
1476
  'topology/local-overlays/development.json',
779
- '.modernjs/ultramodern-workspace-template-manifest.json',
780
- '.modernjs/ultramodern-package-source.json',
781
- '.modernjs/ultramodern-generated-contract.json',
782
- 'scripts/assert-mf-types.mjs',
783
- 'scripts/bootstrap-agent-skills.mjs',
784
- 'scripts/check-ultramodern-i18n-boundaries.mjs',
785
- 'scripts/generate-public-surface-assets.mjs',
786
- 'scripts/proof-cloudflare-version.mjs',
787
- 'scripts/setup-agent-reference-repos.mjs',
1477
+ 'scripts/assert-mf-types.mts',
1478
+ 'scripts/bootstrap-agent-skills.mts',
1479
+ 'scripts/check-ultramodern-api-boundaries.mts',
1480
+ 'scripts/check-ultramodern-i18n-boundaries.mts',
1481
+ 'scripts/generate-public-surface-assets.mts',
1482
+ 'scripts/proof-cloudflare-version.mts',
1483
+ 'scripts/setup-agent-reference-repos.mts',
788
1484
  'scripts/ultramodern-performance-readiness.config.mjs',
789
- 'scripts/ultramodern-performance-readiness.mjs',
790
- 'scripts/ultramodern-typecheck.mjs',
1485
+ 'scripts/ultramodern-performance-readiness.mts',
1486
+ 'scripts/ultramodern-typecheck.mts',
1487
+ 'scripts/validate-ultramodern-workspace.mts',
791
1488
  'apps/shell-super-app/package.json',
792
1489
  'apps/shell-super-app/tsconfig.json',
793
1490
  'apps/shell-super-app/tsconfig.mf-types.json',
@@ -795,7 +1492,7 @@ const requiredPaths = [
795
1492
  'apps/shell-super-app/module-federation.config.ts',
796
1493
  'apps/shell-super-app/src/modern-app-env.d.ts',
797
1494
  'apps/shell-super-app/src/modern.runtime.ts',
798
- 'apps/shell-super-app/src/effect/vertical-clients.ts',
1495
+ 'apps/shell-super-app/src/api/vertical-clients.ts',
799
1496
  'apps/shell-super-app/locales/en/translation.json',
800
1497
  `apps/shell-super-app/locales/en/${shellNamespace}.json`,
801
1498
  'apps/shell-super-app/locales/cs/translation.json',
@@ -830,6 +1527,8 @@ if (tailwindEnabled) {
830
1527
  );
831
1528
  }
832
1529
 
1530
+ requiredPaths.push(compactConfigPath);
1531
+
833
1532
  for (const vertical of fullStackVerticals) {
834
1533
  requiredMicroVerticalPaths(vertical).forEach(
835
1534
  assertRequiredVerticalFile(vertical),
@@ -841,9 +1540,15 @@ for (const requiredPath of requiredPaths) {
841
1540
  for (const oldRemotePath of oldRemotePaths) {
842
1541
  assertNotExists(oldRemotePath);
843
1542
  }
1543
+ for (const retiredMetadataPath of retiredMetadataPaths) {
1544
+ assertNotExists(retiredMetadataPath);
1545
+ }
844
1546
  const rootPackage = readJson('package.json');
845
- const packageSource = readJson('.modernjs/ultramodern-package-source.json');
846
- const generatedContract = readJson('.modernjs/ultramodern-generated-contract.json');
1547
+ const ultramodernConfig = readJson(compactConfigPath);
1548
+ const bridgeConfig =
1549
+ ultramodernConfig?.bridge?.enabled === true ? ultramodernConfig.bridge : undefined;
1550
+ const packageSource = readPackageSourceView(ultramodernConfig);
1551
+ const generatedContract = readGeneratedContractView(ultramodernConfig);
847
1552
  const topology = readJson('topology/reference-topology.json');
848
1553
  const ownership = readJson('topology/ownership.json');
849
1554
  const overlay = readJson('topology/local-overlays/development.json');
@@ -882,7 +1587,10 @@ assert(
882
1587
  );
883
1588
  assert(!workflowText.includes('FORCE_JAVASCRIPT_ACTIONS_TO_NODE24'), 'CI workflow must not carry the legacy Node 24 override');
884
1589
  assert(rootPackage.modernjs?.preset === 'presetUltramodern', 'Root must declare presetUltramodern');
885
- assert(rootPackage.modernjs?.packageSource?.config === './.modernjs/ultramodern-package-source.json', 'Root must point at package source metadata');
1590
+ assert(
1591
+ rootPackage.modernjs?.packageSource?.config === './.modernjs/ultramodern.json',
1592
+ 'Root must point at compact UltraModern config',
1593
+ );
886
1594
  assert(rootPackage.modernjs?.packageSource?.strategy === packageSource.strategy, 'Root package source strategy must match metadata');
887
1595
  assert(packageSource.strategy === 'workspace' || packageSource.strategy === 'install', 'Package source strategy must be workspace or install');
888
1596
  assert(packageSource.strategy === 'install' || packageSource.modernPackages?.specifier === 'workspace:*', 'Workspace package source must be explicitly backed by workspace:*');
@@ -930,38 +1638,80 @@ assert(
930
1638
  );
931
1639
  assert(rootPackage.scripts?.['cloudflare:build'] === expectedCloudflareBuildScript, 'Root cloudflare:build script is incorrect');
932
1640
  assert(!('ultramodern:check' in (rootPackage.scripts ?? {})), 'Root must not expose ultramodern:check');
933
- assert(rootPackage.scripts?.typecheck === 'node ./scripts/ultramodern-typecheck.mjs --build tsconfig.json', 'Root typecheck must run TS-Go build mode across project references');
934
- assert(rootPackage.scripts?.['contract:check'] === 'node ./scripts/validate-ultramodern-workspace.mjs', 'Root must expose contract:check');
935
- assert(rootPackage.scripts?.['i18n:boundaries'] === 'node ./scripts/check-ultramodern-i18n-boundaries.mjs', 'Root must expose i18n:boundaries');
936
- assert(rootPackage.scripts?.['performance:readiness'] === 'node ./scripts/ultramodern-performance-readiness.mjs', 'Root must expose default-on performance readiness diagnostics');
937
- assert(rootPackage.scripts?.check?.endsWith('&& pnpm performance:readiness'), 'Root check must run default-on performance readiness diagnostics');
1641
+ if (bridgeConfig) {
1642
+ assert(
1643
+ rootPackage.scripts?.typecheck ===
1644
+ 'pnpm -r --filter "./apps/*" --filter "./verticals/*" --filter "./packages/*" run typecheck',
1645
+ 'Bridge root typecheck must check generated package boundaries without building parent implementation sources',
1646
+ );
1647
+ assert(Array.isArray(bridgeConfig.workspacePackages), 'Bridge config must record workspace package patterns');
1648
+ for (const workspacePackage of bridgeConfig.workspacePackages) {
1649
+ assert(
1650
+ rootPackage.workspaces?.includes(workspacePackage.pattern),
1651
+ `Root workspaces must include bridge package pattern ${workspacePackage.pattern}`,
1652
+ );
1653
+ assert(
1654
+ readText('pnpm-workspace.yaml').includes(` - ${workspacePackage.pattern}`),
1655
+ `pnpm-workspace.yaml must include bridge package pattern ${workspacePackage.pattern}`,
1656
+ );
1657
+ }
1658
+ for (const gate of bridgeConfig.gates ?? []) {
1659
+ const expectedGateScript = `${gate.cwd ? `cd ${gate.cwd} && ` : ''}${gate.command}`;
1660
+ assert(
1661
+ rootPackage.scripts?.[`bridge:${gate.name}`] === expectedGateScript,
1662
+ `Bridge gate script bridge:${gate.name} is incorrect`,
1663
+ );
1664
+ }
1665
+ assert(rootPackage.scripts?.['bridge:check'], 'Bridge workspaces must expose bridge:check');
1666
+ } else {
1667
+ assert(rootPackage.scripts?.typecheck === 'node ./scripts/ultramodern-typecheck.mts --build tsconfig.json', 'Root typecheck must run TS-Go build mode across project references');
1668
+ }
1669
+ assert(rootPackage.scripts?.['contract:check'] === 'node ./scripts/validate-ultramodern-workspace.mts', 'Root must expose contract:check');
1670
+ assert(rootPackage.scripts?.['api:check'] === 'node ./scripts/check-ultramodern-api-boundaries.mts', 'Root must expose api:check');
1671
+ assert(rootPackage.scripts?.['i18n:boundaries'] === 'node ./scripts/check-ultramodern-i18n-boundaries.mts', 'Root must expose i18n:boundaries');
1672
+ assert(rootPackage.scripts?.['performance:readiness'] === 'node ./scripts/ultramodern-performance-readiness.mts', 'Root must expose default-on performance readiness diagnostics');
1673
+ assert(
1674
+ bridgeConfig
1675
+ ? rootPackage.scripts?.check?.includes('pnpm api:check') &&
1676
+ rootPackage.scripts.check.endsWith('&& pnpm performance:readiness && pnpm bridge:check')
1677
+ : rootPackage.scripts?.check?.includes('pnpm api:check') &&
1678
+ rootPackage.scripts.check.endsWith('&& pnpm performance:readiness'),
1679
+ 'Root check must run default-on performance readiness diagnostics and bridge gates when configured',
1680
+ );
938
1681
  const performanceReadinessConfig = readText('scripts/ultramodern-performance-readiness.config.mjs');
939
- const performanceReadinessScript = readText('scripts/ultramodern-performance-readiness.mjs');
1682
+ const assertToolWrapper = (scriptPath, command) => {
1683
+ const source = readText(scriptPath);
1684
+ assert(source.includes('modern-js-create'), `${scriptPath} must delegate to modern-js-create`);
1685
+ assert(source.includes('ULTRAMODERN_CREATE_BIN'), `${scriptPath} must support local create-bin overrides for generated-workspace tests`);
1686
+ assert(source.includes("'ultramodern'") || source.includes('"ultramodern"'), `${scriptPath} must dispatch through the UltraModern tool surface`);
1687
+ assert(source.includes(command), `${scriptPath} must dispatch ${command}`);
1688
+ };
940
1689
  assert(performanceReadinessConfig.includes('UltramodernPerformanceReadinessDiagnosticsConfig'), 'Performance readiness config must carry the typed opt-out surface');
941
1690
  assert(performanceReadinessConfig.includes('enabled: true'), 'Performance readiness diagnostics must be default-on');
942
1691
  assert(performanceReadinessConfig.includes("failOn: 'framework-invariant'"), 'Performance readiness diagnostics must only fail framework invariants by default');
943
- assert(performanceReadinessScript.includes("ULTRAMODERN_PERFORMANCE_READINESS_DIAGNOSTICS"), 'Performance readiness script must support env opt-out');
944
- assert(performanceReadinessScript.includes('ultramodern-performance-readiness-diagnostics-v1'), 'Performance readiness script must emit the deterministic report profile');
945
- const i18nBoundaryScript = readText('scripts/check-ultramodern-i18n-boundaries.mjs');
946
- const ultramodernTypecheckScript = readText('scripts/ultramodern-typecheck.mjs');
947
- assert(ultramodernTypecheckScript.includes("'--checkers'") && ultramodernTypecheckScript.includes("'--builders'"), 'Root typecheck script must drive TS-Go checker and builder parallelism');
948
- assert(ultramodernTypecheckScript.includes('effect-tsgo') && ultramodernTypecheckScript.includes('get-exe-path'), 'Root typecheck script must resolve the @effect/tsgo native-preview binary');
1692
+ assertToolWrapper('scripts/validate-ultramodern-workspace.mts', 'validate');
1693
+ assertToolWrapper('scripts/ultramodern-performance-readiness.mts', 'performance-readiness');
1694
+ const i18nBoundaryScript = readText('scripts/check-ultramodern-i18n-boundaries.mts');
1695
+ assertToolWrapper('scripts/ultramodern-typecheck.mts', 'typecheck');
949
1696
  assert(
950
1697
  i18nBoundaryScript.includes("from '@modern-js/code-tools'") &&
951
1698
  i18nBoundaryScript.includes('runWorkspaceSourceCheck'),
952
1699
  'Root i18n boundary script must call @modern-js/code-tools',
953
1700
  );
954
- assert(rootPackage.scripts?.['mf:types'] === 'node ./scripts/assert-mf-types.mjs', 'Root must expose mf:types');
1701
+ assert(rootPackage.scripts?.['mf:types'] === 'node ./scripts/assert-mf-types.mts', 'Root must expose mf:types');
955
1702
  assert(rootPackage.scripts?.['cloudflare:deploy'] === expectedCloudflareDeployScript, 'Root must expose cloudflare:deploy');
956
- assert(rootPackage.scripts?.['cloudflare:proof'] === 'node ./scripts/proof-cloudflare-version.mjs --out .codex/reports/cloudflare-version-proof/public-url-proof.json', 'Root must expose cloudflare:proof');
957
- assert(rootPackage.scripts?.['skills:install'] === 'node ./scripts/bootstrap-agent-skills.mjs', 'Root must expose skills:install');
958
- assert(rootPackage.scripts?.['skills:check'] === 'node ./scripts/bootstrap-agent-skills.mjs --check', 'Root must expose skills:check');
959
- assert(rootPackage.scripts?.postinstall === "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mjs --postinstall", 'Root postinstall must only format and run the clone-free skills bootstrap; repository clones are explicit opt-in steps');
960
- assert(rootPackage.scripts?.['agents:refs:install'] === 'node ./scripts/setup-agent-reference-repos.mjs', 'Root must expose agents:refs:install as the explicit reference repo installer');
961
- const agentSkillsBootstrap = readText('scripts/bootstrap-agent-skills.mjs');
962
- assert(agentSkillsBootstrap.includes('never installs system packages'), 'Agent skills bootstrap must declare the no-system-install policy');
1703
+ assert(rootPackage.scripts?.['cloudflare:proof'] === 'node ./scripts/proof-cloudflare-version.mts --out .codex/reports/cloudflare-version-proof/public-url-proof.json', 'Root must expose cloudflare:proof');
1704
+ assert(rootPackage.scripts?.['skills:install'] === 'node ./scripts/bootstrap-agent-skills.mts', 'Root must expose skills:install');
1705
+ assert(rootPackage.scripts?.['skills:check'] === 'node ./scripts/bootstrap-agent-skills.mts --check', 'Root must expose skills:check');
1706
+ assert(rootPackage.scripts?.postinstall === "oxfmt . '!repos/**' && node ./scripts/bootstrap-agent-skills.mts --postinstall", 'Root postinstall must format, run the default-on Codex skills bootstrap, and leave reference repository installs explicit');
1707
+ assert(rootPackage.scripts?.['agents:refs:install'] === 'node ./scripts/setup-agent-reference-repos.mts', 'Root must expose agents:refs:install as the explicit reference repo installer');
1708
+ const agentSkillsBootstrap = readText('scripts/bootstrap-agent-skills.mts');
1709
+ assertToolWrapper('scripts/assert-mf-types.mts', 'mf-types');
1710
+ assertToolWrapper('scripts/generate-public-surface-assets.mts', 'public-surface');
1711
+ assertToolWrapper('scripts/proof-cloudflare-version.mts', 'cloudflare-proof');
1712
+ assertToolWrapper('scripts/bootstrap-agent-skills.mts', 'skills');
963
1713
  assert(!agentSkillsBootstrap.includes("run('brew'") && !agentSkillsBootstrap.includes('runShell('), 'Agent skills bootstrap must never invoke system package managers');
964
- const agentReferenceRepoSetup = readText('scripts/setup-agent-reference-repos.mjs');
1714
+ const agentReferenceRepoSetup = readText('scripts/setup-agent-reference-repos.mts');
965
1715
  assert(agentReferenceRepoSetup.includes("['commit', '--no-verify', '-m', message]"), 'Agent reference repo installer commits must skip hooks during postinstall');
966
1716
  assert(agentReferenceRepoSetup.includes("commitInstallerChanges('Initialize UltraModern workspace')"), 'Initial agent reference repo commit must use the installer commit helper');
967
1717
  assert(agentReferenceRepoSetup.includes("commitInstallerChanges('Record agent reference repo manifest')"), 'Agent reference repo manifest commit must use the installer commit helper');
@@ -992,7 +1742,7 @@ const expectedPerformanceReadinessSignals = [
992
1742
  ];
993
1743
  assert(generatedContract.performanceReadiness?.default === 'enabled', 'Performance readiness diagnostics must be default-on in the generated contract');
994
1744
  assert(generatedContract.performanceReadiness?.mode === 'diagnostic', 'Performance readiness must remain diagnostic-only');
995
- assert(generatedContract.performanceReadiness?.report?.script === 'scripts/ultramodern-performance-readiness.mjs', 'Performance readiness contract must point at the generated script');
1745
+ assert(generatedContract.performanceReadiness?.report?.script === 'scripts/ultramodern-performance-readiness.mts', 'Performance readiness contract must point at the generated script');
996
1746
  assert(generatedContract.performanceReadiness?.report?.deterministic === true, 'Performance readiness reports must be deterministic');
997
1747
  assert(generatedContract.performanceReadiness?.optOut?.env === 'ULTRAMODERN_PERFORMANCE_READINESS_DIAGNOSTICS=false', 'Performance readiness env opt-out is incorrect');
998
1748
  assert(JSON.stringify(generatedContract.performanceReadiness?.signals?.map(signal => signal.id)) === JSON.stringify(expectedPerformanceReadinessSignals), 'Performance readiness signal ids are incorrect');
@@ -1033,8 +1783,9 @@ assert(shellModernConfig.includes('name: cloudflareWorkerName'), 'Shell modern.c
1033
1783
  assert(shellModernConfig.includes('const assetPrefix ='), 'Shell modern.config.ts must derive a dedicated asset prefix');
1034
1784
  assert(shellModernConfig.includes("const configuredUltramodernAssetPrefix = envValue('ULTRAMODERN_ASSET_PREFIX')"), 'Shell asset prefix must support ULTRAMODERN_ASSET_PREFIX');
1035
1785
  assert(shellModernConfig.includes("const configuredModernAssetPrefix = envValue('MODERN_ASSET_PREFIX')"), 'Shell asset prefix must support MODERN_ASSET_PREFIX');
1786
+ assert(shellModernConfig.includes("const defaultAssetPrefix = '/'"), 'Shell asset prefix must default to origin-relative assets');
1036
1787
  const shellAssetPrefixExpression = extractAssetPrefixExpression(shellModernConfig);
1037
- assert(shellAssetPrefixExpression.includes("configuredModernAssetPrefix || configuredUltramodernAssetPrefix || '/'"), 'Shell asset prefix fallback order is incorrect');
1788
+ assert(shellAssetPrefixExpression.includes("configuredModernAssetPrefix || configuredUltramodernAssetPrefix || defaultAssetPrefix"), 'Shell asset prefix fallback order is incorrect');
1038
1789
  assert(!shellAssetPrefixExpression.includes('configuredSiteUrl') && !shellAssetPrefixExpression.includes('MODERN_PUBLIC_SITE_URL'), 'Shell asset prefix must not fall back to MODERN_PUBLIC_SITE_URL');
1039
1790
  assert(!shellAssetPrefixExpression.includes('configuredCloudflareUrl') && !shellAssetPrefixExpression.includes('ULTRAMODERN_PUBLIC_URL_SHELL_SUPER_APP'), 'Shell asset prefix must not fall back to the per-app public URL');
1040
1791
  assert(!shellAssetPrefixExpression.includes('inferredCloudflareUrl') && !shellAssetPrefixExpression.includes('ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN'), 'Shell asset prefix must not infer workers.dev URLs');
@@ -1100,8 +1851,8 @@ for (const vertical of fullStackVerticals) {
1100
1851
  assert(packageJson.dependencies?.['@modern-js/plugin-i18n'] === expectedModernPackageSpecifier('@modern-js/plugin-i18n'), `${vertical.id} plugin-i18n dependency must match package source metadata`);
1101
1852
  assert(packageJson.dependencies?.['@modern-js/plugin-tanstack'] === expectedModernPackageSpecifier('@modern-js/plugin-tanstack'), `${vertical.id} plugin-tanstack dependency must match package source metadata`);
1102
1853
  assert(packageJson.dependencies?.['@modern-js/runtime'] === expectedModernPackageSpecifier('@modern-js/runtime'), `${vertical.id} runtime dependency must match package source metadata`);
1103
- assert(packageJson.exports?.['./effect/client'] === `./src/effect/${vertical.stem}-client.ts`, `${vertical.id} must export its Effect client`);
1104
- assert(packageJson.exports?.['./shared/effect/api'] === './shared/effect/api.ts', `${vertical.id} must export its Effect API contract`);
1854
+ assert(packageJson.exports?.['./api/client'] === `./src/api/${vertical.stem}-client.ts`, `${vertical.id} must export its API client`);
1855
+ assert(packageJson.exports?.['./api'] === './shared/api.ts', `${vertical.id} must export its API contract`);
1105
1856
  const expectedVerticalZephyrDependencies = Object.fromEntries(
1106
1857
  fullStackVerticals
1107
1858
  .filter(candidate => vertical.verticalRefs.includes(candidate.id))
@@ -1132,21 +1883,23 @@ for (const vertical of fullStackVerticals) {
1132
1883
  assert(modernConfig.includes('const assetPrefix ='), `${vertical.id} modern.config.ts must derive a dedicated asset prefix`);
1133
1884
  assert(modernConfig.includes("const configuredUltramodernAssetPrefix = envValue('ULTRAMODERN_ASSET_PREFIX')"), `${vertical.id} asset prefix must support ULTRAMODERN_ASSET_PREFIX`);
1134
1885
  assert(modernConfig.includes("const configuredModernAssetPrefix = envValue('MODERN_ASSET_PREFIX')"), `${vertical.id} asset prefix must support MODERN_ASSET_PREFIX`);
1886
+ assert(modernConfig.includes('const defaultRemoteAssetPrefix'), `${vertical.id} asset prefix must derive the remote asset origin`);
1887
+ assert(modernConfig.includes('const defaultAssetPrefix = defaultRemoteAssetPrefix'), `${vertical.id} asset prefix must default to its own remote origin`);
1135
1888
  const verticalAssetPrefixExpression = extractAssetPrefixExpression(modernConfig);
1136
- assert(verticalAssetPrefixExpression.includes("configuredModernAssetPrefix || configuredUltramodernAssetPrefix || '/'"), `${vertical.id} asset prefix fallback order is incorrect`);
1889
+ assert(verticalAssetPrefixExpression.includes("configuredModernAssetPrefix || configuredUltramodernAssetPrefix || defaultAssetPrefix"), `${vertical.id} asset prefix fallback order is incorrect`);
1137
1890
  assert(!verticalAssetPrefixExpression.includes('configuredSiteUrl') && !verticalAssetPrefixExpression.includes('MODERN_PUBLIC_SITE_URL'), `${vertical.id} asset prefix must not fall back to MODERN_PUBLIC_SITE_URL`);
1138
- assert(!verticalAssetPrefixExpression.includes('configuredCloudflareUrl') && !verticalAssetPrefixExpression.includes(`ULTRAMODERN_PUBLIC_URL_${vertical.id.replace(/-/g, '_').toUpperCase()}`), `${vertical.id} asset prefix must not fall back to the per-app public URL`);
1139
- assert(!verticalAssetPrefixExpression.includes('inferredCloudflareUrl') && !verticalAssetPrefixExpression.includes('ULTRAMODERN_CLOUDFLARE_WORKERS_DEV_SUBDOMAIN'), `${vertical.id} asset prefix must not infer workers.dev URLs`);
1891
+ assert(modernConfig.includes(`envValue('ULTRAMODERN_PUBLIC_URL_${vertical.id.replace(/-/g, '_').toUpperCase()}')`), `${vertical.id} asset prefix must read its per-app public URL`);
1892
+ assert(modernConfig.includes('inferredCloudflareUrl'), `${vertical.id} asset prefix must support workers.dev origin inference`);
1140
1893
  assert(modernConfig.includes("assetPrefix: '/'"), `${vertical.id} modern.config.ts must keep dev assets origin-relative`);
1141
1894
  assert(modernConfig.includes('assetPrefix,'), `${vertical.id} modern.config.ts must wire output.assetPrefix to the derived asset prefix`);
1142
1895
  assert(contractEntry?.config?.dev?.assetPrefix === '/', `${vertical.id} dev asset prefix must stay origin-relative`);
1143
- assert(contractEntry?.config?.output?.assetPrefix?.default === '/', `${vertical.id} asset prefix must default to origin-relative paths`);
1896
+ assert(contractEntry?.config?.output?.assetPrefix?.default === 'app-public-origin', `${vertical.id} asset prefix must default to its app public origin`);
1144
1897
  assert(JSON.stringify(contractEntry?.config?.output?.assetPrefix?.envFallbackOrder) === JSON.stringify(['MODERN_ASSET_PREFIX', 'ULTRAMODERN_ASSET_PREFIX']), `${vertical.id} asset prefix env fallback order is incorrect`);
1145
1898
  assert(contractEntry?.config?.output?.disableTsChecker === false, `${vertical.id} must keep the framework TypeScript checker enabled`);
1146
1899
  assert(contractEntry?.config?.performance?.readinessDiagnostics?.default === 'enabled', `${vertical.id} performance readiness diagnostics must be default-on`);
1147
1900
  assert(contractEntry?.config?.performance?.readinessDiagnostics?.failOn === 'framework-invariant', `${vertical.id} performance readiness diagnostics must only fail framework invariants by default`);
1148
1901
  assert(contractEntry?.config?.performance?.readinessDiagnostics?.optOut?.config === 'scripts/ultramodern-performance-readiness.config.mjs', `${vertical.id} performance readiness opt-out config is incorrect`);
1149
- assert(contractEntry?.deploy?.cloudflare?.routes?.effectReadiness === `${vertical.apiPrefix}/effect/${vertical.stem}/readiness`, `${vertical.id} Cloudflare proof readiness route is incorrect`);
1902
+ assert(contractEntry?.deploy?.cloudflare?.routes?.apiReadiness === `${vertical.apiPrefix}/${vertical.stem}/readiness`, `${vertical.id} Cloudflare proof readiness route is incorrect`);
1150
1903
  assert(contractEntry?.config?.rspack?.output?.uniqueName === vertical.mfName, `${vertical.id} Rspack uniqueName is incorrect`);
1151
1904
  assert(contractEntry?.config?.rspack?.output?.chunkLoadingGlobal === expectedChunkLoadingGlobal(vertical.mfName), `${vertical.id} Rspack chunkLoadingGlobal is incorrect`);
1152
1905
  assert(contractEntry?.moduleFederation?.name === vertical.mfName, `${vertical.id} MF name is incorrect`);
@@ -1160,12 +1913,14 @@ for (const vertical of fullStackVerticals) {
1160
1913
  JSON.stringify(vertical.verticalRefs),
1161
1914
  `${vertical.id} MF consumed verticals are incorrect`,
1162
1915
  );
1163
- assert(contractEntry?.effect?.prefix === vertical.apiPrefix, `${vertical.id} Effect API prefix is incorrect`);
1164
- assert(contractEntry?.effect?.group === vertical.group, `${vertical.id} Effect group is incorrect`);
1165
- assert(contractEntry?.effect?.readiness?.endpoint === `/effect/${vertical.stem}/readiness`, `${vertical.id} readiness endpoint is incorrect`);
1166
- assert(contractEntry?.effect?.operations?.readiness?.path === `/effect/${vertical.stem}/readiness`, `${vertical.id} readiness operation is missing`);
1167
- assert(contractEntry?.effect?.requestContext?.propagatedHeaders?.includes('traceparent'), `${vertical.id} trace context propagation is missing`);
1168
- assert(Object.keys(contractEntry?.effect?.domainOperations ?? {}).length >= 3, `${vertical.id} domain operations are missing`);
1916
+ assert(contractEntry?.api?.prefix === vertical.apiPrefix, `${vertical.id} API prefix is incorrect`);
1917
+ assert(contractEntry?.api?.group === vertical.group, `${vertical.id} API group is incorrect`);
1918
+ assert(contractEntry?.api?.runtime === 'effect', `${vertical.id} API runtime must be Effect`);
1919
+ assert(contractEntry?.api?.strictEffectApproach === true, `${vertical.id} strictEffectApproach must be enabled`);
1920
+ assert(contractEntry?.api?.readiness?.endpoint === `/${vertical.stem}/readiness`, `${vertical.id} readiness endpoint is incorrect`);
1921
+ assert(contractEntry?.api?.operations?.readiness?.path === `/${vertical.stem}/readiness`, `${vertical.id} readiness operation is missing`);
1922
+ assert(contractEntry?.api?.requestContext?.propagatedHeaders?.includes('traceparent'), `${vertical.id} trace context propagation is missing`);
1923
+ assert(Object.keys(contractEntry?.api?.domainOperations ?? {}).length >= 3, `${vertical.id} domain operations are missing`);
1169
1924
  assert(contractEntry?.i18n?.languages?.includes('en') && contractEntry?.i18n?.languages?.includes('cs'), `${vertical.id} must declare i18n languages`);
1170
1925
  assert(contractEntry?.i18n?.namespace === vertical.namespace, `${vertical.id} i18n namespace is incorrect`);
1171
1926
  assert(
@@ -1204,10 +1959,11 @@ for (const vertical of fullStackVerticals) {
1204
1959
  assert(topologyEntry?.moduleFederation?.name === vertical.mfName, `${vertical.id} topology MF name is incorrect`);
1205
1960
  assert(JSON.stringify(topologyEntry?.moduleFederation?.exposes) === JSON.stringify(vertical.exposes), `${vertical.id} topology exposes are incorrect`);
1206
1961
  assert(JSON.stringify(topologyEntry?.moduleFederation?.verticalRefs ?? []) === JSON.stringify(vertical.verticalRefs), `${vertical.id} topology verticalRefs are incorrect`);
1207
- assert(topologyEntry?.api?.effect?.bff?.prefix === vertical.apiPrefix, `${vertical.id} topology API prefix is incorrect`);
1208
- assert(topologyEntry?.api?.effect?.serverEntry === `${vertical.path}/api/effect/index.ts`, `${vertical.id} topology server entry is incorrect`);
1209
- assert(topologyEntry?.api?.effect?.readiness?.endpoint === `/effect/${vertical.stem}/readiness`, `${vertical.id} topology readiness endpoint is incorrect`);
1210
- assert(Object.keys(topologyEntry?.api?.effect?.domainOperations ?? {}).length >= 3, `${vertical.id} topology domain operations are missing`);
1962
+ assert(topologyEntry?.api?.bff?.prefix === vertical.apiPrefix, `${vertical.id} topology API prefix is incorrect`);
1963
+ assert(topologyEntry?.api?.bff?.strictEffectApproach === true, `${vertical.id} topology strictEffectApproach is incorrect`);
1964
+ assert(topologyEntry?.api?.serverEntry === `${vertical.path}/api/index.ts`, `${vertical.id} topology server entry is incorrect`);
1965
+ assert(topologyEntry?.api?.readiness?.endpoint === `/${vertical.stem}/readiness`, `${vertical.id} topology readiness endpoint is incorrect`);
1966
+ assert(Object.keys(topologyEntry?.api?.domainOperations ?? {}).length >= 3, `${vertical.id} topology domain operations are missing`);
1211
1967
 
1212
1968
  assert(ownership.owners?.some(owner => owner.id === vertical.id && owner.path === vertical.path), `${vertical.id} ownership entry is missing`);
1213
1969
  assert(overlay.ports?.[vertical.id], `${vertical.id} development port is missing`);