@aglyn/aglyn 1.0.0-beta.143

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 (963) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +11 -0
  3. package/package.json +66 -0
  4. package/src/index.d.ts +25 -0
  5. package/src/index.js +26 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/aglyn.d.ts +31 -0
  8. package/src/lib/aglyn.js +114 -0
  9. package/src/lib/aglyn.js.map +1 -0
  10. package/src/lib/app-utils/abuse-report.d.ts +193 -0
  11. package/src/lib/app-utils/abuse-report.js +321 -0
  12. package/src/lib/app-utils/abuse-report.js.map +1 -0
  13. package/src/lib/app-utils/accept-negotiation.d.ts +129 -0
  14. package/src/lib/app-utils/accept-negotiation.js +266 -0
  15. package/src/lib/app-utils/accept-negotiation.js.map +1 -0
  16. package/src/lib/app-utils/account-emails.d.ts +263 -0
  17. package/src/lib/app-utils/account-emails.js +264 -0
  18. package/src/lib/app-utils/account-emails.js.map +1 -0
  19. package/src/lib/app-utils/actions.d.ts +717 -0
  20. package/src/lib/app-utils/actions.js +1031 -0
  21. package/src/lib/app-utils/actions.js.map +1 -0
  22. package/src/lib/app-utils/activity-presenter.d.ts +152 -0
  23. package/src/lib/app-utils/activity-presenter.js +326 -0
  24. package/src/lib/app-utils/activity-presenter.js.map +1 -0
  25. package/src/lib/app-utils/advertising-tag-mounts.d.ts +133 -0
  26. package/src/lib/app-utils/advertising-tag-mounts.js +118 -0
  27. package/src/lib/app-utils/advertising-tag-mounts.js.map +1 -0
  28. package/src/lib/app-utils/advertising-tags.d.ts +307 -0
  29. package/src/lib/app-utils/advertising-tags.js +525 -0
  30. package/src/lib/app-utils/advertising-tags.js.map +1 -0
  31. package/src/lib/app-utils/agent-api-catalog.d.ts +94 -0
  32. package/src/lib/app-utils/agent-api-catalog.js +106 -0
  33. package/src/lib/app-utils/agent-api-catalog.js.map +1 -0
  34. package/src/lib/app-utils/agent-openapi.d.ts +103 -0
  35. package/src/lib/app-utils/agent-openapi.js +1128 -0
  36. package/src/lib/app-utils/agent-openapi.js.map +1 -0
  37. package/src/lib/app-utils/analytics-beacon.d.ts +154 -0
  38. package/src/lib/app-utils/analytics-beacon.js +152 -0
  39. package/src/lib/app-utils/analytics-beacon.js.map +1 -0
  40. package/src/lib/app-utils/analytics-environment.d.ts +133 -0
  41. package/src/lib/app-utils/analytics-environment.js +152 -0
  42. package/src/lib/app-utils/analytics-environment.js.map +1 -0
  43. package/src/lib/app-utils/analytics-events.d.ts +744 -0
  44. package/src/lib/app-utils/analytics-events.js +650 -0
  45. package/src/lib/app-utils/analytics-events.js.map +1 -0
  46. package/src/lib/app-utils/analytics-link-clicks.d.ts +102 -0
  47. package/src/lib/app-utils/analytics-link-clicks.js +267 -0
  48. package/src/lib/app-utils/analytics-link-clicks.js.map +1 -0
  49. package/src/lib/app-utils/analytics-path-key.d.ts +46 -0
  50. package/src/lib/app-utils/analytics-path-key.js +46 -0
  51. package/src/lib/app-utils/analytics-path-key.js.map +1 -0
  52. package/src/lib/app-utils/api-adapter.d.ts +47 -0
  53. package/src/lib/app-utils/api-adapter.js +367 -0
  54. package/src/lib/app-utils/api-adapter.js.map +1 -0
  55. package/src/lib/app-utils/api-idempotency.d.ts +169 -0
  56. package/src/lib/app-utils/api-idempotency.js +213 -0
  57. package/src/lib/app-utils/api-idempotency.js.map +1 -0
  58. package/src/lib/app-utils/api-plugins.d.ts +210 -0
  59. package/src/lib/app-utils/api-plugins.js +221 -0
  60. package/src/lib/app-utils/api-plugins.js.map +1 -0
  61. package/src/lib/app-utils/assist-credits.d.ts +482 -0
  62. package/src/lib/app-utils/assist-credits.js +509 -0
  63. package/src/lib/app-utils/assist-credits.js.map +1 -0
  64. package/src/lib/app-utils/attribution-attribute.d.ts +34 -0
  65. package/src/lib/app-utils/attribution-attribute.js +34 -0
  66. package/src/lib/app-utils/attribution-attribute.js.map +1 -0
  67. package/src/lib/app-utils/attribution-guard.d.ts +130 -0
  68. package/src/lib/app-utils/attribution-guard.js +410 -0
  69. package/src/lib/app-utils/attribution-guard.js.map +1 -0
  70. package/src/lib/app-utils/author-css.d.ts +123 -0
  71. package/src/lib/app-utils/author-css.js +275 -0
  72. package/src/lib/app-utils/author-css.js.map +1 -0
  73. package/src/lib/app-utils/author-html-markdown.d.ts +31 -0
  74. package/src/lib/app-utils/author-html-markdown.js +497 -0
  75. package/src/lib/app-utils/author-html-markdown.js.map +1 -0
  76. package/src/lib/app-utils/author-html.d.ts +135 -0
  77. package/src/lib/app-utils/author-html.js +1037 -0
  78. package/src/lib/app-utils/author-html.js.map +1 -0
  79. package/src/lib/app-utils/automation-placeholders.d.ts +72 -0
  80. package/src/lib/app-utils/automation-placeholders.js +207 -0
  81. package/src/lib/app-utils/automation-placeholders.js.map +1 -0
  82. package/src/lib/app-utils/bandwidth-cap.d.ts +183 -0
  83. package/src/lib/app-utils/bandwidth-cap.js +193 -0
  84. package/src/lib/app-utils/bandwidth-cap.js.map +1 -0
  85. package/src/lib/app-utils/binding-token-catalog.d.ts +82 -0
  86. package/src/lib/app-utils/binding-token-catalog.js +293 -0
  87. package/src/lib/app-utils/binding-token-catalog.js.map +1 -0
  88. package/src/lib/app-utils/binding-tokens.d.ts +157 -0
  89. package/src/lib/app-utils/binding-tokens.js +251 -0
  90. package/src/lib/app-utils/binding-tokens.js.map +1 -0
  91. package/src/lib/app-utils/breadcrumb-json-ld.d.ts +57 -0
  92. package/src/lib/app-utils/breadcrumb-json-ld.js +67 -0
  93. package/src/lib/app-utils/breadcrumb-json-ld.js.map +1 -0
  94. package/src/lib/app-utils/campaign-attribution.d.ts +117 -0
  95. package/src/lib/app-utils/campaign-attribution.js +162 -0
  96. package/src/lib/app-utils/campaign-attribution.js.map +1 -0
  97. package/src/lib/app-utils/campaign-forwarding.d.ts +220 -0
  98. package/src/lib/app-utils/campaign-forwarding.js +332 -0
  99. package/src/lib/app-utils/campaign-forwarding.js.map +1 -0
  100. package/src/lib/app-utils/campaign-membership.d.ts +109 -0
  101. package/src/lib/app-utils/campaign-membership.js +176 -0
  102. package/src/lib/app-utils/campaign-membership.js.map +1 -0
  103. package/src/lib/app-utils/campaign-touch.d.ts +206 -0
  104. package/src/lib/app-utils/campaign-touch.js +326 -0
  105. package/src/lib/app-utils/campaign-touch.js.map +1 -0
  106. package/src/lib/app-utils/child-contract-compose.d.ts +28 -0
  107. package/src/lib/app-utils/child-contract-compose.js +140 -0
  108. package/src/lib/app-utils/child-contract-compose.js.map +1 -0
  109. package/src/lib/app-utils/child-contract.d.ts +129 -0
  110. package/src/lib/app-utils/child-contract.js +153 -0
  111. package/src/lib/app-utils/child-contract.js.map +1 -0
  112. package/src/lib/app-utils/collection-delete.d.ts +113 -0
  113. package/src/lib/app-utils/collection-delete.js +120 -0
  114. package/src/lib/app-utils/collection-delete.js.map +1 -0
  115. package/src/lib/app-utils/collection-entries.d.ts +833 -0
  116. package/src/lib/app-utils/collection-entries.js +1285 -0
  117. package/src/lib/app-utils/collection-entries.js.map +1 -0
  118. package/src/lib/app-utils/collection-entry-date.d.ts +129 -0
  119. package/src/lib/app-utils/collection-entry-date.js +183 -0
  120. package/src/lib/app-utils/collection-entry-date.js.map +1 -0
  121. package/src/lib/app-utils/collection-kind.d.ts +55 -0
  122. package/src/lib/app-utils/collection-kind.js +69 -0
  123. package/src/lib/app-utils/collection-kind.js.map +1 -0
  124. package/src/lib/app-utils/collection-slug.d.ts +79 -0
  125. package/src/lib/app-utils/collection-slug.js +70 -0
  126. package/src/lib/app-utils/collection-slug.js.map +1 -0
  127. package/src/lib/app-utils/compose-layout-nodes.d.ts +147 -0
  128. package/src/lib/app-utils/compose-layout-nodes.js +261 -0
  129. package/src/lib/app-utils/compose-layout-nodes.js.map +1 -0
  130. package/src/lib/app-utils/compose-layout-props.d.ts +71 -0
  131. package/src/lib/app-utils/compose-layout-props.js +61 -0
  132. package/src/lib/app-utils/compose-layout-props.js.map +1 -0
  133. package/src/lib/app-utils/compose-reusable-components.d.ts +504 -0
  134. package/src/lib/app-utils/compose-reusable-components.js +1366 -0
  135. package/src/lib/app-utils/compose-reusable-components.js.map +1 -0
  136. package/src/lib/app-utils/compress.d.ts +35 -0
  137. package/src/lib/app-utils/compress.js +38 -0
  138. package/src/lib/app-utils/compress.js.map +1 -0
  139. package/src/lib/app-utils/consent-banner-ui.d.ts +226 -0
  140. package/src/lib/app-utils/consent-banner-ui.js +583 -0
  141. package/src/lib/app-utils/consent-banner-ui.js.map +1 -0
  142. package/src/lib/app-utils/consent-groups.d.ts +189 -0
  143. package/src/lib/app-utils/consent-groups.js +219 -0
  144. package/src/lib/app-utils/consent-groups.js.map +1 -0
  145. package/src/lib/app-utils/consent-preferences-dialog.d.ts +58 -0
  146. package/src/lib/app-utils/consent-preferences-dialog.js +106 -0
  147. package/src/lib/app-utils/consent-preferences-dialog.js.map +1 -0
  148. package/src/lib/app-utils/console-record-links.d.ts +163 -0
  149. package/src/lib/app-utils/console-record-links.js +178 -0
  150. package/src/lib/app-utils/console-record-links.js.map +1 -0
  151. package/src/lib/app-utils/console-routes.d.ts +658 -0
  152. package/src/lib/app-utils/console-routes.js +489 -0
  153. package/src/lib/app-utils/console-routes.js.map +1 -0
  154. package/src/lib/app-utils/console-widget-slot-context.d.ts +46 -0
  155. package/src/lib/app-utils/console-widget-slot-context.js +23 -0
  156. package/src/lib/app-utils/console-widget-slot-context.js.map +1 -0
  157. package/src/lib/app-utils/contact-custom-fields.d.ts +191 -0
  158. package/src/lib/app-utils/contact-custom-fields.js +349 -0
  159. package/src/lib/app-utils/contact-custom-fields.js.map +1 -0
  160. package/src/lib/app-utils/contact-holder.d.ts +52 -0
  161. package/src/lib/app-utils/contact-holder.js +98 -0
  162. package/src/lib/app-utils/contact-holder.js.map +1 -0
  163. package/src/lib/app-utils/contact-merge.d.ts +136 -0
  164. package/src/lib/app-utils/contact-merge.js +379 -0
  165. package/src/lib/app-utils/contact-merge.js.map +1 -0
  166. package/src/lib/app-utils/contacts.d.ts +554 -0
  167. package/src/lib/app-utils/contacts.js +401 -0
  168. package/src/lib/app-utils/contacts.js.map +1 -0
  169. package/src/lib/app-utils/content-author-profile.d.ts +68 -0
  170. package/src/lib/app-utils/content-author-profile.js +118 -0
  171. package/src/lib/app-utils/content-author-profile.js.map +1 -0
  172. package/src/lib/app-utils/content-authors.d.ts +662 -0
  173. package/src/lib/app-utils/content-authors.js +771 -0
  174. package/src/lib/app-utils/content-authors.js.map +1 -0
  175. package/src/lib/app-utils/content-schema-type.d.ts +81 -0
  176. package/src/lib/app-utils/content-schema-type.js +87 -0
  177. package/src/lib/app-utils/content-schema-type.js.map +1 -0
  178. package/src/lib/app-utils/contexts.d.ts +35 -0
  179. package/src/lib/app-utils/contexts.js +35 -0
  180. package/src/lib/app-utils/contexts.js.map +1 -0
  181. package/src/lib/app-utils/create-resource-uid.d.ts +18 -0
  182. package/src/lib/app-utils/create-resource-uid.js +23 -0
  183. package/src/lib/app-utils/create-resource-uid.js.map +1 -0
  184. package/src/lib/app-utils/crm-booking.d.ts +75 -0
  185. package/src/lib/app-utils/crm-booking.js +133 -0
  186. package/src/lib/app-utils/crm-booking.js.map +1 -0
  187. package/src/lib/app-utils/crm-csv.d.ts +232 -0
  188. package/src/lib/app-utils/crm-csv.js +432 -0
  189. package/src/lib/app-utils/crm-csv.js.map +1 -0
  190. package/src/lib/app-utils/crm-digest.d.ts +179 -0
  191. package/src/lib/app-utils/crm-digest.js +271 -0
  192. package/src/lib/app-utils/crm-digest.js.map +1 -0
  193. package/src/lib/app-utils/crm-email-templates.d.ts +172 -0
  194. package/src/lib/app-utils/crm-email-templates.js +382 -0
  195. package/src/lib/app-utils/crm-email-templates.js.map +1 -0
  196. package/src/lib/app-utils/crm-inbound.d.ts +245 -0
  197. package/src/lib/app-utils/crm-inbound.js +407 -0
  198. package/src/lib/app-utils/crm-inbound.js.map +1 -0
  199. package/src/lib/app-utils/crm-kinds.d.ts +73 -0
  200. package/src/lib/app-utils/crm-kinds.js +92 -0
  201. package/src/lib/app-utils/crm-kinds.js.map +1 -0
  202. package/src/lib/app-utils/crm-next-activity.d.ts +107 -0
  203. package/src/lib/app-utils/crm-next-activity.js +140 -0
  204. package/src/lib/app-utils/crm-next-activity.js.map +1 -0
  205. package/src/lib/app-utils/crm-reports.d.ts +479 -0
  206. package/src/lib/app-utils/crm-reports.js +680 -0
  207. package/src/lib/app-utils/crm-reports.js.map +1 -0
  208. package/src/lib/app-utils/crm-task-reminders.d.ts +129 -0
  209. package/src/lib/app-utils/crm-task-reminders.js +139 -0
  210. package/src/lib/app-utils/crm-task-reminders.js.map +1 -0
  211. package/src/lib/app-utils/crm.d.ts +1546 -0
  212. package/src/lib/app-utils/crm.js +1814 -0
  213. package/src/lib/app-utils/crm.js.map +1 -0
  214. package/src/lib/app-utils/csp-report.d.ts +84 -0
  215. package/src/lib/app-utils/csp-report.js +177 -0
  216. package/src/lib/app-utils/csp-report.js.map +1 -0
  217. package/src/lib/app-utils/csv-import.d.ts +192 -0
  218. package/src/lib/app-utils/csv-import.js +279 -0
  219. package/src/lib/app-utils/csv-import.js.map +1 -0
  220. package/src/lib/app-utils/dataset-csv.d.ts +109 -0
  221. package/src/lib/app-utils/dataset-csv.js +235 -0
  222. package/src/lib/app-utils/dataset-csv.js.map +1 -0
  223. package/src/lib/app-utils/dataset-models.d.ts +194 -0
  224. package/src/lib/app-utils/dataset-models.js +409 -0
  225. package/src/lib/app-utils/dataset-models.js.map +1 -0
  226. package/src/lib/app-utils/dataset-query.d.ts +57 -0
  227. package/src/lib/app-utils/dataset-query.js +126 -0
  228. package/src/lib/app-utils/dataset-query.js.map +1 -0
  229. package/src/lib/app-utils/datasets.d.ts +136 -0
  230. package/src/lib/app-utils/datasets.js +177 -0
  231. package/src/lib/app-utils/datasets.js.map +1 -0
  232. package/src/lib/app-utils/decompress.d.ts +36 -0
  233. package/src/lib/app-utils/decompress.js +32 -0
  234. package/src/lib/app-utils/decompress.js.map +1 -0
  235. package/src/lib/app-utils/dedicated-sending-domain.d.ts +47 -0
  236. package/src/lib/app-utils/dedicated-sending-domain.js +114 -0
  237. package/src/lib/app-utils/dedicated-sending-domain.js.map +1 -0
  238. package/src/lib/app-utils/deferred-image.d.ts +86 -0
  239. package/src/lib/app-utils/deferred-image.js +83 -0
  240. package/src/lib/app-utils/deferred-image.js.map +1 -0
  241. package/src/lib/app-utils/definition-canvas-tree.d.ts +61 -0
  242. package/src/lib/app-utils/definition-canvas-tree.js +126 -0
  243. package/src/lib/app-utils/definition-canvas-tree.js.map +1 -0
  244. package/src/lib/app-utils/deployment-shape.d.ts +167 -0
  245. package/src/lib/app-utils/deployment-shape.js +238 -0
  246. package/src/lib/app-utils/deployment-shape.js.map +1 -0
  247. package/src/lib/app-utils/detect-template-placeholders.d.ts +30 -0
  248. package/src/lib/app-utils/detect-template-placeholders.js +53 -0
  249. package/src/lib/app-utils/detect-template-placeholders.js.map +1 -0
  250. package/src/lib/app-utils/dmca-counter-notice.d.ts +185 -0
  251. package/src/lib/app-utils/dmca-counter-notice.js +277 -0
  252. package/src/lib/app-utils/dmca-counter-notice.js.map +1 -0
  253. package/src/lib/app-utils/docs-deflection.d.ts +156 -0
  254. package/src/lib/app-utils/docs-deflection.js +547 -0
  255. package/src/lib/app-utils/docs-deflection.js.map +1 -0
  256. package/src/lib/app-utils/docs-help.d.ts +57 -0
  257. package/src/lib/app-utils/docs-help.generated.d.ts +303 -0
  258. package/src/lib/app-utils/docs-help.generated.js +867 -0
  259. package/src/lib/app-utils/docs-help.generated.js.map +1 -0
  260. package/src/lib/app-utils/docs-help.js +46 -0
  261. package/src/lib/app-utils/docs-help.js.map +1 -0
  262. package/src/lib/app-utils/docs-index.generated.d.ts +29 -0
  263. package/src/lib/app-utils/docs-index.generated.js +8388 -0
  264. package/src/lib/app-utils/docs-index.generated.js.map +1 -0
  265. package/src/lib/app-utils/docs-retrieval.d.ts +67 -0
  266. package/src/lib/app-utils/docs-retrieval.js +188 -0
  267. package/src/lib/app-utils/docs-retrieval.js.map +1 -0
  268. package/src/lib/app-utils/document-landmark.d.ts +50 -0
  269. package/src/lib/app-utils/document-landmark.js +100 -0
  270. package/src/lib/app-utils/document-landmark.js.map +1 -0
  271. package/src/lib/app-utils/duplicate-resource.d.ts +101 -0
  272. package/src/lib/app-utils/duplicate-resource.js +206 -0
  273. package/src/lib/app-utils/duplicate-resource.js.map +1 -0
  274. package/src/lib/app-utils/dynamic-list-rule.d.ts +471 -0
  275. package/src/lib/app-utils/dynamic-list-rule.js +914 -0
  276. package/src/lib/app-utils/dynamic-list-rule.js.map +1 -0
  277. package/src/lib/app-utils/element-animation.d.ts +200 -0
  278. package/src/lib/app-utils/element-animation.js +233 -0
  279. package/src/lib/app-utils/element-animation.js.map +1 -0
  280. package/src/lib/app-utils/element-hidden-style.d.ts +46 -0
  281. package/src/lib/app-utils/element-hidden-style.js +48 -0
  282. package/src/lib/app-utils/element-hidden-style.js.map +1 -0
  283. package/src/lib/app-utils/element-ui.d.ts +243 -0
  284. package/src/lib/app-utils/element-ui.js +459 -0
  285. package/src/lib/app-utils/element-ui.js.map +1 -0
  286. package/src/lib/app-utils/email-starter-policy.d.ts +160 -0
  287. package/src/lib/app-utils/email-starter-policy.js +327 -0
  288. package/src/lib/app-utils/email-starter-policy.js.map +1 -0
  289. package/src/lib/app-utils/email-topics.d.ts +310 -0
  290. package/src/lib/app-utils/email-topics.js +336 -0
  291. package/src/lib/app-utils/email-topics.js.map +1 -0
  292. package/src/lib/app-utils/enabled-plugins-context.d.ts +100 -0
  293. package/src/lib/app-utils/enabled-plugins-context.js +113 -0
  294. package/src/lib/app-utils/enabled-plugins-context.js.map +1 -0
  295. package/src/lib/app-utils/ensure-canvas-root.d.ts +38 -0
  296. package/src/lib/app-utils/ensure-canvas-root.js +61 -0
  297. package/src/lib/app-utils/ensure-canvas-root.js.map +1 -0
  298. package/src/lib/app-utils/entity-picker-context.d.ts +199 -0
  299. package/src/lib/app-utils/entity-picker-context.js +93 -0
  300. package/src/lib/app-utils/entity-picker-context.js.map +1 -0
  301. package/src/lib/app-utils/error-beacon.d.ts +107 -0
  302. package/src/lib/app-utils/error-beacon.js +296 -0
  303. package/src/lib/app-utils/error-beacon.js.map +1 -0
  304. package/src/lib/app-utils/expand-repeatables.d.ts +172 -0
  305. package/src/lib/app-utils/expand-repeatables.js +299 -0
  306. package/src/lib/app-utils/expand-repeatables.js.map +1 -0
  307. package/src/lib/app-utils/foreign-script.d.ts +82 -0
  308. package/src/lib/app-utils/foreign-script.js +102 -0
  309. package/src/lib/app-utils/foreign-script.js.map +1 -0
  310. package/src/lib/app-utils/form-abuse-ceiling.d.ts +146 -0
  311. package/src/lib/app-utils/form-abuse-ceiling.js +158 -0
  312. package/src/lib/app-utils/form-abuse-ceiling.js.map +1 -0
  313. package/src/lib/app-utils/form-contract.d.ts +198 -0
  314. package/src/lib/app-utils/form-contract.js +282 -0
  315. package/src/lib/app-utils/form-contract.js.map +1 -0
  316. package/src/lib/app-utils/form-dataset-binding.d.ts +50 -0
  317. package/src/lib/app-utils/form-dataset-binding.js +74 -0
  318. package/src/lib/app-utils/form-dataset-binding.js.map +1 -0
  319. package/src/lib/app-utils/forms.d.ts +727 -0
  320. package/src/lib/app-utils/forms.js +777 -0
  321. package/src/lib/app-utils/forms.js.map +1 -0
  322. package/src/lib/app-utils/functions.d.ts +188 -0
  323. package/src/lib/app-utils/functions.js +529 -0
  324. package/src/lib/app-utils/functions.js.map +1 -0
  325. package/src/lib/app-utils/guarded-version-save.d.ts +91 -0
  326. package/src/lib/app-utils/guarded-version-save.js +131 -0
  327. package/src/lib/app-utils/guarded-version-save.js.map +1 -0
  328. package/src/lib/app-utils/health-report.d.ts +1766 -0
  329. package/src/lib/app-utils/health-report.js +2072 -0
  330. package/src/lib/app-utils/health-report.js.map +1 -0
  331. package/src/lib/app-utils/host-naming.d.ts +135 -0
  332. package/src/lib/app-utils/host-naming.js +188 -0
  333. package/src/lib/app-utils/host-naming.js.map +1 -0
  334. package/src/lib/app-utils/host-permissions.d.ts +76 -0
  335. package/src/lib/app-utils/host-permissions.js +119 -0
  336. package/src/lib/app-utils/host-permissions.js.map +1 -0
  337. package/src/lib/app-utils/host-tokens.d.ts +228 -0
  338. package/src/lib/app-utils/host-tokens.js +304 -0
  339. package/src/lib/app-utils/host-tokens.js.map +1 -0
  340. package/src/lib/app-utils/idp-profile.d.ts +83 -0
  341. package/src/lib/app-utils/idp-profile.js +268 -0
  342. package/src/lib/app-utils/idp-profile.js.map +1 -0
  343. package/src/lib/app-utils/image-upload-types.d.ts +49 -0
  344. package/src/lib/app-utils/image-upload-types.js +86 -0
  345. package/src/lib/app-utils/image-upload-types.js.map +1 -0
  346. package/src/lib/app-utils/index.d.ts +18 -0
  347. package/src/lib/app-utils/index.js +23 -0
  348. package/src/lib/app-utils/index.js.map +1 -0
  349. package/src/lib/app-utils/internal-traffic.d.ts +197 -0
  350. package/src/lib/app-utils/internal-traffic.js +288 -0
  351. package/src/lib/app-utils/internal-traffic.js.map +1 -0
  352. package/src/lib/app-utils/lineal-order.d.ts +62 -0
  353. package/src/lib/app-utils/lineal-order.js +65 -0
  354. package/src/lib/app-utils/lineal-order.js.map +1 -0
  355. package/src/lib/app-utils/link-references.d.ts +36 -0
  356. package/src/lib/app-utils/link-references.js +89 -0
  357. package/src/lib/app-utils/link-references.js.map +1 -0
  358. package/src/lib/app-utils/link-target-search-context.d.ts +123 -0
  359. package/src/lib/app-utils/link-target-search-context.js +221 -0
  360. package/src/lib/app-utils/link-target-search-context.js.map +1 -0
  361. package/src/lib/app-utils/list-assignment-policy.d.ts +169 -0
  362. package/src/lib/app-utils/list-assignment-policy.js +170 -0
  363. package/src/lib/app-utils/list-assignment-policy.js.map +1 -0
  364. package/src/lib/app-utils/list-import.d.ts +158 -0
  365. package/src/lib/app-utils/list-import.js +332 -0
  366. package/src/lib/app-utils/list-import.js.map +1 -0
  367. package/src/lib/app-utils/llms-txt.d.ts +104 -0
  368. package/src/lib/app-utils/llms-txt.js +144 -0
  369. package/src/lib/app-utils/llms-txt.js.map +1 -0
  370. package/src/lib/app-utils/local-storage-budget.d.ts +75 -0
  371. package/src/lib/app-utils/local-storage-budget.js +153 -0
  372. package/src/lib/app-utils/local-storage-budget.js.map +1 -0
  373. package/src/lib/app-utils/lockdown.d.ts +698 -0
  374. package/src/lib/app-utils/lockdown.js +929 -0
  375. package/src/lib/app-utils/lockdown.js.map +1 -0
  376. package/src/lib/app-utils/margin-utilization.d.ts +267 -0
  377. package/src/lib/app-utils/margin-utilization.js +351 -0
  378. package/src/lib/app-utils/margin-utilization.js.map +1 -0
  379. package/src/lib/app-utils/markdown-lite.d.ts +297 -0
  380. package/src/lib/app-utils/markdown-lite.js +705 -0
  381. package/src/lib/app-utils/markdown-lite.js.map +1 -0
  382. package/src/lib/app-utils/marketing-consent.d.ts +704 -0
  383. package/src/lib/app-utils/marketing-consent.js +783 -0
  384. package/src/lib/app-utils/marketing-consent.js.map +1 -0
  385. package/src/lib/app-utils/marketplace-listing-visibility.d.ts +120 -0
  386. package/src/lib/app-utils/marketplace-listing-visibility.js +139 -0
  387. package/src/lib/app-utils/marketplace-listing-visibility.js.map +1 -0
  388. package/src/lib/app-utils/marketplace-overrides.d.ts +271 -0
  389. package/src/lib/app-utils/marketplace-overrides.js +462 -0
  390. package/src/lib/app-utils/marketplace-overrides.js.map +1 -0
  391. package/src/lib/app-utils/marketplace-provenance.d.ts +150 -0
  392. package/src/lib/app-utils/marketplace-provenance.js +136 -0
  393. package/src/lib/app-utils/marketplace-provenance.js.map +1 -0
  394. package/src/lib/app-utils/marketplace-theme.d.ts +237 -0
  395. package/src/lib/app-utils/marketplace-theme.js +525 -0
  396. package/src/lib/app-utils/marketplace-theme.js.map +1 -0
  397. package/src/lib/app-utils/marketplace-update-state.d.ts +119 -0
  398. package/src/lib/app-utils/marketplace-update-state.js +132 -0
  399. package/src/lib/app-utils/marketplace-update-state.js.map +1 -0
  400. package/src/lib/app-utils/marketplace-verification.d.ts +95 -0
  401. package/src/lib/app-utils/marketplace-verification.js +81 -0
  402. package/src/lib/app-utils/marketplace-verification.js.map +1 -0
  403. package/src/lib/app-utils/measure-node-map.d.ts +76 -0
  404. package/src/lib/app-utils/measure-node-map.js +111 -0
  405. package/src/lib/app-utils/measure-node-map.js.map +1 -0
  406. package/src/lib/app-utils/media-alt.d.ts +55 -0
  407. package/src/lib/app-utils/media-alt.js +58 -0
  408. package/src/lib/app-utils/media-alt.js.map +1 -0
  409. package/src/lib/app-utils/media-asset-facts.d.ts +125 -0
  410. package/src/lib/app-utils/media-asset-facts.js +467 -0
  411. package/src/lib/app-utils/media-asset-facts.js.map +1 -0
  412. package/src/lib/app-utils/media-cdn-scope.d.ts +65 -0
  413. package/src/lib/app-utils/media-cdn-scope.js +75 -0
  414. package/src/lib/app-utils/media-cdn-scope.js.map +1 -0
  415. package/src/lib/app-utils/media-folders.d.ts +161 -0
  416. package/src/lib/app-utils/media-folders.js +230 -0
  417. package/src/lib/app-utils/media-folders.js.map +1 -0
  418. package/src/lib/app-utils/media-metadata.d.ts +277 -0
  419. package/src/lib/app-utils/media-metadata.js +388 -0
  420. package/src/lib/app-utils/media-metadata.js.map +1 -0
  421. package/src/lib/app-utils/media-picker-context.d.ts +93 -0
  422. package/src/lib/app-utils/media-picker-context.js +26 -0
  423. package/src/lib/app-utils/media-picker-context.js.map +1 -0
  424. package/src/lib/app-utils/media-quarantine.d.ts +247 -0
  425. package/src/lib/app-utils/media-quarantine.js +323 -0
  426. package/src/lib/app-utils/media-quarantine.js.map +1 -0
  427. package/src/lib/app-utils/media-ref.d.ts +661 -0
  428. package/src/lib/app-utils/media-ref.js +1055 -0
  429. package/src/lib/app-utils/media-ref.js.map +1 -0
  430. package/src/lib/app-utils/media-takedown-reach.d.ts +126 -0
  431. package/src/lib/app-utils/media-takedown-reach.js +143 -0
  432. package/src/lib/app-utils/media-takedown-reach.js.map +1 -0
  433. package/src/lib/app-utils/member-email-aliases.d.ts +180 -0
  434. package/src/lib/app-utils/member-email-aliases.js +217 -0
  435. package/src/lib/app-utils/member-email-aliases.js.map +1 -0
  436. package/src/lib/app-utils/merge-node-sx.d.ts +47 -0
  437. package/src/lib/app-utils/merge-node-sx.js +123 -0
  438. package/src/lib/app-utils/merge-node-sx.js.map +1 -0
  439. package/src/lib/app-utils/name-match.d.ts +155 -0
  440. package/src/lib/app-utils/name-match.js +175 -0
  441. package/src/lib/app-utils/name-match.js.map +1 -0
  442. package/src/lib/app-utils/name-search.d.ts +117 -0
  443. package/src/lib/app-utils/name-search.js +145 -0
  444. package/src/lib/app-utils/name-search.js.map +1 -0
  445. package/src/lib/app-utils/node-capabilities.d.ts +85 -0
  446. package/src/lib/app-utils/node-capabilities.js +88 -0
  447. package/src/lib/app-utils/node-capabilities.js.map +1 -0
  448. package/src/lib/app-utils/node-definition-sanitizer.d.ts +164 -0
  449. package/src/lib/app-utils/node-definition-sanitizer.js +402 -0
  450. package/src/lib/app-utils/node-definition-sanitizer.js.map +1 -0
  451. package/src/lib/app-utils/node-identity.d.ts +47 -0
  452. package/src/lib/app-utils/node-identity.js +50 -0
  453. package/src/lib/app-utils/node-identity.js.map +1 -0
  454. package/src/lib/app-utils/node-interactions.d.ts +102 -0
  455. package/src/lib/app-utils/node-interactions.js +192 -0
  456. package/src/lib/app-utils/node-interactions.js.map +1 -0
  457. package/src/lib/app-utils/node-url-policy.d.ts +54 -0
  458. package/src/lib/app-utils/node-url-policy.js +72 -0
  459. package/src/lib/app-utils/node-url-policy.js.map +1 -0
  460. package/src/lib/app-utils/notifications.d.ts +71 -0
  461. package/src/lib/app-utils/notifications.js +101 -0
  462. package/src/lib/app-utils/notifications.js.map +1 -0
  463. package/src/lib/app-utils/onboarding-deep-link.d.ts +120 -0
  464. package/src/lib/app-utils/onboarding-deep-link.js +142 -0
  465. package/src/lib/app-utils/onboarding-deep-link.js.map +1 -0
  466. package/src/lib/app-utils/operator-identity.d.ts +207 -0
  467. package/src/lib/app-utils/operator-identity.js +186 -0
  468. package/src/lib/app-utils/operator-identity.js.map +1 -0
  469. package/src/lib/app-utils/org-billing-doc.d.ts +231 -0
  470. package/src/lib/app-utils/org-billing-doc.js +238 -0
  471. package/src/lib/app-utils/org-billing-doc.js.map +1 -0
  472. package/src/lib/app-utils/org-override-reason.d.ts +100 -0
  473. package/src/lib/app-utils/org-override-reason.js +116 -0
  474. package/src/lib/app-utils/org-override-reason.js.map +1 -0
  475. package/src/lib/app-utils/org-permissions.d.ts +194 -0
  476. package/src/lib/app-utils/org-permissions.js +357 -0
  477. package/src/lib/app-utils/org-permissions.js.map +1 -0
  478. package/src/lib/app-utils/org-roles.d.ts +72 -0
  479. package/src/lib/app-utils/org-roles.js +131 -0
  480. package/src/lib/app-utils/org-roles.js.map +1 -0
  481. package/src/lib/app-utils/organizations.d.ts +407 -0
  482. package/src/lib/app-utils/organizations.js +511 -0
  483. package/src/lib/app-utils/organizations.js.map +1 -0
  484. package/src/lib/app-utils/page-header-actions-context.d.ts +83 -0
  485. package/src/lib/app-utils/page-header-actions-context.js +58 -0
  486. package/src/lib/app-utils/page-header-actions-context.js.map +1 -0
  487. package/src/lib/app-utils/page-header-record-context.d.ts +80 -0
  488. package/src/lib/app-utils/page-header-record-context.js +64 -0
  489. package/src/lib/app-utils/page-header-record-context.js.map +1 -0
  490. package/src/lib/app-utils/page-markdown.d.ts +103 -0
  491. package/src/lib/app-utils/page-markdown.js +385 -0
  492. package/src/lib/app-utils/page-markdown.js.map +1 -0
  493. package/src/lib/app-utils/paid-media-source.d.ts +90 -0
  494. package/src/lib/app-utils/paid-media-source.js +184 -0
  495. package/src/lib/app-utils/paid-media-source.js.map +1 -0
  496. package/src/lib/app-utils/palette-sx.d.ts +34 -0
  497. package/src/lib/app-utils/palette-sx.js +150 -0
  498. package/src/lib/app-utils/palette-sx.js.map +1 -0
  499. package/src/lib/app-utils/password-policy.d.ts +47 -0
  500. package/src/lib/app-utils/password-policy.js +46 -0
  501. package/src/lib/app-utils/password-policy.js.map +1 -0
  502. package/src/lib/app-utils/payments-configured.d.ts +84 -0
  503. package/src/lib/app-utils/payments-configured.js +88 -0
  504. package/src/lib/app-utils/payments-configured.js.map +1 -0
  505. package/src/lib/app-utils/person-erasure.d.ts +126 -0
  506. package/src/lib/app-utils/person-erasure.js +121 -0
  507. package/src/lib/app-utils/person-erasure.js.map +1 -0
  508. package/src/lib/app-utils/person-key.d.ts +32 -0
  509. package/src/lib/app-utils/person-key.js +62 -0
  510. package/src/lib/app-utils/person-key.js.map +1 -0
  511. package/src/lib/app-utils/plan-entitlements.d.ts +2756 -0
  512. package/src/lib/app-utils/plan-entitlements.js +4085 -0
  513. package/src/lib/app-utils/plan-entitlements.js.map +1 -0
  514. package/src/lib/app-utils/platform-ad-conversions.d.ts +122 -0
  515. package/src/lib/app-utils/platform-ad-conversions.js +174 -0
  516. package/src/lib/app-utils/platform-ad-conversions.js.map +1 -0
  517. package/src/lib/app-utils/platform-advertising-tags.d.ts +139 -0
  518. package/src/lib/app-utils/platform-advertising-tags.js +203 -0
  519. package/src/lib/app-utils/platform-advertising-tags.js.map +1 -0
  520. package/src/lib/app-utils/platform-brand.d.ts +151 -0
  521. package/src/lib/app-utils/platform-brand.js +175 -0
  522. package/src/lib/app-utils/platform-brand.js.map +1 -0
  523. package/src/lib/app-utils/platform-consent-default.d.ts +142 -0
  524. package/src/lib/app-utils/platform-consent-default.js +295 -0
  525. package/src/lib/app-utils/platform-consent-default.js.map +1 -0
  526. package/src/lib/app-utils/platform-marketing-consent.d.ts +151 -0
  527. package/src/lib/app-utils/platform-marketing-consent.js +182 -0
  528. package/src/lib/app-utils/platform-marketing-consent.js.map +1 -0
  529. package/src/lib/app-utils/platform-marketing-host.d.ts +33 -0
  530. package/src/lib/app-utils/platform-marketing-host.js +97 -0
  531. package/src/lib/app-utils/platform-marketing-host.js.map +1 -0
  532. package/src/lib/app-utils/platform-visitor-consent.d.ts +252 -0
  533. package/src/lib/app-utils/platform-visitor-consent.js +533 -0
  534. package/src/lib/app-utils/platform-visitor-consent.js.map +1 -0
  535. package/src/lib/app-utils/plugin-api-cross-origin.d.ts +61 -0
  536. package/src/lib/app-utils/plugin-api-cross-origin.js +202 -0
  537. package/src/lib/app-utils/plugin-api-cross-origin.js.map +1 -0
  538. package/src/lib/app-utils/plugin-api-rate-limit.d.ts +192 -0
  539. package/src/lib/app-utils/plugin-api-rate-limit.js +270 -0
  540. package/src/lib/app-utils/plugin-api-rate-limit.js.map +1 -0
  541. package/src/lib/app-utils/plugin-artifact-path.d.ts +32 -0
  542. package/src/lib/app-utils/plugin-artifact-path.js +33 -0
  543. package/src/lib/app-utils/plugin-artifact-path.js.map +1 -0
  544. package/src/lib/app-utils/plugin-bundle-checks.d.ts +148 -0
  545. package/src/lib/app-utils/plugin-bundle-checks.js +989 -0
  546. package/src/lib/app-utils/plugin-bundle-checks.js.map +1 -0
  547. package/src/lib/app-utils/plugin-manifest.d.ts +516 -0
  548. package/src/lib/app-utils/plugin-manifest.js +687 -0
  549. package/src/lib/app-utils/plugin-manifest.js.map +1 -0
  550. package/src/lib/app-utils/published-legal-pages.d.ts +71 -0
  551. package/src/lib/app-utils/published-legal-pages.js +90 -0
  552. package/src/lib/app-utils/published-legal-pages.js.map +1 -0
  553. package/src/lib/app-utils/publisher-agreement.d.ts +254 -0
  554. package/src/lib/app-utils/publisher-agreement.js +274 -0
  555. package/src/lib/app-utils/publisher-agreement.js.map +1 -0
  556. package/src/lib/app-utils/publisher-attestation.d.ts +99 -0
  557. package/src/lib/app-utils/publisher-attestation.js +158 -0
  558. package/src/lib/app-utils/publisher-attestation.js.map +1 -0
  559. package/src/lib/app-utils/recipient-email-render.d.ts +216 -0
  560. package/src/lib/app-utils/recipient-email-render.js +221 -0
  561. package/src/lib/app-utils/recipient-email-render.js.map +1 -0
  562. package/src/lib/app-utils/redispatch-caught-error.d.ts +38 -0
  563. package/src/lib/app-utils/redispatch-caught-error.js +46 -0
  564. package/src/lib/app-utils/redispatch-caught-error.js.map +1 -0
  565. package/src/lib/app-utils/registering-plugin.d.ts +19 -0
  566. package/src/lib/app-utils/registering-plugin.js +38 -0
  567. package/src/lib/app-utils/registering-plugin.js.map +1 -0
  568. package/src/lib/app-utils/release-flags.d.ts +283 -0
  569. package/src/lib/app-utils/release-flags.js +518 -0
  570. package/src/lib/app-utils/release-flags.js.map +1 -0
  571. package/src/lib/app-utils/repair-canvas-nodes.d.ts +130 -0
  572. package/src/lib/app-utils/repair-canvas-nodes.js +298 -0
  573. package/src/lib/app-utils/repair-canvas-nodes.js.map +1 -0
  574. package/src/lib/app-utils/repeat-infringer.d.ts +166 -0
  575. package/src/lib/app-utils/repeat-infringer.js +188 -0
  576. package/src/lib/app-utils/repeat-infringer.js.map +1 -0
  577. package/src/lib/app-utils/repeat-sources.d.ts +115 -0
  578. package/src/lib/app-utils/repeat-sources.js +86 -0
  579. package/src/lib/app-utils/repeat-sources.js.map +1 -0
  580. package/src/lib/app-utils/request-geo.d.ts +114 -0
  581. package/src/lib/app-utils/request-geo.js +247 -0
  582. package/src/lib/app-utils/request-geo.js.map +1 -0
  583. package/src/lib/app-utils/request-ip.d.ts +213 -0
  584. package/src/lib/app-utils/request-ip.js +344 -0
  585. package/src/lib/app-utils/request-ip.js.map +1 -0
  586. package/src/lib/app-utils/resolve-named-tokens.d.ts +26 -0
  587. package/src/lib/app-utils/resolve-named-tokens.js +59 -0
  588. package/src/lib/app-utils/resolve-named-tokens.js.map +1 -0
  589. package/src/lib/app-utils/responsive-typography-sx.d.ts +77 -0
  590. package/src/lib/app-utils/responsive-typography-sx.js +122 -0
  591. package/src/lib/app-utils/responsive-typography-sx.js.map +1 -0
  592. package/src/lib/app-utils/reusable-component-keys.d.ts +135 -0
  593. package/src/lib/app-utils/reusable-component-keys.js +140 -0
  594. package/src/lib/app-utils/reusable-component-keys.js.map +1 -0
  595. package/src/lib/app-utils/reusable-prop-values.d.ts +199 -0
  596. package/src/lib/app-utils/reusable-prop-values.js +494 -0
  597. package/src/lib/app-utils/reusable-prop-values.js.map +1 -0
  598. package/src/lib/app-utils/safe-json-ld.d.ts +29 -0
  599. package/src/lib/app-utils/safe-json-ld.js +37 -0
  600. package/src/lib/app-utils/safe-json-ld.js.map +1 -0
  601. package/src/lib/app-utils/sanitize-svg.d.ts +55 -0
  602. package/src/lib/app-utils/sanitize-svg.js +460 -0
  603. package/src/lib/app-utils/sanitize-svg.js.map +1 -0
  604. package/src/lib/app-utils/scheme-sx.d.ts +84 -0
  605. package/src/lib/app-utils/scheme-sx.js +148 -0
  606. package/src/lib/app-utils/scheme-sx.js.map +1 -0
  607. package/src/lib/app-utils/scope-tokens.d.ts +249 -0
  608. package/src/lib/app-utils/scope-tokens.js +331 -0
  609. package/src/lib/app-utils/scope-tokens.js.map +1 -0
  610. package/src/lib/app-utils/screen-link-context-value.d.ts +57 -0
  611. package/src/lib/app-utils/screen-link-context-value.js +43 -0
  612. package/src/lib/app-utils/screen-link-context-value.js.map +1 -0
  613. package/src/lib/app-utils/screen-link-context.d.ts +185 -0
  614. package/src/lib/app-utils/screen-link-context.js +304 -0
  615. package/src/lib/app-utils/screen-link-context.js.map +1 -0
  616. package/src/lib/app-utils/screen-link-value.d.ts +269 -0
  617. package/src/lib/app-utils/screen-link-value.js +384 -0
  618. package/src/lib/app-utils/screen-link-value.js.map +1 -0
  619. package/src/lib/app-utils/screen-route.d.ts +669 -0
  620. package/src/lib/app-utils/screen-route.js +751 -0
  621. package/src/lib/app-utils/screen-route.js.map +1 -0
  622. package/src/lib/app-utils/screen-seo-fields.d.ts +37 -0
  623. package/src/lib/app-utils/screen-seo-fields.js +42 -0
  624. package/src/lib/app-utils/screen-seo-fields.js.map +1 -0
  625. package/src/lib/app-utils/search-indexing.d.ts +162 -0
  626. package/src/lib/app-utils/search-indexing.js +207 -0
  627. package/src/lib/app-utils/search-indexing.js.map +1 -0
  628. package/src/lib/app-utils/seo-listing-fields.d.ts +70 -0
  629. package/src/lib/app-utils/seo-listing-fields.js +75 -0
  630. package/src/lib/app-utils/seo-listing-fields.js.map +1 -0
  631. package/src/lib/app-utils/seo-locale.d.ts +119 -0
  632. package/src/lib/app-utils/seo-locale.js +133 -0
  633. package/src/lib/app-utils/seo-locale.js.map +1 -0
  634. package/src/lib/app-utils/seo-title-variables.d.ts +149 -0
  635. package/src/lib/app-utils/seo-title-variables.js +190 -0
  636. package/src/lib/app-utils/seo-title-variables.js.map +1 -0
  637. package/src/lib/app-utils/seo-title.d.ts +70 -0
  638. package/src/lib/app-utils/seo-title.js +117 -0
  639. package/src/lib/app-utils/seo-title.js.map +1 -0
  640. package/src/lib/app-utils/server.d.ts +174 -0
  641. package/src/lib/app-utils/server.js +314 -0
  642. package/src/lib/app-utils/server.js.map +1 -0
  643. package/src/lib/app-utils/site-context.d.ts +106 -0
  644. package/src/lib/app-utils/site-context.js +100 -0
  645. package/src/lib/app-utils/site-context.js.map +1 -0
  646. package/src/lib/app-utils/sitemap.d.ts +117 -0
  647. package/src/lib/app-utils/sitemap.js +183 -0
  648. package/src/lib/app-utils/sitemap.js.map +1 -0
  649. package/src/lib/app-utils/social-image.d.ts +112 -0
  650. package/src/lib/app-utils/social-image.js +191 -0
  651. package/src/lib/app-utils/social-image.js.map +1 -0
  652. package/src/lib/app-utils/starter-templates.d.ts +99 -0
  653. package/src/lib/app-utils/starter-templates.js +579 -0
  654. package/src/lib/app-utils/starter-templates.js.map +1 -0
  655. package/src/lib/app-utils/stored-nodes.d.ts +120 -0
  656. package/src/lib/app-utils/stored-nodes.js +174 -0
  657. package/src/lib/app-utils/stored-nodes.js.map +1 -0
  658. package/src/lib/app-utils/strip-undefined.d.ts +59 -0
  659. package/src/lib/app-utils/strip-undefined.js +95 -0
  660. package/src/lib/app-utils/strip-undefined.js.map +1 -0
  661. package/src/lib/app-utils/stripe-deployment-mode.d.ts +47 -0
  662. package/src/lib/app-utils/stripe-deployment-mode.js +70 -0
  663. package/src/lib/app-utils/stripe-deployment-mode.js.map +1 -0
  664. package/src/lib/app-utils/support-tiers.d.ts +108 -0
  665. package/src/lib/app-utils/support-tiers.js +201 -0
  666. package/src/lib/app-utils/support-tiers.js.map +1 -0
  667. package/src/lib/app-utils/timezone-geo-hint.d.ts +36 -0
  668. package/src/lib/app-utils/timezone-geo-hint.js +180 -0
  669. package/src/lib/app-utils/timezone-geo-hint.js.map +1 -0
  670. package/src/lib/app-utils/upload-cors.d.ts +155 -0
  671. package/src/lib/app-utils/upload-cors.js +254 -0
  672. package/src/lib/app-utils/upload-cors.js.map +1 -0
  673. package/src/lib/app-utils/upload-inspection.d.ts +159 -0
  674. package/src/lib/app-utils/upload-inspection.js +539 -0
  675. package/src/lib/app-utils/upload-inspection.js.map +1 -0
  676. package/src/lib/app-utils/url-slug.d.ts +40 -0
  677. package/src/lib/app-utils/url-slug.js +42 -0
  678. package/src/lib/app-utils/url-slug.js.map +1 -0
  679. package/src/lib/app-utils/usage-budget.d.ts +429 -0
  680. package/src/lib/app-utils/usage-budget.js +421 -0
  681. package/src/lib/app-utils/usage-budget.js.map +1 -0
  682. package/src/lib/app-utils/variables.d.ts +96 -0
  683. package/src/lib/app-utils/variables.js +233 -0
  684. package/src/lib/app-utils/variables.js.map +1 -0
  685. package/src/lib/app-utils/video-asset-facts.d.ts +61 -0
  686. package/src/lib/app-utils/video-asset-facts.js +70 -0
  687. package/src/lib/app-utils/video-asset-facts.js.map +1 -0
  688. package/src/lib/app-utils/video-object.d.ts +89 -0
  689. package/src/lib/app-utils/video-object.js +245 -0
  690. package/src/lib/app-utils/video-object.js.map +1 -0
  691. package/src/lib/app-utils/visitor-consent.d.ts +757 -0
  692. package/src/lib/app-utils/visitor-consent.js +981 -0
  693. package/src/lib/app-utils/visitor-consent.js.map +1 -0
  694. package/src/lib/app-utils/visitor-record-ceiling.d.ts +223 -0
  695. package/src/lib/app-utils/visitor-record-ceiling.js +215 -0
  696. package/src/lib/app-utils/visitor-record-ceiling.js.map +1 -0
  697. package/src/lib/app-utils/web-vitals-rum.d.ts +53 -0
  698. package/src/lib/app-utils/web-vitals-rum.js +278 -0
  699. package/src/lib/app-utils/web-vitals-rum.js.map +1 -0
  700. package/src/lib/app-utils/webhook-delivery.d.ts +324 -0
  701. package/src/lib/app-utils/webhook-delivery.js +413 -0
  702. package/src/lib/app-utils/webhook-delivery.js.map +1 -0
  703. package/src/lib/app-utils/where-used.d.ts +57 -0
  704. package/src/lib/app-utils/where-used.js +59 -0
  705. package/src/lib/app-utils/where-used.js.map +1 -0
  706. package/src/lib/app-utils/wistia-embed.d.ts +86 -0
  707. package/src/lib/app-utils/wistia-embed.js +119 -0
  708. package/src/lib/app-utils/wistia-embed.js.map +1 -0
  709. package/src/lib/app-utils/workflows.d.ts +136 -0
  710. package/src/lib/app-utils/workflows.js +346 -0
  711. package/src/lib/app-utils/workflows.js.map +1 -0
  712. package/src/lib/canvas-manager/canvas-manager-tree.d.ts +109 -0
  713. package/src/lib/canvas-manager/canvas-manager-tree.js +139 -0
  714. package/src/lib/canvas-manager/canvas-manager-tree.js.map +1 -0
  715. package/src/lib/canvas-manager/canvas-manager.d.ts +549 -0
  716. package/src/lib/canvas-manager/canvas-manager.js +1311 -0
  717. package/src/lib/canvas-manager/canvas-manager.js.map +1 -0
  718. package/src/lib/canvas-manager/index.d.ts +20 -0
  719. package/src/lib/canvas-manager/index.js +21 -0
  720. package/src/lib/canvas-manager/index.js.map +1 -0
  721. package/src/lib/canvas-manager/stores/index.d.ts +17 -0
  722. package/src/lib/canvas-manager/stores/index.js +18 -0
  723. package/src/lib/canvas-manager/stores/index.js.map +1 -0
  724. package/src/lib/canvas-manager/stores/node.store.d.ts +30 -0
  725. package/src/lib/canvas-manager/stores/node.store.js +45 -0
  726. package/src/lib/canvas-manager/stores/node.store.js.map +1 -0
  727. package/src/lib/components-manager/components-manager.d.ts +56 -0
  728. package/src/lib/components-manager/components-manager.js +191 -0
  729. package/src/lib/components-manager/components-manager.js.map +1 -0
  730. package/src/lib/components-manager/index.d.ts +18 -0
  731. package/src/lib/components-manager/index.js +19 -0
  732. package/src/lib/components-manager/index.js.map +1 -0
  733. package/src/lib/emit-manager/emit-manager.d.ts +56 -0
  734. package/src/lib/emit-manager/emit-manager.js +60 -0
  735. package/src/lib/emit-manager/emit-manager.js.map +1 -0
  736. package/src/lib/emit-manager/index.d.ts +18 -0
  737. package/src/lib/emit-manager/index.js +19 -0
  738. package/src/lib/emit-manager/index.js.map +1 -0
  739. package/src/lib/foundation/constants/_internal.d.ts +18 -0
  740. package/src/lib/foundation/constants/_internal.js +62 -0
  741. package/src/lib/foundation/constants/_internal.js.map +1 -0
  742. package/src/lib/foundation/constants/app.d.ts +23 -0
  743. package/src/lib/foundation/constants/app.js +25 -0
  744. package/src/lib/foundation/constants/app.js.map +1 -0
  745. package/src/lib/foundation/constants/canvas.d.ts +18 -0
  746. package/src/lib/foundation/constants/canvas.js +18 -0
  747. package/src/lib/foundation/constants/canvas.js.map +1 -0
  748. package/src/lib/foundation/constants/components.d.ts +54 -0
  749. package/src/lib/foundation/constants/components.js +61 -0
  750. package/src/lib/foundation/constants/components.js.map +1 -0
  751. package/src/lib/foundation/constants/shared.d.ts +50 -0
  752. package/src/lib/foundation/constants/shared.js +49 -0
  753. package/src/lib/foundation/constants/shared.js.map +1 -0
  754. package/src/lib/foundation/constants/symbol.d.ts +63 -0
  755. package/src/lib/foundation/constants/symbol.js +75 -0
  756. package/src/lib/foundation/constants/symbol.js.map +1 -0
  757. package/src/lib/foundation/definitions/components.types.d.ts +372 -0
  758. package/src/lib/foundation/definitions/components.types.js +180 -0
  759. package/src/lib/foundation/definitions/components.types.js.map +1 -0
  760. package/src/lib/foundation/definitions/contact.types.d.ts +73 -0
  761. package/src/lib/foundation/definitions/contact.types.js +107 -0
  762. package/src/lib/foundation/definitions/contact.types.js.map +1 -0
  763. package/src/lib/foundation/definitions/host-content-collections.d.ts +137 -0
  764. package/src/lib/foundation/definitions/host-content-collections.js +219 -0
  765. package/src/lib/foundation/definitions/host-content-collections.js.map +1 -0
  766. package/src/lib/foundation/definitions/org-billing.types.d.ts +1361 -0
  767. package/src/lib/foundation/definitions/org-billing.types.js +77 -0
  768. package/src/lib/foundation/definitions/org-billing.types.js.map +1 -0
  769. package/src/lib/foundation/definitions/organization.types.d.ts +307 -0
  770. package/src/lib/foundation/definitions/organization.types.js +42 -0
  771. package/src/lib/foundation/definitions/organization.types.js.map +1 -0
  772. package/src/lib/foundation/definitions/platform.types.d.ts +1326 -0
  773. package/src/lib/foundation/definitions/platform.types.js +124 -0
  774. package/src/lib/foundation/definitions/platform.types.js.map +1 -0
  775. package/src/lib/foundation/definitions/property-kinds.d.ts +189 -0
  776. package/src/lib/foundation/definitions/property-kinds.js +565 -0
  777. package/src/lib/foundation/definitions/property-kinds.js.map +1 -0
  778. package/src/lib/foundation/definitions/shared.d.ts +23 -0
  779. package/src/lib/foundation/definitions/shared.js +18 -0
  780. package/src/lib/foundation/definitions/shared.js.map +1 -0
  781. package/src/lib/foundation/definitions/write-deny-coverage.util.d.ts +249 -0
  782. package/src/lib/foundation/definitions/write-deny-coverage.util.js +499 -0
  783. package/src/lib/foundation/definitions/write-deny-coverage.util.js.map +1 -0
  784. package/src/lib/foundation/index.d.ts +32 -0
  785. package/src/lib/foundation/index.js +67 -0
  786. package/src/lib/foundation/index.js.map +1 -0
  787. package/src/lib/lifecycle.d.ts +24 -0
  788. package/src/lib/lifecycle.js +39 -0
  789. package/src/lib/lifecycle.js.map +1 -0
  790. package/src/lib/mst/common.d.ts +17 -0
  791. package/src/lib/mst/common.js +23 -0
  792. package/src/lib/mst/common.js.map +1 -0
  793. package/src/lib/mst/index.d.ts +19 -0
  794. package/src/lib/mst/index.js +20 -0
  795. package/src/lib/mst/index.js.map +1 -0
  796. package/src/lib/mst/json.d.ts +22 -0
  797. package/src/lib/mst/json.js +23 -0
  798. package/src/lib/mst/json.js.map +1 -0
  799. package/src/lib/mst/types.d.ts +20 -0
  800. package/src/lib/mst/types.js +18 -0
  801. package/src/lib/mst/types.js.map +1 -0
  802. package/src/lib/plugin-manager/billing-webhook-hooks.d.ts +77 -0
  803. package/src/lib/plugin-manager/billing-webhook-hooks.js +55 -0
  804. package/src/lib/plugin-manager/billing-webhook-hooks.js.map +1 -0
  805. package/src/lib/plugin-manager/commerce-zone-props.d.ts +172 -0
  806. package/src/lib/plugin-manager/commerce-zone-props.js +31 -0
  807. package/src/lib/plugin-manager/commerce-zone-props.js.map +1 -0
  808. package/src/lib/plugin-manager/custom-fields.d.ts +60 -0
  809. package/src/lib/plugin-manager/custom-fields.js +39 -0
  810. package/src/lib/plugin-manager/custom-fields.js.map +1 -0
  811. package/src/lib/plugin-manager/editor-sessions.d.ts +109 -0
  812. package/src/lib/plugin-manager/editor-sessions.js +137 -0
  813. package/src/lib/plugin-manager/editor-sessions.js.map +1 -0
  814. package/src/lib/plugin-manager/enabled-plugins.d.ts +438 -0
  815. package/src/lib/plugin-manager/enabled-plugins.js +403 -0
  816. package/src/lib/plugin-manager/enabled-plugins.js.map +1 -0
  817. package/src/lib/plugin-manager/feature-plugins.d.ts +1314 -0
  818. package/src/lib/plugin-manager/feature-plugins.js +609 -0
  819. package/src/lib/plugin-manager/feature-plugins.js.map +1 -0
  820. package/src/lib/plugin-manager/first-party-plugins.generated.d.ts +11 -0
  821. package/src/lib/plugin-manager/first-party-plugins.generated.js +149 -0
  822. package/src/lib/plugin-manager/first-party-plugins.generated.js.map +1 -0
  823. package/src/lib/plugin-manager/index.d.ts +42 -0
  824. package/src/lib/plugin-manager/index.js +46 -0
  825. package/src/lib/plugin-manager/index.js.map +1 -0
  826. package/src/lib/plugin-manager/install-presets.d.ts +93 -0
  827. package/src/lib/plugin-manager/install-presets.js +86 -0
  828. package/src/lib/plugin-manager/install-presets.js.map +1 -0
  829. package/src/lib/plugin-manager/media-delivery-provider.d.ts +124 -0
  830. package/src/lib/plugin-manager/media-delivery-provider.js +53 -0
  831. package/src/lib/plugin-manager/media-delivery-provider.js.map +1 -0
  832. package/src/lib/plugin-manager/order-fulfilment.d.ts +142 -0
  833. package/src/lib/plugin-manager/order-fulfilment.js +104 -0
  834. package/src/lib/plugin-manager/order-fulfilment.js.map +1 -0
  835. package/src/lib/plugin-manager/plugin-activity-actions.d.ts +122 -0
  836. package/src/lib/plugin-manager/plugin-activity-actions.js +140 -0
  837. package/src/lib/plugin-manager/plugin-activity-actions.js.map +1 -0
  838. package/src/lib/plugin-manager/plugin-bridge.d.ts +98 -0
  839. package/src/lib/plugin-manager/plugin-bridge.js +154 -0
  840. package/src/lib/plugin-manager/plugin-bridge.js.map +1 -0
  841. package/src/lib/plugin-manager/plugin-config.d.ts +148 -0
  842. package/src/lib/plugin-manager/plugin-config.js +228 -0
  843. package/src/lib/plugin-manager/plugin-config.js.map +1 -0
  844. package/src/lib/plugin-manager/plugin-console-crons.d.ts +139 -0
  845. package/src/lib/plugin-manager/plugin-console-crons.js +177 -0
  846. package/src/lib/plugin-manager/plugin-console-crons.js.map +1 -0
  847. package/src/lib/plugin-manager/plugin-contact-capture.d.ts +220 -0
  848. package/src/lib/plugin-manager/plugin-contact-capture.js +89 -0
  849. package/src/lib/plugin-manager/plugin-contact-capture.js.map +1 -0
  850. package/src/lib/plugin-manager/plugin-contributions.d.ts +244 -0
  851. package/src/lib/plugin-manager/plugin-contributions.js +283 -0
  852. package/src/lib/plugin-manager/plugin-contributions.js.map +1 -0
  853. package/src/lib/plugin-manager/plugin-entitlement-keys.d.ts +169 -0
  854. package/src/lib/plugin-manager/plugin-entitlement-keys.js +84 -0
  855. package/src/lib/plugin-manager/plugin-entitlement-keys.js.map +1 -0
  856. package/src/lib/plugin-manager/plugin-entitlements.d.ts +181 -0
  857. package/src/lib/plugin-manager/plugin-entitlements.js +188 -0
  858. package/src/lib/plugin-manager/plugin-entitlements.js.map +1 -0
  859. package/src/lib/plugin-manager/plugin-events.d.ts +145 -0
  860. package/src/lib/plugin-manager/plugin-events.js +79 -0
  861. package/src/lib/plugin-manager/plugin-events.js.map +1 -0
  862. package/src/lib/plugin-manager/plugin-figures.d.ts +251 -0
  863. package/src/lib/plugin-manager/plugin-figures.js +252 -0
  864. package/src/lib/plugin-manager/plugin-figures.js.map +1 -0
  865. package/src/lib/plugin-manager/plugin-host-collections.d.ts +146 -0
  866. package/src/lib/plugin-manager/plugin-host-collections.js +116 -0
  867. package/src/lib/plugin-manager/plugin-host-collections.js.map +1 -0
  868. package/src/lib/plugin-manager/plugin-jobs.d.ts +130 -0
  869. package/src/lib/plugin-manager/plugin-jobs.js +182 -0
  870. package/src/lib/plugin-manager/plugin-jobs.js.map +1 -0
  871. package/src/lib/plugin-manager/plugin-loader.d.ts +86 -0
  872. package/src/lib/plugin-manager/plugin-loader.js +223 -0
  873. package/src/lib/plugin-manager/plugin-loader.js.map +1 -0
  874. package/src/lib/plugin-manager/plugin-manager.d.ts +95 -0
  875. package/src/lib/plugin-manager/plugin-manager.js +343 -0
  876. package/src/lib/plugin-manager/plugin-manager.js.map +1 -0
  877. package/src/lib/plugin-manager/plugin-metered-lines.d.ts +97 -0
  878. package/src/lib/plugin-manager/plugin-metered-lines.js +123 -0
  879. package/src/lib/plugin-manager/plugin-metered-lines.js.map +1 -0
  880. package/src/lib/plugin-manager/plugin-org-erasure.d.ts +52 -0
  881. package/src/lib/plugin-manager/plugin-org-erasure.js +100 -0
  882. package/src/lib/plugin-manager/plugin-org-erasure.js.map +1 -0
  883. package/src/lib/plugin-manager/plugin-permissions.d.ts +69 -0
  884. package/src/lib/plugin-manager/plugin-permissions.js +77 -0
  885. package/src/lib/plugin-manager/plugin-permissions.js.map +1 -0
  886. package/src/lib/plugin-manager/plugin-person-erasure.d.ts +58 -0
  887. package/src/lib/plugin-manager/plugin-person-erasure.js +109 -0
  888. package/src/lib/plugin-manager/plugin-person-erasure.js.map +1 -0
  889. package/src/lib/plugin-manager/plugin-record-cards.d.ts +99 -0
  890. package/src/lib/plugin-manager/plugin-record-cards.js +59 -0
  891. package/src/lib/plugin-manager/plugin-record-cards.js.map +1 -0
  892. package/src/lib/plugin-manager/plugin-record-facts.d.ts +111 -0
  893. package/src/lib/plugin-manager/plugin-record-facts.js +51 -0
  894. package/src/lib/plugin-manager/plugin-record-facts.js.map +1 -0
  895. package/src/lib/plugin-manager/plugin-record-routes.d.ts +129 -0
  896. package/src/lib/plugin-manager/plugin-record-routes.js +93 -0
  897. package/src/lib/plugin-manager/plugin-record-routes.js.map +1 -0
  898. package/src/lib/plugin-manager/plugin-record-timeline.d.ts +147 -0
  899. package/src/lib/plugin-manager/plugin-record-timeline.js +39 -0
  900. package/src/lib/plugin-manager/plugin-record-timeline.js.map +1 -0
  901. package/src/lib/plugin-manager/plugin-resource-drafts.d.ts +137 -0
  902. package/src/lib/plugin-manager/plugin-resource-drafts.js +51 -0
  903. package/src/lib/plugin-manager/plugin-resource-drafts.js.map +1 -0
  904. package/src/lib/plugin-manager/plugin-services.d.ts +94 -0
  905. package/src/lib/plugin-manager/plugin-services.js +153 -0
  906. package/src/lib/plugin-manager/plugin-services.js.map +1 -0
  907. package/src/lib/plugin-manager/plugin-styles-ui.d.ts +71 -0
  908. package/src/lib/plugin-manager/plugin-styles-ui.js +80 -0
  909. package/src/lib/plugin-manager/plugin-styles-ui.js.map +1 -0
  910. package/src/lib/plugin-manager/plugin-styles.d.ts +176 -0
  911. package/src/lib/plugin-manager/plugin-styles.js +186 -0
  912. package/src/lib/plugin-manager/plugin-styles.js.map +1 -0
  913. package/src/lib/plugin-manager/plugin-subprocessors.d.ts +135 -0
  914. package/src/lib/plugin-manager/plugin-subprocessors.js +129 -0
  915. package/src/lib/plugin-manager/plugin-subprocessors.js.map +1 -0
  916. package/src/lib/plugin-manager/plugin-tax-profile.d.ts +84 -0
  917. package/src/lib/plugin-manager/plugin-tax-profile.js +39 -0
  918. package/src/lib/plugin-manager/plugin-tax-profile.js.map +1 -0
  919. package/src/lib/plugin-manager/plugin-user-erasure.d.ts +53 -0
  920. package/src/lib/plugin-manager/plugin-user-erasure.js +84 -0
  921. package/src/lib/plugin-manager/plugin-user-erasure.js.map +1 -0
  922. package/src/lib/plugin-manager/plugin-zones.d.ts +121 -0
  923. package/src/lib/plugin-manager/plugin-zones.js +74 -0
  924. package/src/lib/plugin-manager/plugin-zones.js.map +1 -0
  925. package/src/lib/plugin-manager/realm-plugins.d.ts +112 -0
  926. package/src/lib/plugin-manager/realm-plugins.js +196 -0
  927. package/src/lib/plugin-manager/realm-plugins.js.map +1 -0
  928. package/src/lib/plugin-manager/realm-server.d.ts +54 -0
  929. package/src/lib/plugin-manager/realm-server.js +88 -0
  930. package/src/lib/plugin-manager/realm-server.js.map +1 -0
  931. package/src/lib/plugin-manager/record-zone-props.d.ts +126 -0
  932. package/src/lib/plugin-manager/record-zone-props.js +31 -0
  933. package/src/lib/plugin-manager/record-zone-props.js.map +1 -0
  934. package/src/lib/plugin-manager/site-page-hooks.d.ts +102 -0
  935. package/src/lib/plugin-manager/site-page-hooks.js +114 -0
  936. package/src/lib/plugin-manager/site-page-hooks.js.map +1 -0
  937. package/src/lib/plugin-manager/site-runtime.d.ts +57 -0
  938. package/src/lib/plugin-manager/site-runtime.js +25 -0
  939. package/src/lib/plugin-manager/site-runtime.js.map +1 -0
  940. package/src/lib/plugin-manager/usage-alert-contributors.d.ts +115 -0
  941. package/src/lib/plugin-manager/usage-alert-contributors.js +106 -0
  942. package/src/lib/plugin-manager/usage-alert-contributors.js.map +1 -0
  943. package/src/lib/types/ast.d.ts +199 -0
  944. package/src/lib/types/ast.js +20 -0
  945. package/src/lib/types/ast.js.map +1 -0
  946. package/src/lib/types/index.d.ts +20 -0
  947. package/src/lib/types/index.js +21 -0
  948. package/src/lib/types/index.js.map +1 -0
  949. package/src/lib/types/nodes.d.ts +608 -0
  950. package/src/lib/types/nodes.js +28 -0
  951. package/src/lib/types/nodes.js.map +1 -0
  952. package/src/lib/types/routing.d.ts +17 -0
  953. package/src/lib/types/routing.js +18 -0
  954. package/src/lib/types/routing.js.map +1 -0
  955. package/src/lib/types/screen.d.ts +23 -0
  956. package/src/lib/types/screen.js +18 -0
  957. package/src/lib/types/screen.js.map +1 -0
  958. package/src/lib/utils.d.ts +25 -0
  959. package/src/lib/utils.js +42 -0
  960. package/src/lib/utils.js.map +1 -0
  961. package/src/server.d.ts +37 -0
  962. package/src/server.js +55 -0
  963. package/src/server.js.map +1 -0
@@ -0,0 +1,1766 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Shared shape for the `/api/health` endpoints (AGL-1102).
19
+ *
20
+ * Both the console and the tenant runtime answer this, and they must answer it
21
+ * IDENTICALLY — an uptime series is only comparable across services if the
22
+ * status codes and the field names agree. Two near-identical route files would
23
+ * have drifted the first time one of them was touched.
24
+ *
25
+ * The rules encoded here, each of which is a way health checks routinely lie:
26
+ *
27
+ * **The status code is the contract.** Most uptime monitors read nothing else,
28
+ * so a degraded dependency has to be a 503. A 200 whose body says "degraded"
29
+ * is a signal nobody receives.
30
+ *
31
+ * **Never cacheable.** A cached health check returns 200 from the edge while
32
+ * the origin is on fire, and the graph stays green straight through the
33
+ * outage. Three separate caches have faked a green check in this repo already,
34
+ * so this sets `no-store` on every response including the failures — an error
35
+ * response is the one you least want served from a cache.
36
+ *
37
+ * **No internals in the body.** It is public and unauthenticated, so a failing
38
+ * check reports a CODE and never the underlying message, which can carry
39
+ * project ids, paths or credentials fragments.
40
+ */
41
+ export interface HealthCheck {
42
+ ok: boolean;
43
+ /** How long the dependency took. The number that turns into a latency graph. */
44
+ ms: number;
45
+ /** A stable code on failure — never a raw error message. */
46
+ code?: string;
47
+ }
48
+ export interface HealthReport {
49
+ service: string;
50
+ checks: Record<string, HealthCheck>;
51
+ commit?: string | null;
52
+ /**
53
+ * Which VERSION of the platform answered (AGL-2091).
54
+ *
55
+ * `commit` alone could only ever be answered on Aglyn's own cloud, so a
56
+ * self-host operator had nothing to quote in a bug report and no way to ask
57
+ * whether a fix had reached them. This is the field that answers it, and
58
+ * unlike the commit it needs no operator configuration —
59
+ * `platformVersion()` reads the number the build inlined from package.json.
60
+ */
61
+ version?: string | null;
62
+ environment?: string | null;
63
+ region?: string | null;
64
+ /** Injected so the body is deterministic in tests. */
65
+ at?: string;
66
+ }
67
+ export declare const HEALTH_NO_STORE = "no-store, no-cache, must-revalidate, max-age=0";
68
+ /** Degraded if ANY check failed. There is no partial credit for uptime. */
69
+ export declare function healthStatus(checks: Record<string, HealthCheck>): 'ok' | 'degraded';
70
+ export declare function healthBody(report: HealthReport): Record<string, unknown>;
71
+ export declare function healthHeaders(status: 'ok' | 'degraded'): Record<string, string>;
72
+ export declare function healthHttpStatus(status: 'ok' | 'degraded'): number;
73
+ /**
74
+ * A HEAD response for a health endpoint: the SAME status and headers its GET
75
+ * would return, with no body (AGL-1148).
76
+ *
77
+ * ## Why this exists
78
+ *
79
+ * Every health route used to answer HEAD with a hardcoded `200` and the
80
+ * comment "cheap liveness for monitors that only issue HEAD. Touches
81
+ * nothing." Touching nothing is precisely the problem: **a HEAD that knows
82
+ * nothing is a health check that cannot go red.** A monitor configured with
83
+ * HEAD — which several uptime providers use by default — would have reported
84
+ * green through any outage that left the function able to boot, which is most
85
+ * of them. `/api/health/crons` sat at 503 for fifty-one hours; a HEAD monitor
86
+ * pointed at it would have agreed with the green board the whole time.
87
+ *
88
+ * It also violated the contract this file opens with. "The status code is the
89
+ * contract" cannot hold for one method and not another, and HTTP requires a
90
+ * HEAD response to carry the same status and headers its GET would.
91
+ *
92
+ * ## The cost argument, which is why this is safe
93
+ *
94
+ * Delegating to GET means HEAD runs the dependency probe. Every route
95
+ * memoizes that probe (`memoizeWithTtl`, 15s on the root and 5 minutes on the
96
+ * subsystems) explicitly so a public unauthenticated endpoint cannot be made
97
+ * to read in a loop — the same bound that already lets a fifteen-minute probe
98
+ * hit seven endpoints for nearly nothing. HEAD now costs exactly what GET
99
+ * costs, which is a memo lookup between refreshes, and it serializes no body.
100
+ *
101
+ * Headers are carried over rather than rebuilt so `Cache-Control: no-store`,
102
+ * the open CORS origin and `Retry-After` reach a HEAD client identically — a
103
+ * HEAD response that was cacheable while its GET was not would be the same
104
+ * lie one layer down.
105
+ */
106
+ export declare function healthHeadOf(get: () => Promise<Response>): Promise<Response>;
107
+ /**
108
+ * Firestore backup state, reduced to a health verdict (AGL-1490, AGL-1502).
109
+ *
110
+ * The 2026-08-02 backup sat at `NOT_AVAILABLE` for eleven days and nothing
111
+ * noticed — the schedule ran, the API reported the failure, and no one was
112
+ * listening. This turns "is the newest backup real and recent" into the same
113
+ * 200/503 contract the other health checks speak, so the existing uptime
114
+ * probe + alert path is the listener.
115
+ *
116
+ * Pure on purpose: the route fetches, this decides, the spec exercises every
117
+ * branch without a network.
118
+ */
119
+ export interface BackupSnapshot {
120
+ /** `READY` | `CREATING` | `NOT_AVAILABLE` (or whatever the API adds next). */
121
+ state?: string;
122
+ /** ISO timestamp of the data the backup captured. */
123
+ snapshotTime?: string;
124
+ }
125
+ export interface BackupsCheck extends HealthCheck {
126
+ /**
127
+ * Histogram by state — `{ READY: 1, NOT_AVAILABLE: 1 }`. Counts only: the
128
+ * endpoint is public, and backup ids or resource paths have no business in
129
+ * it. Counts are enough to know WHAT is wrong before opening gcloud.
130
+ */
131
+ states: Record<string, number>;
132
+ /** Age of the newest READY backup, in days. Null when there is none. */
133
+ newestReadyAgeDays: number | null;
134
+ /**
135
+ * Present, and always `false`, ONLY in the third state (AGL-1843): the
136
+ * check could not determine whether backups are healthy. Omitted entirely
137
+ * from a real verdict, exactly as `code` is omitted from a healthy one, so
138
+ * `ok: true` with no `determinate` key means "measured, and fine".
139
+ *
140
+ * An indeterminate check reports `ok: true` and therefore does not page.
141
+ * That is deliberate and it is bounded — see the escalation note in
142
+ * `backupsHealth`.
143
+ */
144
+ determinate?: false;
145
+ }
146
+ /**
147
+ * Weekly Sunday schedule + one day of slack. A healthy cadence never exceeds
148
+ * 7; day 8 means the last run produced nothing usable.
149
+ */
150
+ export declare const MAX_BACKUP_AGE_DAYS = 8;
151
+ /**
152
+ * `backups` is the listing, or `null` when it could not be read at all.
153
+ *
154
+ * `options.unreachable` is `ListBackupsResponse.unreachable` — the locations
155
+ * the API could not reach. Non-empty means the listing is a PARTIAL result
156
+ * set. `options.code` is the code to report when `backups` is `null`.
157
+ */
158
+ export declare function backupsHealth(backups: BackupSnapshot[] | null, ms: number, now?: number, options?: {
159
+ unreachable?: string[];
160
+ code?: string;
161
+ }): BackupsCheck;
162
+ /**
163
+ * GCS export freshness, reduced to a health verdict (AGL-1843).
164
+ *
165
+ * Exports are NOT managed backups — they are the independent copy that exists
166
+ * BECAUSE the managed backups proved unreliable (every backup this project
167
+ * took flipped `READY` → `NOT_AVAILABLE` at roughly one week old, AGL-1843).
168
+ * A weekly `exportDocuments` run writes portable snapshot files to a GCS
169
+ * bucket, and this check watches that the newest one is real and recent, so
170
+ * a managed-backup flip no longer means "one copy only". The two are kept as
171
+ * SEPARATE checks in the same endpoint precisely so the body says which layer
172
+ * is degraded rather than blending them into one dishonest verdict.
173
+ *
174
+ * The input is the list of `*.overall_export_metadata` completion markers —
175
+ * Firestore writes exactly one per FINISHED export, so the marker's creation
176
+ * time is the moment the export completed, not the moment it started. An
177
+ * export that hangs forever never produces a marker and fails the age rule,
178
+ * the same trick `backupsHealth` plays with `CREATING`.
179
+ *
180
+ * Pure on purpose, like its siblings: the route lists, this decides, the
181
+ * spec exercises every branch without a network.
182
+ */
183
+ export interface ExportMarker {
184
+ /** ISO timestamp the completion marker was written — when the export FINISHED. */
185
+ timeCreated?: string;
186
+ }
187
+ export interface ExportsCheck extends HealthCheck {
188
+ /**
189
+ * Completed exports currently retained. A COUNT only — the endpoint is
190
+ * public, and bucket names or object paths have no business in it. Null
191
+ * when the listing itself failed.
192
+ */
193
+ exportCount: number | null;
194
+ /** Age of the newest completed export, in days. Null when there is none. */
195
+ newestExportAgeDays: number | null;
196
+ }
197
+ /**
198
+ * Weekly cadence (Mondays, `scheduled-crons.yml`) + one day of slack — the
199
+ * same budget as `MAX_BACKUP_AGE_DAYS`, for the same reason: a schedule that
200
+ * stops producing is as broken as one that fails.
201
+ */
202
+ export declare const MAX_EXPORT_AGE_DAYS = 8;
203
+ export declare function exportsHealth(markers: ExportMarker[] | null, ms: number, now?: number): ExportsCheck;
204
+ /**
205
+ * Org-creation volume, reduced to a health verdict (AGL-1536).
206
+ *
207
+ * The detection layer over the AGL-1534 rate limit: the limiter bounds each
208
+ * uid (3/h) and each IP (10/h), so a distributed farm holding every actor
209
+ * under both caps is invisible to it — but visible in aggregate. This turns
210
+ * "how many orgs appeared in the trailing hour" into the same 200/503
211
+ * contract the other health checks speak, so the existing uptime check +
212
+ * alert + email path is the listener, and a wave becomes an email instead of
213
+ * a surprise. The manual response lever is the AGL-1510 signups feature-lock.
214
+ *
215
+ * Pure on purpose, like `backupsHealth`: the route counts, this decides, the
216
+ * spec exercises every branch without a network.
217
+ */
218
+ export interface SignupsCheck extends HealthCheck {
219
+ /**
220
+ * Orgs created inside the trailing window. A COUNT only — the endpoint is
221
+ * public, and org names, slugs or owners have no business in it. Null when
222
+ * the count query itself failed.
223
+ */
224
+ recentOrgCreations: number | null;
225
+ /** The trailing window the count covers, so the body is self-describing. */
226
+ windowMinutes: number;
227
+ /** The count above which this reports degraded. */
228
+ threshold: number;
229
+ }
230
+ /** Trailing window the org-creation count covers. */
231
+ export declare const ORG_CREATION_WINDOW_MINUTES = 60;
232
+ /**
233
+ * Degraded above 10 creations/hour. Calibrated against two facts: production
234
+ * holds 4 orgs TOTAL (2026-08), so the organic baseline is ~zero per hour;
235
+ * and the AGL-1534 per-IP cap is 10/h, so a single maxed-out address can
236
+ * never trip this — 11+/h necessarily means multiple addresses, which is
237
+ * exactly the distributed signature the rate limiter cannot see. If a launch
238
+ * day legitimately beats this, the alert asks a human to glance at the orgs
239
+ * list and enjoy the view; that is the correct outcome, not a false positive.
240
+ */
241
+ export declare const MAX_ORG_CREATIONS_PER_WINDOW = 10;
242
+ export declare function signupsHealth(recentOrgCreations: number | null, ms: number, threshold?: number): SignupsCheck;
243
+ /**
244
+ * Refused org creations, reduced to a health verdict (AGL-1907).
245
+ *
246
+ * `signupsHealth` above counts the signups that SUCCEEDED. That is the right
247
+ * alarm for a wave that gets through, and the wrong one for a wave that is
248
+ * being contained: when the AGL-1534 limiter starts refusing, org-creation
249
+ * volume goes *down*, so the check that watches volume reads calmer at exactly
250
+ * the moment scripted pressure arrives. The 429s are the signature. Before the
251
+ * doors open on Sep 1 this is also the only thing that can answer "has the
252
+ * limiter ever actually fired in production" — a control nobody has seen
253
+ * refuse is a control nobody has tested.
254
+ *
255
+ * Counted from `rateLimits/signupRefused_{minuteBucket}` markers, which carry
256
+ * per-reason counts and no identifiers. This is a separate check rather than
257
+ * more fields on `SignupsCheck` so the AGL-1536 verdict keeps its meaning
258
+ * exactly: a creation wave and a refusal wave are different events with
259
+ * different responses (feature-lock the signups door vs. leave the limiter to
260
+ * do its job and go read the refusal reasons).
261
+ *
262
+ * Pure on purpose, like its siblings: the route queries, this decides.
263
+ */
264
+ export interface SignupRefusalMarker {
265
+ /** Refused attempts merged into this minute bucket. */
266
+ refusals?: number;
267
+ /**
268
+ * Split by what refused: `{ uid?: n, ip?: n, locked?: n, held?: n }`.
269
+ *
270
+ * `uid` and `ip` are the AGL-1534 rate limiter's two caps. `locked` and
271
+ * `held` come from the `beforeUserCreated` blocking function (AGL-2583) — a
272
+ * door the limiter never sees, because it decides account creation on the
273
+ * Identity Platform path before any Aglyn route runs.
274
+ */
275
+ byReason?: Record<string, number>;
276
+ /**
277
+ * Account creations the blocking function admitted BLIND: the signups lock
278
+ * could not be read and nothing this instance remembered said it was pulled
279
+ * (AGL-2583).
280
+ *
281
+ * Deliberately its own field rather than another `byReason` entry. Nobody
282
+ * was refused, so folding it into the refusal split would make both counts
283
+ * lie — and it is graded on its own terms below.
284
+ */
285
+ unreadable?: number;
286
+ /** When the most recent refusal in this bucket happened. */
287
+ refusedAtMs?: number;
288
+ }
289
+ export interface SignupRefusalsCheck extends HealthCheck {
290
+ /**
291
+ * Refused org creations inside the trailing window. A COUNT only — the
292
+ * endpoint is public, and the limiter's keys are a uid and a hashed client
293
+ * IP. Null when the query itself failed.
294
+ */
295
+ refusedSignups: number | null;
296
+ /**
297
+ * Which cap did the refusing. A run that is almost all `ip` is one address
298
+ * hammering; a run that is almost all `uid` is many accounts each pushing
299
+ * past three, which is the distributed shape. Null when the query failed.
300
+ */
301
+ refusedByReason: Record<string, number> | null;
302
+ /**
303
+ * Account creations decided WITHOUT the signups lock being readable
304
+ * (AGL-2583). Graded on its own, at zero tolerance, because it is
305
+ * categorically different from every entry in `refusedByReason`: those are
306
+ * controls working as designed, this is the platform answering the signups
307
+ * question without being able to consult it, and one of those is one too
308
+ * many. Null when the query itself failed.
309
+ */
310
+ lockUnreadable: number | null;
311
+ /** Minutes since the most recent refusal, so the body dates itself. */
312
+ minutesSinceLast: number | null;
313
+ /** The trailing window the count covers, so the body is self-describing. */
314
+ windowMinutes: number;
315
+ /** The count above which this reports degraded. */
316
+ threshold: number;
317
+ }
318
+ /**
319
+ * Trailing window the refusal count covers. One hour, matching the limiter's
320
+ * own window (`org-create` is 3/h and 10/h) so the number is readable against
321
+ * the caps that produced it.
322
+ */
323
+ export declare const SIGNUP_REFUSAL_WINDOW_MINUTES = 60;
324
+ /**
325
+ * Degraded above 50 refusals/hour.
326
+ *
327
+ * Not zero, unlike the limiter-degradation alarm: a refusal is the system
328
+ * working, and a real person who fumbles a workspace slug four times in an
329
+ * hour produces one. The number that means something is *sustained* refusal.
330
+ * Calibrated the same way AGL-1536's was: production holds single-digit orgs
331
+ * (2026-08), so organic refusals are ~zero per hour, and 50 is far above any
332
+ * plausible human while being reached in under a minute by a script. One
333
+ * determined address can generate this alone — that is intended, because "one
334
+ * address is hammering the signup door" is worth an email even though the
335
+ * limiter is containing it.
336
+ */
337
+ export declare const MAX_SIGNUP_REFUSALS_PER_WINDOW = 50;
338
+ /**
339
+ * The marker field the blocking function counts blind decisions under
340
+ * (AGL-2583).
341
+ *
342
+ * `signupsCreationVerdict` answers `locked` when a completed read found the
343
+ * lever pulled, `held` when a failed read fell back on an earlier one that
344
+ * had, and — the case this names — admits the account when the read failed
345
+ * and nothing remembered said the lever was pulled. That last one refuses
346
+ * nobody, so it is not a `byReason` entry; it is the platform deciding the
347
+ * signups question without being able to consult it, which is the visible
348
+ * edge of a Firestore read outage on the account-creation path. AGL-2581 was
349
+ * three days of that same read failing, and its only trace was a
350
+ * `logger.warn` nothing alerts on.
351
+ */
352
+ export declare const SIGNUP_LOCK_UNREADABLE_FIELD = "unreadable";
353
+ /**
354
+ * Blind signups-lock decisions tolerated per window: NONE.
355
+ *
356
+ * Deliberately not calibrated like `MAX_SIGNUP_REFUSALS_PER_WINDOW` above,
357
+ * which is a volume threshold over refusals that mean the system is working.
358
+ * A blind decision is never routine — a single one says the signups lock was
359
+ * unreadable at least once, and the lock is unenforceable for as long as that
360
+ * lasts. False positives here cost a glance at one endpoint.
361
+ */
362
+ export declare const MAX_UNREADABLE_SIGNUP_DECISIONS_PER_WINDOW = 0;
363
+ export declare function signupRefusalsHealth(markers: SignupRefusalMarker[] | null, ms: number, now?: number, threshold?: number, windowMinutes?: number, unreadableThreshold?: number): SignupRefusalsCheck;
364
+ /**
365
+ * NOBODY GOT AN ACCOUNT WHILE PEOPLE WERE TRYING (AGL-2583).
366
+ *
367
+ * `signupsHealth` watches for a FLOOD. Its healthiest possible reading —
368
+ * zero orgs created in the trailing hour — is also what total failure looks
369
+ * like, so the monitor named "signups" reports green precisely when nobody
370
+ * can sign up. That is not a hypothetical: account creation was refused for
371
+ * every visitor from Sep 1 to Sep 4 (AGL-2581) and the signup check was
372
+ * green through all of it, because zero is comfortably under ten.
373
+ *
374
+ * ## Zero is only a signal next to a denominator
375
+ *
376
+ * Alone, "no accounts this hour" describes a quiet Tuesday night as loudly as
377
+ * an outage, and an alarm that fires on quiet nights is an alarm everyone
378
+ * mutes. What makes zero mean something is TRAFFIC: people arrived at the
379
+ * signup page and none of them ended up with an account.
380
+ *
381
+ * ## The denominator is ATTEMPTS, and was once SERVES (AGL-2714)
382
+ *
383
+ * It began as signup-page serves — `signupServed_` markers written when the
384
+ * page asks `/api/lockdown-status?feature=signups`, the one server request
385
+ * every rendering makes. That counts LOOKERS: crawlers, link previews, a
386
+ * person reading the plan names and closing the tab. On 2026-09-09 it paged
387
+ * "Signups is down" on an hour with six such hits and no account, while the
388
+ * signup page rendered clean, the lockdown was off, all seven auth doors were
389
+ * green and not one signup had been refused. One of the six was the
390
+ * diagnostic load made while investigating the alert.
391
+ *
392
+ * At this platform's conversion rate a quiet hour and a broken door produce
393
+ * the same reading, so no threshold on serves could separate them. The
394
+ * quantity was wrong, not the number.
395
+ *
396
+ * `signupAttempted_` markers are the right one: written at the top of
397
+ * `/api/orgs/create` before any outcome is known, so an attempt means
398
+ * somebody authenticated, filled the form and asked for an org. Arrivals with
399
+ * no account is then a statement about the door rather than about demand.
400
+ *
401
+ * Writing the marker BEFORE the outcome is what makes this stronger than the
402
+ * refusal check beside it: `signupRefusals` counts what the route chose to
403
+ * turn away, so a request that 500s, hangs, or dies between the limiter and
404
+ * the write leaves no refusal at all — and leaves an attempt with no org,
405
+ * which is exactly this verdict.
406
+ *
407
+ * Not GA4, for the reason it was never GA4: its API needs a service account
408
+ * and an OAuth round trip from a public health route, its data lands with
409
+ * hours of latency, and a monitor that depends on an analytics vendor is a
410
+ * monitor that reports an outage every time that vendor has one.
411
+ *
412
+ * The denominator UNDER-counts on purpose and that is the safe direction: a
413
+ * marker write is fire-and-forget and a lost one is simply not counted.
414
+ * Under-counting can only make this check quieter, never louder — it cannot
415
+ * invent attempts that did not happen, so it cannot invent an outage.
416
+ *
417
+ * Serves are still read and still reported, as CONTEXT. They cost nothing
418
+ * extra and they answer the second question an on-call person asks: was
419
+ * anybody even looking.
420
+ *
421
+ * Pure on purpose, like its siblings: the route counts, this decides.
422
+ */
423
+ export interface SignupServedMarker {
424
+ /** Signup-page serves merged into this minute bucket. */
425
+ serves?: number;
426
+ /** When the most recent serve in this bucket happened. */
427
+ servedAtMs?: number;
428
+ }
429
+ export interface SignupAttemptMarker {
430
+ /** Org-creation attempts merged into this minute bucket. */
431
+ attempts?: number;
432
+ /** When the most recent attempt in this bucket happened. */
433
+ attemptedAtMs?: number;
434
+ }
435
+ export interface SignupDroughtCheck extends HealthCheck {
436
+ /**
437
+ * Signup pages served inside the trailing window — the denominator. A
438
+ * COUNT only; the markers carry no visitor, no IP and no referrer. Null
439
+ * when the query itself failed.
440
+ */
441
+ signupPagesServed: number | null;
442
+ /**
443
+ * Org-creation attempts inside the same window — the denominator the
444
+ * verdict is actually taken on (AGL-2714). Null when that query failed.
445
+ */
446
+ signupAttempts: number | null;
447
+ /** Accounts (orgs) actually created in the same window. The numerator. */
448
+ orgCreations: number | null;
449
+ /** The trailing window all three numbers cover, so the body is self-describing. */
450
+ windowMinutes: number;
451
+ /**
452
+ * Attempts below which zero creations is treated as a quiet hour rather
453
+ * than an outage. Named `minimumTraffic` still, because it is the same
454
+ * question — how much has to have happened before zero means something —
455
+ * and renaming it would break every monitor body that reads it.
456
+ */
457
+ minimumTraffic: number;
458
+ }
459
+ /**
460
+ * Trailing window the drought verdict covers. One hour, matching the sibling
461
+ * checks so the three numbers on this endpoint are all read against the same
462
+ * clock — and long enough that a single slow afternoon does not page anyone.
463
+ */
464
+ export declare const SIGNUP_DROUGHT_WINDOW_MINUTES = 60;
465
+ /**
466
+ * Attempts in the window below which zero accounts means nothing.
467
+ *
468
+ * Three, against attempts rather than the five it once meant against serves
469
+ * (AGL-2714). The unit changed, so the number had to be re-argued rather than
470
+ * carried over.
471
+ *
472
+ * Not one: a browser can lose a request, and a person can start the form and
473
+ * abandon it between authenticating and the org write. Not ten either — at a
474
+ * handful of signups a week, waiting for ten attempts to fail would mean
475
+ * waiting days to notice a door that stopped opening, which is the failure
476
+ * this check exists to catch inside an hour.
477
+ *
478
+ * Three distinct requests to create an org, none of which produced one and
479
+ * none of which was refused, is a door that does not open. That reading has
480
+ * no quiet-hour interpretation: nobody attempts three times by browsing.
481
+ */
482
+ export declare const MIN_SIGNUP_TRAFFIC_FOR_DROUGHT = 3;
483
+ export declare function signupDroughtHealth(markers: SignupServedMarker[] | null, attemptMarkers: SignupAttemptMarker[] | null, orgCreations: number | null, ms: number, minimumTraffic?: number, windowMinutes?: number): SignupDroughtCheck;
484
+ /**
485
+ * Rate-limiter degradation, reduced to a health verdict (AGL-1693).
486
+ *
487
+ * `consumeRateLimit` fails SOFT: when the Firestore counter is unreachable it
488
+ * answers from a per-instance `Map` and flags `degraded`. AGL-1679 made that
489
+ * findable after the fact — on recovery the instance writes one summary
490
+ * document `rateLimits/degraded_{minuteBucket}` — but nothing reads it, so a
491
+ * degraded window during the beta still passes unnoticed in real time. This
492
+ * turns "did any limiter fall back recently" into the same 200/503 contract
493
+ * the sibling checks speak, so the AGL-1502 uptime check + alert + email path
494
+ * is the listener.
495
+ *
496
+ * **The window is the whole design.** Markers carry a 30-day `expiresAt`, so
497
+ * "does a marker exist" would leave the endpoint red for a month after a
498
+ * thirty-second blip — a recovered incident permanently paging is how a check
499
+ * gets muted, and muted is worse than absent. That is the opposite of the
500
+ * backups check, which stays red BY DESIGN because a missing restore point is
501
+ * a condition that persists until someone fixes it (DISASTER_RECOVERY.md gap
502
+ * 2). A degraded limiter window is an EVENT: it is over, and what is owed is
503
+ * a notification, not a standing alarm. So the verdict covers a trailing
504
+ * window and clears itself.
505
+ *
506
+ * Filtering on `lastAtMs` rather than the marker's id: the id is bucketed on
507
+ * `firstAtMs`, so a long episode's document is stamped with the minute the
508
+ * outage STARTED. An id-range window would miss exactly the longest episodes,
509
+ * which are the ones worth waking up for.
510
+ *
511
+ * Pure on purpose, like `backupsHealth` and `signupsHealth`: the route
512
+ * queries, this decides, the spec exercises every branch without a network.
513
+ */
514
+ export interface RateLimitDegradationMarker {
515
+ /** Calls that fell back to the per-instance cap. */
516
+ calls?: number;
517
+ /** Instance-episodes merged into this minute bucket. */
518
+ episodes?: number;
519
+ /** When the episode's last fallback happened. */
520
+ lastAtMs?: number;
521
+ /** The failure code the episode ended on. */
522
+ code?: string;
523
+ }
524
+ export interface RateLimitsCheck extends HealthCheck {
525
+ /**
526
+ * Fallback calls inside the trailing window. A COUNT only — the endpoint is
527
+ * public, and limiter keys are hashed client IPs. Null when the query
528
+ * itself failed.
529
+ */
530
+ degradedCalls: number | null;
531
+ /** Instance-episodes inside the window. 2+ means several instances saw it. */
532
+ degradedEpisodes: number | null;
533
+ /** Minutes since the most recent fallback, so the body dates itself. */
534
+ minutesSinceLast: number | null;
535
+ /** The trailing window the counts cover, so the body is self-describing. */
536
+ windowMinutes: number;
537
+ /** The count above which this reports degraded. */
538
+ threshold: number;
539
+ }
540
+ /**
541
+ * Trailing window the degradation counts cover.
542
+ *
543
+ * Bounded from below by the alert path, not by taste. The probe memoizes for
544
+ * `HEALTH_PROBE_TTL_MS` (2 minutes), the slowest check on this door runs
545
+ * every 15, and the alert policy wants a minute of sustained failure — so a
546
+ * window shorter than ~18 minutes can go red and green again before that
547
+ * check tells anyone, which is a check that reports nothing while looking
548
+ * like it works. 30 leaves margin and still clears itself inside half an hour.
549
+ */
550
+ export declare const RATE_LIMIT_DEGRADED_WINDOW_MINUTES = 30;
551
+ /**
552
+ * Any fallback at all is worth an email. Unlike the signup alarm there is no
553
+ * organic baseline to clear: a healthy deployment produces exactly zero of
554
+ * these, and one is already the statement "for some requests, the global cap
555
+ * was not the cap". Firestore retries transactions internally, so a failure
556
+ * that reaches this code is not a single unlucky contention.
557
+ */
558
+ export declare const MAX_DEGRADED_CALLS_PER_WINDOW = 0;
559
+ export declare function rateLimitsHealth(markers: RateLimitDegradationMarker[] | null, ms: number, now?: number, threshold?: number, windowMinutes?: number): RateLimitsCheck;
560
+ /**
561
+ * Uncaught server-side errors, reduced to a health verdict (AGL-1921).
562
+ *
563
+ * ## The gap this closes
564
+ *
565
+ * Of the eleven alert policies in `aglyn-main`, not one could see a server
566
+ * error rate. Every check is a LIVENESS probe on one URL: `/api/health` can be
567
+ * green while `/api/billing/checkout` 500s for every paying customer, which is
568
+ * the single most likely shape of a launch-day incident and the one nothing
569
+ * could page on. Server errors lived only in the Vercel runtime log, which
570
+ * retains ~60 minutes and drains nowhere (AGL-1799).
571
+ *
572
+ * The first pass gave both apps an `onRequestError` hook that forwards each
573
+ * error to a `server-errors` log in `aglyn-main`. That closed the CAPTURE gap
574
+ * and left the reading gap wide open, and the reading gap is the one this repo
575
+ * keeps losing to — `/api/health/crons` was correct about a broken job for
576
+ * fifty-one hours because nothing asked it. Measured 2026-08-24: the
577
+ * production credential is refused `entries:list` on that log
578
+ * (`403 Permission denied for all log views`), so no probe here can read what
579
+ * the hook writes. The only reader that log can have is a GCP alert policy
580
+ * created by hand.
581
+ *
582
+ * So the hook ALSO counts into a `rateLimits/serverError_{minute}` marker,
583
+ * and this grades those counts into the same 200/503 contract the sibling
584
+ * checks speak — which hands the signal to readers that already exist and
585
+ * already run: the 15-minute GitHub uptime probe, the external keyword
586
+ * monitors, and `docs.aglyn.com/status`.
587
+ *
588
+ * ## What it can and cannot see, exactly
589
+ *
590
+ * It counts what `onRequestError` counts: an uncaught throw in a render or a
591
+ * route handler, in the nodejs runtime. It does NOT count an error that kills
592
+ * the process before the hook runs, a platform-level 5xx that never reaches
593
+ * our code (function timeout, OOM, cold-start 502), or anything thrown in the
594
+ * edge runtime. A Vercel log drain sees all of those and remains the real fix.
595
+ * This is the arm that ships without a purchase, and its blind spots are
596
+ * written down rather than glossed — `docs/UPTIME_AND_SLA.md`.
597
+ *
598
+ * ## The third state is the one that matters here
599
+ *
600
+ * A monitoring path that cannot measure MUST NOT report a zero. `null` markers
601
+ * — the query failed — is `errors-unavailable` and degraded, never "0 errors".
602
+ * That is the same rule `rateLimitsHealth` and `billingWebhookHealth` follow,
603
+ * and on this check it is the difference between "nothing is wrong" and "we
604
+ * have no idea", which during a 5xx spike are the two readings furthest apart.
605
+ *
606
+ * ## It must be able to go GREEN
607
+ *
608
+ * A spike is an EVENT, not a condition (the AGL-1843 rule). Markers live seven
609
+ * days, so "does a marker exist" would hold this red for a week after a
610
+ * one-minute blip, and a check that stays red after recovery is a check that
611
+ * gets muted. The verdict covers a trailing window and clears itself.
612
+ *
613
+ * Pure on purpose, like its siblings: the route queries, this decides, the
614
+ * spec exercises every branch without a network.
615
+ */
616
+ export interface ServerErrorMarker {
617
+ /** Uncaught server errors merged into this minute bucket. */
618
+ errors?: number;
619
+ /** Split by deployment — `{ 'console-web': n, 'tenant-web': n }`. */
620
+ byService?: Record<string, number>;
621
+ /** When the most recent error in this bucket happened. */
622
+ erroredAtMs?: number;
623
+ }
624
+ export interface ServerErrorsCheck extends HealthCheck {
625
+ /**
626
+ * Uncaught server errors inside the trailing window. A COUNT only — the
627
+ * endpoint is public, and messages, stacks and route patterns have no
628
+ * business in it (they are in the Logging entry, which is not public). Null
629
+ * when the query itself failed, and null is NEVER zero.
630
+ */
631
+ serverErrors: number | null;
632
+ /**
633
+ * Which deployment produced them. The first thing an incident needs, and it
634
+ * is a deployment name rather than anything about a request. Null when the
635
+ * query failed.
636
+ */
637
+ byService: Record<string, number> | null;
638
+ /** Minutes since the most recent error, so the body dates itself. */
639
+ minutesSinceLast: number | null;
640
+ /** The trailing window the count covers, so the body is self-describing. */
641
+ windowMinutes: number;
642
+ /** The count above which this reports degraded. */
643
+ threshold: number;
644
+ }
645
+ /**
646
+ * Trailing window the error count covers.
647
+ *
648
+ * Bounded from below by the alert path, not by taste — the same arithmetic as
649
+ * `RATE_LIMIT_DEGRADED_WINDOW_MINUTES`: the probe memoizes for 2 minutes, the
650
+ * slowest external check runs every 15, and an alert policy wants a minute of
651
+ * sustained failure, so a window under ~18 minutes can go red and green again
652
+ * before that check tells anyone. 30 leaves margin and still clears itself
653
+ * inside half an hour of the last error.
654
+ */
655
+ export declare const SERVER_ERROR_WINDOW_MINUTES = 30;
656
+ /**
657
+ * Errors tolerated in the window.
658
+ *
659
+ * NOT zero, unlike the rate-limiter and billing alarms, and the difference is
660
+ * real rather than a matter of nerve. Those two watch controls that a healthy
661
+ * deployment exercises exactly never. This one watches a count that a single
662
+ * cold-start Firestore deadline, or one visitor's malformed request reaching a
663
+ * route that throws instead of 400ing, can make non-zero on a perfectly good
664
+ * day — and an alarm that pages on the first of those gets muted before the
665
+ * one that matters arrives.
666
+ *
667
+ * Five over thirty minutes is chosen against the only two facts available.
668
+ * Production serves single-digit orgs (2026-08), so the organic rate of
669
+ * UNCAUGHT server errors is ~zero — the codebase answers its expected failures
670
+ * with 4xx, and reaching this hook means nothing handled it. And the shape
671
+ * being caught is "a route is failing for real users", which does not produce
672
+ * six errors an hour; it produces six in a minute. There is deliberately no
673
+ * pretence of calibration: the beta window exists to produce a baseline, and
674
+ * `SERVER_ERROR_ALARM_MAX_ERRORS` moves this without a deploy when it does.
675
+ */
676
+ export declare const MAX_SERVER_ERRORS_PER_WINDOW = 5;
677
+ export declare function serverErrorsHealth(markers: ServerErrorMarker[] | null, ms: number, now?: number, threshold?: number, windowMinutes?: number): ServerErrorsCheck;
678
+ /**
679
+ * How long a health door may reuse its verdict (AGL-2947).
680
+ *
681
+ * Cut from one budget: an outage must reach a person within ten minutes. A
682
+ * green verdict computed just before the onset keeps being served for this
683
+ * long, and only then can a prober see red. The fastest prober on most doors
684
+ * is UptimeRobot, every five minutes, which then confirms before it notifies.
685
+ * So the worst case is this + 5 + that confirmation: at two minutes the budget
686
+ * holds for any confirmation delay up to three. The five minutes every door
687
+ * used before spent the whole ten minutes before a notification could leave.
688
+ *
689
+ * It still bounds what a public door can be made to cost: at most one
690
+ * computation per instance per two minutes, and {@link memoizeWithTtl} shares
691
+ * a computation among the callers that arrive while it runs.
692
+ */
693
+ export declare const HEALTH_PROBE_TTL_MS: number;
694
+ /**
695
+ * Reuse a probe result for `ttlMs`, per instance.
696
+ *
697
+ * The endpoint is public and unauthenticated, so an unthrottled dependency
698
+ * check is a free amplifier: anyone could turn a loop into database reads on
699
+ * our account. This bounds the cost to one probe per instance per interval
700
+ * however hard it is hit.
701
+ *
702
+ * Callers that arrive while a probe is running share it rather than starting
703
+ * their own. The uptime check's regions, UptimeRobot and a HEAD twin routinely
704
+ * land within the same second of an expired entry, and each used to pay for a
705
+ * full probe.
706
+ *
707
+ * FAILURES ARE CACHED TOO, deliberately. A dependency that is down will be
708
+ * down for the next caller as well, and re-probing per request turns an
709
+ * outage into a stampede against the thing that is already failing. A probe
710
+ * that THROWS is not cached: its callers all see the throw, and the next
711
+ * caller probes again.
712
+ */
713
+ export declare function memoizeWithTtl<T>(ttlMs: number, probe: () => Promise<T>, now?: () => number): () => Promise<T>;
714
+ /**
715
+ * The error beacon's own liveness, reduced to a health verdict (AGL-1923).
716
+ *
717
+ * ## The failure this exists for
718
+ *
719
+ * The `Client error beacon` alert policy is a log-match: it fires when an
720
+ * entry APPEARS in `client-errors`. A policy of that shape can only report
721
+ * presence, so if the thing writing the entries stops writing, the policy
722
+ * goes quiet — and quiet is the reading it also gives when everything is
723
+ * healthy. **A dead beacon is indistinguishable from zero errors**, and
724
+ * `reportClientErrors` has three fail-soft paths that each end in a
725
+ * `console.warn` to a log that retains an hour and drains nowhere
726
+ * (AGL-1799). Error Reporting would show zero errors; the policy would stay
727
+ * silent; both readings look exactly like a clean launch.
728
+ *
729
+ * ## Why this shape and not a metric-absence policy
730
+ *
731
+ * AGL-1923 proposed a log-based metric plus `conditionAbsent`. This is the
732
+ * same guarantee with two properties that one lacks. It is PROVABLE — the
733
+ * verdict is graded synchronously against the write's own status, so the
734
+ * degraded branch can be induced and observed rather than waited out over an
735
+ * absence window. And it needs nothing new to run it: the uptime probe is
736
+ * what winds the dead-man's switch, so there is no cron that can itself stop
737
+ * without anyone noticing (which would only move the problem one layer out).
738
+ *
739
+ * ## It must be able to go GREEN
740
+ *
741
+ * The condition is an EVENT, not a state. A failed write degrades; the next
742
+ * successful write clears it, within one probe TTL — nothing latches and
743
+ * there is no retention window to age out of. That is the AGL-1843 rule
744
+ * applied before the fact: the clearing event is named, and it is "the next
745
+ * heartbeat that reaches Cloud Logging". The durable marker AGL-2713 added is
746
+ * evidence of a LANDING, never of a failure, so it can only ever shorten the
747
+ * red — a stale one forgives nothing.
748
+ *
749
+ * Pure on purpose, like its siblings: the route writes, this decides, the
750
+ * spec exercises every branch without a network.
751
+ */
752
+ export interface BeaconCheck extends HealthCheck {
753
+ /**
754
+ * The log id the heartbeat targets, so the body names what to query during
755
+ * an incident rather than making someone go and find it.
756
+ */
757
+ logId: string;
758
+ /** Which deployment's credential was exercised — console and tenant differ. */
759
+ service: string;
760
+ /**
761
+ * How many heartbeat writes this probe attempted. Two means the first one
762
+ * missed, which is a fact a green row must still carry: a credential that
763
+ * needs a second attempt every time is on its way to failing outright.
764
+ */
765
+ attempts: number;
766
+ /**
767
+ * Minutes since a heartbeat last durably landed, or null when the answer
768
+ * could not be established — which includes "none ever has". Null is what
769
+ * makes a missed heartbeat unforgivable, so the two cases fold safely.
770
+ */
771
+ minutesSinceHeartbeat: number | null;
772
+ /** How long a missed heartbeat is tolerated before this door reds. */
773
+ graceMinutes: number;
774
+ }
775
+ /**
776
+ * Codes that mean the heartbeat got no ANSWER, as opposed to a refusal
777
+ * (AGL-2713).
778
+ *
779
+ * The distinction is the whole of the tolerance below, so it is named once
780
+ * and asserted directly rather than being spelled inline at the branch.
781
+ *
782
+ * - `credential-unavailable` — the admin app is configured and its credential
783
+ * simply did not mint a token on this attempt. On a cold lambda that is the
784
+ * first outbound TLS of the instance's life, and it is the measured shape of
785
+ * both 2026-09-09 blips.
786
+ * - `transport-*` — the Logging write never came back inside its 4s deadline,
787
+ * or the fetch layer failed. Same class: nothing was decided.
788
+ *
789
+ * Everything else is a DECISION and must never be tolerated. `http-401` and
790
+ * `http-403` are a lost `logging.logEntries.create` grant, `http-429` is
791
+ * quota, and `no-credential` is a deployment whose `FIREBASE_*` env is absent
792
+ * — every one of them permanent until a person fixes it, and every one of
793
+ * them a state in which browser errors are being collected by nothing. So is
794
+ * `heartbeat-unavailable`, which means a writer documented never to throw
795
+ * threw.
796
+ */
797
+ export declare function isTransientBeaconCode(code: string | undefined): boolean;
798
+ /**
799
+ * How a missed heartbeat is graded (AGL-2713).
800
+ *
801
+ * `landedAtMs` is the durable, cross-instance fact — the last time ANY
802
+ * instance of this deployment put an entry in the log. It has to be durable:
803
+ * the probe memo dies with the lambda, so an in-process counter is at one on
804
+ * every cold start and would forgive nothing at all on the one shape this
805
+ * exists for.
806
+ */
807
+ export interface BeaconTolerance {
808
+ /** Heartbeat writes this probe made. Defaults to the single-attempt shape. */
809
+ attempts?: number;
810
+ /** When a heartbeat last durably landed; null when that cannot be shown. */
811
+ landedAtMs?: number | null;
812
+ /** How long a miss is forgiven after the last landing. Zero forgives none. */
813
+ graceMs?: number;
814
+ now?: number;
815
+ }
816
+ /**
817
+ * ## Tolerating ONE miss without becoming a door that cannot red (AGL-2713)
818
+ *
819
+ * `/api/health/error-beacon` on the console answered `503 no-credential` twice
820
+ * on 2026-09-09 — 15:12 and 17:22 UTC, each shortly after new capacity from
821
+ * the 15:08 deploy, each self-clearing within minutes, with the beacon code
822
+ * path changed by one comment line since the previous release. Between them
823
+ * they took the 15-minute uptime workflow red and opened four GCP alert
824
+ * events, on a monitor whose entire value is that somebody believes it.
825
+ *
826
+ * The tolerance is deliberately NOT "forgive a failure". It is three
827
+ * conditions that must all hold, and each one is what keeps the door able to
828
+ * go red:
829
+ *
830
+ * 1. the code says nothing was decided ({@link isTransientBeaconCode});
831
+ * 2. a heartbeat is PROVEN to have landed within `graceMs` — proof being a
832
+ * durable marker a successful write left behind, so a deployment whose
833
+ * credential never worked has nothing to forgive with and reds on its
834
+ * first probe;
835
+ * 3. that proof is not from the future, because a clock that ran backwards
836
+ * must not mint an unbounded grace.
837
+ *
838
+ * Absence of proof reds. A marker store that cannot be read reds. That is the
839
+ * same rule the `*-unavailable` arms of every sibling grader apply, pointed at
840
+ * the evidence for calm rather than at the evidence for alarm.
841
+ */
842
+ export declare function beaconHealth(write: {
843
+ ok: boolean;
844
+ code?: string;
845
+ } | null, logId: string, service: string, ms: number, tolerance?: BeaconTolerance): BeaconCheck;
846
+ /**
847
+ * A tenant page render, reduced to a health verdict (AGL-2486).
848
+ *
849
+ * ## The gap this closes
850
+ *
851
+ * `marketing-home` (`aglyn.com/`) and `customer-site` (`demo.aglyn.app/`) are
852
+ * the only two external checks that watched a REAL PAGE rather than a health
853
+ * endpoint. Both sat at 0% from 2026-08-21, because bot protection answered
854
+ * Google's checkers with a 429 checkpoint. The health-path firewall bypass
855
+ * that recovered `tenant-health` and `beacon-heartbeat tenant` cannot reach
856
+ * them: they fetch `/`, not `/api/health/*`.
857
+ *
858
+ * The alternative was allowlisting Google's 54 checker IPs — rejected because
859
+ * an IP-valued bypass rule is one the drift checker cannot meaningfully
860
+ * assert, and Google rotates the list. So the render moves to where the
861
+ * bypass already is: an endpoint under `/api/health` that renders the page
862
+ * server-side and grades the result.
863
+ *
864
+ * ## Why this is not "200 because the route exists"
865
+ *
866
+ * The caller runs the SAME loader the catch-all page route runs, against the
867
+ * SAME host, and this grades what came back. A page that resolves no host,
868
+ * 404s, redirects away, or composes an EMPTY node tree is a failure — and
869
+ * those are the shapes an outage actually takes. A canary that cannot go red
870
+ * for a broken page is worse than the dark check it replaces, because it
871
+ * reports a confidence it has not earned.
872
+ *
873
+ * ## What is deliberately NOT asserted
874
+ *
875
+ * Never a string from the page. The marker is STRUCTURAL — a host resolved
876
+ * and a non-empty composed node tree. Asserting copy would page whoever is
877
+ * on call for an ordinary content edit, and this endpoint is public, so
878
+ * customer content must not appear in its body either. `nodeCount` is a
879
+ * count, which is enough to tell "rendered nothing" from "rendered" without
880
+ * disclosing what was rendered.
881
+ */
882
+ export type RenderOutcome =
883
+ /** The loader returned props. `nodeCount` is the composed node total. */
884
+ {
885
+ kind: 'rendered';
886
+ hostResolved: boolean;
887
+ nodeCount: number;
888
+ }
889
+ /** The loader chose the not-found branch. */
890
+ | {
891
+ kind: 'not-found';
892
+ }
893
+ /** The loader chose to redirect — a home page should never do this. */
894
+ | {
895
+ kind: 'redirect';
896
+ }
897
+ /** The loader threw, or could not be reached at all. */
898
+ | {
899
+ kind: 'unavailable';
900
+ }
901
+ /**
902
+ * No target host is configured. A failure on purpose: "we are watching
903
+ * nothing" must never read the same as "the page is fine".
904
+ */
905
+ | {
906
+ kind: 'not-configured';
907
+ };
908
+ export interface RenderCheck extends HealthCheck {
909
+ /**
910
+ * Composed nodes the page produced. A COUNT, never the nodes: this endpoint
911
+ * is public and the nodes are the customer's page. Zero is the failure.
912
+ */
913
+ nodeCount: number;
914
+ /**
915
+ * Which tenant host was rendered — a CONFIGURED host, never one derived
916
+ * from the request, so no caller can choose what we render. Empty string
917
+ * when nothing is configured.
918
+ */
919
+ host: string;
920
+ }
921
+ export declare function renderHealth(outcome: RenderOutcome, host: string, ms: number): RenderCheck;
922
+ /**
923
+ * Billing webhook delivery, reduced to a health verdict (AGL-1924).
924
+ *
925
+ * ## The gap this closes
926
+ *
927
+ * Of the alert policies in `aglyn-main`, none watched billing. Sept 1 opens to
928
+ * PAYING customers, and the billing path is the one place where a failure
929
+ * nobody notices converts directly into lost revenue and a support incident
930
+ * per affected customer. The webhook has a documented history of failing
931
+ * exactly that way: AGL-1551 (every delivery rejected `400 Invalid signature`
932
+ * for a week, behind a green "Active" badge), AGL-1560 (a secret roll 400ing
933
+ * roughly half of deliveries), AGL-1552 (the replay window making every retry
934
+ * unreceivable), AGL-1798 (`charge.refunded` never subscribed). Each is a
935
+ * total or near-total failure of the billing event path, and not one of them
936
+ * would have paged anyone.
937
+ *
938
+ * ## Why the denominator has to come from Stripe
939
+ *
940
+ * `stripeEvents` alone cannot answer this. `route.ts` returns 400 BEFORE
941
+ * claiming the idempotency document, so a rejected delivery writes nothing —
942
+ * an empty collection reads identically whether nothing happened or
943
+ * everything was refused. That is precisely how the 2026-08-14 checklist tick
944
+ * came out green while AGL-1551 was live. Stripe supplies what it TRIED to
945
+ * deliver; we supply what we processed; the gap is the failure.
946
+ *
947
+ * ## Why this cannot false-page on a quiet night
948
+ *
949
+ * The verdict never keys on the ABSENCE of events. At beta volume a night
950
+ * with zero deliveries is legitimate, and a naive freshness rule would page
951
+ * on it — the AGL-1843 mistake in a new costume. `undelivered` is a count of
952
+ * deliveries Stripe attempted AND failed, so a quiet window scores zero and
953
+ * reads healthy for the right reason. `emitted` and `processed` are carried
954
+ * for the human reading the incident and are DELIBERATELY not inputs to the
955
+ * verdict: no floor for them exists yet, and inventing one before the beta
956
+ * produces a baseline would be a threshold nobody could defend.
957
+ *
958
+ * ## Division of labour with the AGL-1906 audit
959
+ *
960
+ * `tools/scripts/lib/stripe-webhook-health.mjs` asserts the endpoint's full
961
+ * subscribed-event list against `WEBHOOK_EVENTS`. That list is deliberately
962
+ * NOT duplicated here — a second copy is the exact failure its own comment
963
+ * warns about, and a subscription set is config that changes on deploys, not
964
+ * a thing that changes minute to minute. This watches the two facts that DO
965
+ * move continuously: whether the destination is still enabled, and whether
966
+ * deliveries are landing.
967
+ *
968
+ * ## It must be able to go GREEN
969
+ *
970
+ * Everything here is a trailing window over live Stripe state. A destination
971
+ * re-enabled, or a fixed handler whose retries then succeed, reads healthy on
972
+ * the next probe. There is no marker to age out and nothing to latch
973
+ * (AGL-1843): the clearing event is "a window with no failed deliveries and
974
+ * an enabled endpoint".
975
+ *
976
+ * Pure on purpose, like its siblings: the route fetches, this decides, the
977
+ * spec exercises every branch without a network.
978
+ */
979
+ export interface BillingWebhookFacts {
980
+ /** Our production destination, as Stripe currently holds it. */
981
+ endpointStatus: 'enabled' | 'disabled' | 'missing';
982
+ /** Events Stripe attempted and failed to deliver inside the window. */
983
+ undelivered: number;
984
+ /** Events Stripe emitted inside the window. Reported, never a verdict input. */
985
+ emitted: number;
986
+ /**
987
+ * Events our handler claimed inside the window. Reported, never a verdict
988
+ * input — and null when the Firestore arm could not run, which does NOT on
989
+ * its own make the check red: Stripe already answered the question that
990
+ * matters.
991
+ */
992
+ processed: number | null;
993
+ /**
994
+ * Deliveries that answered 200 and moved NOTHING inside the window
995
+ * (AGL-1954) — a required event type that produced neither a committed
996
+ * effect nor a named deliberate skip. See `webhook-delivery.ts` for why
997
+ * that is a defect by construction and a legitimate no-op is not one.
998
+ *
999
+ * Null when the Firestore arm could not run, and null is NOT red on its
1000
+ * own: Stripe already answered the question that matters, and a health
1001
+ * check that reds on its own read failure trains people to ignore it.
1002
+ */
1003
+ inert: number | null;
1004
+ /**
1005
+ * Deliveries that only landed on a RETRY inside the window (AGL-2039).
1006
+ *
1007
+ * The arm every other count here is structurally blind to.
1008
+ * `undelivered` comes from `delivery_success=false`, which is a TERMINAL
1009
+ * filter over EVENTS: an event that 400s three times and then succeeds
1010
+ * reads back clean and is indistinguishable from one that succeeded
1011
+ * immediately. The Stripe Dashboard scores delivery ATTEMPTS and counted
1012
+ * all three — which is why AGL-1906 read 0% against the Dashboard's 30% and
1013
+ * both figures were correct. The three attempts it could not see were
1014
+ * AGL-1551.
1015
+ *
1016
+ * The webhook stamps `retriedAtMs` when the distance from `event.created`
1017
+ * to its own claim exceeds `RETRY_LAG_SECONDS`, so this is an aggregation
1018
+ * over a marker field rather than a scan of every claim in the window.
1019
+ *
1020
+ * Null when the Firestore arm could not run, and null is NOT red on its
1021
+ * own — same rule as `processed` and `inert`.
1022
+ */
1023
+ retried: number | null;
1024
+ /**
1025
+ * Required event types the destination is NOT subscribed to (AGL-1948 /
1026
+ * AGL-1798). Empty is the healthy answer; null means the endpoint did not
1027
+ * report its subscriptions and the coverage question is unanswered.
1028
+ */
1029
+ unsubscribedEvents: readonly string[] | null;
1030
+ /**
1031
+ * The CONNECT destination, as Stripe currently holds it (AGL-1948).
1032
+ *
1033
+ * A SECOND destination, and the platform one being perfectly healthy says
1034
+ * nothing about it: connected-account events are delivered only to a
1035
+ * destination created with `connect: true`, so its absence is invisible to
1036
+ * every count above. AGL-2122 found exactly that — `account.updated`
1037
+ * handled in two plugins, and no destination that could ever deliver it,
1038
+ * so every merchant's `stripeChargesEnabled` rotted silently.
1039
+ *
1040
+ * Null when the endpoint census itself could not be taken.
1041
+ */
1042
+ connectEndpoint: 'enabled' | 'disabled' | 'missing' | null;
1043
+ /**
1044
+ * Required Connect events the Connect destination is NOT subscribed to.
1045
+ * Empty is healthy; null means there was no destination to ask, or it did
1046
+ * not state its subscriptions.
1047
+ */
1048
+ unsubscribedConnectEvents: readonly string[] | null;
1049
+ }
1050
+ export interface BillingWebhookCheck extends HealthCheck {
1051
+ endpointStatus: BillingWebhookFacts['endpointStatus'] | null;
1052
+ undelivered: number | null;
1053
+ emitted: number | null;
1054
+ processed: number | null;
1055
+ inert: number | null;
1056
+ retried: number | null;
1057
+ unsubscribedEvents: readonly string[] | null;
1058
+ connectEndpoint: BillingWebhookFacts['connectEndpoint'] | null;
1059
+ unsubscribedConnectEvents: readonly string[] | null;
1060
+ /** The trailing window the counts cover, so the body is self-describing. */
1061
+ windowMinutes: number;
1062
+ }
1063
+ /**
1064
+ * Trailing window the delivery counts cover.
1065
+ *
1066
+ * Bounded from below by the alert path, not by taste, exactly like
1067
+ * `RATE_LIMIT_DEGRADED_WINDOW_MINUTES`: the probe memoizes for 5 minutes, the
1068
+ * uptime check runs every 5, and the policy wants ~10 minutes of sustained
1069
+ * failure before it emails — so a window under ~20 minutes can go red and
1070
+ * green again before anyone is told. Bounded from ABOVE by Stripe's retry
1071
+ * schedule: an event that fails and then succeeds on retry stops counting, so
1072
+ * a window much longer than an hour would hold transient blips red past their
1073
+ * own recovery.
1074
+ */
1075
+ export declare const WEBHOOK_FAILURE_WINDOW_MINUTES = 60;
1076
+ /**
1077
+ * Failed deliveries tolerated in the window.
1078
+ *
1079
+ * Zero, and unlike the signup alarm there is no organic baseline to clear: a
1080
+ * healthy account produces exactly zero, and one is already the statement
1081
+ * "Stripe tried to tell us something about money and could not". Stripe
1082
+ * retries on its own, so a failure visible here is not one unlucky packet.
1083
+ */
1084
+ export declare const MAX_FAILED_DELIVERIES_PER_WINDOW = 0;
1085
+ /**
1086
+ * Inert deliveries tolerated in the window (AGL-1954).
1087
+ *
1088
+ * Zero — and unlike `processed`, the count this check reports but refuses to
1089
+ * gate on because no defensible floor exists before the beta produces a
1090
+ * baseline, this one's floor follows from the definition. A delivery is
1091
+ * counted inert only when a required event type produced neither a committed
1092
+ * effect nor a NAMED deliberate skip (`classifyWebhookDelivery`). No
1093
+ * legitimate traffic pattern generates one: a tenant shopper's subscription,
1094
+ * a marketplace refund, a `won` dispute nobody claimed all name their reason
1095
+ * and classify as `ignored`. So any at all is the statement "Stripe told us
1096
+ * about money and nothing here moved" — the same "any at all" rule the
1097
+ * rate-limiter degradation markers use (AGL-1679).
1098
+ */
1099
+ export declare const MAX_INERT_DELIVERIES_PER_WINDOW = 0;
1100
+ /**
1101
+ * Retried deliveries tolerated in the window (AGL-2039).
1102
+ *
1103
+ * Zero, and the reasoning is `MAX_FAILED_DELIVERIES_PER_WINDOW`'s: a delivery
1104
+ * counted here is one whose FIRST attempt did not get through, which is a
1105
+ * failed attempt that happened, not a statistical wobble. The healthy band
1106
+ * measured against the live account is 1.0–3.7 seconds against a 120-second
1107
+ * bar, so nothing organic sits anywhere near it.
1108
+ *
1109
+ * Cheap to be wrong in the safe direction, because this cannot latch: the
1110
+ * window is trailing and the marker is on the event's own claim, so a single
1111
+ * blip reds for at most one window and then clears itself — an event, not a
1112
+ * condition (the AGL-1843 rule). It is a parameter rather than a literal so
1113
+ * that if beta traffic turns out to produce organic retries, the knob is one
1114
+ * argument and not a rewrite.
1115
+ */
1116
+ export declare const MAX_RETRIED_DELIVERIES_PER_WINDOW = 0;
1117
+ export declare function billingWebhookHealth(facts: BillingWebhookFacts | null, ms: number, windowMinutes?: number, threshold?: number, inertThreshold?: number, retriedThreshold?: number): BillingWebhookCheck;
1118
+ /**
1119
+ * Is every interval we can SELL also an interval we can BILL? (AGL-1931)
1120
+ *
1121
+ * The metered item is what turns reported usage into money. It is attached
1122
+ * from an env-configured price id that is keyed by billing interval —
1123
+ * `STRIPE_PRICE_METERED` for monthly, `STRIPE_PRICE_METERED_YEARLY` for
1124
+ * annual — because Stripe forbids one subscription mixing
1125
+ * `recurring.interval`.
1126
+ *
1127
+ * When one of those ids is missing, `meteredPriceId(interval)` returns null
1128
+ * and every subscription-mutating path does the only safe thing: it attaches
1129
+ * nothing and carries on. Failing a checkout over it would be worse. But the
1130
+ * result is a subscription that accrues usage against a meter and carries no
1131
+ * item to bill it, and NOTHING about that is visible — the plan is right, the
1132
+ * entitlements are right, the invoice looks right, and the only trace is
1133
+ * revenue that never arrives.
1134
+ *
1135
+ * That is the defect shape this check exists to end. The absence of a price
1136
+ * was indistinguishable from "correctly no overage", so it hid behind a
1137
+ * `console.warn` on a server log nobody reads. Here it is a 503 on the same
1138
+ * probe the uptime check and alert email already watch.
1139
+ *
1140
+ * ## Why ASYMMETRY is the loudest code
1141
+ *
1142
+ * One interval configured and the other not means one cohort of customers is
1143
+ * billed for overage and the other silently is not — off the same meter, on
1144
+ * the same plans, with no screen anywhere showing the difference. It cannot
1145
+ * be a deliberate state: there is no product reason to meter monthly
1146
+ * subscribers and exempt annual ones.
1147
+ *
1148
+ * ## Why BOTH missing is still red, but only with Stripe configured
1149
+ *
1150
+ * Both unset with no `STRIPE_SECRET_KEY` is simply an unprovisioned
1151
+ * deployment — local dev, a fresh preview — where no money is at stake and
1152
+ * going red would train everyone to ignore this check. That is the exact
1153
+ * reasoning the checkout and subscription routes already apply to their
1154
+ * warning, and it is preserved here.
1155
+ *
1156
+ * But both unset while Stripe IS configured is a deployment that can take
1157
+ * money and cannot bill a single unit of overage on ANY interval. That is
1158
+ * the same revenue loss, merely total instead of partial, and the earlier
1159
+ * code treated it as calm because it only ever compared the two ids to each
1160
+ * other. Comparing them to Stripe's presence instead is what closes it.
1161
+ */
1162
+ export interface MeteredPricingFacts {
1163
+ /** Whether this deployment holds a Stripe secret key at all. */
1164
+ stripeConfigured: boolean;
1165
+ /** `STRIPE_PRICE_METERED` — the monthly metered price — is set. */
1166
+ monthly: boolean;
1167
+ /** `STRIPE_PRICE_METERED_YEARLY` — the annual metered price — is set. */
1168
+ yearly: boolean;
1169
+ }
1170
+ export interface MeteredPricingCheck extends HealthCheck {
1171
+ stripeConfigured: boolean;
1172
+ monthly: boolean;
1173
+ yearly: boolean;
1174
+ /**
1175
+ * The interval that would accrue unbilled usage, named so the body says
1176
+ * which cohort is affected without anyone re-deriving it from two booleans.
1177
+ */
1178
+ unbilledInterval: 'month' | 'year' | 'both' | null;
1179
+ }
1180
+ export declare function meteredPricingHealth(facts: MeteredPricingFacts, ms: number): MeteredPricingCheck;
1181
+ /** Where the marks live. One document per job id, written by the job. */
1182
+ export declare const CRON_BEAT_COLLECTION = "platformCronBeats";
1183
+ /**
1184
+ * The document that records when this deployment STARTED watching.
1185
+ *
1186
+ * Without it a job that has never reported cannot be told apart from a job
1187
+ * that has stopped reporting, and every board would come up red on the day
1188
+ * the feature deploys — for `usage-email`, red until the 1st of the next
1189
+ * month. The rule this enables is stated once, in `cronJobsHealth`: a job
1190
+ * with no mark is only silent once a scheduled fire time has passed SINCE
1191
+ * we started watching.
1192
+ *
1193
+ * Not a reserved id: Firestore reserves `__.*__`, and this is a plain slug
1194
+ * that no job id can collide with (job ids never contain the word `watch`,
1195
+ * and the wiring spec asserts the inventory's ids against the workflow).
1196
+ */
1197
+ export declare const CRON_BEAT_WATCH_DOC = "watch-window";
1198
+ /**
1199
+ * Where a degraded verdict is recorded, so a red window survives it.
1200
+ *
1201
+ * The response body names the late job, but only to whoever is holding it,
1202
+ * and the uptime probe reads the status and discards the body. Vercel's
1203
+ * runtime log keeps a `console.error` for about an hour, and the Cloud
1204
+ * Logging drain deliberately does not forward one — `isServerErrorEntry`
1205
+ * drops `level: 'error'`, because that is every fail-soft line the beacons
1206
+ * write and forwarding it is what a self-feeding bill is made of. So the
1207
+ * only sink that outlives the window is the one the endpoint already holds
1208
+ * a handle to.
1209
+ *
1210
+ * Written by the READER, like the verdict itself. One document, replaced on
1211
+ * each degraded probe, holding the failing rows and when the window opened.
1212
+ * Same collision argument as the watch document: a plain slug, and no job id
1213
+ * contains `degraded`.
1214
+ */
1215
+ export declare const CRON_BEAT_DEGRADED_DOC = "last-degraded";
1216
+ /**
1217
+ * Every job's latest mark in one document, `{ beats: { [jobId]: atMs } }`.
1218
+ *
1219
+ * The reader's fast path (AGL-2946). Listing the collection costs one read per
1220
+ * job on every uncached probe — ~23 reads, several hundred times a day, on a
1221
+ * project that pays for reads past the free tier — to answer a question this
1222
+ * one document answers.
1223
+ *
1224
+ * A COPY, never the authority. `writeCronBeat` writes it second, so a job
1225
+ * whose own mark landed can still be missing or stale here, and the reader
1226
+ * confirms any job this document calls late against that job's own mark
1227
+ * before reporting it. Stale costs a read; it never costs a false red.
1228
+ *
1229
+ * Same collision argument as the other two: a plain slug no job id equals.
1230
+ */
1231
+ export declare const CRON_BEAT_SUMMARY_DOC = "summary";
1232
+ /** The reserved documents in `CRON_BEAT_COLLECTION` that are not job marks. */
1233
+ export declare const CRON_BEAT_RESERVED_DOCS: ReadonlySet<string>;
1234
+ /**
1235
+ * How long a gap may be before the next degraded probe counts as a NEW
1236
+ * window rather than a continuation of the one on file.
1237
+ *
1238
+ * Three probe TTLs. Long enough that an instance answering intermittently
1239
+ * does not split one outage into a dozen, short enough that yesterday's
1240
+ * window is never mistaken for today's. The comparison is against the
1241
+ * failing set as well, so a different set always opens a new window.
1242
+ */
1243
+ export declare const CRON_DEGRADED_WINDOW_CONTINUITY_MS: number;
1244
+ /** Who fires the job. The two are operated, and fail, differently. */
1245
+ export type CronRunner = 'github-actions' | 'cloud-scheduler';
1246
+ export interface ScheduledJob {
1247
+ /** Stable id. The Firestore document id, and the health check's name. */
1248
+ id: string;
1249
+ label: string;
1250
+ /**
1251
+ * Five-field cron, UTC. The SAME string the scheduler holds — the wiring
1252
+ * spec asserts each one against its runner's source of truth
1253
+ * (`.github/workflows/scheduled-crons.yml` for `github-actions`,
1254
+ * `cloud/functions/src/index.ts` for `cloud-scheduler`), so an edit there
1255
+ * that is not made here fails the build rather than quietly changing what
1256
+ * "on time" means.
1257
+ */
1258
+ cron: string;
1259
+ runner: CronRunner;
1260
+ /** What the scheduler actually invokes, for the operator reading a red row. */
1261
+ target: string;
1262
+ /**
1263
+ * How late a run may be before the row goes red.
1264
+ *
1265
+ * Generous on purpose, and the generosity is not padding. GitHub only runs
1266
+ * scheduled workflows from the default branch and delays them under load —
1267
+ * routinely by minutes, occasionally by an hour. The question this check
1268
+ * answers is "is this job still scheduled at all", not "did it start on the
1269
+ * second"; a grace that reds on ordinary lateness is alert fatigue, and an
1270
+ * alert people learn to ignore is the failure this issue is about wearing
1271
+ * a different hat.
1272
+ *
1273
+ * SO THE GRACE IS A PROPERTY OF THE RUNNER, not of the job (AGL-1617). The
1274
+ * ninety minutes the two frequent sweeps used to carry was GitHub's drift
1275
+ * budget, and it was bought with detection: on a fifteen-minute schedule it
1276
+ * takes SIX consecutive missed fires before anything is said. Moving those
1277
+ * two onto Cloud Scheduler — which is punctual, as `plugin-jobs-beat` has
1278
+ * been demonstrating at `every 1 minutes` in the same payload the whole
1279
+ * time — is what let the bar go back UP, to forty-five minutes and three
1280
+ * missed fires. That direction is the point: widening a grace to make a
1281
+ * monitor agree with a runner that drops 60% of its triggers is not a fix,
1282
+ * it is deciding not to look.
1283
+ *
1284
+ * IT IS A FLOOR, NOT THE EXACT BAR. `cronJobsHealth` compares the mark
1285
+ * against the last fire that is ALREADY this old, so where the threshold
1286
+ * lands depends on the clock's phase against the schedule: forty-five
1287
+ * minutes on a fifteen-minute cron reds somewhere between 45 and 60 minutes
1288
+ * of silence, six hours on a daily one between 6h and 30h. Quote the range,
1289
+ * not the number, when reasoning about how fast a dead job is found — and
1290
+ * never write a test that only holds at one phase.
1291
+ */
1292
+ graceMinutes: number;
1293
+ /** What stops happening when this job stops. Rendered on the board. */
1294
+ drives: string;
1295
+ }
1296
+ /**
1297
+ * THE INVENTORY.
1298
+ *
1299
+ * Seven GitHub Actions schedules (`.github/workflows/scheduled-crons.yml`) —
1300
+ * the weekly jobs, the month-boundary usage-email sweep and the hourly CRM
1301
+ * task reminders, for which an hour of drift is nothing — and the rows
1302
+ * driven by Cloud Scheduler out of
1303
+ * `cloud/functions/src/index.ts`: `pluginJobsBeat` and `consoleAiJobsBeat`
1304
+ * (every minute), the routes the `consoleFastCrons` job carries every
1305
+ * fifteen (AGL-1617), and one `consoleDailyCron` export per daily job.
1306
+ *
1307
+ * `scheduled-crons-wiring.spec.ts` holds BOTH runners against their source —
1308
+ * the workflow for the `github-actions` rows, the functions file for the
1309
+ * `cloud-scheduler` ones — in both directions. An inventory row for a job
1310
+ * nobody schedules and a scheduled job nobody watches are the same bug seen
1311
+ * from opposite ends, and both fail the build.
1312
+ *
1313
+ * `report-usage` appears TWICE and is two jobs, not one. The 02:00 run
1314
+ * rolls up the closed month and is the only run that ever reaches Stripe;
1315
+ * the 07:00 `?month=current` run writes the in-progress figure every usage
1316
+ * budget reads (AGL-2219). Either can stop without the other, and folding
1317
+ * them into one row would hide exactly that.
1318
+ */
1319
+ export declare const SCHEDULED_JOBS: readonly ScheduledJob[];
1320
+ /** One job's most recent mark, as read from `CRON_BEAT_COLLECTION`. */
1321
+ export interface CronBeat {
1322
+ jobId: string;
1323
+ /** Epoch ms of the invocation that left the mark. */
1324
+ atMs: number;
1325
+ }
1326
+ export interface CronJobCheck extends HealthCheck {
1327
+ /** The schedule this row was judged against, so the body is self-describing. */
1328
+ schedule: string;
1329
+ runner: CronRunner;
1330
+ /** Minutes since the job last reported. Null when it never has. */
1331
+ lastBeatAgeMinutes: number | null;
1332
+ /**
1333
+ * The most recent fire time the job should already have reported for, ISO.
1334
+ * Null when no such time has passed since we started watching — which is
1335
+ * the healthy reading for a job that is legitimately idle.
1336
+ */
1337
+ dueAt: string | null;
1338
+ graceMinutes: number;
1339
+ }
1340
+ /**
1341
+ * The latest time at or before `atMs` that `expression` fires, UTC.
1342
+ *
1343
+ * Null when the expression is unparsable, or when it does not fire inside
1344
+ * the lookback — 45 days, which comfortably clears the longest gap any
1345
+ * inventory entry has (`usage-email`'s twenty-nine idle days).
1346
+ *
1347
+ * Whole non-matching DAYS are skipped rather than walked minute by minute,
1348
+ * so the worst case is ~45 day checks plus 1,440 minute checks rather than
1349
+ * 64,800 of them.
1350
+ */
1351
+ export declare function previousCronFire(expression: string, atMs: number, lookbackDays?: number): number | null;
1352
+ /**
1353
+ * The scheduled jobs, reduced to one health check per job (AGL-1955).
1354
+ *
1355
+ * `beats` null means the marks could not be read at all — degraded for every
1356
+ * row, the same rule `signupsHealth`, `rateLimitsHealth` and `beaconHealth`
1357
+ * follow. An alarm that cannot see the thing it watches must say so rather
1358
+ * than report calm; here it is the literal condition the issue is about.
1359
+ *
1360
+ * `watchStartedAtMs` is when this deployment first read the marks. A job with
1361
+ * no mark is silent only once a fire time has passed SINCE then — otherwise
1362
+ * every row would be red on the day this deploys, and `usage-email` would
1363
+ * stay red until the 1st.
1364
+ *
1365
+ * Pure on purpose, like its siblings: the route reads, this decides, the
1366
+ * spec exercises every branch without a network.
1367
+ */
1368
+ export declare function cronJobsHealth(beats: readonly CronBeat[] | null, watchStartedAtMs: number, ms: number, now?: number, jobs?: readonly ScheduledJob[]): Record<string, CronJobCheck>;
1369
+ /**
1370
+ * The mark a run leaves — the only writes on the beat path.
1371
+ *
1372
+ * Structurally typed against firebase-admin's Firestore rather than importing
1373
+ * it: this module is pure and is imported by tenant Server Components, and a
1374
+ * health verdict library that drags in the admin SDK would be a new reason
1375
+ * for a page to fail. The console routes, the marketing plugin's scheduled
1376
+ * campaign processor and the tenant job runner all pass their own handle.
1377
+ *
1378
+ * Two writes, in order: the job's own document, which is the authority, then
1379
+ * its entry in {@link CRON_BEAT_SUMMARY_DOC}, which is what the reader reads
1380
+ * first. The summary merges one map key, so jobs beating at the same moment
1381
+ * do not overwrite each other's entries.
1382
+ *
1383
+ * NEVER THROWS. A beat that cannot be written must not take down the job it
1384
+ * is describing — the monitor becoming the outage is its own failure mode.
1385
+ * It returns false when the job's own mark could not be written, and a write
1386
+ * that keeps failing shows up where it should: as a silent job on the board.
1387
+ * A failed summary write still returns true, because the mark that decides
1388
+ * the verdict landed.
1389
+ */
1390
+ export interface CronBeatStore {
1391
+ collection(name: string): {
1392
+ doc(id: string): {
1393
+ set(data: Record<string, unknown>, options?: unknown): Promise<unknown>;
1394
+ };
1395
+ };
1396
+ }
1397
+ export declare function writeCronBeat(store: CronBeatStore, jobId: string, now?: number): Promise<boolean>;
1398
+ /**
1399
+ * The beats a summary document holds, ignoring anything malformed.
1400
+ *
1401
+ * `raw` is the document's `beats` field as Firestore returns it — a plain map,
1402
+ * or undefined when the document does not exist yet.
1403
+ */
1404
+ export declare function cronBeatsFromSummary(raw: unknown): CronBeat[];
1405
+ /**
1406
+ * DID A STRANGER ACTUALLY SIGN UP? (AGL-2715)
1407
+ *
1408
+ * Every other signup check on this platform is an inference. The auth doors
1409
+ * assert that Identity Platform is reachable and refuses an account that
1410
+ * cannot exist — configuration, not a signup. `probeCreate` reads that the
1411
+ * platform is unlocked and the probe's name is free — preconditions, not a
1412
+ * signup. `signupVolume`, `signupRefusals` and `signupDrought` count what
1413
+ * happened afterwards — a consequence, observed late.
1414
+ *
1415
+ * The strongest thing any of them could say, on the day AGL-2714 paged, was
1416
+ * "somebody got an account recently", and recently was 24 hours ago. AGL-2581
1417
+ * is what that costs: signup refused every visitor for three days while the
1418
+ * monitor named for signups stayed green.
1419
+ *
1420
+ * So something has to WALK it. A canary creates an account, verifies it,
1421
+ * mints a session, provisions an org, and deletes all of it — against
1422
+ * production, on a schedule — then stamps what happened into one marker. This
1423
+ * verdict reads that marker.
1424
+ *
1425
+ * ## Why the walk is not done here
1426
+ *
1427
+ * Health probes on this platform are read-only and cost-bounded by contract,
1428
+ * and this one is served from a PUBLIC unauthenticated endpoint. A probe that
1429
+ * created an account would hand anyone with `curl` an org factory. The write
1430
+ * lives in a scheduled job; the door only reports. Same split as the beacon
1431
+ * heartbeat (AGL-2713), for the same reason.
1432
+ *
1433
+ * ## The four ways this reds, and why residue is one of them
1434
+ *
1435
+ * A canary that walks perfectly and fails to clean up is not a success. It
1436
+ * leaves a real org, with a real slug reservation and a real host, on the
1437
+ * production estate — every hour, forever. `canary-left-residue` is red even
1438
+ * though the signup itself worked, because the alternative is a monitor that
1439
+ * quietly fills the database it is monitoring.
1440
+ */
1441
+ export interface SignupCanaryMarker {
1442
+ /** When the walk finished. The freshness clock. */
1443
+ walkedAtMs?: number;
1444
+ /** Whether every step of the walk succeeded. */
1445
+ ok?: boolean;
1446
+ /** Which step broke, for the body. Never an error message, never a uid. */
1447
+ failedStep?: string | null;
1448
+ /** Wall clock for the whole walk. */
1449
+ elapsedMs?: number;
1450
+ /** Whether the walk deleted everything it created. */
1451
+ reapedCleanly?: boolean;
1452
+ }
1453
+ export interface SignupCanaryCheck extends HealthCheck {
1454
+ /** Age of the last recorded walk, or null when there is no marker. */
1455
+ ageMs: number | null;
1456
+ /** Which step broke on that walk, when one did. */
1457
+ failedStep: string | null;
1458
+ /** How long the walk took, for the latency graph. */
1459
+ walkMs: number | null;
1460
+ /** Whether it cleaned up after itself. */
1461
+ reapedCleanly: boolean | null;
1462
+ /** The age past which a walk stops counting as evidence. */
1463
+ staleAfterMs: number;
1464
+ }
1465
+ /**
1466
+ * How old the last successful walk may be before this reds.
1467
+ *
1468
+ * Two hours against an hourly schedule — one missed run is tolerated, two are
1469
+ * not. A canary that runs hourly and reds at 61 minutes would page on every
1470
+ * GitHub Actions queue delay, and an alarm that cries wolf on infrastructure
1471
+ * latency is one nobody reads by the time signup actually breaks. Two misses
1472
+ * is a pattern rather than a hiccup.
1473
+ *
1474
+ * This is deliberately NOT generous enough to sleep through AGL-2581: three
1475
+ * days of refused signups would red this inside two hours.
1476
+ */
1477
+ /**
1478
+ * Workspace-slug prefix the signup canary owns, and the one piece of the
1479
+ * product that has to know the canary exists (AGL-2715).
1480
+ *
1481
+ * ## Why an exclusion is not optional
1482
+ *
1483
+ * The canary creates a real org and then deletes it. `signupDrought` compares
1484
+ * durable ATTEMPT markers against a live COUNT of orgs — and a deleted org
1485
+ * leaves the count while its attempt marker stays. So every canary walk adds
1486
+ * 1 to the denominator and 0 to the numerator, and after three walks the
1487
+ * platform reports `signup-drought` with nothing wrong.
1488
+ *
1489
+ * That is not theoretical. It fired on 2026-09-09 at six attempts against
1490
+ * zero creations — six walks that had each just proved, end to end, that a
1491
+ * stranger could sign up. A monitor that manufactures the outage it watches
1492
+ * for is worse than no monitor, and it is the same alarm fatigue AGL-2714
1493
+ * removed, arriving from inside the house.
1494
+ *
1495
+ * ## Why the slug, and what that costs
1496
+ *
1497
+ * `/api/orgs/create` receives the requested slug before it does anything, so
1498
+ * this needs no secret, no header and no second code path — the canary is
1499
+ * excluded by being what it says it is.
1500
+ *
1501
+ * The cost is that the prefix is caller-supplied: someone naming their
1502
+ * workspace `signup-canary-…` would not be counted in the drought's
1503
+ * denominator. That is bounded to one uncounted attempt per such workspace,
1504
+ * and it cannot hide an outage, because an outage is many attempts by many
1505
+ * people and only the oddly-named ones would go missing.
1506
+ *
1507
+ * The canary declares the same prefix in `tools/e2e/signup-canary.mjs`, which
1508
+ * cannot import this file — it runs outside the workspace. They are held
1509
+ * together by `apps/console/specs/signup-canary-marker-wiring.spec.ts`.
1510
+ */
1511
+ export declare const SIGNUP_CANARY_ORG_SLUG_PREFIX = "signup-canary-";
1512
+ /**
1513
+ * Is this org creation the canary's own?
1514
+ *
1515
+ * Exported as a function rather than leaving callers to compare strings, so
1516
+ * the one place that decides is the one place to read when asking why a
1517
+ * number looks wrong.
1518
+ */
1519
+ export declare function isSignupCanaryOrgSlug(slug: string | null | undefined): boolean;
1520
+ /**
1521
+ * How old the last walk may be before the check goes red.
1522
+ *
1523
+ * Six hours, far wider than the schedule that writes it, and deliberately so.
1524
+ * GitHub Actions serves `schedule` from a best-effort queue that drops most
1525
+ * requests under load: measured 2026-09-10, `uptime-probe.yml` asks for every
1526
+ * fifteen minutes and actually fired at gaps of 1h55m to 4h38m across the
1527
+ * preceding day and a half. A window sized to the cron expression rather than
1528
+ * to that behavior reds on ordinary queue depth.
1529
+ *
1530
+ * Widening it costs no detection speed, because staleness is not how a broken
1531
+ * signup surfaces. A walk that cannot sign up FAILS and still writes its
1532
+ * marker, which reads `signup-walk-failed` on the next poll. Staleness can
1533
+ * only mean the walker never reported — a CI condition, not a product one —
1534
+ * so this window's whole job is to notice a canary that has genuinely stopped,
1535
+ * and it must not fire before then: this check grades the monitor that must
1536
+ * never be muted.
1537
+ */
1538
+ export declare const SIGNUP_CANARY_STALE_AFTER_MS: number;
1539
+ /**
1540
+ * Grade the last recorded signup walk.
1541
+ *
1542
+ * Pure, like every sibling: the route reads the marker, this decides. Ordered
1543
+ * by which mistake costs most — a missing marker is treated as failure, never
1544
+ * as calm, because "no evidence" and "evidence of success" are the two
1545
+ * readings this whole issue exists to stop anyone from confusing.
1546
+ */
1547
+ export declare function signupCanaryHealth(marker: SignupCanaryMarker | null, ms: number, nowMs?: number, staleAfterMs?: number): SignupCanaryCheck;
1548
+ /**
1549
+ * IS ATTESTATION WORKING FOR REAL PEOPLE? (AGL-2715)
1550
+ *
1551
+ * The signup canary walks the real journey, but it attests with an App Check
1552
+ * DEBUG TOKEN — because this project's provider is reCAPTCHA Enterprise, which
1553
+ * is built to score headless automation as a bot and always will. Everything
1554
+ * else in that walk is real; the attestation step is not. So the canary is
1555
+ * structurally blind to the one failure it sits closest to: App Check refusing
1556
+ * the people it is supposed to admit.
1557
+ *
1558
+ * That blindness is not acceptable on its own, and it is not fixed by
1559
+ * argument. It is fixed by measuring the thing directly.
1560
+ *
1561
+ * ## What this reads, and why a token cannot fool it
1562
+ *
1563
+ * Firebase publishes `firebaseappcheck.googleapis.com/services/verification_count`
1564
+ * to Cloud Monitoring, labelled by `result` (ALLOW / DENY) and `security`
1565
+ * (VALID / INVALID / MISSING_UNKNOWN_ORIGIN), per service. Those counts are
1566
+ * every request from every visitor.
1567
+ *
1568
+ * The canary contributes at most one verification an hour against roughly a
1569
+ * thousand a day, and its debug-token attestation lands in the same ALLOW
1570
+ * bucket as everyone else's. So it cannot hold this green: if attestation
1571
+ * collapses for real people the rate collapses with it, one canary request
1572
+ * notwithstanding.
1573
+ *
1574
+ * ## Why only Identity Platform is graded
1575
+ *
1576
+ * `identitytoolkit.googleapis.com` is the service signup depends on, and it
1577
+ * runs clean — 939 ALLOW against 3 DENY over the 24 hours to 2026-09-09.
1578
+ * `firestore.googleapis.com` in the same window was 5493 ALLOW against 1046
1579
+ * DENY, because client Firestore reads are reached by crawlers and stale tabs
1580
+ * that legitimately fail attestation. Grading that number would either mute
1581
+ * this check with a floor low enough to admit the noise, or page on the noise.
1582
+ * The other services are reported for diagnosis and decide nothing.
1583
+ */
1584
+ export interface AppCheckVerificationSample {
1585
+ /** `ALLOW` or `DENY`. */
1586
+ result?: string;
1587
+ /** `VALID`, `INVALID`, `MISSING_UNKNOWN_ORIGIN`, … — for the body only. */
1588
+ security?: string;
1589
+ /** The service the verdict was rendered for. */
1590
+ service?: string;
1591
+ /** Requests in this bucket over the window. */
1592
+ count?: number;
1593
+ }
1594
+ /**
1595
+ * IS THE EDGE STILL LETTING REAL VISITORS IN? (AGL-2720)
1596
+ *
1597
+ * Every synthetic on this platform carries the `x-aglyn-probe` firewall
1598
+ * bypass, because bot protection refuses a datacenter IP outright. So if the
1599
+ * edge started challenging real people, every check would ride past the thing
1600
+ * that was broken and stay green.
1601
+ *
1602
+ * Measured 2026-09-10 while looking for something to close that: Vercel
1603
+ * publishes no challenged-versus-allowed metric — seven endpoints probed, the
1604
+ * only one that answers returns rule actions rather than traffic. And a probe
1605
+ * cannot substitute, because the discriminator is not "was this request
1606
+ * challenged" but "can a REAL BROWSER get in": `curl` from a residential
1607
+ * address is challenged too, and that is the healthy state, since the
1608
+ * challenge is answerable and a non-JS client cannot answer it.
1609
+ *
1610
+ * What is left is the outcome, and it was already being counted for money.
1611
+ * Metered page views are written by real browsers on real customer sites
1612
+ * after the edge admitted them — 57 to 563 a day across hosts over the
1613
+ * preceding week. Nothing synthetic touches that number: the probes ride the
1614
+ * bypass and the signup canary walks the console, neither of which is a
1615
+ * metered tenant page view.
1616
+ *
1617
+ * So the question this asks is simply whether that number is still moving. A
1618
+ * platform serving tens of views an hour that serves none for hours has
1619
+ * either lost its edge or lost every customer site, and both are worth waking
1620
+ * somebody for.
1621
+ *
1622
+ * ⛔ What it is NOT. It watches the TENANT edge, because that is where the
1623
+ * volume is. The console's own front door serves a handful of signup views a
1624
+ * day — too few to floor, and now partly synthetic — so a firewall change
1625
+ * scoped only to `aglyn-console` would not show up here. It is also not a
1626
+ * latency or correctness check: it says traffic arrives, nothing more.
1627
+ *
1628
+ * ⚠️ And the volume is CONCENTRATED. On the day this was built, one host of
1629
+ * thirteen produced every view. So this reds if that one site goes quiet for
1630
+ * half a day, which is why the window is what it is — see
1631
+ * {@link EDGE_ADMISSION_QUIET_AFTER_MS}.
1632
+ */
1633
+ /**
1634
+ * What the metered-traffic sampler leaves behind.
1635
+ *
1636
+ * `advancedAtMs` is the whole point and it is the WRITER's judgement, not the
1637
+ * reader's: the sampler compares this reading against the last one and stamps
1638
+ * the moment the total actually grew. A day rollover sets the counter back to
1639
+ * zero, so a grader handed a single sample could not tell midnight from an
1640
+ * outage.
1641
+ */
1642
+ export interface EdgeAdmissionMarker {
1643
+ /** When the sampler last ran. Context; the verdict does not use it. */
1644
+ sampledAtMs?: number;
1645
+ /** The last moment the metered total was seen to GROW. The clock. */
1646
+ advancedAtMs?: number;
1647
+ /** Which UTC day the total belongs to. */
1648
+ day?: string;
1649
+ /** The running total for that day at the last sample. */
1650
+ total?: number;
1651
+ }
1652
+ export interface EdgeAdmissionCheck extends HealthCheck {
1653
+ /** How long since the metered total last moved, or null with no marker. */
1654
+ quietMs: number | null;
1655
+ /** The day the sampled total belongs to, so a rollover is readable. */
1656
+ day: string | null;
1657
+ /** The running total for that day at the last sample. */
1658
+ total: number | null;
1659
+ /** How long the total may sit still before this reds. */
1660
+ quietAfterMs: number;
1661
+ /** How long since the sampler last reported, or null with no marker. */
1662
+ sampleAgeMs: number | null;
1663
+ }
1664
+ /**
1665
+ * How long metered page views may sit still before the edge is presumed shut.
1666
+ *
1667
+ * Twelve hours, and the width is deliberate rather than lazy.
1668
+ *
1669
+ * The quietest full day in the sampled week carried 57 views — about 2.4 an
1670
+ * hour on average, which would make six hours of zero look damning. But the
1671
+ * average is the wrong statistic here: measured 2026-09-10, the day's 62 views
1672
+ * came from ONE host of thirteen. Traffic that concentrated arrives in bursts,
1673
+ * and a burst distribution produces long empty stretches with nothing wrong.
1674
+ * A window sized to the average would page on one of them, which is how the
1675
+ * monitor that must never be ignored gets ignored.
1676
+ *
1677
+ * Twelve hours of exactly zero, on a platform serving 57 to 563 views a day,
1678
+ * is not a quiet stretch. It is slower to fire than anyone would like, and it
1679
+ * is the only thing that catches a fully blocked edge at all — nothing else
1680
+ * would ever fire, because every other check rides the bypass.
1681
+ *
1682
+ * ⚑ Tighten it once the real quiet-period distribution is known: the sampler
1683
+ * stamps `advancedAtMs` on every run, so a week of markers says what the true
1684
+ * maximum gap is. Do not tighten it from the daily average.
1685
+ */
1686
+ export declare const EDGE_ADMISSION_QUIET_AFTER_MS: number;
1687
+ /**
1688
+ * How old the sampler's own reading may be before it stops being evidence.
1689
+ *
1690
+ * Six hours, sized like `SIGNUP_CANARY_STALE_AFTER_MS` to a scheduler that
1691
+ * drops most of what it is asked for (AGL-2723) rather than to the cron
1692
+ * expression. Shorter than the quiet window on purpose: a stalled sampler
1693
+ * should be named as one BEFORE its frozen reading has had time to look like
1694
+ * an edge outage.
1695
+ */
1696
+ export declare const EDGE_ADMISSION_SAMPLE_STALE_AFTER_MS: number;
1697
+ /**
1698
+ * Grade the last recorded metered-traffic sample.
1699
+ *
1700
+ * Pure, like every sibling. The sampler decides when the total last MOVED and
1701
+ * stamps it; this only asks how long ago that was. Keeping the movement
1702
+ * detection in the writer is what lets the door stay a read: a day rollover
1703
+ * resets the counter to zero, and a grader looking at one sample could not
1704
+ * tell that from traffic stopping.
1705
+ */
1706
+ export declare function edgeAdmissionHealth(marker: EdgeAdmissionMarker | null, ms: number, nowMs?: number, quietAfterMs?: number, sampleStaleAfterMs?: number): EdgeAdmissionCheck;
1707
+ export interface AppCheckAttestationCheck extends HealthCheck {
1708
+ /** Allowed over total for the graded service, or null with no traffic. */
1709
+ allowRate: number | null;
1710
+ /** Requests the rate is taken over. */
1711
+ allowed: number;
1712
+ denied: number;
1713
+ /** Below this many requests the rate says nothing and is not graded. */
1714
+ minimumRequests: number;
1715
+ /** The floor the rate must clear. */
1716
+ minimumAllowRate: number;
1717
+ /** The service graded. Everything else is context. */
1718
+ service: string;
1719
+ /** Denials by `security`, so a red says which way it broke. */
1720
+ deniedBy: Record<string, number>;
1721
+ /** The window the counts cover. */
1722
+ windowMinutes: number;
1723
+ }
1724
+ /** The service signup depends on. See the docblock for why it is the only one. */
1725
+ export declare const APP_CHECK_GRADED_SERVICE = "identitytoolkit.googleapis.com";
1726
+ /**
1727
+ * Window the attestation rate is taken over.
1728
+ *
1729
+ * Six hours, not one. This metric is aggregated by Google on its own schedule
1730
+ * and arrives late, so a one-hour window reads empty for reasons that have
1731
+ * nothing to do with attestation. Six hours is long enough to always carry
1732
+ * traffic on this platform and short enough that a real collapse is caught the
1733
+ * same working day.
1734
+ */
1735
+ export declare const APP_CHECK_WINDOW_MINUTES: number;
1736
+ /**
1737
+ * Requests below which the rate is not graded.
1738
+ *
1739
+ * A ratio over three requests is noise wearing a percentage. Twenty is a
1740
+ * fraction of the ~940 a day Identity Platform sees, so a healthy platform
1741
+ * always clears it, and a platform quiet enough not to is a platform where
1742
+ * this check has nothing to say.
1743
+ */
1744
+ export declare const APP_CHECK_MIN_REQUESTS = 20;
1745
+ /**
1746
+ * The floor the allow rate must clear.
1747
+ *
1748
+ * 0.90, against a measured 0.997. The gap is deliberate: a handful of genuine
1749
+ * denials is ordinary — a stale tab, a bot, a browser that failed its
1750
+ * reCAPTCHA — and a floor set near the observed rate would page on those.
1751
+ *
1752
+ * What this is built to catch is not a drift of a few percent; it is the
1753
+ * documented failure mode of `recaptcha-allowlist.ts`, where an origin that is
1754
+ * attached and routed but not allowlisted renders a console that can never
1755
+ * sign anyone in. That reads as ~0%, not 85%.
1756
+ */
1757
+ export declare const APP_CHECK_MIN_ALLOW_RATE = 0.9;
1758
+ /**
1759
+ * Grade attestation for real visitors.
1760
+ *
1761
+ * Pure, like every sibling: something else reads Cloud Monitoring, this
1762
+ * decides. Null samples are degraded rather than calm — an unreadable metric
1763
+ * is not evidence that attestation works, and this check exists precisely
1764
+ * because "we did not look" was being reported as "it is fine".
1765
+ */
1766
+ export declare function appCheckAttestationHealth(samples: AppCheckVerificationSample[] | null, ms: number, service?: string, minimumRequests?: number, minimumAllowRate?: number, windowMinutes?: number): AppCheckAttestationCheck;