@tokenoftrust/storefront-runner 1.4.2-rc.0 → 2.0.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 (363) hide show
  1. package/apps/storefront/astro.config.mjs +3 -3
  2. package/apps/storefront/env.d.ts +54 -5
  3. package/apps/storefront/integrations/materialize-guard.mjs +12 -14
  4. package/apps/storefront/migrations-apps/0004_deep_morph.sql +36 -0
  5. package/apps/storefront/migrations-apps/0005_common_mystique.sql +23 -0
  6. package/apps/storefront/migrations-apps/0006_broad_microchip.sql +16 -0
  7. package/apps/storefront/migrations-apps/0007_brave_outlaw_kid.sql +15 -0
  8. package/apps/storefront/migrations-apps/0008_blue_dazzler.sql +11 -0
  9. package/apps/storefront/migrations-apps/0009_bored_shinobi_shaw.sql +15 -0
  10. package/apps/storefront/migrations-apps/0010_ws4_verified_provider_measurement.sql +35 -0
  11. package/apps/storefront/migrations-apps/meta/0004_snapshot.json +1474 -0
  12. package/apps/storefront/migrations-apps/meta/0005_snapshot.json +1617 -0
  13. package/apps/storefront/migrations-apps/meta/0006_snapshot.json +1716 -0
  14. package/apps/storefront/migrations-apps/meta/0007_snapshot.json +1812 -0
  15. package/apps/storefront/migrations-apps/meta/0008_snapshot.json +1881 -0
  16. package/apps/storefront/migrations-apps/meta/0009_snapshot.json +1979 -0
  17. package/apps/storefront/migrations-apps/meta/_journal.json +42 -0
  18. package/apps/storefront/public/apps/tot.demo.analytics/0.1.0/entry.js +42 -0
  19. package/apps/storefront/public/platform/amplitude-http/v1/entry.mjs +19 -0
  20. package/apps/storefront/public/platform/google-measurement/v1/entry.mjs +19 -0
  21. package/apps/storefront/public/shared/commerce-chrome.css +20 -2
  22. package/apps/storefront/scripts/build-v84-clean-clone-standalone.mjs +68 -0
  23. package/apps/storefront/scripts/deny-v84-clean-clone-standalone-capabilities.mjs +111 -0
  24. package/apps/storefront/scripts/deny-v84-dogfood-capabilities.mjs +2 -0
  25. package/apps/storefront/scripts/deny-v84-lifecycle-capabilities.mjs +247 -0
  26. package/apps/storefront/scripts/dogfood-v84-nonportable-routes.ts +73 -0
  27. package/apps/storefront/scripts/fixed-v84-native-install-producer.ts +79 -0
  28. package/apps/storefront/scripts/generated/v84-clean-clone-replay.bundle.mjs +10982 -0
  29. package/apps/storefront/scripts/import-v84-through-ws2.ts +38 -0
  30. package/apps/storefront/scripts/initialize-v84-lifecycle-tooling-dependency.ts +2 -0
  31. package/apps/storefront/scripts/initialize-v84-lifecycle-tooling.ts +4 -0
  32. package/apps/storefront/scripts/install-v84-native-through-ws1.ts +185 -0
  33. package/apps/storefront/scripts/prove-clone-isolation.ts +506 -0
  34. package/apps/storefront/scripts/replay-v84-clean-clone-pass.ts +148 -0
  35. package/apps/storefront/scripts/replay-v84-clean-clone-standalone.ts +35 -0
  36. package/apps/storefront/scripts/replay-v84-clean-clone.ts +214 -0
  37. package/apps/storefront/scripts/run-fixed-v84-native-install-producer.mjs +18 -0
  38. package/apps/storefront/scripts/run-v84-clone-isolation-proof.mjs +18 -0
  39. package/apps/storefront/scripts/run-v84-clone-lifecycle-proof.mjs +18 -0
  40. package/apps/storefront/scripts/run-v84-import-through-ws2-proof.mjs +17 -0
  41. package/apps/storefront/scripts/run-v84-nonportable-route-dogfood.mjs +15 -0
  42. package/apps/storefront/scripts/sanitize-v84-proof-environment.mjs +21 -0
  43. package/apps/storefront/scripts/v84CleanCloneGraphPin.ts +42 -0
  44. package/apps/storefront/scripts/v84CleanCloneSourceGraph.ts +145 -0
  45. package/apps/storefront/scripts/validate-v84-clone-lifecycle.ts +18 -0
  46. package/apps/storefront/src/components/Img.astro +1 -1
  47. package/apps/storefront/src/components/admin/AdminBlogTab.astro +19 -16
  48. package/apps/storefront/src/components/admin/AdminIntegrationsTab.astro +105 -0
  49. package/apps/storefront/src/components/admin/AdminPublishTab.astro +1057 -412
  50. package/apps/storefront/src/components/admin/AdminSettingsTab.astro +2 -2
  51. package/apps/storefront/src/components/admin/orders/OrdersWorkspace.astro +5 -5
  52. package/apps/storefront/src/components/chrome/NavDropdown.astro +12 -0
  53. package/apps/storefront/src/components/chrome/SiteFooter.astro +7 -2
  54. package/apps/storefront/src/components/chrome/SiteHeader.astro +46 -10
  55. package/apps/storefront/src/components/compliance/AdultSignatureNotice.astro +1 -1
  56. package/apps/storefront/src/components/compliance/ComplianceNotice.astro +1 -2
  57. package/apps/storefront/src/components/compliance/ExciseTaxNotice.astro +1 -2
  58. package/apps/storefront/src/components/compliance/PactActNotice.astro +1 -1
  59. package/apps/storefront/src/components/compliance/Prop65Warning.astro +1 -2
  60. package/apps/storefront/src/components/compliance/PurchaseLimitNotice.astro +2 -3
  61. package/apps/storefront/src/components/compliance/ShippingRestrictionNotice.astro +2 -2
  62. package/apps/storefront/src/components/compliance/StateEligibilityNotice.astro +2 -3
  63. package/apps/storefront/src/components/content/TrustStrip.astro +4 -4
  64. package/apps/storefront/src/components/islands/MobileNav.tsx +26 -1
  65. package/apps/storefront/src/components/islands/VariantSelector.tsx +27 -2
  66. package/apps/storefront/src/components/islands/useCheckoutHandoffCorrelation.ts +75 -0
  67. package/apps/storefront/src/components/membership/IllustrativeLabel.astro +1 -2
  68. package/apps/storefront/src/components/membership/TierCards.astro +2 -2
  69. package/apps/storefront/src/components/membership/TierComparisonTable.astro +2 -2
  70. package/apps/storefront/src/components/subscription/SavingsExplainer.astro +2 -2
  71. package/apps/storefront/src/config/adminTenantLookup.ts +35 -0
  72. package/apps/storefront/src/config/devTenantSeed.ts +9 -9
  73. package/apps/storefront/src/config/resolver.ts +4 -4
  74. package/apps/storefront/src/layouts/Layout.astro +100 -20
  75. package/apps/storefront/src/lib/activity/candidateSubmitLease.ts +87 -0
  76. package/apps/storefront/src/lib/activity/changeActorAttribution.ts +86 -6
  77. package/apps/storefront/src/lib/activity/deployVersion.ts +1 -1
  78. package/apps/storefront/src/lib/admin/adminShell.ts +2 -0
  79. package/apps/storefront/src/lib/admin/envelope.ts +1 -2
  80. package/apps/storefront/src/lib/apps/adminService.ts +10 -0
  81. package/apps/storefront/src/lib/apps/adminSession.ts +1 -1
  82. package/apps/storefront/src/lib/apps/appVersionStore.ts +281 -0
  83. package/apps/storefront/src/lib/apps/consentConfigStore.ts +228 -0
  84. package/apps/storefront/src/lib/apps/gtmMigrationInstall.ts +447 -0
  85. package/apps/storefront/src/lib/apps/gtmMigrationReport.ts +367 -0
  86. package/apps/storefront/src/lib/apps/gtmMigrationTab.ts +315 -0
  87. package/apps/storefront/src/lib/apps/integrationLifecycle.ts +614 -0
  88. package/apps/storefront/src/lib/apps/integrationLifecycleController.ts +125 -0
  89. package/apps/storefront/src/lib/apps/integrationReadModel.ts +563 -0
  90. package/apps/storefront/src/lib/apps/integrationsTab.ts +547 -0
  91. package/apps/storefront/src/lib/apps/integrationsView.ts +106 -0
  92. package/apps/storefront/src/lib/apps/managedAnalyticsService.ts +599 -0
  93. package/apps/storefront/src/lib/apps/orders/orderConversionD1.ts +150 -0
  94. package/apps/storefront/src/lib/apps/orders/orderForwardReceiver.ts +8 -0
  95. package/apps/storefront/src/lib/apps/orders/ordersStore.ts +1 -1
  96. package/apps/storefront/src/lib/apps/orders/verifiedProviderMeasurement.ts +117 -0
  97. package/apps/storefront/src/lib/apps/registryService.ts +264 -10
  98. package/apps/storefront/src/lib/apps/tenantIntegrationMaterialization.ts +170 -0
  99. package/apps/storefront/src/lib/apps/v84CleanCloneReplayContext.ts +16 -0
  100. package/apps/storefront/src/lib/apps/v84CloneLifecycleCacheEvidence.ts +105 -0
  101. package/apps/storefront/src/lib/apps/v84CloneLifecycleEvidence.ts +177 -0
  102. package/apps/storefront/src/lib/apps/v84CloneLifecycleMaterialization.ts +251 -0
  103. package/apps/storefront/src/lib/apps/v84CloneLifecycleSemantics.ts +241 -0
  104. package/apps/storefront/src/lib/apps/v84CloneMigrationEvidence.ts +211 -0
  105. package/apps/storefront/src/lib/apps/v84CloneNativeInstallEvidence.ts +409 -0
  106. package/apps/storefront/src/lib/apps/v84NonportableCodeCoaching.ts +368 -0
  107. package/apps/storefront/src/lib/apps/v84NonportableRouteContract.ts +188 -0
  108. package/apps/storefront/src/lib/apps/v84NonportableRouteDogfood.ts +291 -0
  109. package/apps/storefront/src/lib/apps/ws1ManagedAnalyticsClient.ts +95 -0
  110. package/apps/storefront/src/lib/auth/adminApiGuard.ts +66 -0
  111. package/apps/storefront/src/lib/auth/adminEntry.ts +2 -2
  112. package/apps/storefront/src/lib/auth/adminLanding.ts +88 -0
  113. package/apps/storefront/src/lib/blog/collection.ts +97 -10
  114. package/apps/storefront/src/lib/blog/markdown.ts +1 -1
  115. package/apps/storefront/src/lib/blog/provider.ts +57 -3
  116. package/apps/storefront/src/lib/blog/types.ts +9 -9
  117. package/apps/storefront/src/lib/chrome/examples/tokenoftrust.chrome-assignments.example.json +6 -0
  118. package/apps/storefront/src/lib/chrome/examples/tokenoftrust.chrome.example.json +79 -0
  119. package/apps/storefront/src/lib/chrome/model.ts +48 -253
  120. package/apps/storefront/src/lib/chrome/navCurrent.ts +29 -0
  121. package/apps/storefront/src/lib/chrome/parseConfig.ts +18 -32
  122. package/apps/storefront/src/lib/chrome/variant.ts +39 -0
  123. package/apps/storefront/src/lib/commerce/checkoutHandoffCorrelation.ts +105 -0
  124. package/apps/storefront/src/lib/compliance/tamper-sentinel-boot.ts +152 -0
  125. package/apps/storefront/src/lib/compliance/tamper-sentinel.ts +327 -0
  126. package/apps/storefront/src/lib/content/index.ts +5 -5
  127. package/apps/storefront/src/lib/content-edit/applyDiff.ts +1 -1
  128. package/apps/storefront/src/lib/content-edit/route.ts +1 -1
  129. package/apps/storefront/src/lib/d1/catalog.ts +12 -0
  130. package/apps/storefront/src/lib/d1/schema-apps.ts +276 -0
  131. package/apps/storefront/src/lib/dev/cockpit/ask.ts +49 -0
  132. package/apps/storefront/src/lib/dev/cockpit/clickToSource.ts +71 -0
  133. package/apps/storefront/src/lib/dev/cockpit/copyCommand.ts +227 -0
  134. package/apps/storefront/src/lib/dev/cockpit/files.ts +249 -0
  135. package/apps/storefront/src/lib/dev/cockpit/hostedActivity.ts +500 -0
  136. package/apps/storefront/src/lib/dev/cockpit/infoPopover.ts +12 -0
  137. package/apps/storefront/src/lib/dev/cockpit/mcpCopy.ts +34 -0
  138. package/apps/storefront/src/lib/dev/cockpit/monitor.ts +107 -0
  139. package/apps/storefront/src/lib/dev/cockpit/stepper.ts +116 -0
  140. package/apps/storefront/src/lib/dev/cockpit/themeToggle.ts +23 -0
  141. package/apps/storefront/src/lib/dev/runtimeStore.ts +1 -1
  142. package/apps/storefront/src/lib/edgeCache.ts +18 -6
  143. package/apps/storefront/src/lib/email/candidateConflictEmail.ts +80 -0
  144. package/apps/storefront/src/lib/integration/browserEnvironment.ts +137 -0
  145. package/apps/storefront/src/lib/integration/managedInstallDeclarations.ts +72 -0
  146. package/apps/storefront/src/lib/integration/nonceStamp.ts +49 -0
  147. package/apps/storefront/src/lib/integration/tenantDeclarations.ts +116 -0
  148. package/apps/storefront/src/lib/membership/eligibility.ts +1 -1
  149. package/apps/storefront/src/lib/membership/model.ts +1 -2
  150. package/apps/storefront/src/lib/newsletter/confirmationEmail.ts +2 -2
  151. package/apps/storefront/src/lib/newsletter/consent.ts +2 -2
  152. package/apps/storefront/src/lib/newsletter/send.ts +3 -3
  153. package/apps/storefront/src/lib/previewReload.ts +57 -1
  154. package/apps/storefront/src/lib/publish/adminPublishTab.ts +1775 -669
  155. package/apps/storefront/src/lib/publish/buildStream.ts +269 -0
  156. package/apps/storefront/src/lib/publish/collapsePersistence.ts +72 -0
  157. package/apps/storefront/src/lib/publish/lifecycleState.ts +369 -0
  158. package/apps/storefront/src/lib/publish/liveReleaseSummary.ts +29 -0
  159. package/apps/storefront/src/lib/publish/mergeDoctorOnFailure.ts +78 -0
  160. package/apps/storefront/src/lib/publish/mergeHealthBanner.ts +62 -0
  161. package/apps/storefront/src/lib/publish/mergeRowFindings.ts +124 -0
  162. package/apps/storefront/src/lib/publish/mergeSupportEscalation.ts +75 -0
  163. package/apps/storefront/src/lib/publish/publish-guard.ts +88 -0
  164. package/apps/storefront/src/lib/publish/publishFormat.ts +165 -0
  165. package/apps/storefront/src/lib/publish/publishHero.ts +177 -0
  166. package/apps/storefront/src/lib/publish/reviewRelease/changeState.ts +66 -0
  167. package/apps/storefront/src/lib/publish/reviewRelease/copy.ts +141 -0
  168. package/apps/storefront/src/lib/publish/reviewRelease/index.ts +41 -0
  169. package/apps/storefront/src/lib/publish/reviewRelease/permissions.ts +47 -0
  170. package/apps/storefront/src/lib/publish/reviewRelease/releaseState.ts +42 -0
  171. package/apps/storefront/src/lib/publish/reviewRelease/types.ts +59 -0
  172. package/apps/storefront/src/lib/publish/reviewRelease/viewModel.ts +440 -0
  173. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/actions.ts +161 -0
  174. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/controller.ts +325 -0
  175. package/apps/storefront/src/lib/publish/reviewReleaseWorkspace/render.ts +241 -0
  176. package/apps/storefront/src/lib/publish/shipWorkspace.ts +22 -3
  177. package/apps/storefront/src/lib/publish/sseRoute.ts +119 -0
  178. package/apps/storefront/src/lib/publish/streamLogConsole.ts +142 -0
  179. package/apps/storefront/src/lib/publish/versionNumber.ts +52 -0
  180. package/apps/storefront/src/lib/rawChrome.ts +125 -47
  181. package/apps/storefront/src/lib/rawMarketingHtml.ts +74 -3
  182. package/apps/storefront/src/lib/seo/alternates.ts +1 -1
  183. package/apps/storefront/src/lib/social/notify.ts +4 -4
  184. package/apps/storefront/src/lib/storyblok/content-model.ts +7 -33
  185. package/apps/storefront/src/lib/storyblok/provider.ts +168 -60
  186. package/apps/storefront/src/lib/subscription/model.ts +4 -4
  187. package/apps/storefront/src/lib/the-build/provider.ts +9 -4
  188. package/apps/storefront/src/middleware/index.ts +273 -51
  189. package/apps/storefront/src/pages/[...slug].astro +9 -4
  190. package/apps/storefront/src/pages/admin/review-release.astro +265 -0
  191. package/apps/storefront/src/pages/admin/select.astro +96 -0
  192. package/apps/storefront/src/pages/admin.astro +16 -2
  193. package/apps/storefront/src/pages/api/activity.ts +8 -8
  194. package/apps/storefront/src/pages/api/admin/activity-alerts.ts +5 -20
  195. package/apps/storefront/src/pages/api/admin/orders/[id].ts +7 -2
  196. package/apps/storefront/src/pages/api/admin/orders.ts +8 -2
  197. package/apps/storefront/src/pages/api/apps/admin/gtm-migration-install.ts +174 -0
  198. package/apps/storefront/src/pages/api/apps/admin/gtm-migration.ts +96 -0
  199. package/apps/storefront/src/pages/api/apps/admin/integration-lifecycle.ts +118 -0
  200. package/apps/storefront/src/pages/api/apps/admin/integrations.ts +89 -0
  201. package/apps/storefront/src/pages/api/apps/admin/platform-adapters.ts +85 -0
  202. package/apps/storefront/src/pages/api/apps/internal/order-forward.ts +74 -2
  203. package/apps/storefront/src/pages/api/commerce/checkout-handoff.ts +77 -0
  204. package/apps/storefront/src/pages/api/compliance/tamper.ts +88 -0
  205. package/apps/storefront/src/pages/api/integrations/v1/[operation].ts +108 -0
  206. package/apps/storefront/src/pages/api/rum/vitals.ts +1 -2
  207. package/apps/storefront/src/pages/blog/[slug].astro +5 -5
  208. package/apps/storefront/src/pages/blog/author/[author].astro +3 -3
  209. package/apps/storefront/src/pages/blog/category/[category].astro +2 -2
  210. package/apps/storefront/src/pages/blog/index.astro +2 -2
  211. package/apps/storefront/src/pages/blog/tag/[tag].astro +2 -2
  212. package/apps/storefront/src/pages/cockpit.astro +61 -1362
  213. package/apps/storefront/src/pages/index.astro +10 -5
  214. package/apps/storefront/src/pages/llms.txt.ts +1 -1
  215. package/apps/storefront/src/pages/products/[handle].astro +7 -6
  216. package/apps/storefront/src/pages/sitemap.xml.ts +2 -2
  217. package/apps/storefront/src/pages/style-guide/[tenant]/[theme].astro +31 -27
  218. package/apps/storefront/src/pages/style-guide/[tenant]/chrome/[theme].astro +1 -1
  219. package/apps/storefront/src/pages/tenants/[id]/[...path].ts +38 -2
  220. package/apps/storefront/src/pages/the-build/[slug].astro +4 -4
  221. package/apps/storefront/src/pages/the-build/index.astro +2 -2
  222. package/apps/storefront/src/pages/the-build/rss.xml.ts +2 -2
  223. package/apps/storefront/src/styles/admin.css +27 -1
  224. package/apps/storefront/tsconfig.json +1 -1
  225. package/package.json +1 -1
  226. package/packages/public-runtime/package.json +2 -1
  227. package/packages/public-runtime/schemas/managed-analytics/v1/adapter-definition.schema.json +427 -0
  228. package/packages/public-runtime/schemas/managed-analytics/v1/create-integration-install-request.schema.json +161 -0
  229. package/packages/public-runtime/schemas/managed-analytics/v1/create-migration-draft-request.schema.json +157 -0
  230. package/packages/public-runtime/schemas/managed-analytics/v1/delete-integration-install-request.schema.json +84 -0
  231. package/packages/public-runtime/schemas/managed-analytics/v1/delete-migration-draft-request.schema.json +84 -0
  232. package/packages/public-runtime/schemas/managed-analytics/v1/error-envelope.schema.json +180 -0
  233. package/packages/public-runtime/schemas/managed-analytics/v1/get-adapter-definition-request.schema.json +52 -0
  234. package/packages/public-runtime/schemas/managed-analytics/v1/get-integration-install-request.schema.json +52 -0
  235. package/packages/public-runtime/schemas/managed-analytics/v1/get-integration-revision-request.schema.json +79 -0
  236. package/packages/public-runtime/schemas/managed-analytics/v1/get-migration-draft-request.schema.json +52 -0
  237. package/packages/public-runtime/schemas/managed-analytics/v1/integration-install.schema.json +167 -0
  238. package/packages/public-runtime/schemas/managed-analytics/v1/integration-revision.schema.json +208 -0
  239. package/packages/public-runtime/schemas/managed-analytics/v1/list-adapter-definitions-request.schema.json +53 -0
  240. package/packages/public-runtime/schemas/managed-analytics/v1/list-integration-installs-request.schema.json +53 -0
  241. package/packages/public-runtime/schemas/managed-analytics/v1/list-integration-revisions-request.schema.json +82 -0
  242. package/packages/public-runtime/schemas/managed-analytics/v1/migration-draft.schema.json +218 -0
  243. package/packages/public-runtime/schemas/managed-analytics/v1/mutation-request.schema.json +52 -0
  244. package/packages/public-runtime/schemas/managed-analytics/v1/mutation-success-envelope.schema.json +49 -0
  245. package/packages/public-runtime/schemas/managed-analytics/v1/read-request.schema.json +20 -0
  246. package/packages/public-runtime/schemas/managed-analytics/v1/read-success-envelope.schema.json +45 -0
  247. package/packages/public-runtime/schemas/managed-analytics/v1/revise-integration-install-request.schema.json +156 -0
  248. package/packages/public-runtime/schemas/managed-analytics/v1/set-integration-install-status-request.schema.json +92 -0
  249. package/packages/public-runtime/schemas/managed-analytics/v1/update-migration-draft-request.schema.json +184 -0
  250. package/packages/public-runtime/scripts/generate-managed-analytics-api-v1-schemas.mjs +13 -0
  251. package/packages/public-runtime/src/activity/catalog.ts +41 -37
  252. package/packages/public-runtime/src/activity/event.ts +6 -6
  253. package/packages/public-runtime/src/activity/index.ts +2 -2
  254. package/packages/public-runtime/src/activity/redaction.ts +4 -4
  255. package/packages/public-runtime/src/candidate-index.ts +42 -8
  256. package/packages/public-runtime/src/checkout-orders.ts +2 -2
  257. package/packages/public-runtime/src/checkout-style-publish.ts +2 -2
  258. package/packages/public-runtime/src/checkout-style.ts +7 -7
  259. package/packages/public-runtime/src/checkout.ts +3 -3
  260. package/packages/public-runtime/src/chrome.ts +777 -0
  261. package/packages/public-runtime/src/compliance-obligations.ts +310 -0
  262. package/packages/public-runtime/src/csp.ts +99 -0
  263. package/packages/public-runtime/src/customization-runtime.ts +32 -1
  264. package/packages/public-runtime/src/destination-webhook/contract.ts +353 -0
  265. package/packages/public-runtime/src/embed-catalog.d.mts +9 -0
  266. package/packages/public-runtime/src/embed-catalog.mjs +40 -0
  267. package/packages/public-runtime/src/evidence.ts +288 -0
  268. package/packages/public-runtime/src/gtm-migration/bounds.ts +138 -0
  269. package/packages/public-runtime/src/gtm-migration/disposition-rules.ts +361 -0
  270. package/packages/public-runtime/src/gtm-migration/dispositions.ts +181 -0
  271. package/packages/public-runtime/src/gtm-migration/draft-generator.ts +400 -0
  272. package/packages/public-runtime/src/gtm-migration/graph.ts +468 -0
  273. package/packages/public-runtime/src/gtm-migration/index.ts +95 -0
  274. package/packages/public-runtime/src/gtm-migration/parse.ts +410 -0
  275. package/packages/public-runtime/src/gtm-migration/references.ts +266 -0
  276. package/packages/public-runtime/src/gtm-migration/types.ts +86 -0
  277. package/packages/public-runtime/src/index.ts +16 -1
  278. package/packages/public-runtime/src/integration/assurance-decision.ts +259 -0
  279. package/packages/public-runtime/src/integration/assurance.ts +228 -0
  280. package/packages/public-runtime/src/integration/candidate-evidence.ts +377 -0
  281. package/packages/public-runtime/src/integration/commerce-broker.ts +497 -0
  282. package/packages/public-runtime/src/integration/consent-broker.ts +337 -0
  283. package/packages/public-runtime/src/integration/consent-cmp-demand.ts +115 -0
  284. package/packages/public-runtime/src/integration/consent-config.ts +260 -0
  285. package/packages/public-runtime/src/integration/consent-preview.ts +125 -0
  286. package/packages/public-runtime/src/integration/correlation-token.ts +444 -0
  287. package/packages/public-runtime/src/integration/csp-compiler.ts +267 -0
  288. package/packages/public-runtime/src/integration/csp.ts +105 -0
  289. package/packages/public-runtime/src/integration/digest.ts +43 -0
  290. package/packages/public-runtime/src/integration/environment.ts +228 -0
  291. package/packages/public-runtime/src/integration/events-catalog.ts +186 -0
  292. package/packages/public-runtime/src/integration/events.ts +701 -0
  293. package/packages/public-runtime/src/integration/g2-action-boundary.ts +106 -0
  294. package/packages/public-runtime/src/integration/index.ts +90 -0
  295. package/packages/public-runtime/src/integration/interim-bridge.ts +138 -0
  296. package/packages/public-runtime/src/integration/lifecycle-boot.ts +317 -0
  297. package/packages/public-runtime/src/integration/lifecycle-runtime.ts +393 -0
  298. package/packages/public-runtime/src/integration/lifecycle.ts +94 -0
  299. package/packages/public-runtime/src/integration/managed-analytics-api-v1-safety.d.mts +2 -0
  300. package/packages/public-runtime/src/integration/managed-analytics-api-v1-safety.mjs +10 -0
  301. package/packages/public-runtime/src/integration/managed-analytics-api-v1.schemas.ts +382 -0
  302. package/packages/public-runtime/src/integration/managed-analytics-api-v1.ts +684 -0
  303. package/packages/public-runtime/src/integration/managed-analytics-bridge.ts +383 -0
  304. package/packages/public-runtime/src/integration/managed-analytics-value-safety.ts +14 -0
  305. package/packages/public-runtime/src/integration/managed-analytics.ts +277 -0
  306. package/packages/public-runtime/src/integration/manifest.ts +470 -0
  307. package/packages/public-runtime/src/integration/native-amplitude.ts +362 -0
  308. package/packages/public-runtime/src/integration/native-ga4.ts +352 -0
  309. package/packages/public-runtime/src/integration/observability.ts +451 -0
  310. package/packages/public-runtime/src/integration/order-conversion.ts +0 -0
  311. package/packages/public-runtime/src/integration/phases.ts +182 -0
  312. package/packages/public-runtime/src/integration/plan.ts +112 -0
  313. package/packages/public-runtime/src/integration/platform-adapter-runtime.ts +146 -0
  314. package/packages/public-runtime/src/integration/platform-adapters.ts +671 -0
  315. package/packages/public-runtime/src/integration/promotion-gate.ts +451 -0
  316. package/packages/public-runtime/src/integration/provider-checkout-extension.ts +425 -0
  317. package/packages/public-runtime/src/integration/receipt-measurement.ts +370 -0
  318. package/packages/public-runtime/src/integration/regulated-parent-cert.ts +311 -0
  319. package/packages/public-runtime/src/integration/render-phases.ts +267 -0
  320. package/packages/public-runtime/src/integration/resolve.ts +465 -0
  321. package/packages/public-runtime/src/integration/result.ts +239 -0
  322. package/packages/public-runtime/src/integration/secrets.ts +92 -0
  323. package/packages/public-runtime/src/integration/tamper-evidence.ts +205 -0
  324. package/packages/public-runtime/src/integration/tamper-recovery.ts +127 -0
  325. package/packages/public-runtime/src/integration/version.ts +92 -0
  326. package/packages/public-runtime/src/integration-capabilities.ts +520 -0
  327. package/packages/public-runtime/src/membership.ts +2 -2
  328. package/packages/public-runtime/src/raw-html-policy.ts +2 -4
  329. package/packages/public-runtime/src/regulated-commerce/broker/consent-dedupe.ts +144 -0
  330. package/packages/public-runtime/src/regulated-commerce/correlation/contract.ts +177 -0
  331. package/packages/public-runtime/src/regulated-commerce/diagnostics/local-dispatch.ts +24 -0
  332. package/packages/public-runtime/src/regulated-commerce/diagnostics/read-model.ts +69 -0
  333. package/packages/public-runtime/src/regulated-commerce/dispatch/core.ts +134 -0
  334. package/packages/public-runtime/src/regulated-commerce/events/contract.ts +113 -0
  335. package/packages/public-runtime/src/regulated-commerce/ledger/core.ts +81 -0
  336. package/packages/public-runtime/src/regulated-commerce/mappings/ga4-ads.ts +87 -0
  337. package/packages/public-runtime/src/regulated-commerce/provider-order/bridge.ts +52 -0
  338. package/packages/public-runtime/src/regulated-commerce/purchase-truth/contract.ts +252 -0
  339. package/packages/public-runtime/src/regulated-commerce/sources/accepted-browser-operation.ts +67 -0
  340. package/packages/public-runtime/src/regulated-commerce/testing/fake-destination.ts +93 -0
  341. package/packages/public-runtime/src/static-bundle.ts +5 -5
  342. package/packages/public-runtime/src/tenant-assets.ts +143 -4
  343. package/packages/public-runtime/src/tenant.ts +45 -9
  344. package/packages/public-runtime/tests/fixtures/integration/browser-environment.example.json +8 -0
  345. package/packages/public-runtime/tests/fixtures/integration/commerce-event.example.json +44 -0
  346. package/packages/public-runtime/tests/fixtures/integration/commerce-order-event.example.json +44 -0
  347. package/packages/public-runtime/tests/fixtures/integration/compliance-assurance-record.example.json +50 -0
  348. package/packages/public-runtime/tests/fixtures/integration/integration-manifest-v2.example.json +120 -0
  349. package/packages/public-runtime/tests/fixtures/integration/managed-analytics-v1/fake-adapter-catalog.json +35 -0
  350. package/packages/public-runtime/tests/fixtures/integration/tenant-action-registry.example.json +11 -0
  351. package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/README.md +22 -0
  352. package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/entry.js +30 -0
  353. package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/manifest.json +75 -0
  354. package/packages/public-runtime/tests/fixtures/integration/tenant-local-example/public-config.json +3 -0
  355. package/packages/public-runtime/tests/fixtures/regulated-commerce/fake-destinations.ts +38 -0
  356. package/packages/public-runtime/tests/gtm-migration/fixtures/gtm-sample-container-v84.provenance.json +29 -0
  357. package/packages/public-runtime/tests/gtm-migration/fixtures/gtm-sample-container-v84.redacted.json +3397 -0
  358. package/scripts/dev/file-browser.mjs +2 -2
  359. package/scripts/dev/file-writer.mjs +2 -2
  360. package/scripts/dev/integration-guardrails.mjs +498 -0
  361. package/scripts/dev/safe-path.mjs +2 -2
  362. package/scripts/dev/tenant-source-root.mjs +1 -1
  363. package/scripts/tot-dev.mjs +2 -2
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Inert typed model of a GTM (Google Tag Manager) container export, format v2.
3
+ *
4
+ * Every value here is DATA. Fields that in a live GTM runtime would be code — a
5
+ * Custom HTML tag's `html`, a Custom Template's `templateData` /
6
+ * `sandboxedJsForServer`, a Custom JavaScript variable's `javascript` — are
7
+ * captured as opaque inert strings inside each record's `raw` bag and are NEVER
8
+ * executed, evaluated, or interpreted by this package.
9
+ */
10
+
11
+ import type { GtmViolation } from "./bounds.js";
12
+
13
+ /**
14
+ * One inert record from a GTM collection (a tag, trigger, variable, …).
15
+ *
16
+ * `id`, `name`, and `type` are convenience fields lifted from whatever key GTM
17
+ * used (e.g. `tagId`/`triggerId`/`variableId`). `raw` is the COMPLETE inert bag
18
+ * of the record's fields (a null-prototype object, strings bounded/truncated),
19
+ * so nothing is silently dropped and downstream units can read any field they
20
+ * need without this package having to model it.
21
+ */
22
+ export interface GtmInertRecord {
23
+ readonly id: string | null;
24
+ readonly name: string | null;
25
+ readonly type: string | null;
26
+ /** Null-prototype bag of the record's full field set, captured as inert data. */
27
+ readonly raw: Record<string, unknown>;
28
+ }
29
+
30
+ /**
31
+ * The `containerVersion` object: container metadata plus the known collections.
32
+ * Every collection is present as an array (empty when the export omitted it).
33
+ */
34
+ export interface GtmContainerVersion {
35
+ // Container metadata (lifted from `containerVersion` or its nested `container`).
36
+ readonly containerId: string | null;
37
+ readonly path: string | null;
38
+ readonly publicId: string | null;
39
+ readonly fingerprint: string | null;
40
+ readonly name: string | null;
41
+
42
+ // Known collections, each a list of inert records.
43
+ readonly tag: GtmInertRecord[];
44
+ readonly trigger: GtmInertRecord[];
45
+ readonly variable: GtmInertRecord[];
46
+ readonly builtInVariable: GtmInertRecord[];
47
+ readonly customTemplate: GtmInertRecord[];
48
+ readonly folder: GtmInertRecord[];
49
+ readonly zone: GtmInertRecord[];
50
+ readonly client: GtmInertRecord[];
51
+ readonly gtagConfig: GtmInertRecord[];
52
+ readonly transformation: GtmInertRecord[];
53
+ }
54
+
55
+ /** The top-level v2 export: `{ exportFormatVersion, containerVersion }`. */
56
+ export interface GtmContainer {
57
+ readonly exportFormatVersion: number;
58
+ readonly containerVersion: GtmContainerVersion;
59
+ }
60
+
61
+ /**
62
+ * Complete object accounting so nothing in the input is silently dropped — a
63
+ * reviewer and downstream units check that every input object is accounted for.
64
+ */
65
+ export interface GtmParseAccounting {
66
+ /** Per modeled collection name → number of records extracted. */
67
+ readonly counts: Record<string, number>;
68
+ /** Top-level keys other than `exportFormatVersion` / `containerVersion`. */
69
+ readonly unknownTopLevelKeys: string[];
70
+ /** `containerVersion` keys that are neither modeled metadata nor a known collection. */
71
+ readonly unknownContainerKeys: string[];
72
+ /** Number of strings truncated to `maxStringLen` during capture. */
73
+ readonly truncatedStrings: number;
74
+ /** Number of `__proto__` / `constructor` / `prototype` keys skipped (quarantined). */
75
+ readonly quarantinedKeys: number;
76
+ /** Total nodes visited by the bounds walk. */
77
+ readonly totalNodes: number;
78
+ }
79
+
80
+ /**
81
+ * Structured result — the parser NEVER throws on bad input. On success it returns
82
+ * the inert container plus accounting; on failure a list of violations.
83
+ */
84
+ export type GtmParseResult =
85
+ | { ok: true; container: GtmContainer; accounting: GtmParseAccounting }
86
+ | { ok: false; violations: GtmViolation[] };
@@ -19,6 +19,8 @@ export * from "./checkout.js";
19
19
  export * from "./membership.js";
20
20
  export * from "./checkout-orders.js";
21
21
  export * from "./capabilities.js";
22
+ export * from "./compliance-obligations.js";
23
+ export * from "./evidence.js";
22
24
  export * from "./checkout-style.js";
23
25
  export * from "./checkout-style-publish.js";
24
26
  export * from "./catalog-api.js";
@@ -30,8 +32,10 @@ export * from "./customization-runtime.js";
30
32
  export * from "./customization-versioning.js";
31
33
  export * from "./customization-scripts.js";
32
34
  export * from "./customization-reconcile.js";
35
+ export * from "./chrome.js";
33
36
  export * from "./candidate-index.js";
34
37
  export * from "./extension-contract.js";
38
+ export * from "./integration-capabilities.js";
35
39
  export * from "./raw-html-policy.js";
36
40
  export * from "./review-trust-proof.js";
37
41
  export * from "./compliance/index.js";
@@ -42,8 +46,19 @@ export * from "./hot-standby-readiness.js";
42
46
  export * from "./hash.js";
43
47
  export * from "./widget-postmessage.js";
44
48
 
45
- // Operational activity telemetry contract (card D0): the actor×action
49
+ // Versioned public browser-integration contracts (environment, declaration,
50
+ // effective plan, phases, dependencies, lifecycle, config, assurance).
51
+ // See ./integration/index.ts.
52
+ export * from "./integration/index.js";
53
+
54
+ // Operational activity telemetry contract: the actor×action
46
55
  // ActivityEvent envelope, the allowlisted action catalog, and the default-deny
47
56
  // redaction contract. Pure types + pure functions; the store decision + cost
48
57
  // model live in the repo-root DECISIONS.md §8. See ./activity/README.md.
49
58
  export * from "./activity/index.js";
59
+
60
+ // GTM container-export migration: the SAFE, non-executing parser that turns an
61
+ // untrusted GTM export into an inert typed model + complete accounting. Pure
62
+ // data-in/data-out; never executes any part of the export. See
63
+ // ./gtm-migration/parse.ts for the full security contract.
64
+ export * from "./gtm-migration/index.js";
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Assurance enforcement — the decision layer over a validated
3
+ * {@link ComplianceAssuranceRecord} (ADR 0014 G1/G2, ADR 0023 Q2 legal gate).
4
+ *
5
+ * A record is the tenant-scoped audit of an elevated integration's declared
6
+ * effects. `validateComplianceAssuranceRecord` proves its shape and that it
7
+ * carries no secret; this module decides whether the audited state is actually
8
+ * approvable and whether a prior approval still holds. The two are separate
9
+ * concerns: a well-formed record can still be denied because the regulated
10
+ * floor is non-waivable, the vendor tried to approve its own code, the
11
+ * acknowledgement expired, the outside-guarantee wording is not yet wired, or
12
+ * the served integration no longer matches what was acknowledged.
13
+ *
14
+ * Invariants:
15
+ * - G1: the regulated shared-runtime floor is non-waivable. No acknowledgement
16
+ * path — no `eligibleForOutsideGuarantee` on a regulated surface — reduces it.
17
+ * - Outside-guarantee is a full-parent (`elevated-parent`) posture accepted
18
+ * ONLY on the eligible unregulated-marketing surface, and only once the Q2
19
+ * counsel wording is wired (`outsideGuaranteeEnabled`, default off).
20
+ * - G2: a regulated elevated-parent integration needs a green certification
21
+ * (`certifiedImmutable`, default off), never a mere acknowledgement.
22
+ * - The vendor cannot self-approve: the approver is a tenant owner or platform
23
+ * operator whose identity is not the integration's own.
24
+ * - A material change to the integration's code, version, scopes, CSP, or
25
+ * consent invalidates the prior approval; re-acknowledgement is required.
26
+ */
27
+ import {
28
+ type ComplianceAssuranceRecord,
29
+ type AssuranceActorRole,
30
+ ASSURANCE_ACTOR_ROLES,
31
+ validateComplianceAssuranceRecord,
32
+ } from "./assurance.js";
33
+ import type { ExecutionTier } from "./phases.js";
34
+
35
+ /**
36
+ * The roles authorized to acknowledge an elevated integration (charter
37
+ * responsibility matrix: the vendor "Cannot self-approve"). The vendor role is
38
+ * structurally absent from the record's actor enum; this constant is the
39
+ * decision-layer restatement so the authorization test reads against one name.
40
+ */
41
+ export const AUTHORIZED_APPROVER_ROLES: readonly AssuranceActorRole[] = ASSURANCE_ACTOR_ROLES;
42
+
43
+ /**
44
+ * The bound, material state an acknowledgement covers. A change to any field
45
+ * invalidates a prior approval. It is the integration reference plus the
46
+ * declared effects (scopes, consent purposes, CSP origins, data classes) — the
47
+ * exact things the operator reviewed.
48
+ */
49
+ export interface ApprovedIntegrationState {
50
+ appId: string;
51
+ version: string;
52
+ digest: string;
53
+ executionTier: ExecutionTier;
54
+ capabilities: readonly string[];
55
+ consentPurposes: readonly string[];
56
+ cspOrigins: readonly string[];
57
+ dataClasses: readonly string[];
58
+ }
59
+
60
+ /** The material state an assurance record acknowledges. */
61
+ export function assuredStateOfRecord(record: ComplianceAssuranceRecord): ApprovedIntegrationState {
62
+ return {
63
+ appId: record.integration.appId,
64
+ version: record.integration.version,
65
+ digest: record.integration.digest,
66
+ executionTier: record.integration.executionTier,
67
+ capabilities: record.declaredEffects.capabilities,
68
+ consentPurposes: record.declaredEffects.consentPurposes,
69
+ cspOrigins: record.declaredEffects.cspOrigins,
70
+ dataClasses: record.declaredEffects.dataClasses,
71
+ };
72
+ }
73
+
74
+ /**
75
+ * A stable, order-independent fingerprint of the material integration state.
76
+ * Two states with the same code/version/tier/scopes/CSP/consent fingerprint
77
+ * identically regardless of array ordering; any difference changes the digest.
78
+ */
79
+ export function assuranceFingerprint(state: ApprovedIntegrationState): string {
80
+ const canonical = {
81
+ appId: state.appId,
82
+ version: state.version,
83
+ digest: state.digest,
84
+ executionTier: state.executionTier,
85
+ capabilities: [...state.capabilities].sort(),
86
+ consentPurposes: [...state.consentPurposes].sort(),
87
+ cspOrigins: [...state.cspOrigins].sort(),
88
+ dataClasses: [...state.dataClasses].sort(),
89
+ };
90
+ return JSON.stringify(canonical);
91
+ }
92
+
93
+ /**
94
+ * True when the currently-resolved integration state differs materially from
95
+ * what the record acknowledged — a new digest, version, tier, capability,
96
+ * consent purpose, CSP origin, or data class. Such a change invalidates the
97
+ * prior approval and requires re-acknowledgement.
98
+ */
99
+ export function hasMaterialChange(
100
+ record: ComplianceAssuranceRecord,
101
+ current: ApprovedIntegrationState,
102
+ ): boolean {
103
+ return assuranceFingerprint(assuredStateOfRecord(record)) !== assuranceFingerprint(current);
104
+ }
105
+
106
+ export interface AssuranceDecisionContext {
107
+ /** Wall clock for expiry evaluation (ISO 8601). */
108
+ now: string;
109
+ /**
110
+ * Q2: the outside-guarantee acknowledgement wording is wired with the counsel
111
+ * language and eligibility. Defaults off — the tier stays gated until it is.
112
+ */
113
+ outsideGuaranteeEnabled?: boolean;
114
+ /**
115
+ * G2: a green capability-specific certification exists for this pinned,
116
+ * immutable regulated integration. Defaults off — regulated elevated-parent
117
+ * stays disabled until it is present.
118
+ */
119
+ certifiedImmutable?: boolean;
120
+ /**
121
+ * The integration's own publisher/vendor identity, when known server-side.
122
+ * An acknowledgement by this identity is a self-approval and is rejected even
123
+ * if it carries an operator role.
124
+ */
125
+ vendorActorId?: string;
126
+ /**
127
+ * The currently-resolved material integration state. When supplied, a
128
+ * material difference from the acknowledged state invalidates the approval.
129
+ */
130
+ current?: ApprovedIntegrationState;
131
+ }
132
+
133
+ export type AssuranceDenialReason =
134
+ | "invalid-record"
135
+ | "regulated-floor-waiver-attempt"
136
+ | "outside-guarantee-surface-ineligible"
137
+ | "outside-guarantee-not-eligible"
138
+ | "outside-guarantee-counsel-pending"
139
+ | "regulated-cert-missing"
140
+ | "elevated-parent-prohibited"
141
+ | "unauthorized-approver"
142
+ | "vendor-self-approval"
143
+ | "approval-expired"
144
+ | "material-change";
145
+
146
+ export interface AssuranceDenial {
147
+ reason: AssuranceDenialReason;
148
+ /** The offending value (surface, actor id, tier, or a timestamp), when one applies. */
149
+ subject?: string;
150
+ }
151
+
152
+ export type AssuranceDecision =
153
+ | { ok: true; record: ComplianceAssuranceRecord; outsideGuarantee: boolean }
154
+ | { ok: false; denials: AssuranceDenial[] };
155
+
156
+ /**
157
+ * Whether a record's surface/tier combination is the outside-guarantee posture:
158
+ * full parent authority moved onto the one eligible unregulated-marketing
159
+ * surface. It is never regulated (that would waive the floor) and never
160
+ * commerce (parent code is prohibited there).
161
+ */
162
+ function isOutsideGuaranteePosture(record: ComplianceAssuranceRecord): boolean {
163
+ return (
164
+ record.integration.executionTier === "elevated-parent" &&
165
+ record.surface === "unregulated-marketing"
166
+ );
167
+ }
168
+
169
+ /**
170
+ * Decide whether an assurance record approves the audited integration. Validates
171
+ * the record shape first (a malformed or secret-bearing payload is `invalid-record`),
172
+ * then applies the floor, eligibility, authorization, expiry, and material-change
173
+ * rules. Fail-closed: every failed rule is reported and `ok` is false unless the
174
+ * record clears all of them.
175
+ */
176
+ export function decideAssurance(
177
+ input: unknown,
178
+ context: AssuranceDecisionContext,
179
+ ): AssuranceDecision {
180
+ const validation = validateComplianceAssuranceRecord(input);
181
+ if (!validation.ok) {
182
+ return { ok: false, denials: [{ reason: "invalid-record" }] };
183
+ }
184
+ const record = validation.value;
185
+ const denials: AssuranceDenial[] = [];
186
+
187
+ const { surface, compliance, integration, acknowledgement } = record;
188
+ const elevated = integration.executionTier === "elevated-parent";
189
+
190
+ // G1 — the regulated shared-runtime floor is non-waivable. An
191
+ // outside-guarantee eligibility claim on a regulated surface is an attempt to
192
+ // move regulated execution outside the guarantee; it is rejected, never honored.
193
+ if (surface === "regulated" && compliance.eligibleForOutsideGuarantee) {
194
+ denials.push({ reason: "regulated-floor-waiver-attempt", subject: surface });
195
+ }
196
+
197
+ // Outside-guarantee is claimable only in its one posture. On any other
198
+ // surface/tier combination the eligibility flag is an ineligible claim.
199
+ if (
200
+ compliance.eligibleForOutsideGuarantee &&
201
+ surface !== "regulated" &&
202
+ !isOutsideGuaranteePosture(record)
203
+ ) {
204
+ denials.push({ reason: "outside-guarantee-surface-ineligible", subject: surface });
205
+ }
206
+
207
+ // Elevated-parent (full parent authority) gating, by surface.
208
+ if (elevated) {
209
+ switch (surface) {
210
+ case "unregulated-marketing":
211
+ if (!compliance.eligibleForOutsideGuarantee) {
212
+ denials.push({ reason: "outside-guarantee-not-eligible", subject: surface });
213
+ }
214
+ // Q2: the tier stays gated off until the counsel wording is wired.
215
+ if (!context.outsideGuaranteeEnabled) {
216
+ denials.push({ reason: "outside-guarantee-counsel-pending", subject: surface });
217
+ }
218
+ break;
219
+ case "regulated":
220
+ // G2: proof, never acknowledgement. The floor is not waived here.
221
+ if (!context.certifiedImmutable) {
222
+ denials.push({ reason: "regulated-cert-missing", subject: surface });
223
+ }
224
+ break;
225
+ case "commerce":
226
+ denials.push({ reason: "elevated-parent-prohibited", subject: surface });
227
+ break;
228
+ }
229
+ }
230
+
231
+ // The vendor cannot self-approve. The approver holds an operator role and is
232
+ // not the integration's own publisher identity.
233
+ if (!AUTHORIZED_APPROVER_ROLES.includes(acknowledgement.actorRole)) {
234
+ denials.push({ reason: "unauthorized-approver", subject: acknowledgement.actorRole });
235
+ }
236
+ if (
237
+ acknowledgement.actorId === integration.appId ||
238
+ (context.vendorActorId !== undefined && acknowledgement.actorId === context.vendorActorId)
239
+ ) {
240
+ denials.push({ reason: "vendor-self-approval", subject: acknowledgement.actorId });
241
+ }
242
+
243
+ // Expiry / re-review. A window that has passed — or one that never opened
244
+ // (expiry at or before the acknowledgement) — is expired.
245
+ const recordedAt = Date.parse(acknowledgement.recordedAt);
246
+ const expiresAt = Date.parse(acknowledgement.expiresAt);
247
+ const now = Date.parse(context.now);
248
+ if (Number.isNaN(now) || expiresAt <= recordedAt || now >= expiresAt) {
249
+ denials.push({ reason: "approval-expired", subject: acknowledgement.expiresAt });
250
+ }
251
+
252
+ // A material change to the served integration invalidates the approval.
253
+ if (context.current && hasMaterialChange(record, context.current)) {
254
+ denials.push({ reason: "material-change", subject: integration.digest });
255
+ }
256
+
257
+ if (denials.length > 0) return { ok: false, denials };
258
+ return { ok: true, record, outsideGuarantee: isOutsideGuaranteePosture(record) };
259
+ }
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Compliance assurance metadata (ADR 0014 G1 `integration-regulated-floor-
3
+ * nonwaivable`, G2, and ADR 0023 legal release gates).
4
+ *
5
+ * An assurance record is the tenant-scoped audit of an elevated integration's
6
+ * declared effects, the operator acknowledgement, and the known-good rollback
7
+ * target. It carries no secret and no authorization token. The regulated
8
+ * shared-runtime floor is non-waivable: `regulatedSharedRuntimeWaiver` must be
9
+ * `false` — a `true` is rejected, never honored.
10
+ */
11
+ import type { ContractResult } from "./result.js";
12
+ import {
13
+ Violations,
14
+ reqObject,
15
+ childObject,
16
+ reqEnum,
17
+ reqLiteral,
18
+ reqString,
19
+ reqBool,
20
+ reqStringArray,
21
+ reqIsoTimestamp,
22
+ rejectUnknownKeys,
23
+ } from "./result.js";
24
+ import { ASSURANCE_RECORD_SCHEMA_VERSION } from "./version.js";
25
+ import { INTEGRATION_ENVIRONMENTS } from "./environment.js";
26
+ import type { IntegrationEnvironment } from "./environment.js";
27
+ import {
28
+ EXECUTION_TIERS,
29
+ type ExecutionTier,
30
+ } from "./phases.js";
31
+ import {
32
+ ASSURANCE_CLASSIFICATIONS,
33
+ type AssuranceClassification,
34
+ } from "./manifest.js";
35
+ import { validateOriginList } from "./csp.js";
36
+ import { findForbiddenFields } from "./secrets.js";
37
+ import type { Surface } from "../integration-capabilities.js";
38
+
39
+ /**
40
+ * The compliance-authority axis: the canonical {@link Surface} taxonomy projected
41
+ * so `checkout-payment` shares `commerce` authority (it is a strictly-more-protected
42
+ * sub-surface of commerce, but carries the same tenant authority tier). The
43
+ * `satisfies` binding is a compile-time proof that every authority surface is a
44
+ * canonical surface — the two vocabularies cannot drift. Use `surfaceAuthority`
45
+ * to project a surface onto this axis.
46
+ */
47
+ export const ASSURANCE_SURFACES = [
48
+ "unregulated-marketing",
49
+ "commerce",
50
+ "regulated",
51
+ ] as const satisfies readonly Surface[];
52
+ export type AssuranceSurface = (typeof ASSURANCE_SURFACES)[number];
53
+
54
+ // Compile-time proof the authority axis is exactly the canonical surfaces minus
55
+ // the `checkout-payment` sub-surface — no authority distinction is lost or invented.
56
+ type _AssuranceSurfaceIsSurfaceMinusCheckout = Surface extends AssuranceSurface | "checkout-payment"
57
+ ? AssuranceSurface extends Exclude<Surface, "checkout-payment">
58
+ ? true
59
+ : never
60
+ : never;
61
+ const _assuranceSurfaceExhaustive: _AssuranceSurfaceIsSurfaceMinusCheckout = true;
62
+ void _assuranceSurfaceExhaustive;
63
+
64
+ /**
65
+ * Project a surface onto its compliance-authority tier. `checkout-payment` folds
66
+ * into `commerce` (same authority, stricter capability floor enforced by the
67
+ * surface × tenant-tier matrix); every other surface is its own authority tier.
68
+ */
69
+ export function surfaceAuthority(surface: Surface): AssuranceSurface {
70
+ return surface === "checkout-payment" ? "commerce" : surface;
71
+ }
72
+
73
+ export const ASSURANCE_ACTOR_ROLES = ["tenant-owner", "platform-operator"] as const;
74
+ export type AssuranceActorRole = (typeof ASSURANCE_ACTOR_ROLES)[number];
75
+
76
+ export interface AssuranceDeclaredEffects {
77
+ capabilities: string[];
78
+ consentPurposes: string[];
79
+ cspOrigins: string[];
80
+ dataClasses: string[];
81
+ }
82
+
83
+ export interface AssuranceCompliance {
84
+ /** The regulated floor is non-waivable; this is always false. */
85
+ regulatedSharedRuntimeWaiver: false;
86
+ configuredObligations: string[];
87
+ eligibleForOutsideGuarantee: boolean;
88
+ protectedSurfaceEvidence: string;
89
+ }
90
+
91
+ export interface AssuranceAcknowledgement {
92
+ actorId: string;
93
+ actorRole: AssuranceActorRole;
94
+ reason: string;
95
+ recordedAt: string;
96
+ expiresAt: string;
97
+ }
98
+
99
+ export interface AssuranceIntegrationRef {
100
+ appId: string;
101
+ version: string;
102
+ digest: string;
103
+ executionTier: ExecutionTier;
104
+ }
105
+
106
+ export interface AssuranceRollback {
107
+ knownGoodVersion: string;
108
+ knownGoodRevision: string;
109
+ }
110
+
111
+ export interface ComplianceAssuranceRecord {
112
+ schemaVersion: typeof ASSURANCE_RECORD_SCHEMA_VERSION;
113
+ recordId: string;
114
+ tenantPublicId: string;
115
+ environment: IntegrationEnvironment;
116
+ surface: AssuranceSurface;
117
+ classification: AssuranceClassification;
118
+ integration: AssuranceIntegrationRef;
119
+ declaredEffects: AssuranceDeclaredEffects;
120
+ compliance: AssuranceCompliance;
121
+ acknowledgement: AssuranceAcknowledgement;
122
+ rollback: AssuranceRollback;
123
+ }
124
+
125
+ export function validateComplianceAssuranceRecord(
126
+ input: unknown,
127
+ ): ContractResult<ComplianceAssuranceRecord> {
128
+ const v = new Violations();
129
+ const obj = reqObject(input, v, "");
130
+ if (!obj) return { ok: false, violations: v.items };
131
+
132
+ rejectUnknownKeys(
133
+ obj,
134
+ [
135
+ "schemaVersion",
136
+ "recordId",
137
+ "tenantPublicId",
138
+ "environment",
139
+ "surface",
140
+ "classification",
141
+ "integration",
142
+ "declaredEffects",
143
+ "compliance",
144
+ "acknowledgement",
145
+ "rollback",
146
+ ],
147
+ v,
148
+ "",
149
+ );
150
+
151
+ reqLiteral(obj, "schemaVersion", ASSURANCE_RECORD_SCHEMA_VERSION, v, "");
152
+ reqString(obj, "recordId", v, "");
153
+ reqString(obj, "tenantPublicId", v, "");
154
+ reqEnum(obj, "environment", INTEGRATION_ENVIRONMENTS, v, "");
155
+ reqEnum(obj, "surface", ASSURANCE_SURFACES, v, "");
156
+ reqEnum(obj, "classification", ASSURANCE_CLASSIFICATIONS, v, "");
157
+
158
+ const integration = childObject(obj, "integration", v, "");
159
+ if (integration) {
160
+ rejectUnknownKeys(integration, ["appId", "version", "digest", "executionTier"], v, "integration");
161
+ reqString(integration, "appId", v, "integration");
162
+ reqString(integration, "version", v, "integration");
163
+ reqString(integration, "digest", v, "integration");
164
+ reqEnum(integration, "executionTier", EXECUTION_TIERS, v, "integration");
165
+ }
166
+
167
+ const declaredEffects = childObject(obj, "declaredEffects", v, "");
168
+ if (declaredEffects) {
169
+ rejectUnknownKeys(
170
+ declaredEffects,
171
+ ["capabilities", "consentPurposes", "cspOrigins", "dataClasses"],
172
+ v,
173
+ "declaredEffects",
174
+ );
175
+ reqStringArray(declaredEffects, "capabilities", v, "declaredEffects");
176
+ reqStringArray(declaredEffects, "consentPurposes", v, "declaredEffects");
177
+ const origins = reqStringArray(declaredEffects, "cspOrigins", v, "declaredEffects");
178
+ if (origins) validateOriginList(origins, v, "declaredEffects.cspOrigins");
179
+ reqStringArray(declaredEffects, "dataClasses", v, "declaredEffects");
180
+ }
181
+
182
+ const compliance = childObject(obj, "compliance", v, "");
183
+ if (compliance) {
184
+ rejectUnknownKeys(
185
+ compliance,
186
+ [
187
+ "regulatedSharedRuntimeWaiver",
188
+ "configuredObligations",
189
+ "eligibleForOutsideGuarantee",
190
+ "protectedSurfaceEvidence",
191
+ ],
192
+ v,
193
+ "compliance",
194
+ );
195
+ // The regulated floor is non-waivable: a waiver of true is rejected.
196
+ reqLiteral(compliance, "regulatedSharedRuntimeWaiver", false, v, "compliance");
197
+ reqStringArray(compliance, "configuredObligations", v, "compliance");
198
+ reqBool(compliance, "eligibleForOutsideGuarantee", v, "compliance");
199
+ reqString(compliance, "protectedSurfaceEvidence", v, "compliance");
200
+ }
201
+
202
+ const acknowledgement = childObject(obj, "acknowledgement", v, "");
203
+ if (acknowledgement) {
204
+ rejectUnknownKeys(
205
+ acknowledgement,
206
+ ["actorId", "actorRole", "reason", "recordedAt", "expiresAt"],
207
+ v,
208
+ "acknowledgement",
209
+ );
210
+ reqString(acknowledgement, "actorId", v, "acknowledgement");
211
+ reqEnum(acknowledgement, "actorRole", ASSURANCE_ACTOR_ROLES, v, "acknowledgement");
212
+ reqString(acknowledgement, "reason", v, "acknowledgement");
213
+ reqIsoTimestamp(acknowledgement, "recordedAt", v, "acknowledgement");
214
+ reqIsoTimestamp(acknowledgement, "expiresAt", v, "acknowledgement");
215
+ }
216
+
217
+ const rollback = childObject(obj, "rollback", v, "");
218
+ if (rollback) {
219
+ rejectUnknownKeys(rollback, ["knownGoodVersion", "knownGoodRevision"], v, "rollback");
220
+ reqString(rollback, "knownGoodVersion", v, "rollback");
221
+ reqString(rollback, "knownGoodRevision", v, "rollback");
222
+ }
223
+
224
+ for (const violation of findForbiddenFields(obj)) v.items.push(violation);
225
+
226
+ if (!v.ok) return { ok: false, violations: v.items };
227
+ return { ok: true, value: input as ComplianceAssuranceRecord };
228
+ }