@greatwait/contracts 0.1.0-alpha.3 → 0.1.0-alpha.4

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 (299) hide show
  1. package/README.md +11 -9
  2. package/dist/authority.d.ts +33 -27
  3. package/dist/authority.js +12 -2
  4. package/dist/billing.d.ts +1001 -0
  5. package/dist/billing.js +684 -0
  6. package/dist/callback-safety.d.ts +2 -2
  7. package/dist/callback-safety.js +2 -2
  8. package/dist/compatibility.d.ts +3 -3
  9. package/dist/compatibility.js +1 -1
  10. package/dist/data-export.d.ts +67 -0
  11. package/dist/data-export.js +182 -0
  12. package/dist/endpoints.d.ts +181 -240
  13. package/dist/endpoints.js +77 -81
  14. package/dist/events.d.ts +17 -17
  15. package/dist/events.js +1 -1
  16. package/dist/first-value-journey.d.ts +49 -55
  17. package/dist/first-value-journey.js +6 -13
  18. package/dist/forecast.d.ts +71 -71
  19. package/dist/forecast.js +1 -1
  20. package/dist/identifiers.d.ts +20 -20
  21. package/dist/identifiers.js +1 -1
  22. package/dist/identity.d.ts +41 -37
  23. package/dist/identity.js +5 -4
  24. package/dist/index.d.ts +10 -5
  25. package/dist/index.js +10 -5
  26. package/dist/mcp.d.ts +21 -19
  27. package/dist/mcp.js +1 -1
  28. package/dist/naming.d.ts +45 -0
  29. package/dist/naming.js +159 -0
  30. package/dist/oauth.d.ts +186 -172
  31. package/dist/oauth.js +1 -1
  32. package/dist/operation-definitions.d.ts +9 -0
  33. package/dist/operation-definitions.js +7 -0
  34. package/dist/operations.d.ts +4162 -2171
  35. package/dist/operations.js +2679 -908
  36. package/dist/organization-lifecycle.d.ts +34 -0
  37. package/dist/organization-lifecycle.js +122 -0
  38. package/dist/partition.d.ts +26 -0
  39. package/dist/policy.d.ts +4 -4
  40. package/dist/policy.js +9 -5
  41. package/dist/problems.d.ts +32 -26
  42. package/dist/problems.js +6 -2
  43. package/dist/protocol.d.ts +204 -75
  44. package/dist/protocol.js +108 -36
  45. package/dist/scheduling-records.d.ts +343 -285
  46. package/dist/scheduling-records.js +1 -1
  47. package/dist/scheduling.d.ts +670 -360
  48. package/dist/scheduling.js +382 -56
  49. package/dist/secrets.d.ts +119 -105
  50. package/dist/secrets.js +1 -1
  51. package/dist/signatures.d.ts +74 -74
  52. package/dist/signatures.js +1 -1
  53. package/dist/tenancy.d.ts +142 -68
  54. package/dist/tenancy.js +70 -17
  55. package/dist/test-sink.d.ts +127 -127
  56. package/dist/test-sink.js +1 -1
  57. package/dist/time.d.ts +4 -4
  58. package/dist/time.js +1 -1
  59. package/dist/timing.d.ts +65 -0
  60. package/dist/timing.js +82 -0
  61. package/dist/usage.d.ts +103 -47
  62. package/dist/usage.js +197 -31
  63. package/dist/workspace.d.ts +34 -34
  64. package/dist/workspace.js +1 -1
  65. package/dist/zod-values.d.ts +3 -0
  66. package/dist/zod-values.js +2 -0
  67. package/dist/zod.d.ts +2 -0
  68. package/dist/zod.js +2 -0
  69. package/generated/v1/examples/attempts.list.response.json +4 -0
  70. package/generated/v1/examples/attempts.read.response.json +4 -0
  71. package/generated/v1/examples/billing.autotopup.request.json +5 -0
  72. package/generated/v1/examples/billing.autotopup.response.json +120 -0
  73. package/generated/v1/examples/billing.autotopuppreview.request.json +19 -0
  74. package/generated/v1/examples/billing.autotopuppreview.response.json +45 -0
  75. package/generated/v1/examples/billing.budgets.request.json +13 -0
  76. package/generated/v1/examples/billing.budgets.response.json +22 -0
  77. package/generated/v1/examples/billing.ceiling.request.json +8 -0
  78. package/generated/v1/examples/billing.ceiling.response.json +120 -0
  79. package/generated/v1/examples/billing.change.request.json +5 -0
  80. package/generated/v1/examples/billing.change.response.json +12 -0
  81. package/generated/v1/examples/billing.funding.response.json +120 -0
  82. package/generated/v1/examples/billing.fundingquote.request.json +7 -0
  83. package/generated/v1/examples/billing.fundingquote.response.json +13 -0
  84. package/generated/v1/examples/billing.ledger.response.json +23 -0
  85. package/generated/v1/examples/billing.notices.response.json +41 -0
  86. package/generated/v1/examples/billing.notificationsettings.response.json +17 -0
  87. package/generated/v1/examples/billing.notificationsettingsupdate.request.json +9 -0
  88. package/generated/v1/examples/billing.notificationsettingsupdate.response.json +17 -0
  89. package/generated/v1/examples/billing.portal.response.json +3 -0
  90. package/generated/v1/examples/billing.projects.response.json +12 -0
  91. package/generated/v1/examples/billing.purchase.request.json +5 -0
  92. package/generated/v1/examples/billing.purchase.response.json +120 -0
  93. package/generated/v1/examples/billing.quote.request.json +4 -0
  94. package/generated/v1/examples/billing.quote.response.json +19 -0
  95. package/generated/v1/examples/billing.reconcile.response.json +73 -0
  96. package/generated/v1/examples/billing.refundrequest.request.json +10 -0
  97. package/generated/v1/examples/billing.refundrequest.response.json +11 -0
  98. package/generated/v1/examples/billing.refundresolution.request.json +4 -0
  99. package/generated/v1/examples/billing.refundresolution.response.json +120 -0
  100. package/generated/v1/examples/billing.summary.response.json +73 -0
  101. package/generated/v1/examples/endpoints.acknowledgeSigningKeyRotation.response.json +18 -0
  102. package/generated/v1/examples/endpoints.create.response.json +1 -1
  103. package/generated/v1/examples/endpoints.disable.response.json +0 -1
  104. package/generated/v1/examples/{endpoints.verify.response.json → endpoints.enable.response.json} +4 -5
  105. package/generated/v1/examples/endpoints.list.response.json +1 -2
  106. package/generated/v1/examples/endpoints.read.response.json +2 -2
  107. package/generated/v1/examples/endpoints.revealSigningSecret.response.json +7 -0
  108. package/generated/v1/examples/endpoints.rotateSigningKey.response.json +1 -2
  109. package/generated/v1/examples/endpoints.update.response.json +1 -1
  110. package/generated/v1/examples/executions.list.response.json +20 -0
  111. package/generated/v1/examples/exports.cancel.response.json +11 -0
  112. package/generated/v1/examples/exports.create.request.json +1 -0
  113. package/generated/v1/examples/exports.create.response.json +8 -0
  114. package/generated/v1/examples/exports.part.response.json +5 -0
  115. package/generated/v1/examples/exports.read.response.json +8 -0
  116. package/generated/v1/examples/occurrences.read.response.json +4 -0
  117. package/generated/v1/examples/organizations.close.request.json +5 -0
  118. package/generated/v1/examples/organizations.close.response.json +10 -0
  119. package/generated/v1/examples/organizations.lifecycle.response.json +10 -0
  120. package/generated/v1/examples/organizations.restore.request.json +3 -0
  121. package/generated/v1/examples/organizations.restore.response.json +10 -0
  122. package/generated/v1/examples/projects.archive.request.json +3 -0
  123. package/generated/v1/examples/projects.archive.response.json +14 -0
  124. package/generated/v1/examples/projects.create.response.json +10 -1
  125. package/generated/v1/examples/projects.delete.response.json +9 -0
  126. package/generated/v1/examples/projects.list.response.json +12 -2
  127. package/generated/v1/examples/projects.rename.request.json +3 -0
  128. package/generated/v1/examples/projects.rename.response.json +14 -0
  129. package/generated/v1/examples/schedules.archive.response.json +3 -0
  130. package/generated/v1/examples/schedules.cancel.response.json +3 -0
  131. package/generated/v1/examples/schedules.create.request.json +4 -0
  132. package/generated/v1/examples/schedules.create.response.json +3 -0
  133. package/generated/v1/examples/schedules.list.response.json +3 -0
  134. package/generated/v1/examples/schedules.pause.response.json +3 -0
  135. package/generated/v1/examples/schedules.read.response.json +6 -0
  136. package/generated/v1/examples/schedules.replace.request.json +4 -0
  137. package/generated/v1/examples/schedules.replace.response.json +3 -0
  138. package/generated/v1/examples/schedules.resume.response.json +3 -0
  139. package/generated/v1/examples/timing.summary.response.json +35 -0
  140. package/generated/v1/examples/usage.read.response.json +1 -0
  141. package/generated/v1/first-value-journey.json +19 -10
  142. package/generated/v1/manifest.json +936 -23
  143. package/generated/v1/openapi.json +29983 -5784
  144. package/generated/v1/policy-matrix.json +278 -47
  145. package/generated/v1/schemas/attempts.list.response.json +24 -1
  146. package/generated/v1/schemas/attempts.read.response.json +24 -1
  147. package/generated/v1/schemas/billing.autotopup.request-headers.json +13 -0
  148. package/generated/v1/schemas/billing.autotopup.request.json +22 -0
  149. package/generated/v1/schemas/billing.autotopup.response-headers.json +10 -0
  150. package/generated/v1/schemas/billing.autotopup.response.json +552 -0
  151. package/generated/v1/schemas/billing.autotopuppreview.request.json +77 -0
  152. package/generated/v1/schemas/billing.autotopuppreview.response.json +277 -0
  153. package/generated/v1/schemas/billing.budgets.request-headers.json +13 -0
  154. package/generated/v1/schemas/billing.budgets.request.json +66 -0
  155. package/generated/v1/schemas/billing.budgets.response-headers.json +10 -0
  156. package/generated/v1/schemas/billing.budgets.response.json +92 -0
  157. package/generated/v1/schemas/billing.ceiling.request-headers.json +13 -0
  158. package/generated/v1/schemas/billing.ceiling.request.json +40 -0
  159. package/generated/v1/schemas/billing.ceiling.response-headers.json +10 -0
  160. package/generated/v1/schemas/billing.ceiling.response.json +552 -0
  161. package/generated/v1/schemas/billing.change.request-headers.json +13 -0
  162. package/generated/v1/schemas/billing.change.request.json +22 -0
  163. package/generated/v1/schemas/billing.change.response.json +119 -0
  164. package/generated/v1/schemas/billing.funding.response.json +552 -0
  165. package/generated/v1/schemas/billing.fundingquote.request.json +28 -0
  166. package/generated/v1/schemas/billing.fundingquote.response.json +61 -0
  167. package/generated/v1/schemas/billing.ledger.query.json +16 -0
  168. package/generated/v1/schemas/billing.ledger.response.json +125 -0
  169. package/generated/v1/schemas/billing.notices.query.json +16 -0
  170. package/generated/v1/schemas/billing.notices.response.json +278 -0
  171. package/generated/v1/schemas/billing.notificationsettings.response.json +70 -0
  172. package/generated/v1/schemas/billing.notificationsettingsupdate.request-headers.json +13 -0
  173. package/generated/v1/schemas/billing.notificationsettingsupdate.request.json +36 -0
  174. package/generated/v1/schemas/billing.notificationsettingsupdate.response-headers.json +10 -0
  175. package/generated/v1/schemas/billing.notificationsettingsupdate.response.json +70 -0
  176. package/generated/v1/schemas/billing.portal.response.json +11 -0
  177. package/generated/v1/schemas/billing.projects.response.json +119 -0
  178. package/generated/v1/schemas/billing.purchase.request-headers.json +13 -0
  179. package/generated/v1/schemas/billing.purchase.request.json +22 -0
  180. package/generated/v1/schemas/billing.purchase.response-headers.json +10 -0
  181. package/generated/v1/schemas/billing.purchase.response.json +552 -0
  182. package/generated/v1/schemas/billing.quote.request.json +20 -0
  183. package/generated/v1/schemas/billing.quote.response.json +86 -0
  184. package/generated/v1/schemas/billing.reconcile.response.json +468 -0
  185. package/generated/v1/schemas/billing.refundrequest.request-headers.json +13 -0
  186. package/generated/v1/schemas/billing.refundrequest.request.json +42 -0
  187. package/generated/v1/schemas/billing.refundrequest.response-headers.json +10 -0
  188. package/generated/v1/schemas/billing.refundrequest.response.json +45 -0
  189. package/generated/v1/schemas/billing.refundresolution.request-headers.json +13 -0
  190. package/generated/v1/schemas/billing.refundresolution.request.json +61 -0
  191. package/generated/v1/schemas/billing.refundresolution.response-headers.json +10 -0
  192. package/generated/v1/schemas/billing.refundresolution.response.json +552 -0
  193. package/generated/v1/schemas/billing.summary.response.json +468 -0
  194. package/generated/v1/schemas/context.read.response.json +2 -0
  195. package/generated/v1/schemas/credentials.connection.response.json +2 -0
  196. package/generated/v1/schemas/credentials.create.request.json +2 -0
  197. package/generated/v1/schemas/credentials.create.response.json +2 -0
  198. package/generated/v1/schemas/credentials.list.response.json +2 -0
  199. package/generated/v1/schemas/credentials.revoke.response.json +2 -0
  200. package/generated/v1/schemas/credentials.rotate.response.json +4 -0
  201. package/generated/v1/schemas/{endpoints.verify.request-headers.json → endpoints.acknowledgeSigningKeyRotation.request-headers.json} +2 -1
  202. package/generated/v1/schemas/{endpoints.verify.response.json → endpoints.acknowledgeSigningKeyRotation.response.json} +8 -21
  203. package/generated/v1/schemas/endpoints.create.request.json +5 -0
  204. package/generated/v1/schemas/endpoints.create.response.json +8 -21
  205. package/generated/v1/schemas/endpoints.disable.response.json +8 -21
  206. package/generated/v1/schemas/endpoints.enable.response-headers.json +11 -0
  207. package/generated/v1/schemas/endpoints.enable.response.json +87 -0
  208. package/generated/v1/schemas/endpoints.list.response.json +8 -21
  209. package/generated/v1/schemas/endpoints.read.response.json +8 -21
  210. package/generated/v1/schemas/endpoints.revealSigningSecret.response.json +43 -0
  211. package/generated/v1/schemas/endpoints.rotateSigningKey.response.json +8 -21
  212. package/generated/v1/schemas/endpoints.update.request.json +5 -0
  213. package/generated/v1/schemas/endpoints.update.response.json +8 -21
  214. package/generated/v1/schemas/executions.list.query.json +46 -0
  215. package/generated/v1/schemas/executions.list.response.json +116 -0
  216. package/generated/v1/schemas/exports.cancel.response.json +48 -0
  217. package/generated/v1/schemas/exports.create.request.json +6 -0
  218. package/generated/v1/schemas/exports.create.response.json +38 -0
  219. package/generated/v1/schemas/exports.part.query.json +11 -0
  220. package/generated/v1/schemas/exports.part.response.json +22 -0
  221. package/generated/v1/schemas/exports.read.response.json +38 -0
  222. package/generated/v1/schemas/grants.list.response.json +2 -0
  223. package/generated/v1/schemas/grants.revoke.response.json +2 -0
  224. package/generated/v1/schemas/occurrences.list.query.json +5 -0
  225. package/generated/v1/schemas/occurrences.list.response.json +23 -0
  226. package/generated/v1/schemas/occurrences.read.response.json +23 -0
  227. package/generated/v1/schemas/occurrences.redeliver.response.json +24 -1
  228. package/generated/v1/schemas/organizations.close.request.json +20 -0
  229. package/generated/v1/schemas/organizations.close.response.json +68 -0
  230. package/generated/v1/schemas/organizations.lifecycle.response.json +68 -0
  231. package/generated/v1/schemas/organizations.restore.request.json +13 -0
  232. package/generated/v1/schemas/organizations.restore.response.json +68 -0
  233. package/generated/v1/schemas/projects.archive.request-headers.json +11 -0
  234. package/generated/v1/schemas/projects.archive.request.json +10 -0
  235. package/generated/v1/schemas/projects.archive.response-headers.json +11 -0
  236. package/generated/v1/schemas/projects.archive.response.json +79 -0
  237. package/generated/v1/schemas/projects.create.response.json +55 -1
  238. package/generated/v1/schemas/projects.delete.request-headers.json +11 -0
  239. package/generated/v1/schemas/projects.delete.response.json +37 -0
  240. package/generated/v1/schemas/projects.list.response.json +61 -2
  241. package/generated/v1/schemas/projects.rename.request-headers.json +11 -0
  242. package/generated/v1/schemas/projects.rename.request.json +12 -0
  243. package/generated/v1/schemas/projects.rename.response-headers.json +11 -0
  244. package/generated/v1/schemas/projects.rename.response.json +79 -0
  245. package/generated/v1/schemas/schedules.archive.response.json +90 -2
  246. package/generated/v1/schemas/schedules.cancel.response.json +90 -2
  247. package/generated/v1/schemas/schedules.create.request.json +24 -3
  248. package/generated/v1/schemas/schedules.create.response.json +90 -2
  249. package/generated/v1/schemas/schedules.list.query.json +13 -0
  250. package/generated/v1/schemas/schedules.list.response.json +67 -2
  251. package/generated/v1/schemas/schedules.pause.response.json +90 -2
  252. package/generated/v1/schemas/schedules.read.response.json +90 -2
  253. package/generated/v1/schemas/schedules.replace.request.json +24 -3
  254. package/generated/v1/schemas/schedules.replace.response.json +90 -2
  255. package/generated/v1/schemas/schedules.resume.response.json +90 -2
  256. package/generated/v1/schemas/timing.summary.response.json +191 -0
  257. package/generated/v1/schemas/usage.read.query.json +7 -0
  258. package/generated/v1/schemas/usage.read.response.json +36 -1
  259. package/generated/v1/snippets/billing.autotopup.json +6 -0
  260. package/generated/v1/snippets/billing.autotopuppreview.json +6 -0
  261. package/generated/v1/snippets/billing.budgets.json +6 -0
  262. package/generated/v1/snippets/billing.ceiling.json +6 -0
  263. package/generated/v1/snippets/billing.change.json +6 -0
  264. package/generated/v1/snippets/billing.funding.json +6 -0
  265. package/generated/v1/snippets/billing.fundingquote.json +6 -0
  266. package/generated/v1/snippets/billing.ledger.json +6 -0
  267. package/generated/v1/snippets/billing.notices.json +6 -0
  268. package/generated/v1/snippets/billing.notificationsettings.json +6 -0
  269. package/generated/v1/snippets/billing.notificationsettingsupdate.json +6 -0
  270. package/generated/v1/snippets/billing.portal.json +6 -0
  271. package/generated/v1/snippets/billing.projects.json +6 -0
  272. package/generated/v1/snippets/billing.purchase.json +6 -0
  273. package/generated/v1/snippets/billing.quote.json +6 -0
  274. package/generated/v1/snippets/billing.reconcile.json +6 -0
  275. package/generated/v1/snippets/billing.refundrequest.json +6 -0
  276. package/generated/v1/snippets/billing.refundresolution.json +6 -0
  277. package/generated/v1/snippets/billing.summary.json +6 -0
  278. package/generated/v1/snippets/endpoints.acknowledgeSigningKeyRotation.json +6 -0
  279. package/generated/v1/snippets/{endpoints.verify.json → endpoints.enable.json} +3 -3
  280. package/generated/v1/snippets/endpoints.revealSigningSecret.json +6 -0
  281. package/generated/v1/snippets/executions.list.json +6 -0
  282. package/generated/v1/snippets/exports.cancel.json +6 -0
  283. package/generated/v1/snippets/exports.create.json +6 -0
  284. package/generated/v1/snippets/exports.part.json +6 -0
  285. package/generated/v1/snippets/exports.read.json +6 -0
  286. package/generated/v1/snippets/organizations.close.json +6 -0
  287. package/generated/v1/snippets/organizations.lifecycle.json +6 -0
  288. package/generated/v1/snippets/organizations.restore.json +6 -0
  289. package/generated/v1/snippets/projects.archive.json +6 -0
  290. package/generated/v1/snippets/projects.delete.json +6 -0
  291. package/generated/v1/snippets/projects.rename.json +6 -0
  292. package/generated/v1/snippets/schedules.create.json +3 -3
  293. package/generated/v1/snippets/schedules.replace.json +3 -3
  294. package/generated/v1/snippets/timing.summary.json +6 -0
  295. package/package.json +1 -6
  296. package/dist/callback-ownership.d.ts +0 -58
  297. package/dist/callback-ownership.js +0 -71
  298. package/generated/v1/callback-endpoint-verification.json +0 -59
  299. /package/generated/v1/schemas/{endpoints.verify.response-headers.json → endpoints.acknowledgeSigningKeyRotation.response-headers.json} +0 -0
package/dist/endpoints.js CHANGED
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import { z } from "./zod.js";
2
2
  import { environmentKindSchema } from "./authority.js";
3
3
  import { evaluateCallbackUrl } from "./callback-safety.js";
4
4
  import { callbackSigningKeyIdSchema, endpointIdSchema, projectIdSchema, } from "./identifiers.js";
@@ -12,15 +12,22 @@ import { timestampSchema } from "./time.js";
12
12
  * a caller can use to widen that tuple: `project` and `environmentKind` are
13
13
  * display metadata, while every lookup is scoped by the verified principal.
14
14
  */
15
- export const CALLBACK_ENDPOINT_STATUSES = [
16
- "pending",
17
- "verified",
18
- "disabled",
19
- ];
15
+ /**
16
+ * An endpoint is usable the moment it exists (W4-12). `active` is every
17
+ * endpoint that is not disabled; `disabled` stops delivery until
18
+ * `endpoints.enable` turns it back on. There is no state in between and
19
+ * nothing to prove.
20
+ */
21
+ export const CALLBACK_ENDPOINT_STATUSES = ["active", "disabled"];
20
22
  export const callbackEndpointStatusSchema = z.enum(CALLBACK_ENDPOINT_STATUSES);
21
- export const CALLBACK_VERIFICATION_FAILURES = [
23
+ /**
24
+ * Why an address could not be resolved or reached: the classification the
25
+ * DNS inspection at create and update, and the delivery egress, share. It
26
+ * was the verification-failure vocabulary until W4-12 removed verification;
27
+ * what remains is what those two paths can still observe.
28
+ */
29
+ export const CALLBACK_EGRESS_FAILURES = [
22
30
  "address_forbidden",
23
- "challenge_failed",
24
31
  "connection_failed",
25
32
  "dns_unresolved",
26
33
  "rate_limited",
@@ -29,51 +36,74 @@ export const CALLBACK_VERIFICATION_FAILURES = [
29
36
  "timed_out",
30
37
  "unexpected_status",
31
38
  ];
32
- export const callbackVerificationFailureSchema = z.enum(CALLBACK_VERIFICATION_FAILURES);
39
+ export const callbackEgressFailureSchema = z.enum(CALLBACK_EGRESS_FAILURES);
33
40
  /**
34
41
  * A safety ceiling on retained endpoint records, independent of later
35
42
  * commercial plan limits. Disabled records remain readable for audit and count
36
43
  * toward it; changing that lifetime semantic needs a product decision.
37
44
  */
38
45
  export const CALLBACK_ENDPOINT_LIMIT_PER_ENVIRONMENT = 50;
39
- /** Verification egress is admitted through both buckets before DNS or fetch. */
40
- export const CALLBACK_VERIFICATION_RATE_LIMITS = {
46
+ /**
47
+ * DNS inspection at create and update is admitted through both buckets
48
+ * before the first lookup, so an address a caller retypes cannot make this
49
+ * service resolve names without bound.
50
+ */
51
+ export const CALLBACK_ADMISSION_RATE_LIMITS = {
41
52
  destinationPerMinute: 5,
42
53
  projectPerMinute: 20,
43
54
  windowSeconds: 60,
44
55
  };
45
- /** Total bytes a verification response may return before it is refused. */
46
- export const CALLBACK_VERIFICATION_RESPONSE_BYTES = 1_024;
47
- /** Total DNS + connect + response bound for one verification attempt. */
48
- export const CALLBACK_VERIFICATION_TIMEOUT_MILLISECONDS = 5_000;
49
56
  /** Longest period during which a receiver may accept current and next keys. */
50
57
  export const CALLBACK_SIGNING_KEY_ROTATION_OVERLAP_SECONDS = 86_400;
51
58
  export const callbackSigningKeysSchema = z.object({
52
59
  current: callbackSigningKeyIdSchema,
53
60
  next: z
54
61
  .object({
62
+ /** When a person confirmed their server accepts this next key. */
63
+ acknowledgedAt: timestampSchema.optional(),
55
64
  id: callbackSigningKeyIdSchema,
56
65
  overlapEndsAt: timestampSchema,
57
66
  })
58
67
  .optional(),
59
68
  });
69
+ /**
70
+ * An endpoint's name: unique within its project and environment, compared
71
+ * exactly (W4-14, FXO-2255).
72
+ *
73
+ * Generated on save when nobody types one — the whole URL — because an
74
+ * endpoint appears in a dropdown, and two identical rows in a dropdown are
75
+ * two rows nobody can choose between. So a second endpoint at an address one
76
+ * already has is refused unless it is given a name of its own. **Case
77
+ * matters**: two webhook URLs differing only in the case of a token are two
78
+ * endpoints and both save unnamed; the cost, accepted knowingly, is that
79
+ * "Prod receiver" and "prod receiver" are both allowed. Deliberately unlike a
80
+ * project's name, which ignores case and spacing.
81
+ */
82
+ export const callbackEndpointNameSchema = z
83
+ .string()
84
+ .trim()
85
+ .min(1, "must not be blank")
86
+ .max(2_048, "must be at most 2048 characters");
60
87
  /**
61
88
  * A metadata-only endpoint shape. The sealed signing secret has no public
62
- * field, so list/get/update/verify/disable cannot accidentally recover it.
89
+ * field, so list/get/update/disable/enable cannot accidentally recover it.
63
90
  */
64
91
  export const callbackEndpointSchema = z.object({
65
92
  createdAt: timestampSchema,
66
93
  disabledAt: timestampSchema.optional(),
67
94
  environmentKind: environmentKindSchema,
68
95
  id: endpointIdSchema,
69
- lastVerificationAttemptAt: timestampSchema.optional(),
70
- lastVerificationFailure: callbackVerificationFailureSchema.optional(),
96
+ /**
97
+ * The endpoint's name. Every endpoint written since W4-14 has one — its
98
+ * URL when none was given — and it is optional on the wire only so a row
99
+ * from before the column parses rather than fails.
100
+ */
101
+ name: callbackEndpointNameSchema.optional(),
71
102
  project: projectIdSchema,
72
103
  signingKeys: callbackSigningKeysSchema,
73
104
  status: callbackEndpointStatusSchema,
74
105
  updatedAt: timestampSchema,
75
106
  url: z.string().url(),
76
- verifiedAt: timestampSchema.optional(),
77
107
  version: z.number().int().positive(),
78
108
  });
79
109
  export const callbackEndpointPageSchema = pageSchema(callbackEndpointSchema);
@@ -97,6 +127,27 @@ export const callbackEndpointRotatedSchema = z.object({
97
127
  secret: z.string().min(1),
98
128
  shownOnce: z.literal(true),
99
129
  });
130
+ /** One signing key and the secret behind it, as a signed-in person may see it. */
131
+ export const callbackEndpointSigningSecretSchema = z.object({
132
+ keyId: callbackSigningKeyIdSchema,
133
+ secret: z.string().min(1),
134
+ });
135
+ /**
136
+ * What `endpoints.revealSigningSecret` answers (FXO-2244).
137
+ *
138
+ * The same value `endpoints.create` and `endpoints.rotateSigningKey` hand out
139
+ * once, readable again by a signed-in member. Mirrors `signingKeys`: during a
140
+ * rotation both keys are here, with the instant the overlap ends, because a
141
+ * receiver being moved to the new key needs both until then.
142
+ */
143
+ export const callbackEndpointSigningSecretsSchema = z.object({
144
+ current: callbackEndpointSigningSecretSchema,
145
+ /** The endpoint these belong to, so an answer names what it is about. */
146
+ id: endpointIdSchema,
147
+ next: callbackEndpointSigningSecretSchema
148
+ .extend({ overlapEndsAt: timestampSchema })
149
+ .optional(),
150
+ });
100
151
  function callbackUrlSchema() {
101
152
  return z
102
153
  .string()
@@ -113,67 +164,12 @@ function callbackUrlSchema() {
113
164
  });
114
165
  }
115
166
  export const callbackEndpointRequestSchema = z.object({
167
+ /**
168
+ * A name for people (W4-14, FXO-2255). Omitted on a create, the endpoint
169
+ * takes its whole URL as its name; omitted on an update, the stored name
170
+ * stays. Unique within the project and environment, compared exactly: a
171
+ * name another endpoint holds is refused as `state_conflict`.
172
+ */
173
+ name: callbackEndpointNameSchema.optional(),
116
174
  url: callbackUrlSchema(),
117
175
  });
118
- export const CALLBACK_VERIFICATION_PROTOCOL_VERSION = "2026-08-05";
119
- export const CALLBACK_VERIFICATION_TYPE = "callback.endpoint.verification";
120
- /**
121
- * Exact verification bytes sent to the receiver. The receiver validates the
122
- * request signature and proves possession of the one-time secret by returning
123
- * an HMAC of `challenge` in `Callback-Verification-Response`.
124
- */
125
- export const callbackVerificationChallengeSchema = z.object({
126
- challenge: z.string().regex(/^cvc_[A-Za-z0-9_-]{43}$/u),
127
- endpointId: endpointIdSchema,
128
- type: z.literal(CALLBACK_VERIFICATION_TYPE),
129
- version: z.literal(CALLBACK_VERIFICATION_PROTOCOL_VERSION),
130
- });
131
- export const CALLBACK_VERIFICATION_HEADERS = {
132
- challenge: "Callback-Verification-Challenge",
133
- requestSignature: "Callback-Verification-Signature",
134
- responseSignature: "Callback-Verification-Response",
135
- };
136
- /**
137
- * Machine-readable receiver contract for endpoint ownership verification.
138
- *
139
- * This is deliberately separate from W3-02's occurrence-delivery signature:
140
- * the request proves control of a receiver before the endpoint may be used,
141
- * while a delivery signature authenticates an occurrence body later. The
142
- * generator publishes this object beside OpenAPI and the JSON Schema.
143
- */
144
- export const CALLBACK_VERIFICATION_PROTOCOL = {
145
- purpose: "Prove that the receiver possesses the one-time endpoint secret before Greatwait marks the endpoint verified.",
146
- request: {
147
- bodyEncoding: "UTF-8 bytes of the compact JSON object in schema property order: challenge, endpointId, type, version.",
148
- contentType: "application/json",
149
- method: "POST",
150
- redirectPolicy: "manual; every 3xx response is refused",
151
- signature: {
152
- algorithm: "HMAC-SHA-256",
153
- format: "v1=<64 lowercase hexadecimal characters>",
154
- header: CALLBACK_VERIFICATION_HEADERS.requestSignature,
155
- input: "the exact request body bytes",
156
- key: "the one-time endpoint secret returned by REST endpoint creation",
157
- },
158
- },
159
- response: {
160
- body: "ignored after enforcing the 1024-byte response limit; return an empty body",
161
- proof: {
162
- algorithm: "HMAC-SHA-256",
163
- format: "v1=<64 lowercase hexadecimal characters>",
164
- header: CALLBACK_VERIFICATION_HEADERS.responseSignature,
165
- input: "the UTF-8 bytes of the challenge string",
166
- key: "the same endpoint secret",
167
- },
168
- status: "any 2xx status",
169
- },
170
- testVector: {
171
- challenge: "cvc_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
172
- endpointId: "ep_00000000000000000000000000",
173
- exactBodyBase64: "eyJjaGFsbGVuZ2UiOiJjdmNfQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQSIsImVuZHBvaW50SWQiOiJlcF8wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCIsInR5cGUiOiJjYWxsYmFjay5lbmRwb2ludC52ZXJpZmljYXRpb24iLCJ2ZXJzaW9uIjoiMjAyNi0wOC0wNSJ9",
174
- requestSignature: "v1=0d24c7fed4d752411b88025a9923627b329e0eb9d53978a6ebcf92c0678c731e",
175
- responseSignature: "v1=efc690a23f1870930ff3388313162c0e06406902a7a4d3f9273ffe0abcef86bd",
176
- secret: "verification-vector-secret",
177
- },
178
- version: CALLBACK_VERIFICATION_PROTOCOL_VERSION,
179
- };
package/dist/events.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import { z } from "./zod.js";
2
2
  /**
3
3
  * Product events.
4
4
  *
@@ -11,7 +11,7 @@ import { z } from "zod";
11
11
  * collapsing them is how "why is this event from the future" bugs start.
12
12
  */
13
13
  export declare const EVENT_TYPES: readonly ["endpoint.verified", "occurrence.attempt.recorded", "occurrence.due", "occurrence.succeeded", "occurrence.terminal_failed", "schedule.cancelled", "schedule.completed", "schedule.created", "schedule.replaced"];
14
- export declare const eventTypeSchema: z.ZodEnum<{
14
+ export declare const eventTypeSchema: import("zod").ZodEnum<{
15
15
  "endpoint.verified": "endpoint.verified";
16
16
  "occurrence.attempt.recorded": "occurrence.attempt.recorded";
17
17
  "occurrence.due": "occurrence.due";
@@ -23,13 +23,13 @@ export declare const eventTypeSchema: z.ZodEnum<{
23
23
  "schedule.replaced": "schedule.replaced";
24
24
  }>;
25
25
  export type EventType = z.infer<typeof eventTypeSchema>;
26
- export declare function eventEnvelopeSchema<TData extends z.ZodTypeAny>(data: TData): z.ZodObject<{
26
+ export declare function eventEnvelopeSchema<TData extends z.ZodTypeAny>(data: TData): import("zod").ZodObject<{
27
27
  data: TData;
28
- id: z.ZodString;
29
- occurredAt: z.ZodString;
30
- recordedAt: z.ZodString;
31
- schemaVersion: z.ZodNumber;
32
- type: z.ZodEnum<{
28
+ id: import("zod").ZodString;
29
+ occurredAt: import("zod").ZodString;
30
+ recordedAt: import("zod").ZodString;
31
+ schemaVersion: import("zod").ZodNumber;
32
+ type: import("zod").ZodEnum<{
33
33
  "endpoint.verified": "endpoint.verified";
34
34
  "occurrence.attempt.recorded": "occurrence.attempt.recorded";
35
35
  "occurrence.due": "occurrence.due";
@@ -40,14 +40,14 @@ export declare function eventEnvelopeSchema<TData extends z.ZodTypeAny>(data: TD
40
40
  "schedule.created": "schedule.created";
41
41
  "schedule.replaced": "schedule.replaced";
42
42
  }>;
43
- }, z.core.$strip>;
44
- export declare const genericEventSchema: z.ZodObject<{
45
- data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
46
- id: z.ZodString;
47
- occurredAt: z.ZodString;
48
- recordedAt: z.ZodString;
49
- schemaVersion: z.ZodNumber;
50
- type: z.ZodEnum<{
43
+ }, import("zod/v4/core").$strip>;
44
+ export declare const genericEventSchema: import("zod").ZodObject<{
45
+ data: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
46
+ id: import("zod").ZodString;
47
+ occurredAt: import("zod").ZodString;
48
+ recordedAt: import("zod").ZodString;
49
+ schemaVersion: import("zod").ZodNumber;
50
+ type: import("zod").ZodEnum<{
51
51
  "endpoint.verified": "endpoint.verified";
52
52
  "occurrence.attempt.recorded": "occurrence.attempt.recorded";
53
53
  "occurrence.due": "occurrence.due";
@@ -58,5 +58,5 @@ export declare const genericEventSchema: z.ZodObject<{
58
58
  "schedule.created": "schedule.created";
59
59
  "schedule.replaced": "schedule.replaced";
60
60
  }>;
61
- }, z.core.$strip>;
61
+ }, import("zod/v4/core").$strip>;
62
62
  export type GenericEvent = z.infer<typeof genericEventSchema>;
package/dist/events.js CHANGED
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import { z } from "./zod.js";
2
2
  import { eventIdSchema } from "./identifiers.js";
3
3
  import { timestampSchema } from "./time.js";
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import { z } from "./zod.js";
2
2
  import type { ProblemCode } from "./problems.js";
3
3
  /**
4
4
  * The one bounded sequence that takes a developer from a credential to an
@@ -195,47 +195,47 @@ export interface JourneyStep {
195
195
  * carrying a real one would be a leak that no reviewer reads carefully enough
196
196
  * to catch, so the refusal is here rather than in a convention.
197
197
  */
198
- export declare const journeyVariableSchema: z.ZodObject<{
199
- defaultExpression: z.ZodOptional<z.ZodObject<{
200
- javascript: z.ZodString;
201
- shell: z.ZodString;
202
- }, z.core.$strip>>;
203
- detail: z.ZodString;
204
- name: z.ZodString;
205
- placeholder: z.ZodString;
206
- secret: z.ZodBoolean;
207
- title: z.ZodString;
208
- }, z.core.$strip>;
209
- export declare const journeyStepSchema: z.ZodObject<{
210
- capture: z.ZodOptional<z.ZodArray<z.ZodObject<{
211
- from: z.ZodString;
212
- header: z.ZodOptional<z.ZodBoolean>;
213
- secret: z.ZodOptional<z.ZodBoolean>;
214
- variable: z.ZodString;
215
- }, z.core.$strip>>>;
216
- expect: z.ZodOptional<z.ZodArray<z.ZodObject<{
217
- equals: z.ZodString;
218
- message: z.ZodString;
219
- subject: z.ZodString;
220
- }, z.core.$strip>>>;
221
- key: z.ZodString;
222
- observe: z.ZodString;
223
- operationId: z.ZodString;
224
- poll: z.ZodOptional<z.ZodObject<{
225
- describe: z.ZodString;
226
- intervalSeconds: z.ZodNumber;
227
- timeoutSeconds: z.ZodNumber;
228
- }, z.core.$strip>>;
229
- purpose: z.ZodString;
230
- query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
231
- recovery: z.ZodArray<z.ZodObject<{
232
- nextMove: z.ZodString;
233
- when: z.ZodString;
234
- }, z.core.$strip>>;
235
- request: z.ZodOptional<z.ZodUnknown>;
236
- requestHeaders: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
237
- title: z.ZodString;
238
- }, z.core.$strip>;
198
+ export declare const journeyVariableSchema: import("zod").ZodObject<{
199
+ defaultExpression: import("zod").ZodOptional<import("zod").ZodObject<{
200
+ javascript: import("zod").ZodString;
201
+ shell: import("zod").ZodString;
202
+ }, import("zod/v4/core").$strip>>;
203
+ detail: import("zod").ZodString;
204
+ name: import("zod").ZodString;
205
+ placeholder: import("zod").ZodString;
206
+ secret: import("zod").ZodBoolean;
207
+ title: import("zod").ZodString;
208
+ }, import("zod/v4/core").$strip>;
209
+ export declare const journeyStepSchema: import("zod").ZodObject<{
210
+ capture: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
211
+ from: import("zod").ZodString;
212
+ header: import("zod").ZodOptional<import("zod").ZodBoolean>;
213
+ secret: import("zod").ZodOptional<import("zod").ZodBoolean>;
214
+ variable: import("zod").ZodString;
215
+ }, import("zod/v4/core").$strip>>>;
216
+ expect: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
217
+ equals: import("zod").ZodString;
218
+ message: import("zod").ZodString;
219
+ subject: import("zod").ZodString;
220
+ }, import("zod/v4/core").$strip>>>;
221
+ key: import("zod").ZodString;
222
+ observe: import("zod").ZodString;
223
+ operationId: import("zod").ZodString;
224
+ poll: import("zod").ZodOptional<import("zod").ZodObject<{
225
+ describe: import("zod").ZodString;
226
+ intervalSeconds: import("zod").ZodNumber;
227
+ timeoutSeconds: import("zod").ZodNumber;
228
+ }, import("zod/v4/core").$strip>>;
229
+ purpose: import("zod").ZodString;
230
+ query: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
231
+ recovery: import("zod").ZodArray<import("zod").ZodObject<{
232
+ nextMove: import("zod").ZodString;
233
+ when: import("zod").ZodString;
234
+ }, import("zod/v4/core").$strip>>;
235
+ request: import("zod").ZodOptional<import("zod").ZodUnknown>;
236
+ requestHeaders: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
237
+ title: import("zod").ZodString;
238
+ }, import("zod/v4/core").$strip>;
239
239
  /**
240
240
  * The lowest curl that runs the generated commands.
241
241
  *
@@ -320,11 +320,6 @@ export declare function journeyCapturedVariables(): readonly string[];
320
320
  * sentence of its own. What the browser prints is what the curl page prints,
321
321
  * because it is the same declaration rendered twice.
322
322
  *
323
- * **`verified` maps to nothing, deliberately.** The ownership challenge is
324
- * optional and off by default since W4-09, so the journey does not perform it;
325
- * a deployment that turns it on gets the step from
326
- * `endpoints.verify`'s own snippet. Mapping it to a journey step that does not
327
- * exist would be worse than mapping it to none.
328
323
  */
329
324
  export declare const WEBSITE_JOURNEY_STEP_KEYS: Readonly<Record<string, readonly string[]>>;
330
325
  /** The journey steps a website step renders, resolved against the sequence. */
@@ -370,7 +365,7 @@ export declare function journeyActivationDuration(elapsedMs: number): JourneyAct
370
365
  export declare const JOURNEY_ACTIVATION_OUTCOMES: readonly ["reached", "refused", "timed_out", "failed"];
371
366
  export type JourneyActivationOutcome = (typeof JOURNEY_ACTIVATION_OUTCOMES)[number];
372
367
  /** The website steps an activation fact may name. */
373
- export declare const WEBSITE_JOURNEY_STEPS: readonly ["destination", "verified", "scheduled", "delivered"];
368
+ export declare const WEBSITE_JOURNEY_STEPS: readonly ["destination", "scheduled", "delivered"];
374
369
  /**
375
370
  * What is recorded when somebody moves through the website journey, and the
376
371
  * only thing that is.
@@ -388,27 +383,26 @@ export declare const WEBSITE_JOURNEY_STEPS: readonly ["destination", "verified",
388
383
  * The MCP schema learned that from a test and this one inherits the lesson
389
384
  * rather than rediscovering it.
390
385
  */
391
- export declare const websiteActivationEventSchema: z.ZodObject<{
392
- duration: z.ZodEnum<{
386
+ export declare const websiteActivationEventSchema: import("zod").ZodObject<{
387
+ duration: import("zod").ZodEnum<{
393
388
  under_1m: "under_1m";
394
389
  under_5m: "under_5m";
395
390
  under_15m: "under_15m";
396
391
  over_15m: "over_15m";
397
392
  }>;
398
- outcome: z.ZodEnum<{
393
+ outcome: import("zod").ZodEnum<{
399
394
  failed: "failed";
400
395
  timed_out: "timed_out";
401
396
  refused: "refused";
402
397
  reached: "reached";
403
398
  }>;
404
- step: z.ZodEnum<{
405
- verified: "verified";
399
+ step: import("zod").ZodEnum<{
406
400
  delivered: "delivered";
407
401
  destination: "destination";
408
402
  scheduled: "scheduled";
409
403
  }>;
410
- type: z.ZodLiteral<"website.journey_step">;
411
- }, z.core.$strict>;
404
+ type: import("zod").ZodLiteral<"website.journey_step">;
405
+ }, import("zod/v4/core").$strict>;
412
406
  export type WebsiteActivationEvent = z.infer<typeof websiteActivationEventSchema>;
413
407
  /**
414
408
  * Parses an activation fact before it leaves the browser.
@@ -1,4 +1,4 @@
1
- import { z } from "zod";
1
+ import { z } from "./zod.js";
2
2
  import { findOperation } from "./operations.js";
3
3
  /**
4
4
  * One thing that can go wrong at a step, and the next move.
@@ -262,12 +262,12 @@ export const FIRST_VALUE_STEPS = [
262
262
  purpose: "Creates the one-shot. The delay is converted to an absolute instant when the request is accepted, so the schedule reads back the same afterwards however it was expressed.",
263
263
  recovery: [
264
264
  {
265
- nextMove: "This deployment requires a destination to answer its ownership challenge before anything is delivered there, and yours has not. Answer the challenge with the secret the create call returned, then create the schedule.",
266
- when: "endpoint_unverified",
265
+ nextMove: "The endpoint identifier is not one this credential's project can deliver to — it belongs to another project, or there is no such endpoint. Create a destination in this project, or check the identifier.",
266
+ when: "not_found",
267
267
  },
268
268
  {
269
- nextMove: "The endpoint identifier is not one this credential's project can deliver to — it belongs to another project, or it has been disabled. Disabling is terminal, so create a new destination rather than trying to re-enable that one.",
270
- when: "not_found",
269
+ nextMove: "The endpoint is disabled. Enable it with `endpoints.enable` and the schedule is accepted as sent, or point the schedule at another destination.",
270
+ when: "state_conflict",
271
271
  },
272
272
  {
273
273
  nextMove: "The same idempotency key was used for a different request. Use a new key, or send the byte-identical body the key was first used with.",
@@ -385,7 +385,7 @@ export const FIRST_VALUE_STEPS = [
385
385
  key: "clean-up",
386
386
  observe: "The endpoint in status `disabled`. Nothing further is delivered to it, and it stays readable so the attempts above keep their context.",
387
387
  operationId: "endpoints.disable",
388
- purpose: "Stops delivery to the destination you registered for this walkthrough. Disabling is terminal and deliberate: it leaves the history intact rather than deleting evidence of what happened.",
388
+ purpose: "Stops delivery to the destination you registered for this walkthrough. Disabling is deliberate rather than final: it leaves the history intact rather than deleting evidence of what happened, and `endpoints.enable` turns the destination back on if you want it again.",
389
389
  recovery: [
390
390
  {
391
391
  nextMove: "Already gone, or never in this project. Nothing to clean up.",
@@ -482,17 +482,11 @@ export function journeyCapturedVariables() {
482
482
  * sentence of its own. What the browser prints is what the curl page prints,
483
483
  * because it is the same declaration rendered twice.
484
484
  *
485
- * **`verified` maps to nothing, deliberately.** The ownership challenge is
486
- * optional and off by default since W4-09, so the journey does not perform it;
487
- * a deployment that turns it on gets the step from
488
- * `endpoints.verify`'s own snippet. Mapping it to a journey step that does not
489
- * exist would be worse than mapping it to none.
490
485
  */
491
486
  export const WEBSITE_JOURNEY_STEP_KEYS = {
492
487
  delivered: ["await-occurrence", "read-attempt"],
493
488
  destination: ["create-destination"],
494
489
  scheduled: ["create-one-shot"],
495
- verified: [],
496
490
  };
497
491
  /** The journey steps a website step renders, resolved against the sequence. */
498
492
  export function websiteJourneySteps(step) {
@@ -580,7 +574,6 @@ export const JOURNEY_ACTIVATION_OUTCOMES = [
580
574
  /** The website steps an activation fact may name. */
581
575
  export const WEBSITE_JOURNEY_STEPS = [
582
576
  "destination",
583
- "verified",
584
577
  "scheduled",
585
578
  "delivered",
586
579
  ];