@greatwait/contracts 0.1.0-alpha.1

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 (241) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -0
  3. package/dist/authority.d.ts +217 -0
  4. package/dist/authority.js +261 -0
  5. package/dist/callback-ownership.d.ts +58 -0
  6. package/dist/callback-ownership.js +71 -0
  7. package/dist/callback-safety.d.ts +38 -0
  8. package/dist/callback-safety.js +403 -0
  9. package/dist/compatibility.d.ts +82 -0
  10. package/dist/compatibility.js +115 -0
  11. package/dist/delivery.d.ts +401 -0
  12. package/dist/delivery.js +311 -0
  13. package/dist/endpoints.d.ts +305 -0
  14. package/dist/endpoints.js +179 -0
  15. package/dist/events.d.ts +62 -0
  16. package/dist/events.js +38 -0
  17. package/dist/first-value-journey.d.ts +305 -0
  18. package/dist/first-value-journey.js +466 -0
  19. package/dist/forecast.d.ts +443 -0
  20. package/dist/forecast.js +729 -0
  21. package/dist/identifiers.d.ts +109 -0
  22. package/dist/identifiers.js +131 -0
  23. package/dist/identity.d.ts +196 -0
  24. package/dist/identity.js +182 -0
  25. package/dist/index.d.ts +27 -0
  26. package/dist/index.js +27 -0
  27. package/dist/mcp.d.ts +51 -0
  28. package/dist/mcp.js +56 -0
  29. package/dist/oauth.d.ts +796 -0
  30. package/dist/oauth.js +708 -0
  31. package/dist/operations.d.ts +3985 -0
  32. package/dist/operations.js +1837 -0
  33. package/dist/partition.d.ts +771 -0
  34. package/dist/partition.js +206 -0
  35. package/dist/policy.d.ts +93 -0
  36. package/dist/policy.js +180 -0
  37. package/dist/problems.d.ts +158 -0
  38. package/dist/problems.js +104 -0
  39. package/dist/protocol.d.ts +308 -0
  40. package/dist/protocol.js +515 -0
  41. package/dist/scheduling-records.d.ts +395 -0
  42. package/dist/scheduling-records.js +284 -0
  43. package/dist/scheduling.d.ts +1098 -0
  44. package/dist/scheduling.js +1116 -0
  45. package/dist/secrets.d.ts +383 -0
  46. package/dist/secrets.js +272 -0
  47. package/dist/signatures.d.ts +704 -0
  48. package/dist/signatures.js +867 -0
  49. package/dist/tenancy.d.ts +178 -0
  50. package/dist/tenancy.js +145 -0
  51. package/dist/test-sink.d.ts +986 -0
  52. package/dist/test-sink.js +755 -0
  53. package/dist/time.d.ts +45 -0
  54. package/dist/time.js +128 -0
  55. package/dist/usage.d.ts +121 -0
  56. package/dist/usage.js +200 -0
  57. package/dist/webhooks.d.ts +116 -0
  58. package/dist/webhooks.js +161 -0
  59. package/dist/workspace.d.ts +92 -0
  60. package/dist/workspace.js +59 -0
  61. package/generated/v1/callback-delivery-signature.json +467 -0
  62. package/generated/v1/callback-endpoint-verification.json +59 -0
  63. package/generated/v1/callback-receiver.json +241 -0
  64. package/generated/v1/examples/attempts.list.response.json +24 -0
  65. package/generated/v1/examples/attempts.read.response.json +20 -0
  66. package/generated/v1/examples/credentials.create.request.json +5 -0
  67. package/generated/v1/examples/credentials.create.response.json +10 -0
  68. package/generated/v1/examples/credentials.list.response.json +17 -0
  69. package/generated/v1/examples/credentials.revoke.response.json +11 -0
  70. package/generated/v1/examples/credentials.rotate.request.json +3 -0
  71. package/generated/v1/examples/credentials.rotate.response.json +22 -0
  72. package/generated/v1/examples/endpoints.create.request.json +3 -0
  73. package/generated/v1/examples/endpoints.create.response.json +16 -0
  74. package/generated/v1/examples/endpoints.disable.response.json +15 -0
  75. package/generated/v1/examples/endpoints.list.response.json +21 -0
  76. package/generated/v1/examples/endpoints.read.response.json +14 -0
  77. package/generated/v1/examples/endpoints.rotateSigningKey.request.json +3 -0
  78. package/generated/v1/examples/endpoints.rotateSigningKey.response.json +23 -0
  79. package/generated/v1/examples/endpoints.update.request.json +3 -0
  80. package/generated/v1/examples/endpoints.update.response.json +13 -0
  81. package/generated/v1/examples/endpoints.verify.response.json +15 -0
  82. package/generated/v1/examples/forecast.read.response.json +28 -0
  83. package/generated/v1/examples/forecast.windows.response.json +21 -0
  84. package/generated/v1/examples/grants.list.response.json +17 -0
  85. package/generated/v1/examples/grants.revoke.response.json +16 -0
  86. package/generated/v1/examples/meta.scaffold.response.json +5 -0
  87. package/generated/v1/examples/meta.version.response.json +5 -0
  88. package/generated/v1/examples/occurrences.list.response.json +17 -0
  89. package/generated/v1/examples/occurrences.read.response.json +15 -0
  90. package/generated/v1/examples/occurrences.redeliver.response.json +16 -0
  91. package/generated/v1/examples/projects.create.request.json +3 -0
  92. package/generated/v1/examples/projects.create.response.json +5 -0
  93. package/generated/v1/examples/projects.list.response.json +9 -0
  94. package/generated/v1/examples/schedules.archive.response.json +25 -0
  95. package/generated/v1/examples/schedules.cancel.response.json +24 -0
  96. package/generated/v1/examples/schedules.create.request.json +9 -0
  97. package/generated/v1/examples/schedules.create.response.json +25 -0
  98. package/generated/v1/examples/schedules.list.response.json +23 -0
  99. package/generated/v1/examples/schedules.pause.response.json +23 -0
  100. package/generated/v1/examples/schedules.read.response.json +25 -0
  101. package/generated/v1/examples/schedules.replace.request.json +8 -0
  102. package/generated/v1/examples/schedules.replace.response.json +25 -0
  103. package/generated/v1/examples/schedules.resume.response.json +23 -0
  104. package/generated/v1/examples/sinkdeliveries.list.response.json +19 -0
  105. package/generated/v1/examples/sinkdeliveries.read.response.json +16 -0
  106. package/generated/v1/examples/testsinks.configure.request.json +3 -0
  107. package/generated/v1/examples/testsinks.configure.response.json +13 -0
  108. package/generated/v1/examples/testsinks.create.request.json +8 -0
  109. package/generated/v1/examples/testsinks.create.response.json +13 -0
  110. package/generated/v1/examples/testsinks.delete.response.json +13 -0
  111. package/generated/v1/examples/testsinks.list.response.json +20 -0
  112. package/generated/v1/examples/testsinks.read.response.json +14 -0
  113. package/generated/v1/examples/usage.read.response.json +20 -0
  114. package/generated/v1/first-value-journey.json +436 -0
  115. package/generated/v1/manifest.json +1037 -0
  116. package/generated/v1/openapi.json +23665 -0
  117. package/generated/v1/policy-matrix.json +305 -0
  118. package/generated/v1/schemas/attempts.list.query.json +16 -0
  119. package/generated/v1/schemas/attempts.list.response.json +175 -0
  120. package/generated/v1/schemas/attempts.read.response.json +168 -0
  121. package/generated/v1/schemas/credentials.create.request.json +39 -0
  122. package/generated/v1/schemas/credentials.create.response.json +88 -0
  123. package/generated/v1/schemas/credentials.list.query.json +16 -0
  124. package/generated/v1/schemas/credentials.list.response.json +124 -0
  125. package/generated/v1/schemas/credentials.revoke.response.json +84 -0
  126. package/generated/v1/schemas/credentials.rotate.request.json +11 -0
  127. package/generated/v1/schemas/credentials.rotate.response.json +171 -0
  128. package/generated/v1/schemas/endpoints.create.request.json +12 -0
  129. package/generated/v1/schemas/endpoints.create.response.json +115 -0
  130. package/generated/v1/schemas/endpoints.disable.response-headers.json +11 -0
  131. package/generated/v1/schemas/endpoints.disable.response.json +100 -0
  132. package/generated/v1/schemas/endpoints.list.query.json +16 -0
  133. package/generated/v1/schemas/endpoints.list.response.json +146 -0
  134. package/generated/v1/schemas/endpoints.read.response-headers.json +11 -0
  135. package/generated/v1/schemas/endpoints.read.response.json +100 -0
  136. package/generated/v1/schemas/endpoints.rotateSigningKey.request-headers.json +10 -0
  137. package/generated/v1/schemas/endpoints.rotateSigningKey.request.json +11 -0
  138. package/generated/v1/schemas/endpoints.rotateSigningKey.response-headers.json +11 -0
  139. package/generated/v1/schemas/endpoints.rotateSigningKey.response.json +118 -0
  140. package/generated/v1/schemas/endpoints.update.request-headers.json +10 -0
  141. package/generated/v1/schemas/endpoints.update.request.json +12 -0
  142. package/generated/v1/schemas/endpoints.update.response-headers.json +11 -0
  143. package/generated/v1/schemas/endpoints.update.response.json +100 -0
  144. package/generated/v1/schemas/endpoints.verify.request-headers.json +10 -0
  145. package/generated/v1/schemas/endpoints.verify.response-headers.json +11 -0
  146. package/generated/v1/schemas/endpoints.verify.response.json +100 -0
  147. package/generated/v1/schemas/forecast.read.query.json +26 -0
  148. package/generated/v1/schemas/forecast.read.response.json +100 -0
  149. package/generated/v1/schemas/forecast.windows.query.json +26 -0
  150. package/generated/v1/schemas/forecast.windows.response.json +94 -0
  151. package/generated/v1/schemas/grants.list.response.json +98 -0
  152. package/generated/v1/schemas/grants.revoke.response.json +95 -0
  153. package/generated/v1/schemas/meta.scaffold.response.json +36 -0
  154. package/generated/v1/schemas/meta.version.response.json +19 -0
  155. package/generated/v1/schemas/occurrences.list.query.json +16 -0
  156. package/generated/v1/schemas/occurrences.list.response.json +83 -0
  157. package/generated/v1/schemas/occurrences.read.response.json +76 -0
  158. package/generated/v1/schemas/occurrences.redeliver.request-headers.json +13 -0
  159. package/generated/v1/schemas/occurrences.redeliver.response-headers.json +10 -0
  160. package/generated/v1/schemas/occurrences.redeliver.response.json +168 -0
  161. package/generated/v1/schemas/projects.create.request.json +12 -0
  162. package/generated/v1/schemas/projects.create.response.json +25 -0
  163. package/generated/v1/schemas/projects.list.response.json +35 -0
  164. package/generated/v1/schemas/schedules.archive.request-headers.json +10 -0
  165. package/generated/v1/schemas/schedules.archive.response-headers.json +11 -0
  166. package/generated/v1/schemas/schedules.archive.response.json +189 -0
  167. package/generated/v1/schemas/schedules.cancel.request-headers.json +10 -0
  168. package/generated/v1/schemas/schedules.cancel.response-headers.json +11 -0
  169. package/generated/v1/schemas/schedules.cancel.response.json +189 -0
  170. package/generated/v1/schemas/schedules.create.request-headers.json +12 -0
  171. package/generated/v1/schemas/schedules.create.request.json +99 -0
  172. package/generated/v1/schemas/schedules.create.response-headers.json +15 -0
  173. package/generated/v1/schemas/schedules.create.response.json +189 -0
  174. package/generated/v1/schemas/schedules.list.query.json +16 -0
  175. package/generated/v1/schemas/schedules.list.response.json +170 -0
  176. package/generated/v1/schemas/schedules.pause.request-headers.json +10 -0
  177. package/generated/v1/schemas/schedules.pause.response-headers.json +11 -0
  178. package/generated/v1/schemas/schedules.pause.response.json +189 -0
  179. package/generated/v1/schemas/schedules.read.response-headers.json +11 -0
  180. package/generated/v1/schemas/schedules.read.response.json +189 -0
  181. package/generated/v1/schemas/schedules.replace.request-headers.json +10 -0
  182. package/generated/v1/schemas/schedules.replace.request.json +99 -0
  183. package/generated/v1/schemas/schedules.replace.response-headers.json +11 -0
  184. package/generated/v1/schemas/schedules.replace.response.json +189 -0
  185. package/generated/v1/schemas/schedules.resume.request-headers.json +10 -0
  186. package/generated/v1/schemas/schedules.resume.response-headers.json +11 -0
  187. package/generated/v1/schemas/schedules.resume.response.json +189 -0
  188. package/generated/v1/schemas/sinkdeliveries.list.query.json +16 -0
  189. package/generated/v1/schemas/sinkdeliveries.list.response.json +126 -0
  190. package/generated/v1/schemas/sinkdeliveries.read.response.json +98 -0
  191. package/generated/v1/schemas/testsinks.configure.request.json +66 -0
  192. package/generated/v1/schemas/testsinks.configure.response.json +115 -0
  193. package/generated/v1/schemas/testsinks.create.request.json +76 -0
  194. package/generated/v1/schemas/testsinks.create.response.json +115 -0
  195. package/generated/v1/schemas/testsinks.delete.response.json +115 -0
  196. package/generated/v1/schemas/testsinks.list.query.json +16 -0
  197. package/generated/v1/schemas/testsinks.list.response.json +161 -0
  198. package/generated/v1/schemas/testsinks.read.response.json +115 -0
  199. package/generated/v1/schemas/usage.read.query.json +15 -0
  200. package/generated/v1/schemas/usage.read.response.json +71 -0
  201. package/generated/v1/snippets/attempts.list.json +5 -0
  202. package/generated/v1/snippets/attempts.read.json +5 -0
  203. package/generated/v1/snippets/credentials.create.json +5 -0
  204. package/generated/v1/snippets/credentials.list.json +5 -0
  205. package/generated/v1/snippets/credentials.revoke.json +5 -0
  206. package/generated/v1/snippets/credentials.rotate.json +5 -0
  207. package/generated/v1/snippets/endpoints.create.json +5 -0
  208. package/generated/v1/snippets/endpoints.disable.json +5 -0
  209. package/generated/v1/snippets/endpoints.list.json +5 -0
  210. package/generated/v1/snippets/endpoints.read.json +5 -0
  211. package/generated/v1/snippets/endpoints.rotateSigningKey.json +5 -0
  212. package/generated/v1/snippets/endpoints.update.json +5 -0
  213. package/generated/v1/snippets/endpoints.verify.json +5 -0
  214. package/generated/v1/snippets/forecast.read.json +5 -0
  215. package/generated/v1/snippets/forecast.windows.json +5 -0
  216. package/generated/v1/snippets/grants.list.json +5 -0
  217. package/generated/v1/snippets/grants.revoke.json +5 -0
  218. package/generated/v1/snippets/meta.scaffold.json +5 -0
  219. package/generated/v1/snippets/meta.version.json +5 -0
  220. package/generated/v1/snippets/occurrences.list.json +5 -0
  221. package/generated/v1/snippets/occurrences.read.json +5 -0
  222. package/generated/v1/snippets/occurrences.redeliver.json +5 -0
  223. package/generated/v1/snippets/projects.create.json +5 -0
  224. package/generated/v1/snippets/projects.list.json +5 -0
  225. package/generated/v1/snippets/schedules.archive.json +5 -0
  226. package/generated/v1/snippets/schedules.cancel.json +5 -0
  227. package/generated/v1/snippets/schedules.create.json +5 -0
  228. package/generated/v1/snippets/schedules.list.json +5 -0
  229. package/generated/v1/snippets/schedules.pause.json +5 -0
  230. package/generated/v1/snippets/schedules.read.json +5 -0
  231. package/generated/v1/snippets/schedules.replace.json +5 -0
  232. package/generated/v1/snippets/schedules.resume.json +5 -0
  233. package/generated/v1/snippets/sinkdeliveries.list.json +5 -0
  234. package/generated/v1/snippets/sinkdeliveries.read.json +5 -0
  235. package/generated/v1/snippets/testsinks.configure.json +5 -0
  236. package/generated/v1/snippets/testsinks.create.json +5 -0
  237. package/generated/v1/snippets/testsinks.delete.json +5 -0
  238. package/generated/v1/snippets/testsinks.list.json +5 -0
  239. package/generated/v1/snippets/testsinks.read.json +5 -0
  240. package/generated/v1/snippets/usage.read.json +5 -0
  241. package/package.json +153 -0
@@ -0,0 +1,241 @@
1
+ {
2
+ "idempotency": {
3
+ "occurrence": {
4
+ "identity": "Callback-Occurrence-Id",
5
+ "note": "Every automatic delivery of one occurrence — the first attempt and every retry the system chose — is at most one execution. A receiver claims the occurrence atomically and answers 200 for every later automatic delivery of it. This is what makes at-least-once delivery safe; a receiver that needs a second execution asks for a second occurrence, or a person orders a redelivery.",
6
+ "requirement": "claim the occurrence atomically before running the handler; release the claim if the handler fails so a later attempt can retry it"
7
+ },
8
+ "redelivery": {
9
+ "identity": "Callback-Occurrence-Id together with the signed attempt number, which is the redelivery's ordinal",
10
+ "note": "A redelivery is a deliberate, authorized instruction to do the work again. Suppressing it as a duplicate answers a person with silence, which is what a customer pressing redeliver after fixing their endpoint experiences as the attempt succeeding while nothing happens.",
11
+ "optOut": "A receiver that genuinely requires strict once-only per occurrence chooses it explicitly and keeps answering duplicate. It is an opt-out, not the default, because a default of suppression makes the product lie to the person who pressed the button.",
12
+ "ordering": "attempt only ever increases within an occurrence and every copy of one redelivery carries the same value, so a receiver keeps the highest redelivery it has run to completion and refuses anything at or below it. That is what recognises a copy delayed in a proxy, a queue or an abandoned connection, however late it arrives and however many redeliveries have completed since. Remembering only the most recent instruction cannot do this and will run a customer's work twice; remembering every instruction can, at the cost of a store that grows without bound. sourceAttemptId names the attempt the person chose to follow and is there to show them, not to decide whether the work runs.",
13
+ "requirement": "run the handler again for a redelivery whose attempt is above the highest this receiver has run to completion for the occurrence, and suppress every redelivery at or below that high-water mark",
14
+ "strictness": "A receiver that chose strict once-only suppresses every delivery for an occurrence once anything has finished, whatever caused it. Reading strictness as a rule about redeliveries alone leaves a hole: a strict receiver that processed a redelivery first would then admit a delayed automatic delivery and run a payment twice.",
15
+ "warranty": "Each accepted redelivery is one logical run. Repeats are suppressed once the receiver has durably completed that run — not from the moment it starts one. A handler that performs its external effect and then dies before its claim is settled will be run again when the lease expires, which is the honest limit of what any at-least-once receiver can promise. A customer whose effect must happen exactly once commits the occurrence and ordinal alongside their own state, or passes them downstream as an idempotency key."
16
+ },
17
+ "replay": {
18
+ "identity": "Callback-Delivery-Id",
19
+ "requirement": "reject a previously accepted delivery identity before parsing, and answer 200 — a duplicated request is not a failure"
20
+ }
21
+ },
22
+ "claimRules": [
23
+ "another delivery holds an unexpired lease, whatever the run, so an ordered redelivery never runs alongside the attempt it follows -> in_flight",
24
+ "the delivery may not retake a settled occurrence and anything at all has finished for it -> settled. This covers every automatic delivery and every delivery at a receiver that chose strict once-only",
25
+ "the delivery is a redelivery whose ordinal is at or below the highest this receiver has run to completion -> settled",
26
+ "otherwise take it, recording the holder and the run -> claimed"
27
+ ],
28
+ "order": [
29
+ "read the exact request bytes before any body parser sees them",
30
+ "reject a body over the receiver's byte bound without buffering it",
31
+ "validate the five Callback-* headers and the content type",
32
+ "reject a timestamp outside tolerance",
33
+ "select the signing key by Callback-Key-Id within the receiver's own endpoint, project, and environment",
34
+ "compare the HMAC in constant time over <timestamp>.<delivery-id>. plus the exact bytes",
35
+ "compare the canonical envelope identifiers with the occurrence header",
36
+ "claim the delivery identity atomically",
37
+ "only now parse the body, and read the trigger that says why this delivery exists",
38
+ "claim the occurrence identity atomically, for the run the signed body names — the occurrence for an automatic delivery, and the occurrence with the redelivery's attempt ordinal for one a person ordered",
39
+ "run the application handler"
40
+ ],
41
+ "responses": {
42
+ "body_too_large": 413,
43
+ "duplicate": 200,
44
+ "handler_failed": 500,
45
+ "in_flight": 503,
46
+ "invalid_envelope": 400,
47
+ "invalid_headers": 401,
48
+ "invalid_signature": 401,
49
+ "processed": 200,
50
+ "replay": 200,
51
+ "stale_timestamp": 408
52
+ },
53
+ "sink": {
54
+ "behaviors": {
55
+ "client_error": {
56
+ "defaultStatus": 422,
57
+ "receiverActed": false,
58
+ "senderOutcome": "terminal",
59
+ "summary": "Answers a selected 4xx. The sender records a customer refusal, and retries it only when the status is one the receiver may recover from — 401, 403 and 404, listed as `clientErrorStatusesRetried`. The default, 422, is not one of those, so it settles on the first attempt."
60
+ },
61
+ "defer_abandon": {
62
+ "defaultStatus": 202,
63
+ "deferredReport": "never",
64
+ "receiverActed": true,
65
+ "senderOutcome": "ambiguous",
66
+ "summary": "Acknowledges the delivery and then never reports at all. The sender waits until the deadline in the envelope and records ambiguity, because a receiver that took the work and went quiet may well have done it. This is the case the completion deadline exists to bound."
67
+ },
68
+ "defer_fail": {
69
+ "defaultStatus": 202,
70
+ "deferredReport": "failed",
71
+ "receiverActed": true,
72
+ "senderOutcome": "retryable",
73
+ "summary": "Acknowledges the delivery, then reports `failed` with the credential in its signed envelope. The occurrence goes back on the ordinary retry ladder — the same place a 500 puts it — which is how a receiver says its job died rather than that it vanished."
74
+ },
75
+ "defer_succeed": {
76
+ "defaultStatus": 202,
77
+ "deferredReport": "succeeded",
78
+ "receiverActed": true,
79
+ "senderOutcome": "success",
80
+ "summary": "Acknowledges the delivery with 202 and the pending marker, keeps the work, then reports `succeeded` with the credential in its signed envelope. The whole deferred exchange, without writing a receiver."
81
+ },
82
+ "delay": {
83
+ "defaultStatus": 200,
84
+ "receiverActed": true,
85
+ "senderOutcome": "success",
86
+ "summary": "Waits a bounded interval, then accepts. Exercises a slow receiver that still succeeds."
87
+ },
88
+ "disconnect": {
89
+ "receiverActed": false,
90
+ "senderOutcome": "ambiguous",
91
+ "summary": "Authenticates the delivery and then drops the connection without processing it, holding until the sender gives up. Nothing was claimed and nothing ran, but the sender cannot know that."
92
+ },
93
+ "duplicate": {
94
+ "defaultStatus": 200,
95
+ "receiverActed": false,
96
+ "senderOutcome": "success",
97
+ "summary": "Accepts and reports the occurrence as already handled, without processing it again. What occurrence idempotency looks like from the sender's side."
98
+ },
99
+ "invalid_signature": {
100
+ "defaultStatus": 401,
101
+ "receiverActed": false,
102
+ "senderOutcome": "retryable",
103
+ "summary": "Rejects the delivery as unauthenticated regardless of whether the signature verified. Exercises the key-mismatch path without forging a signature. The sender retries on the receiver's ordinary budget, because the usual cause is a credential the receiver is about to redeploy."
104
+ },
105
+ "rate_limited": {
106
+ "defaultStatus": 429,
107
+ "receiverActed": false,
108
+ "senderOutcome": "retryable",
109
+ "summary": "Answers 429 with a bounded Retry-After. The sender honours the hint and does not spend its give-up budget."
110
+ },
111
+ "server_error": {
112
+ "defaultStatus": 503,
113
+ "receiverActed": false,
114
+ "senderOutcome": "retryable",
115
+ "summary": "Answers a selected 5xx. The sender retries with backoff."
116
+ },
117
+ "success": {
118
+ "defaultStatus": 200,
119
+ "receiverActed": true,
120
+ "senderOutcome": "success",
121
+ "summary": "Verifies, records, and accepts."
122
+ },
123
+ "timeout": {
124
+ "receiverActed": true,
125
+ "senderOutcome": "ambiguous",
126
+ "summary": "Verifies and records the delivery, then never answers. The receiver acted and the sender cannot know it."
127
+ }
128
+ },
129
+ "bounds": {
130
+ "maxCompletionDelayMs": 5000,
131
+ "maxDelayMs": 10000,
132
+ "maxHoldMs": 45000,
133
+ "maxRetainedDeliveries": 50,
134
+ "maxSinksPerEnvironment": 10,
135
+ "maxRequestBodyBytes": 65536,
136
+ "maxRetainedBodyBytes": 4096
137
+ },
138
+ "clientErrorStatuses": [400, 401, 403, 404, 409, 410, 422],
139
+ "clientErrorStatusesRetried": [401, 403, 404],
140
+ "deferral": {
141
+ "acknowledgement": "{\"greatwait\":{\"status\":\"pending\"}}",
142
+ "note": "A deferring behavior answers this exact body with this status, then reports with the bearer credential from the delivery's own signed envelope — to the one completion address the stage is configured with, which the envelope's own URL must match. A delivery whose envelope carries no completion material, or names a different address, cannot defer, and the sink answers it as an ordinary success instead.",
143
+ "status": 202
144
+ },
145
+ "egress": "A test sink has no destination field: no program, no control operation and no request header names anywhere for it to send. The one request it performs is a deferred-completion report for a delivery it has already received and authenticated, to the URL and credential carried inside that delivery's signed envelope. It cannot forward or redirect a delivery.",
146
+ "visibility": "Test environments only. Organization, project, environment, and credential kind come from the verified principal; no request may widen them.",
147
+ "programSchema": {
148
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
149
+ "type": "object",
150
+ "properties": {
151
+ "behavior": {
152
+ "type": "string",
153
+ "enum": [
154
+ "client_error",
155
+ "defer_abandon",
156
+ "defer_fail",
157
+ "defer_succeed",
158
+ "delay",
159
+ "disconnect",
160
+ "duplicate",
161
+ "invalid_signature",
162
+ "rate_limited",
163
+ "server_error",
164
+ "success",
165
+ "timeout"
166
+ ]
167
+ },
168
+ "completionDelayMs": {
169
+ "type": "integer",
170
+ "exclusiveMinimum": 0,
171
+ "maximum": 5000
172
+ },
173
+ "delayMs": {
174
+ "type": "integer",
175
+ "exclusiveMinimum": 0,
176
+ "maximum": 10000
177
+ },
178
+ "forDeliveries": {
179
+ "type": "integer",
180
+ "exclusiveMinimum": 0,
181
+ "maximum": 100
182
+ },
183
+ "retryAfterSeconds": {
184
+ "type": "integer",
185
+ "exclusiveMinimum": 0,
186
+ "maximum": 300
187
+ },
188
+ "status": {
189
+ "type": "integer",
190
+ "minimum": 400,
191
+ "maximum": 599
192
+ },
193
+ "then": {
194
+ "type": "string",
195
+ "enum": [
196
+ "client_error",
197
+ "defer_abandon",
198
+ "defer_fail",
199
+ "defer_succeed",
200
+ "delay",
201
+ "disconnect",
202
+ "duplicate",
203
+ "invalid_signature",
204
+ "rate_limited",
205
+ "server_error",
206
+ "success",
207
+ "timeout"
208
+ ]
209
+ }
210
+ },
211
+ "required": ["behavior"]
212
+ }
213
+ },
214
+ "version": "2026-08-23",
215
+ "acknowledgementSchema": {
216
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
217
+ "type": "object",
218
+ "properties": {
219
+ "disposition": {
220
+ "type": "string",
221
+ "enum": [
222
+ "body_too_large",
223
+ "duplicate",
224
+ "handler_failed",
225
+ "in_flight",
226
+ "invalid_envelope",
227
+ "invalid_headers",
228
+ "invalid_signature",
229
+ "processed",
230
+ "replay",
231
+ "stale_timestamp"
232
+ ]
233
+ },
234
+ "occurrenceId": {
235
+ "type": "string",
236
+ "pattern": "^occ_[0-9abcdefghjkmnpqrstvwxyz]{26}$"
237
+ }
238
+ },
239
+ "required": ["disposition"]
240
+ }
241
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "data": [
3
+ {
4
+ "attemptNumber": 1,
5
+ "classifiedAt": "2026-07-28T15:00:00.071Z",
6
+ "delivery": "dlv_01h8xyz9k2m4n6p8r0t2v4w6y8",
7
+ "diagnostic": "http_retryable",
8
+ "durationMs": 71,
9
+ "id": "att_01h8xyz9k2m4n6p8r0t2v4w6y8",
10
+ "occurrence": "occ_01h8xyz9k2m4n6p8r0t2v4w6y8",
11
+ "remediation": "review_retry_policy",
12
+ "responseStatus": 503,
13
+ "startedAt": "2026-07-28T15:00:00.000Z",
14
+ "state": "retryable_failure",
15
+ "trigger": {
16
+ "kind": "automatic"
17
+ }
18
+ }
19
+ ],
20
+ "freshness": {
21
+ "kind": "authoritative"
22
+ },
23
+ "nextCursor": "eyJhIjoxNzg1MjUwODAwMDAwLCJpIjoiYXR0XzAxaDh4eXo5azJtNG42cDhyMHQydjR3Nnk4IiwiayI6Ijk1MTM1NDZmIn0"
24
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "attempt": {
3
+ "attemptNumber": 2,
4
+ "classifiedAt": "2026-07-28T15:02:00.000Z",
5
+ "delivery": "dlv_11h8xyz9k2m4n6p8r0t2v4w6y8",
6
+ "diagnostic": "network_ambiguous",
7
+ "durationMs": 10000,
8
+ "id": "att_11h8xyz9k2m4n6p8r0t2v4w6y8",
9
+ "occurrence": "occ_01h8xyz9k2m4n6p8r0t2v4w6y8",
10
+ "remediation": "review_before_redelivery",
11
+ "startedAt": "2026-07-28T15:01:50.000Z",
12
+ "state": "ambiguous",
13
+ "trigger": {
14
+ "kind": "automatic"
15
+ }
16
+ },
17
+ "freshness": {
18
+ "kind": "authoritative"
19
+ }
20
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "environmentKind": "test",
3
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
4
+ "scopes": ["schedules:write"]
5
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "createdAt": "2026-07-28T15:00:00.000Z",
3
+ "displayPrefix": "pt_test_a1b2c3d4",
4
+ "environmentKind": "test",
5
+ "id": "ak_01h8xyz9k2m4n6p8r0t2v4w6y8",
6
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
7
+ "scopes": ["schedules:write"],
8
+ "secret": "pt_test_a1b2c3d4<the-32-character-secret-half-here>",
9
+ "shownOnce": true
10
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "data": [
3
+ {
4
+ "createdAt": "2026-07-28T15:00:00.000Z",
5
+ "displayPrefix": "pt_test_a1b2c3d4",
6
+ "environmentKind": "test",
7
+ "id": "ak_01h8xyz9k2m4n6p8r0t2v4w6y8",
8
+ "lastUsedAt": "2026-07-28T15:04:00.000Z",
9
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
10
+ "scopes": ["schedules:write"]
11
+ }
12
+ ],
13
+ "freshness": {
14
+ "kind": "authoritative"
15
+ },
16
+ "nextCursor": "eyJhIjoxNzg1MjUwODAwMDAwLCJpIjoiYWtfMDFoOHh5ejlrMm00bjZwOHIwdDJ2NHc2eTgiLCJrIjoiOTUxMzU0NmYifQ"
17
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "credential": {
3
+ "createdAt": "2026-07-28T15:00:00.000Z",
4
+ "displayPrefix": "pt_test_a1b2c3d4",
5
+ "environmentKind": "test",
6
+ "id": "ak_01h8xyz9k2m4n6p8r0t2v4w6y8",
7
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
8
+ "revokedAt": "2026-07-28T16:00:00.000Z",
9
+ "scopes": ["schedules:write"]
10
+ }
11
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "overlapSeconds": 3600
3
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "credential": {
3
+ "createdAt": "2026-07-28T15:00:00.000Z",
4
+ "displayPrefix": "pt_test_e5f6g7h8",
5
+ "environmentKind": "test",
6
+ "id": "ak_01h8xyz9k2m4n6p8r0t2v4w6y9",
7
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
8
+ "scopes": ["schedules:write"],
9
+ "secret": "pt_test_e5f6g7h8<the-32-character-secret-half-here>",
10
+ "shownOnce": true
11
+ },
12
+ "retired": {
13
+ "createdAt": "2026-07-28T15:00:00.000Z",
14
+ "displayPrefix": "pt_test_a1b2c3d4",
15
+ "environmentKind": "test",
16
+ "expiresAt": "2026-07-29T15:00:00.000Z",
17
+ "id": "ak_01h8xyz9k2m4n6p8r0t2v4w6y8",
18
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
19
+ "supersededBy": "ak_01h8xyz9k2m4n6p8r0t2v4w6y9",
20
+ "scopes": ["schedules:write"]
21
+ }
22
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "url": "https://hooks.example.com/greatwait"
3
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "createdAt": "2026-08-05T15:00:00.000Z",
3
+ "environmentKind": "test",
4
+ "id": "ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
5
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
6
+ "signingKeys": {
7
+ "current": "csk_01h8xyz9k2m4n6p8r0t2v4w6y8"
8
+ },
9
+ "status": "pending",
10
+ "updatedAt": "2026-08-05T15:00:00.000Z",
11
+ "url": "https://hooks.example.com/greatwait",
12
+ "version": 1,
13
+ "keyId": "csk_01h8xyz9k2m4n6p8r0t2v4w6y8",
14
+ "secret": "ptsk_test_<the-one-time-endpoint-secret-here>",
15
+ "shownOnce": true
16
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "createdAt": "2026-08-05T15:00:00.000Z",
3
+ "disabledAt": "2026-08-05T17:00:00.000Z",
4
+ "environmentKind": "test",
5
+ "id": "ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
6
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
7
+ "signingKeys": {
8
+ "current": "csk_01h8xyz9k2m4n6p8r0t2v4w6y8"
9
+ },
10
+ "status": "disabled",
11
+ "updatedAt": "2026-08-05T17:00:00.000Z",
12
+ "url": "https://hooks.example.com/greatwait",
13
+ "verifiedAt": "2026-08-05T15:01:00.000Z",
14
+ "version": 3
15
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "data": [
3
+ {
4
+ "createdAt": "2026-08-05T15:00:00.000Z",
5
+ "environmentKind": "test",
6
+ "id": "ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
7
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
8
+ "signingKeys": {
9
+ "current": "csk_01h8xyz9k2m4n6p8r0t2v4w6y8"
10
+ },
11
+ "status": "verified",
12
+ "updatedAt": "2026-08-05T15:01:00.000Z",
13
+ "url": "https://hooks.example.com/greatwait",
14
+ "verifiedAt": "2026-08-05T15:01:00.000Z",
15
+ "version": 2
16
+ }
17
+ ],
18
+ "freshness": {
19
+ "kind": "authoritative"
20
+ }
21
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "createdAt": "2026-08-05T15:00:00.000Z",
3
+ "environmentKind": "test",
4
+ "id": "ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
5
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
6
+ "signingKeys": {
7
+ "current": "csk_01h8xyz9k2m4n6p8r0t2v4w6y8"
8
+ },
9
+ "status": "verified",
10
+ "updatedAt": "2026-08-05T15:01:00.000Z",
11
+ "url": "https://hooks.example.com/greatwait",
12
+ "verifiedAt": "2026-08-05T15:01:00.000Z",
13
+ "version": 2
14
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "overlapSeconds": 3600
3
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "endpoint": {
3
+ "createdAt": "2026-08-05T15:00:00.000Z",
4
+ "environmentKind": "test",
5
+ "id": "ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
6
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
7
+ "signingKeys": {
8
+ "current": "csk_01h8xyz9k2m4n6p8r0t2v4w6y8",
9
+ "next": {
10
+ "id": "csk_11h8xyz9k2m4n6p8r0t2v4w6y8",
11
+ "overlapEndsAt": "2026-08-06T15:05:00.000Z"
12
+ }
13
+ },
14
+ "status": "verified",
15
+ "updatedAt": "2026-08-05T15:05:00.000Z",
16
+ "url": "https://hooks.example.com/greatwait",
17
+ "verifiedAt": "2026-08-05T15:01:00.000Z",
18
+ "version": 3
19
+ },
20
+ "keyId": "csk_11h8xyz9k2m4n6p8r0t2v4w6y8",
21
+ "secret": "ptsk_test_<the-next-one-time-endpoint-secret-here>",
22
+ "shownOnce": true
23
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "url": "https://hooks.example.com/replacement"
3
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "createdAt": "2026-08-05T15:00:00.000Z",
3
+ "environmentKind": "test",
4
+ "id": "ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
5
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
6
+ "signingKeys": {
7
+ "current": "csk_01h8xyz9k2m4n6p8r0t2v4w6y8"
8
+ },
9
+ "status": "pending",
10
+ "updatedAt": "2026-08-05T16:00:00.000Z",
11
+ "url": "https://hooks.example.com/replacement",
12
+ "version": 3
13
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "createdAt": "2026-08-05T15:00:00.000Z",
3
+ "environmentKind": "test",
4
+ "id": "ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
5
+ "lastVerificationAttemptAt": "2026-08-05T15:01:00.000Z",
6
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
7
+ "signingKeys": {
8
+ "current": "csk_01h8xyz9k2m4n6p8r0t2v4w6y8"
9
+ },
10
+ "status": "verified",
11
+ "updatedAt": "2026-08-05T15:01:00.000Z",
12
+ "url": "https://hooks.example.com/greatwait",
13
+ "verifiedAt": "2026-08-05T15:01:00.000Z",
14
+ "version": 2
15
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "buckets": [
3
+ {
4
+ "byLatencyClass": {
5
+ "bulk": 12,
6
+ "realtime": 3
7
+ },
8
+ "byPartitionKey": {
9
+ "campaign.spring": 9,
10
+ "campaign.winter": 4
11
+ },
12
+ "count": 15,
13
+ "nextFireCount": 4,
14
+ "otherPartitionKeyCount": 2,
15
+ "start": "2026-07-28T15:00:00.000Z"
16
+ }
17
+ ],
18
+ "freshness": {
19
+ "asOf": "2026-07-28T14:58:30.000Z",
20
+ "kind": "projected",
21
+ "lagSeconds": 90
22
+ },
23
+ "window": {
24
+ "bucketSeconds": 1800,
25
+ "from": "2026-07-28T15:00:00.000Z",
26
+ "to": "2026-07-29T15:00:00.000Z"
27
+ }
28
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "bucketSeconds": 600,
3
+ "buckets": [
4
+ {
5
+ "byTenant": {
6
+ "campaign.spring": 9,
7
+ "campaign.winter": 4
8
+ },
9
+ "count": 15,
10
+ "nextFireCount": 4,
11
+ "otherCount": 2,
12
+ "start": "2026-07-28T15:00:00.000Z"
13
+ }
14
+ ],
15
+ "freshness": {
16
+ "asOf": "2026-07-28T14:58:30.000Z",
17
+ "kind": "projected",
18
+ "lagSeconds": 90
19
+ },
20
+ "version": "2026-08-09"
21
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "data": [
3
+ {
4
+ "client": {
5
+ "id": "oc_01h8xyz9k2m4n6p8r0t2v4w6y8",
6
+ "name": "Flow XO"
7
+ },
8
+ "createdAt": "2026-08-14T11:00:00.000Z",
9
+ "environmentKind": "test",
10
+ "id": "og_01h8xyz9k2m4n6p8r0t2v4w6y8",
11
+ "lastUsedAt": "2026-08-15T09:12:00.000Z",
12
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
13
+ "scopes": ["schedules:read", "schedules:write"],
14
+ "status": "active"
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "grant": {
3
+ "client": {
4
+ "id": "oc_01h8xyz9k2m4n6p8r0t2v4w6y8",
5
+ "name": "Flow XO"
6
+ },
7
+ "createdAt": "2026-08-14T11:00:00.000Z",
8
+ "environmentKind": "test",
9
+ "id": "og_01h8xyz9k2m4n6p8r0t2v4w6y8",
10
+ "project": "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
11
+ "revocationReason": "member-revoked",
12
+ "revokedAt": "2026-08-15T10:00:00.000Z",
13
+ "scopes": ["schedules:read", "schedules:write"],
14
+ "status": "revoked"
15
+ }
16
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependsOn": ["application", "contract", "platform"],
3
+ "layer": "adapter",
4
+ "service": "@greatwait/api"
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "buildSha": "9f2c1ab",
3
+ "environment": "development",
4
+ "service": "@greatwait/api"
5
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "data": [
3
+ {
4
+ "attemptCount": 1,
5
+ "generation": 1,
6
+ "id": "occ_01h8xyz9k2m4n6p8r0t2v4w6y8",
7
+ "plannedFor": "2026-07-28T15:00:00.000Z",
8
+ "schedule": "sch_01h8xyz9k2m4n6p8r0t2v4w6y8",
9
+ "sequence": 1,
10
+ "state": "retry_wait"
11
+ }
12
+ ],
13
+ "freshness": {
14
+ "kind": "authoritative"
15
+ },
16
+ "nextCursor": "eyJhIjoxNzg1MjUwODAwMDAwLCJpIjoib2NjXzAxaDh4eXo5azJtNG42cDhyMHQydjR3Nnk4IiwiayI6Ijk1MTM1NDZmIn0"
17
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "freshness": {
3
+ "kind": "authoritative"
4
+ },
5
+ "occurrence": {
6
+ "attemptCount": 2,
7
+ "generation": 1,
8
+ "id": "occ_01h8xyz9k2m4n6p8r0t2v4w6y8",
9
+ "plannedFor": "2026-07-28T15:00:00.000Z",
10
+ "schedule": "sch_01h8xyz9k2m4n6p8r0t2v4w6y8",
11
+ "sequence": 1,
12
+ "settledAt": "2026-07-28T15:02:00.000Z",
13
+ "state": "terminal_failed"
14
+ }
15
+ }