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

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 (190) hide show
  1. package/README.md +1 -1
  2. package/dist/authority.d.ts +4 -1
  3. package/dist/authority.js +1 -0
  4. package/dist/billing.d.ts +231 -1
  5. package/dist/billing.js +150 -1
  6. package/dist/callback-safety.js +13 -3
  7. package/dist/configuration-bounds.d.ts +13 -0
  8. package/dist/configuration-bounds.js +13 -0
  9. package/dist/data-export.d.ts +2 -0
  10. package/dist/delivery.d.ts +26 -0
  11. package/dist/delivery.js +2 -0
  12. package/dist/effective-limits.d.ts +40 -0
  13. package/dist/effective-limits.js +42 -0
  14. package/dist/endpoints.d.ts +173 -5
  15. package/dist/endpoints.js +77 -6
  16. package/dist/first-value-journey.d.ts +1 -1
  17. package/dist/first-value-journey.js +11 -7
  18. package/dist/forecast.d.ts +111 -21
  19. package/dist/forecast.js +87 -24
  20. package/dist/http-request.d.ts +193 -0
  21. package/dist/http-request.js +305 -0
  22. package/dist/identity.d.ts +4 -4
  23. package/dist/index.d.ts +9 -6
  24. package/dist/index.js +8 -5
  25. package/dist/mcp.d.ts +2 -1
  26. package/dist/mcp.js +1 -1
  27. package/dist/members.d.ts +141 -0
  28. package/dist/members.js +223 -0
  29. package/dist/oauth.d.ts +7 -0
  30. package/dist/operation-definitions.d.ts +20 -4
  31. package/dist/operation-definitions.js +9 -1
  32. package/dist/operational-config.d.ts +101 -0
  33. package/dist/operational-config.js +341 -0
  34. package/dist/operations.d.ts +1299 -52
  35. package/dist/operations.js +466 -32
  36. package/dist/organization-lifecycle.d.ts +10 -0
  37. package/dist/partition.d.ts +17 -9
  38. package/dist/partition.js +3 -3
  39. package/dist/policy.js +5 -2
  40. package/dist/problems.d.ts +25 -2
  41. package/dist/problems.js +49 -1
  42. package/dist/protocol.d.ts +5 -5
  43. package/dist/protocol.js +2 -1
  44. package/dist/scheduling-records.d.ts +226 -0
  45. package/dist/scheduling-records.js +5 -0
  46. package/dist/scheduling.d.ts +273 -1
  47. package/dist/scheduling.js +91 -4
  48. package/dist/secrets.d.ts +7 -0
  49. package/dist/tenancy.d.ts +1 -1
  50. package/dist/tenancy.js +1 -1
  51. package/dist/usage.js +6 -21
  52. package/dist/zod-values.d.ts +2 -2
  53. package/dist/zod-values.js +1 -1
  54. package/generated/v1/examples/attempts.list.response.json +2 -0
  55. package/generated/v1/examples/attempts.read.response.json +2 -0
  56. package/generated/v1/examples/billing.fundingconfirm.response.json +120 -0
  57. package/generated/v1/examples/billing.invoicehistory.response.json +6 -0
  58. package/generated/v1/examples/billing.invoices.response.json +15 -0
  59. package/generated/v1/examples/billing.paymenthistory.response.json +6 -0
  60. package/generated/v1/examples/billing.paymentmethod.response.json +16 -0
  61. package/generated/v1/examples/billing.paymentmethodconfirm.request.json +3 -0
  62. package/generated/v1/examples/billing.paymentmethodconfirm.response.json +16 -0
  63. package/generated/v1/examples/billing.paymentmethodremove.request.json +3 -0
  64. package/generated/v1/examples/billing.paymentmethodremove.response.json +4 -0
  65. package/generated/v1/examples/billing.paymentmethodsetup.request.json +1 -0
  66. package/generated/v1/examples/billing.paymentmethodsetup.response.json +3 -0
  67. package/generated/v1/examples/endpoints.ensure.request.json +3 -0
  68. package/generated/v1/examples/endpoints.ensure.response.json +20 -0
  69. package/generated/v1/examples/invitations.create.request.json +5 -0
  70. package/generated/v1/examples/invitations.create.response.json +7 -0
  71. package/generated/v1/examples/invitations.list.response.json +11 -0
  72. package/generated/v1/examples/invitations.resend.request.json +1 -0
  73. package/generated/v1/examples/invitations.resend.response.json +4 -0
  74. package/generated/v1/examples/invitations.revoke.request.json +3 -0
  75. package/generated/v1/examples/invitations.revoke.response.json +4 -0
  76. package/generated/v1/examples/limits.read.response.json +16 -0
  77. package/generated/v1/examples/members.list.response.json +13 -0
  78. package/generated/v1/examples/members.remove.request.json +3 -0
  79. package/generated/v1/examples/members.remove.response.json +4 -0
  80. package/generated/v1/examples/members.role.request.json +3 -0
  81. package/generated/v1/examples/members.role.response.json +4 -0
  82. package/generated/v1/examples/occurrences.redeliver.response.json +2 -0
  83. package/generated/v1/examples/projectmembers.add.request.json +1 -0
  84. package/generated/v1/examples/projectmembers.add.response.json +4 -0
  85. package/generated/v1/examples/projectmembers.remove.request.json +3 -0
  86. package/generated/v1/examples/projectmembers.remove.response.json +4 -0
  87. package/generated/v1/first-value-journey.json +24 -8
  88. package/generated/v1/manifest.json +627 -10
  89. package/generated/v1/openapi.json +29081 -15663
  90. package/generated/v1/policy-matrix.json +137 -2
  91. package/generated/v1/schemas/attempts.list.response.json +15 -0
  92. package/generated/v1/schemas/attempts.read.response.json +15 -0
  93. package/generated/v1/schemas/billing.fundingconfirm.response.json +552 -0
  94. package/generated/v1/schemas/billing.invoicehistory.query.json +16 -0
  95. package/generated/v1/schemas/billing.invoicehistory.response.json +88 -0
  96. package/generated/v1/schemas/billing.invoices.response.json +51 -0
  97. package/generated/v1/schemas/billing.ledger.response.json +5 -0
  98. package/generated/v1/schemas/billing.notificationsettingsupdate.request.json +24 -17
  99. package/generated/v1/schemas/billing.paymenthistory.query.json +16 -0
  100. package/generated/v1/schemas/billing.paymenthistory.response.json +182 -0
  101. package/generated/v1/schemas/billing.paymentmethod.response.json +137 -0
  102. package/generated/v1/schemas/billing.paymentmethodconfirm.request.json +14 -0
  103. package/generated/v1/schemas/billing.paymentmethodconfirm.response.json +137 -0
  104. package/generated/v1/schemas/billing.paymentmethodremove.request.json +12 -0
  105. package/generated/v1/schemas/billing.paymentmethodremove.response.json +137 -0
  106. package/generated/v1/schemas/billing.paymentmethodsetup.request.json +12 -0
  107. package/generated/v1/schemas/billing.paymentmethodsetup.response.json +11 -0
  108. package/generated/v1/schemas/billing.purchase.request.json +4 -0
  109. package/generated/v1/schemas/context.read.response.json +1 -0
  110. package/generated/v1/schemas/credentials.connection.response.json +1 -0
  111. package/generated/v1/schemas/credentials.create.request.json +1 -0
  112. package/generated/v1/schemas/credentials.create.response.json +1 -0
  113. package/generated/v1/schemas/credentials.list.response.json +1 -0
  114. package/generated/v1/schemas/credentials.revoke.response.json +1 -0
  115. package/generated/v1/schemas/credentials.rotate.response.json +2 -0
  116. package/generated/v1/schemas/endpoints.acknowledgeSigningKeyRotation.response.json +59 -0
  117. package/generated/v1/schemas/endpoints.create.request.json +74 -0
  118. package/generated/v1/schemas/endpoints.create.response.json +59 -0
  119. package/generated/v1/schemas/endpoints.disable.response.json +59 -0
  120. package/generated/v1/schemas/endpoints.enable.response.json +59 -0
  121. package/generated/v1/schemas/endpoints.ensure.request.json +91 -0
  122. package/generated/v1/schemas/endpoints.ensure.response.json +169 -0
  123. package/generated/v1/schemas/endpoints.list.response.json +59 -0
  124. package/generated/v1/schemas/endpoints.read.response.json +59 -0
  125. package/generated/v1/schemas/endpoints.rotateSigningKey.response.json +59 -0
  126. package/generated/v1/schemas/endpoints.update.request.json +74 -0
  127. package/generated/v1/schemas/endpoints.update.response.json +59 -0
  128. package/generated/v1/schemas/forecast.read.request-headers.json +10 -0
  129. package/generated/v1/schemas/forecast.read.response.json +148 -0
  130. package/generated/v1/schemas/grants.list.response.json +1 -0
  131. package/generated/v1/schemas/grants.revoke.response.json +1 -0
  132. package/generated/v1/schemas/invitations.create.request-headers.json +13 -0
  133. package/generated/v1/schemas/invitations.create.request.json +24 -0
  134. package/generated/v1/schemas/invitations.create.response.json +31 -0
  135. package/generated/v1/schemas/invitations.list.response.json +40 -0
  136. package/generated/v1/schemas/invitations.resend.request-headers.json +13 -0
  137. package/generated/v1/schemas/invitations.resend.request.json +6 -0
  138. package/generated/v1/schemas/invitations.resend.response.json +27 -0
  139. package/generated/v1/schemas/invitations.revoke.request-headers.json +13 -0
  140. package/generated/v1/schemas/invitations.revoke.request.json +12 -0
  141. package/generated/v1/schemas/invitations.revoke.response.json +27 -0
  142. package/generated/v1/schemas/limits.read.response.json +79 -0
  143. package/generated/v1/schemas/members.list.response.json +53 -0
  144. package/generated/v1/schemas/members.remove.request-headers.json +13 -0
  145. package/generated/v1/schemas/members.remove.request.json +12 -0
  146. package/generated/v1/schemas/members.remove.response.json +27 -0
  147. package/generated/v1/schemas/members.role.request-headers.json +13 -0
  148. package/generated/v1/schemas/members.role.request.json +12 -0
  149. package/generated/v1/schemas/members.role.response.json +27 -0
  150. package/generated/v1/schemas/occurrences.redeliver.response.json +15 -0
  151. package/generated/v1/schemas/projectmembers.add.request-headers.json +13 -0
  152. package/generated/v1/schemas/projectmembers.add.request.json +6 -0
  153. package/generated/v1/schemas/projectmembers.add.response.json +27 -0
  154. package/generated/v1/schemas/projectmembers.remove.request-headers.json +13 -0
  155. package/generated/v1/schemas/projectmembers.remove.request.json +12 -0
  156. package/generated/v1/schemas/projectmembers.remove.response.json +27 -0
  157. package/generated/v1/schemas/schedules.archive.response.json +138 -1
  158. package/generated/v1/schemas/schedules.cancel.response.json +138 -1
  159. package/generated/v1/schemas/schedules.create.request.json +150 -1
  160. package/generated/v1/schemas/schedules.create.response.json +156 -1
  161. package/generated/v1/schemas/schedules.list.response.json +138 -1
  162. package/generated/v1/schemas/schedules.pause.response.json +138 -1
  163. package/generated/v1/schemas/schedules.read.response.json +138 -1
  164. package/generated/v1/schemas/schedules.replace.request.json +150 -1
  165. package/generated/v1/schemas/schedules.replace.response.json +156 -1
  166. package/generated/v1/schemas/schedules.resume.response.json +138 -1
  167. package/generated/v1/snippets/billing.fundingconfirm.json +6 -0
  168. package/generated/v1/snippets/billing.invoicehistory.json +6 -0
  169. package/generated/v1/snippets/billing.invoices.json +6 -0
  170. package/generated/v1/snippets/billing.notificationsettingsupdate.json +1 -1
  171. package/generated/v1/snippets/billing.paymenthistory.json +6 -0
  172. package/generated/v1/snippets/billing.paymentmethod.json +6 -0
  173. package/generated/v1/snippets/billing.paymentmethodconfirm.json +6 -0
  174. package/generated/v1/snippets/billing.paymentmethodremove.json +6 -0
  175. package/generated/v1/snippets/billing.paymentmethodsetup.json +6 -0
  176. package/generated/v1/snippets/endpoints.create.json +1 -1
  177. package/generated/v1/snippets/endpoints.ensure.json +6 -0
  178. package/generated/v1/snippets/forecast.windows.json +1 -1
  179. package/generated/v1/snippets/invitations.create.json +6 -0
  180. package/generated/v1/snippets/invitations.list.json +6 -0
  181. package/generated/v1/snippets/invitations.resend.json +6 -0
  182. package/generated/v1/snippets/invitations.revoke.json +6 -0
  183. package/generated/v1/snippets/journey/create-destination.json +1 -1
  184. package/generated/v1/snippets/limits.read.json +6 -0
  185. package/generated/v1/snippets/members.list.json +6 -0
  186. package/generated/v1/snippets/members.remove.json +6 -0
  187. package/generated/v1/snippets/members.role.json +6 -0
  188. package/generated/v1/snippets/projectmembers.add.json +6 -0
  189. package/generated/v1/snippets/projectmembers.remove.json +6 -0
  190. package/package.json +7 -2
@@ -1,17 +1,19 @@
1
+ import { effectiveCustomerLimitsSchema } from "./effective-limits.js";
1
2
  import { z } from "./zod.js";
3
+ import { MEMBER_OPERATIONS } from "./members.js";
2
4
  import { DATA_EXPORT_OPERATIONS } from "./data-export.js";
3
5
  import { ORGANIZATION_LIFECYCLE_OPERATIONS } from "./organization-lifecycle.js";
4
6
  import { API_UNUSED_RESPONSE_SCHEMA } from "./operation-definitions.js";
5
7
  import { credentialContextSchema } from "./authority.js";
6
- import { callbackEndpointCreatedSchema, callbackEndpointPageSchema, callbackEndpointRequestSchema, callbackEndpointRotatedSchema, callbackEndpointSchema, callbackEndpointSigningSecretsSchema, callbackSigningKeyRotationRequestSchema, } from "./endpoints.js";
7
- import { FORECAST_WINDOW_VERSION, forecastRequestSchema, forecastSchema, forecastWindowsSchema, } from "./forecast.js";
8
+ import { callbackEndpointCreatedSchema, callbackEndpointEnsuredSchema, callbackEndpointPageSchema, callbackEndpointRequestSchema, callbackEndpointRotatedSchema, callbackEndpointSchema, callbackEndpointSigningSecretsSchema, callbackSigningKeyRotationRequestSchema, } from "./endpoints.js";
9
+ import { FORECAST_WINDOW_VERSION, forecastRequestSchema, forecastSchema, forecastRequestHeadersSchema, forecastWindowsSchema, } from "./forecast.js";
8
10
  import { usageRequestSchema, usageSchema } from "./usage.js";
9
11
  import { deliveryTimingSummarySchema } from "./timing.js";
10
- import { billingAutoTopUpApplyRequestSchema, billingAutoTopUpPreviewRequestSchema, billingAutoTopUpPreviewSchema, billingCeilingUpdateRequestSchema, billingFundingQuoteRequestSchema, billingFundingQuoteSchema, billingFundingViewSchema, billingNoticePageSchema, billingNotificationSettingsSchema, billingNotificationSettingsUpdateRequestSchema, billingLedgerPageSchema, billingLedgerRequestSchema, billingBudgetUpdateRequestHeadersSchema, billingBudgetUpdateRequestSchema, billingBudgetUpdateResponseSchema, billingPurchaseRequestSchema, billingRefundRequestCreateSchema, billingRefundResolutionRequestSchema, billingRefundRequestViewSchema, billingSummarySchema, projectBillingStateSchema, projectBillingQuoteSchema, projectBillingQuoteRequestSchema, projectBillingChangeRequestSchema, billingPortalSchema, } from "./billing.js";
12
+ import { billingAutoTopUpApplyRequestSchema, billingAutoTopUpPreviewRequestSchema, billingAutoTopUpPreviewSchema, billingCeilingUpdateRequestSchema, billingFundingQuoteRequestSchema, billingFundingQuoteSchema, billingFundingViewSchema, billingNoticePageSchema, billingNotificationSettingsSchema, billingNotificationSettingsUpdateRequestSchema, billingLedgerPageSchema, billingLedgerRequestSchema, billingBudgetUpdateRequestHeadersSchema, billingBudgetUpdateRequestSchema, billingBudgetUpdateResponseSchema, billingPurchaseRequestSchema, billingRefundRequestCreateSchema, billingRefundResolutionRequestSchema, billingRefundRequestViewSchema, billingSummarySchema, projectBillingStateSchema, projectBillingQuoteSchema, projectBillingQuoteRequestSchema, projectBillingChangeRequestSchema, billingPortalSchema, billingInvoiceListSchema, billingPaymentHistoryPageSchema, billingInvoiceHistoryPageSchema, billingPaymentMethodSchema, billingPaymentMethodSetupRequestSchema, billingPaymentMethodConfirmRequestSchema, billingPaymentMethodRemoveRequestSchema, } from "./billing.js";
11
13
  import { conditionalRequestHeaderSchema, idempotencyReplayResponseHeaderSchema, idempotencyRequestHeaderSchema, historyPageRequestSchema, pageRequestSchema, scheduleListRequestSchema, replayedResponseHeaderSchema, requiredConditionalRequestHeaderSchema, requiredIdempotencyRequestHeaderSchema, versionResponseHeaderSchema, } from "./protocol.js";
12
14
  import { oauthGrantListSchema, oauthGrantRevokedSchema } from "./oauth.js";
13
15
  import { credentialCreatedSchema, credentialPageSchema, credentialRequestSchema, credentialRevokedSchema, credentialRotatedSchema, credentialRotationRequestSchema, } from "./secrets.js";
14
- import { attemptPageSchema, attemptViewSchema, occurrencePageSchema, projectOccurrenceListRequestSchema, projectOccurrencePageSchema, occurrenceViewSchema, schedulePageSchema, scheduleRequestSchema, scheduleViewSchema, } from "./scheduling.js";
16
+ import { attemptPageSchema, attemptViewSchema, occurrencePageSchema, projectOccurrenceListRequestSchema, projectOccurrencePageSchema, occurrenceViewSchema, schedulePageSchema, scheduleRequestSchema, scheduleViewSchema, scheduleWrittenViewSchema, } from "./scheduling.js";
15
17
  import { testSinkCreateRequestSchema, testSinkDeliveryBodySchema, testSinkDeliveryPageSchema, testSinkPageSchema, testSinkProgramSchema, testSinkSchema, } from "./test-sink.js";
16
18
  import { projectArchiveRequestSchema, projectCreateRequestSchema, projectDeletedSchema, projectListSchema, projectSummarySchema, projectUpdateRequestSchema, } from "./tenancy.js";
17
19
  import { mcpConnectionSchema } from "./mcp.js";
@@ -299,7 +301,7 @@ const BILLING_NOTIFICATION_SETTINGS_OPERATION = {
299
301
  creates: false,
300
302
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
301
303
  ? ""
302
- : "Reads the USD 2.00 default low-credit threshold and optional-email choice. Critical email remains mandatory for owners and active billing-role members; addresses and contact management are absent.",
304
+ : "Reads the low-credit threshold in effect and the optional-email choice. Unless a threshold was chosen, it is one fifth of the organization's most recent credit purchase or grant, rounded down to a whole cent, and zero before any credit was granted. Critical email remains mandatory for owners and active billing-role members; addresses and contact management are absent.",
303
305
  example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
304
306
  ? {}
305
307
  : BILLING_NOTIFICATION_SETTINGS_EXAMPLE,
@@ -325,7 +327,7 @@ const BILLING_NOTIFICATION_SETTINGS_UPDATE_OPERATION = {
325
327
  creates: false,
326
328
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
327
329
  ? ""
328
- : "Replaces the low-credit threshold and noncritical email choice at an expected revision. Critical email stays mandatory; idempotent retries converge and agents require explicit approval.",
330
+ : "Replaces the low-credit threshold and noncritical email choice at an expected revision. A null threshold returns to the default of one fifth of the most recent credit purchase or grant; an omitted threshold is left exactly as it is. Critical email stays mandatory; idempotent retries converge and agents require explicit approval.",
329
331
  environments: ["live"],
330
332
  example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
331
333
  ? {}
@@ -469,7 +471,62 @@ const BILLING_AUTO_TOP_UP_APPLY_OPERATION = withBillingFundingContract({
469
471
  surfaces: ["api", "mock"],
470
472
  });
471
473
  export const OPERATIONS = [
474
+ {
475
+ creates: false,
476
+ description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
477
+ ? ""
478
+ : "Read the verified organization's execution-credit payments with bounded cursor continuation. Existing recent-history responses remain compatible.",
479
+ example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
480
+ ? {}
481
+ : { data: [], freshness: { kind: "authoritative" } },
482
+ id: "billing.paymenthistory",
483
+ idempotent: true,
484
+ mcp: { destructive: false, kind: "tool", openWorld: false },
485
+ method: "GET",
486
+ mutates: false,
487
+ path: "/v1/billing/payment-history",
488
+ principals: ["api-credential", "oauth", "session"],
489
+ problems: ["invalid_request", "service_unavailable"],
490
+ query: pageRequestSchema,
491
+ response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
492
+ ? API_UNUSED_RESPONSE_SCHEMA
493
+ : billingPaymentHistoryPageSchema,
494
+ scopes: ["usage:read"],
495
+ sessionAuthority: "headers",
496
+ summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
497
+ ? ""
498
+ : "Page execution-credit payments",
499
+ surfaces: ["api", "mock"],
500
+ },
501
+ {
502
+ creates: false,
503
+ description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
504
+ ? ""
505
+ : "Read the verified organization's project subscription invoices with bounded cursor continuation. Existing recent-history responses remain compatible.",
506
+ example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
507
+ ? {}
508
+ : { data: [], freshness: { kind: "authoritative" } },
509
+ id: "billing.invoicehistory",
510
+ idempotent: true,
511
+ mcp: { destructive: false, kind: "tool", openWorld: false },
512
+ method: "GET",
513
+ mutates: false,
514
+ path: "/v1/billing/invoice-history",
515
+ principals: ["api-credential", "oauth", "session"],
516
+ problems: ["invalid_request", "service_unavailable"],
517
+ query: pageRequestSchema,
518
+ response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
519
+ ? API_UNUSED_RESPONSE_SCHEMA
520
+ : billingInvoiceHistoryPageSchema,
521
+ scopes: ["usage:read"],
522
+ sessionAuthority: "headers",
523
+ summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
524
+ ? ""
525
+ : "Page project subscription invoices",
526
+ surfaces: ["api", "mock"],
527
+ },
472
528
  ...DATA_EXPORT_OPERATIONS,
529
+ ...MEMBER_OPERATIONS,
473
530
  ...ORGANIZATION_LIFECYCLE_OPERATIONS,
474
531
  {
475
532
  creates: false,
@@ -604,7 +661,7 @@ export const OPERATIONS = [
604
661
  creates: true,
605
662
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
606
663
  ? ""
607
- : "Creates a reusable callback endpoint in the caller's project and environment. The destination must be HTTPS on effective port 443, contain no URL credentials or fragment, and resolve only to public unicast addresses. The endpoint is active and usable the moment it exists; there is nothing to verify. A disabled endpoint is never delivered to, and a schedule write naming one answers not_found, because disabling is terminal rather than a state to recover from. The per-endpoint secret is returned in this response and nowhere else. The 50-record safety ceiling includes disabled endpoints because they remain readable for audit.",
664
+ : "Creates a reusable callback endpoint in the caller's project and environment. The destination must be HTTPS on effective port 443, contain no URL credentials or fragment, and resolve only to public unicast addresses. The endpoint is active and usable the moment it exists; there is nothing to verify. A disabled endpoint is never delivered to, and a schedule write naming one answers not_found, because disabling is terminal rather than a state to recover from. The per-endpoint secret is returned to this call and to no other call an API credential or an OAuth token can make; a signed-in member can read it again through endpoints.revealSigningSecret. There is no endpoint-count ceiling. Disabled endpoints remain readable for audit; request and DNS inspection admission bound creation work and reads are paged. Optional `headers` set reusable defaults. Ordinary values remain readable; `secret: true` encrypts a write-only value that is never returned. Header edits use explicit `set`, `keep`, and `remove` actions.",
608
665
  example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
609
666
  ? {}
610
667
  : {
@@ -625,7 +682,7 @@ export const OPERATIONS = [
625
682
  idempotent: false,
626
683
  mcp: {
627
684
  kind: "unavailable",
628
- reason: "Creation returns a one-time endpoint signing secret, and MCP has no negotiated secure-result channel that can keep it out of ordinary tool history.",
685
+ reason: "Creation returns a one-time endpoint signing secret, and MCP has no negotiated secure-result channel that can keep it out of ordinary tool history. Agents use endpoints_ensure, or schedules_create with a `url`, which create an endpoint without returning its secret.",
629
686
  },
630
687
  method: "POST",
631
688
  mutates: true,
@@ -652,6 +709,67 @@ export const OPERATIONS = [
652
709
  : "Create a callback endpoint",
653
710
  surfaces: ["api", "mock"],
654
711
  },
712
+ {
713
+ // Sometimes brings an endpoint into being and sometimes finds one, and a
714
+ // single success status has to be true of both, so it answers 200 and
715
+ // says which in `created`. `schedules.pause` set the precedent for a
716
+ // mutating POST that is not a 201.
717
+ creates: false,
718
+ description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
719
+ ? ""
720
+ : "Finds or creates the callback endpoint at a URL in the caller's project and environment, without returning its signing secret. With no `name`, an existing endpoint that is not disabled at exactly this address is returned unchanged, preferring the one named after its URL; with a `name`, the endpoint must also carry that name. Otherwise one is created under the same rules as endpoints.create — HTTPS on effective port 443, no URL credentials or fragment, resolving only to public unicast addresses — and `created` is true. Optional `headers` apply only to an endpoint this call creates. Sent when the endpoint already exists, they are accepted if they are exactly its ordinary headers — what a retry of the creating call sends — and otherwise refused as `state_conflict` naming it; endpoints.update changes them. A secret value cannot be compared, so a call carrying one is refused for an endpoint that already exists. The result is metadata only: `signingSecret` says that the secret is not returned and where a signed-in member reveals it (`revealUrl`, the endpoint's dashboard page). Every callback is signed with that secret whether or not the receiver checks it. This is the endpoint operation agents use over MCP; endpoints.create, which returns the secret once, is withheld there.",
721
+ example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
722
+ ? {}
723
+ : {
724
+ created: true,
725
+ createdAt: "2026-08-05T15:00:00.000Z",
726
+ environmentKind: "test",
727
+ id: "ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
728
+ name: "https://hooks.example.com/greatwait",
729
+ project: "proj_01h8xyz9k2m4n6p8r0t2v4w6y8",
730
+ signingKeys: { current: "csk_01h8xyz9k2m4n6p8r0t2v4w6y8" },
731
+ signingSecret: {
732
+ guidance: "GreatWait signs every callback to this endpoint. The signing secret is never returned here; a signed-in member of the project reveals it on the endpoint's page in the GreatWait dashboard, and your receiver uses it to verify that a callback came from GreatWait.",
733
+ returned: false,
734
+ revealUrl: "https://app.greatwait.dev/o/org_2example0organization0id/p/proj_01h8xyz9k2m4n6p8r0t2v4w6y8/test/settings/endpoints/ep_01h8xyz9k2m4n6p8r0t2v4w6y8",
735
+ },
736
+ status: "active",
737
+ updatedAt: "2026-08-05T15:00:00.000Z",
738
+ url: "https://hooks.example.com/greatwait",
739
+ version: 1,
740
+ },
741
+ id: "endpoints.ensure",
742
+ // Repeating it returns the same endpoint: the second call finds what the
743
+ // first created. That is the property this field states, with no key.
744
+ idempotent: true,
745
+ // Additive, and open-world for the reason endpoints.update is: deliveries
746
+ // go to the customer's receiver afterwards.
747
+ mcp: { destructive: false, kind: "tool", openWorld: true },
748
+ method: "POST",
749
+ mutates: true,
750
+ path: "/v1/endpoints/ensure",
751
+ principals: ["api-credential", "oauth", "session"],
752
+ problems: [
753
+ "state_conflict",
754
+ "invalid_request",
755
+ "plan_limit_reached",
756
+ "rate_limited",
757
+ ],
758
+ request: callbackEndpointRequestSchema,
759
+ requestExample: globalThis
760
+ .GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
761
+ ? {}
762
+ : { url: "https://hooks.example.com/greatwait" },
763
+ response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
764
+ ? API_UNUSED_RESPONSE_SCHEMA
765
+ : callbackEndpointEnsuredSchema,
766
+ scopes: ["endpoints:write"],
767
+ sessionAuthority: "headers",
768
+ summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
769
+ ? ""
770
+ : "Find or create a callback endpoint by URL",
771
+ surfaces: ["api", "mock"],
772
+ },
655
773
  {
656
774
  creates: false,
657
775
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
@@ -741,7 +859,7 @@ export const OPERATIONS = [
741
859
  creates: false,
742
860
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
743
861
  ? ""
744
- : "Replaces an endpoint's destination after applying the complete URL and DNS policy, and renames it when a name is given. Deliveries go to the new destination from the next one on. Disabled endpoints cannot be updated. Send If-Match with the version the endpoint was read at to be refused rather than overwrite a destination somebody else changed in the meantime.",
862
+ : "Replaces an endpoint's destination after applying the complete URL and DNS policy, and renames it when a name is given. Optional `headers` patch endpoint defaults with `set`, `keep`, or `remove`; omitted headers preserve them. A secret value can be retained, replaced (including an empty string), or removed, but cannot be revealed. Header and destination edits apply to newly admitted attempts, including retries; recovery of the same admitted attempt keeps its snapshot. Disabled endpoints cannot be updated. Send If-Match with the version the endpoint was read at to be refused rather than overwrite a destination somebody else changed in the meantime.",
745
863
  example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
746
864
  ? {}
747
865
  : {
@@ -792,7 +910,7 @@ export const OPERATIONS = [
792
910
  creates: true,
793
911
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
794
912
  ? ""
795
- : "Creates the next endpoint signing key and selects it immediately for new deliveries while retaining the current key in the receiver acceptance set for a bounded overlap. The overlap defaults to and cannot exceed 24 hours. A second rotation is refused until the current overlap ends. The new secret is returned once and has no recovery operation, so a call whose answer was never read may have rotated a key nobody holds: read the endpoint and compare its signing keys before repeating one. Send If-Match with the version the endpoint was read at to be refused rather than rotate an endpoint that has changed since.",
913
+ : "Creates the next endpoint signing key and selects it immediately for new deliveries while retaining the current key in the receiver acceptance set for a bounded overlap. The overlap defaults to and cannot exceed 24 hours. A second rotation is refused until the current overlap ends. The new secret is returned once to this call, so a call whose answer was never read has rotated a key the caller does not hold. It is recoverable: a signed-in member can read both keys, and the instant the overlap ends, through endpoints.revealSigningSecret. An API credential or an OAuth token cannot, so an integration that loses the answer needs a member to read it back rather than a second rotation, which is refused until the overlap ends. Send If-Match with the version the endpoint was read at to be refused rather than rotate an endpoint that has changed since.",
796
914
  example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
797
915
  ? {}
798
916
  : {
@@ -2033,7 +2151,7 @@ export const OPERATIONS = [
2033
2151
  creates: true,
2034
2152
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
2035
2153
  ? ""
2036
- : "Creates a schedule and returns it together with its first planned occurrence. Give exactly one of `at`, `delaySeconds`, `everySeconds` and `cron`. An optional `partitionKey` selects a fairness lane inside this project and environment; it is fixed after create. Add a verified `endpoint` to deliver each occurrence there; optional JSON `data` is encrypted before PostgreSQL persistence, placed in the signed callback, and returned as given by a schedule read. `at` and `delaySeconds` fire once; a delay is converted to an absolute instant when the request is accepted, so a schedule created either way reads back the same afterwards. `everySeconds` is a fixed duration and its first occurrence falls one interval after acceptance — it stays the same length across a daylight-saving change, and takes no timezone for that reason. `cron` is a wall clock: it is read against the IANA `timeZone` sent with it, `UTC` when none is, and the first occurrence is the first instant the expression names after acceptance. Where the clocks go forward and the wall time named does not exist that day, the occurrence falls at the first instant after the gap; where they go back and it happens twice, it falls once, at the earlier of the two. A recurring schedule is materialized one occurrence at a time: the next one is planned once the current one is due, so a read always shows one occurrence still to come. `lateness.policy` decides what happens when an occurrence reaches its first attempt after its planned instant: `skipAhead` never carries a recurring arrival across its next scheduled instant (and a shorter custom window may retire it earlier), while `catchUp` admits one arrival within `maxStalenessSeconds` even after later recurrence instants passed. A one-shot has no next recurrence, so either explicit policy uses its window and the default is `catchUp` with 24 hours; recurring schedules default to `skipAhead`, and a `catchUp` without an override has a one-interval window. A retry already in progress is exempt because it arrived and failed; its retry and give-up policy still decide the outcome. The organization, project and environment come from the verified principal; a body cannot name them, and the endpoint must belong to the same tuple, so a credential issued for one project can only ever create schedules in that project. Send an `Idempotency-Key` to make a retry safe: the identical request returns the schedule that key already created, marked `Idempotency-Replayed: true`, and creates nothing further; the same key with a different request is refused `idempotency_key_reused`. A replay reports the schedule **as it stands now**, not a frozen copy of the first response — if it was paused in between, the replay says so.",
2154
+ : "Creates a schedule and returns it together with its first planned occurrence. Give exactly one of `at`, `delaySeconds`, `everySeconds` and `cron`. An optional `partitionKey` selects a fairness lane inside this project and environment; it is fixed after create. Add a verified `endpoint` to deliver each occurrence there. Instead of `endpoint`, give a `url`: the service uses this project and environment's existing endpoint at exactly that address, or creates one silently. Its signing secret is never returned; the response's `endpointSigningSecret` says where a signed-in member reveals it. Reusing an endpoint needs only `schedules:write`; creating one also needs `endpoints:write`, and without it the request is refused as `scope_missing`. Optional JSON `data` is encrypted before PostgreSQL persistence, placed in the signed callback, and returned as given by a schedule read. Optional `http` selects POST (default), PUT, or bodyless GET and schedule header overrides. Omitted HTTP settings preserve the signed structured envelope; `body: { mode: 'json', value: ... }` sends that JSON directly without interpolation. Ordinary headers remain readable and secret values are encrypted and write-only. Schedule headers override endpoint defaults case-insensitively, with `suppress` to omit an inherited header and `remove` to resume inheritance. Product signing, content and transport headers are reserved. Raw JSON and GET carry asynchronous completion details in reserved Callback-Completion headers. `at` and `delaySeconds` fire once; a delay is converted to an absolute instant when the request is accepted, so a schedule created either way reads back the same afterwards. `everySeconds` is a fixed duration and its first occurrence falls one interval after acceptance — it stays the same length across a daylight-saving change, and takes no timezone for that reason. `cron` is a wall clock: it is read against the IANA `timeZone` sent with it, `UTC` when none is, and the first occurrence is the first instant the expression names after acceptance. Where the clocks go forward and the wall time named does not exist that day, the occurrence falls at the first instant after the gap; where they go back and it happens twice, it falls once, at the earlier of the two. A recurring schedule is materialized one occurrence at a time: the next one is planned once the current one is due, so a read always shows one occurrence still to come. `lateness.policy` decides what happens when an occurrence reaches its first attempt after its planned instant: `skipAhead` never carries a recurring arrival across its next scheduled instant (and a shorter custom window may retire it earlier), while `catchUp` admits one arrival within `maxStalenessSeconds` even after later recurrence instants passed. A one-shot has no next recurrence, so either explicit policy uses its window and the default is `catchUp` with 24 hours; recurring schedules default to `skipAhead`, and a `catchUp` without an override has a one-interval window. A retry already in progress is exempt because it arrived and failed; its retry and give-up policy still decide the outcome. The organization, project and environment come from the verified principal; a body cannot name them, and the endpoint must belong to the same tuple, so a credential issued for one project can only ever create schedules in that project. Send an `Idempotency-Key` to make a retry safe: the identical request returns the schedule that key already created, marked `Idempotency-Replayed: true`, and creates nothing further; the same key with a different request is refused `idempotency_key_reused`. A replay reports the schedule **as it stands now**, not a frozen copy of the first response — if it was paused in between, the replay says so.",
2037
2155
  example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
2038
2156
  ? {}
2039
2157
  : {
@@ -2076,6 +2194,9 @@ export const OPERATIONS = [
2076
2194
  method: "POST",
2077
2195
  mutates: true,
2078
2196
  path: "/v1/schedules",
2197
+ // Creating the endpoint a `url` names is an endpoint write (W9-44).
2198
+ conditionalScopes: ["endpoints:write"],
2199
+ conditionalScopesWhen: "the request names a `url` this project and environment has no endpoint at yet",
2079
2200
  principals: ["api-credential", "oauth", "session"],
2080
2201
  problems: [
2081
2202
  "idempotency_key_reused",
@@ -2083,11 +2204,14 @@ export const OPERATIONS = [
2083
2204
  "not_found",
2084
2205
  // The organization ceiling, the same code and the same shape
2085
2206
  // `projects.create` and `endpoints.create` use. A plan may bound the
2086
- // live schedules an organization holds, the distinct partition keys it
2087
- // has live, and how large a `data` body it may carry; all three refuse
2088
- // here rather than truncating, because a schedule created without the
2089
- // body the caller sent is not the schedule they asked for.
2207
+ // distinct partition keys an organization has live and how large a
2208
+ // `data` body it may carry; both refuse here rather than truncating,
2209
+ // because a schedule created without the body the caller sent is not
2210
+ // the schedule they asked for. How many schedules an organization holds
2211
+ // is not bounded (FXO-2556).
2090
2212
  "plan_limit_reached",
2213
+ "rate_limited",
2214
+ "scope_missing",
2091
2215
  "service_unavailable",
2092
2216
  // A schedule against a disabled endpoint. Refused rather than accepted
2093
2217
  // and never fired, and refused by its state rather than as `not_found`,
@@ -2109,7 +2233,7 @@ export const OPERATIONS = [
2109
2233
  requestHeaders: idempotencyRequestHeaderSchema,
2110
2234
  response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2111
2235
  ? API_UNUSED_RESPONSE_SCHEMA
2112
- : scheduleViewSchema,
2236
+ : scheduleWrittenViewSchema,
2113
2237
  ...(globalThis.GREATWAIT_API_REQUEST_REGISTRY
2114
2238
  ? {}
2115
2239
  : { responseHeaders: replayedResponseHeaderSchema }),
@@ -2124,7 +2248,7 @@ export const OPERATIONS = [
2124
2248
  creates: false,
2125
2249
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
2126
2250
  ? ""
2127
- : "Reads one schedule and its next occurrence from the partition that owns it. A schedule belonging to another organization, project or environment answers not_found rather than a refusal that would confirm it exists. The response carries the schedule's version as a strong ETag; send it back in `If-Match` to make a later write conditional on nothing having changed in between. The response carries the schedule's `data` when it has one, exactly as it was given; the listing leaves it off.",
2251
+ : "Reads one schedule and its next occurrence from the partition that owns it. A schedule belonging to another organization, project or environment answers not_found rather than a refusal that would confirm it exists. The response carries the schedule's version as a strong ETag; send it back in `If-Match` to make a later write conditional on nothing having changed in between. The response carries the schedule's `data` when it has one, exactly as it was given; the listing leaves it off. Detail reads also include the custom JSON body; listings and mutation responses omit its content. HTTP settings expose ordinary values and configured secret markers, never secret values.",
2128
2252
  example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
2129
2253
  ? {}
2130
2254
  : {
@@ -2230,7 +2354,7 @@ export const OPERATIONS = [
2230
2354
  creates: false,
2231
2355
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
2232
2356
  ? ""
2233
- : "Counts the occurrences this project and environment expect to fire, in epoch-aligned time buckets, with a latency-class split on every bucket and an optional customer partition-key breakdown. A recurring series contributes every instant it fires inside the window rather than only its next one, and `nextFireCount` reports how many of a bucket's occurrences are a schedule's next firing. The answer states its own freshness and is refused rather than shortened when a partition cannot complete it. It carries counts only: no schedule identifier, callback destination, payload or endpoint detail has a field in the response.",
2357
+ : "Counts the occurrences this project and environment expect to fire, in epoch-aligned time buckets, with a latency-class split on every bucket and an optional customer partition-key breakdown. A recurring series contributes every instant it fires inside the window rather than only its next one, and `nextFireCount` reports how many of a bucket's occurrences are a schedule's next firing. The answer states freshness and explicit coverage. Clients sending X-Greatwait-Accept-Partial-Forecast: true receive bounded lower-bound counts when a book reaches a row, cell or recurrence-work bound, with coverage.complete false and the exact bounds reached. Without this capability header the previous refusal behavior remains safe for clients that only read totals. Unavailable or stale sources still refuse. Coverage identifies the selected recurring schedule range but never includes destinations, payload or endpoint detail.",
2234
2358
  example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
2235
2359
  ? {}
2236
2360
  : {
@@ -2255,6 +2379,7 @@ export const OPERATIONS = [
2255
2379
  to: "2026-07-29T15:00:00.000Z",
2256
2380
  },
2257
2381
  },
2382
+ requestHeaders: forecastRequestHeadersSchema,
2258
2383
  id: "forecast.read",
2259
2384
  idempotent: true,
2260
2385
  mcp: { destructive: false, kind: "tool", openWorld: false },
@@ -2278,7 +2403,7 @@ export const OPERATIONS = [
2278
2403
  creates: false,
2279
2404
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
2280
2405
  ? ""
2281
- : "Reads the verified principal's organization-wide prepaid execution position from the authoritative PostgreSQL ledger. Desired and effective revisions remain distinct, and pending stays true until D1 records PostgreSQL confirmation. Amounts are exact integer microdollars encoded as decimal strings; currency is USD and scale is six. Reserved credit has already been committed to a logical attempt but is not yet a settled debit. A missing hard cap means the customer elected no execution spending cap, never zero room. Shadow mode records what enforcement would have done without charging or blocking, and the activation boundary prevents retroactive charges.",
2406
+ : "Reads the verified principal's organization-wide prepaid execution position from the authoritative PostgreSQL ledger. Desired and effective revisions remain distinct, and pending stays true until the control plane records PostgreSQL confirmation. Amounts are exact integer microdollars encoded as decimal strings; currency is USD and scale is six. Reserved credit has already been committed to a logical attempt but is not yet a settled debit. A missing hard cap means the customer elected no execution spending cap, never zero room. Shadow mode records what enforcement would have done without charging or blocking, and the activation boundary prevents retroactive charges.",
2282
2407
  example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
2283
2408
  ? {}
2284
2409
  : BILLING_SUMMARY_EXAMPLE,
@@ -2289,7 +2414,7 @@ export const OPERATIONS = [
2289
2414
  mutates: false,
2290
2415
  path: "/v1/billing/summary",
2291
2416
  principals: ["api-credential", "oauth", "session"],
2292
- problems: [],
2417
+ problems: ["billing_not_ready", "service_unavailable"],
2293
2418
  response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2294
2419
  ? API_UNUSED_RESPONSE_SCHEMA
2295
2420
  : billingSummarySchema,
@@ -2405,6 +2530,32 @@ export const OPERATIONS = [
2405
2530
  : "Confirm manual execution funding",
2406
2531
  surfaces: ["api", "mock"],
2407
2532
  }),
2533
+ withBillingFundingContract({
2534
+ creates: false,
2535
+ description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
2536
+ ? ""
2537
+ : "Confirms one execution-credit payment or saved-payment-method setup now, typically when the customer returns from hosted Checkout, instead of waiting for the provider's notification or the scheduled repair. It reads that one operation from the payment provider under the caller organization's authenticated account and applies what the provider reports: a paid Checkout grants its exact credit once, an open or unpaid one stays pending, and an operation already settled is answered without reading the provider. Nothing in the request can claim a payment succeeded — it names only which operation to read. Repeating the call is safe and converges on the same state. Returns the same execution-funding position as billing.funding.",
2538
+ environments: ["live"],
2539
+ id: "billing.fundingconfirm",
2540
+ idempotent: true,
2541
+ mcp: { destructive: false, kind: "tool", openWorld: false },
2542
+ method: "POST",
2543
+ mutates: true,
2544
+ path: "/v1/billing/funding/{paymentOperation}/confirm",
2545
+ principals: ["api-credential", "oauth", "session"],
2546
+ problems: [
2547
+ "not_found",
2548
+ "service_unavailable",
2549
+ "state_conflict",
2550
+ "test_to_live_escalation",
2551
+ ],
2552
+ scopes: ["billing:write"],
2553
+ sessionAuthority: "headers",
2554
+ summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2555
+ ? ""
2556
+ : "Confirm one payment with the provider now",
2557
+ surfaces: ["api", "mock"],
2558
+ }),
2408
2559
  withBillingFundingContract({
2409
2560
  creates: false,
2410
2561
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
@@ -2455,7 +2606,7 @@ export const OPERATIONS = [
2455
2606
  creates: true,
2456
2607
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
2457
2608
  ? ""
2458
- : "Records an explicitly approved billing-owner request for operator review of unused purchased execution credit. It never submits a refund, cashes out credit or grants an MCP cash-out path; the Idempotency-Key preserves one request across retries. Trial credit has no cash value, provider submission remains an operator action, and any later refund does not restore automatic purchasing authority for the month.",
2609
+ : "Reserves unused purchased execution credit against one original payment, with the billing owner's explicit confirmation. Purchased credit is not refundable except where a charge is refunded because the service did not work as described, so this records no promise of a refund: it never calls Stripe, cashes out credit or grants an MCP cash-out path. A Stripe refund of that payment settles the reservation when it carries the same credit and supersedes it otherwise; the Idempotency-Key preserves one reservation across retries. Trial credit has no cash value, and a refund does not restore automatic purchasing authority used in the month.",
2459
2610
  environments: ["live"],
2460
2611
  example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
2461
2612
  ? {}
@@ -2472,7 +2623,14 @@ export const OPERATIONS = [
2472
2623
  method: "POST",
2473
2624
  mutates: true,
2474
2625
  path: "/v1/billing/funding/refunds",
2475
- principals: ["api-credential", "oauth", "session"],
2626
+ // **No browser session** (W9-09). The dashboard's refund request and
2627
+ // refund review forms were an operator's procedure rendered on a customer's
2628
+ // home screen, and they are gone; refunds are a conversation with support.
2629
+ // The operation is unchanged for an API credential and OAuth — the CLI's
2630
+ // `billing refund-request` — and a session write nothing calls is an
2631
+ // authorization path nobody exercises, which `workspace-mutations.test.ts`
2632
+ // exists to refuse.
2633
+ principals: ["api-credential", "oauth"],
2476
2634
  problems: [
2477
2635
  "idempotency_key_reused",
2478
2636
  "invalid_request",
@@ -2499,17 +2657,16 @@ export const OPERATIONS = [
2499
2657
  ? {}
2500
2658
  : { responseHeaders: idempotencyReplayResponseHeaderSchema }),
2501
2659
  scopes: ["billing:write"],
2502
- sessionAuthority: "headers",
2503
2660
  summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2504
2661
  ? ""
2505
- : "Request operator-reviewed refund",
2662
+ : "Reserve credit against a payment for refund",
2506
2663
  surfaces: ["api", "mock"],
2507
2664
  },
2508
2665
  withBillingFundingContract({
2509
2666
  creates: false,
2510
2667
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
2511
2668
  ? ""
2512
- : "Records an already-made external operator decision on a pending unused-credit refund request. Completion verifies an existing Stripe refund by authenticated provider read before applying the exact credit, tax and gross adjustment; it never creates a provider refund. Decline releases the reserved credit without contacting the provider. The Idempotency-Key makes either decision converge across retries.",
2669
+ : "Completes or declines a pending refund reservation. Completion verifies an existing Stripe refund by authenticated provider read before applying the exact credit, tax and gross adjustment, and converges on the recorded adjustment when that refund already settled the reservation; it never creates a provider refund. Decline releases the reserved credit without contacting the provider, and a reservation a Stripe refund superseded is refused as a state conflict. The Idempotency-Key makes either outcome converge across retries.",
2513
2670
  environments: ["live"],
2514
2671
  id: "billing.refundresolution",
2515
2672
  idempotent: true,
@@ -2517,7 +2674,14 @@ export const OPERATIONS = [
2517
2674
  method: "PATCH",
2518
2675
  mutates: true,
2519
2676
  path: "/v1/billing/funding/refunds/{refundRequest}",
2520
- principals: ["api-credential", "oauth", "session"],
2677
+ // **No browser session** (W9-09). The dashboard's refund request and
2678
+ // refund review forms were an operator's procedure rendered on a customer's
2679
+ // home screen, and they are gone; refunds are a conversation with support.
2680
+ // The operation is unchanged for an API credential and OAuth — the CLI's
2681
+ // `billing refund-request` — and a session write nothing calls is an
2682
+ // authorization path nobody exercises, which `workspace-mutations.test.ts`
2683
+ // exists to refuse.
2684
+ principals: ["api-credential", "oauth"],
2521
2685
  problems: [
2522
2686
  "idempotency_key_reused",
2523
2687
  "invalid_request",
@@ -2539,10 +2703,9 @@ export const OPERATIONS = [
2539
2703
  ? {}
2540
2704
  : { responseHeaders: idempotencyReplayResponseHeaderSchema }),
2541
2705
  scopes: ["billing:write"],
2542
- sessionAuthority: "headers",
2543
2706
  summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2544
2707
  ? ""
2545
- : "Record a reviewed refund decision",
2708
+ : "Complete or decline a refund reservation",
2546
2709
  surfaces: ["api", "mock"],
2547
2710
  }),
2548
2711
  {
@@ -2695,6 +2858,209 @@ export const OPERATIONS = [
2695
2858
  "test_to_live_escalation",
2696
2859
  ],
2697
2860
  },
2861
+ {
2862
+ creates: false,
2863
+ description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
2864
+ ? ""
2865
+ : "Reads the verified organization's saved payment method: the one method automatic execution top-ups and project subscriptions charge. It is the payment provider's default payment method for the organization, read by authenticated provider call. method says what it is — type card with brand, last four digits and expiry; type link with the email Link reports, when it reports one; or type other with the provider's type name (cashapp, amazon_pay, klarna and the like) — and every variant carries label, the name to show a person. card repeats the card details when the method is a card and is null otherwise; it is kept for clients written before other payment methods were accepted. A method the organization already authorized for automatic top-up or a project subscription is adopted as the saved method, so an existing customer is not told they have none. method and card are null when the organization has none.",
2866
+ example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
2867
+ ? {}
2868
+ : {
2869
+ card: { brand: "visa", expMonth: 12, expYear: 2030, last4: "4242" },
2870
+ method: {
2871
+ brand: "visa",
2872
+ expMonth: 12,
2873
+ expYear: 2030,
2874
+ label: "Visa ending in 4242",
2875
+ last4: "4242",
2876
+ type: "card",
2877
+ },
2878
+ },
2879
+ id: "billing.paymentmethod",
2880
+ idempotent: true,
2881
+ mcp: { destructive: false, kind: "tool", openWorld: false },
2882
+ method: "GET",
2883
+ mutates: false,
2884
+ path: "/v1/billing/payment-method",
2885
+ principals: ["api-credential", "oauth", "session"],
2886
+ problems: ["service_unavailable"],
2887
+ response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2888
+ ? API_UNUSED_RESPONSE_SCHEMA
2889
+ : billingPaymentMethodSchema,
2890
+ scopes: ["usage:read"],
2891
+ sessionAuthority: "headers",
2892
+ summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2893
+ ? ""
2894
+ : "Read the saved payment method",
2895
+ surfaces: ["api", "mock"],
2896
+ },
2897
+ {
2898
+ creates: false,
2899
+ description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
2900
+ ? ""
2901
+ : "Lists the verified organization's project subscription charges: the payment provider's invoices for its project subscription, read by authenticated provider call, most recent first and at most 24. Execution-credit purchases are not listed here; billing.funding reports them. Draft and zero-amount invoices are omitted. Each amount is the invoice total including tax, and the receipt link, when present, is the provider-hosted invoice page. An organization that has never been billed has an empty list; reading it creates nothing and changes nothing.",
2902
+ example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
2903
+ ? {}
2904
+ : {
2905
+ data: [
2906
+ {
2907
+ amount: {
2908
+ currency: "USD",
2909
+ microdollars: "5000000",
2910
+ scale: 6,
2911
+ },
2912
+ createdAt: "2026-09-01T12:00:00.000Z",
2913
+ id: "in_example_project_charge",
2914
+ receiptUrl: "https://invoice.stripe.com/i/acct_example/example",
2915
+ state: "paid",
2916
+ },
2917
+ ],
2918
+ },
2919
+ id: "billing.invoices",
2920
+ idempotent: true,
2921
+ mcp: { destructive: false, kind: "tool", openWorld: false },
2922
+ method: "GET",
2923
+ mutates: false,
2924
+ path: "/v1/billing/invoices",
2925
+ principals: ["api-credential", "oauth", "session"],
2926
+ problems: ["service_unavailable"],
2927
+ response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2928
+ ? API_UNUSED_RESPONSE_SCHEMA
2929
+ : billingInvoiceListSchema,
2930
+ scopes: ["usage:read"],
2931
+ sessionAuthority: "headers",
2932
+ summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2933
+ ? ""
2934
+ : "List project subscription charges",
2935
+ surfaces: ["api", "mock"],
2936
+ },
2937
+ {
2938
+ creates: false,
2939
+ description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
2940
+ ? ""
2941
+ : "Creates a short-lived provider-hosted payment-method setup session for the verified organization and returns its address. It offers every payment method the provider account enables that can be charged later without the customer present — cards, Link and others. Saving one there charges nothing; it becomes the saved payment method only once billing.paymentmethodconfirm (when the browser returns) or the provider's notification reads the completed setup by authenticated provider call. An optional return address must share the origin of the configured billing page.",
2942
+ environments: ["live"],
2943
+ example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
2944
+ ? {}
2945
+ : { url: "https://checkout.stripe.com/c/pay/example-card-setup" },
2946
+ id: "billing.paymentmethodsetup",
2947
+ idempotent: false,
2948
+ mcp: { destructive: false, kind: "tool", openWorld: false },
2949
+ method: "POST",
2950
+ mutates: true,
2951
+ path: "/v1/billing/payment-method/setup",
2952
+ principals: ["api-credential", "oauth", "session"],
2953
+ problems: [
2954
+ "invalid_request",
2955
+ "service_unavailable",
2956
+ "state_conflict",
2957
+ "not_found",
2958
+ "revision_conflict",
2959
+ "test_to_live_escalation",
2960
+ ],
2961
+ request: billingPaymentMethodSetupRequestSchema,
2962
+ requestExample: globalThis
2963
+ .GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
2964
+ ? {}
2965
+ : {},
2966
+ response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2967
+ ? API_UNUSED_RESPONSE_SCHEMA
2968
+ : billingPortalSchema,
2969
+ scopes: ["billing:write"],
2970
+ sessionAuthority: "headers",
2971
+ summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2972
+ ? ""
2973
+ : "Start saving a payment method",
2974
+ surfaces: ["api", "mock"],
2975
+ },
2976
+ {
2977
+ creates: false,
2978
+ description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
2979
+ ? ""
2980
+ : "Makes the payment method saved in one completed hosted setup the organization's saved payment method, typically when the browser returns from it. The session is read by authenticated provider call and must belong to the verified organization's own customer; a session of another organization is answered not found. It becomes the provider default for invoices, the default of the organization's project subscription, and the automatic top-up payment method — readying a top-up rule that was waiting for one. The response has the shape billing.paymentmethod returns. When the previous method was removed (billing.paymentmethodremove) and the paid period it let run out has not ended, renewal resumes for the projects that removal stopped; a project the customer cancelled themselves stays cancelled. Nothing in the request can claim a setup succeeded, and repeating the call is safe.",
2981
+ environments: ["live"],
2982
+ example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
2983
+ ? {}
2984
+ : {
2985
+ card: { brand: "visa", expMonth: 12, expYear: 2030, last4: "4242" },
2986
+ method: {
2987
+ brand: "visa",
2988
+ expMonth: 12,
2989
+ expYear: 2030,
2990
+ label: "Visa ending in 4242",
2991
+ last4: "4242",
2992
+ type: "card",
2993
+ },
2994
+ },
2995
+ id: "billing.paymentmethodconfirm",
2996
+ idempotent: true,
2997
+ mcp: { destructive: false, kind: "tool", openWorld: false },
2998
+ method: "POST",
2999
+ mutates: true,
3000
+ path: "/v1/billing/payment-method/confirm",
3001
+ principals: ["api-credential", "oauth", "session"],
3002
+ problems: [
3003
+ "invalid_request",
3004
+ "not_found",
3005
+ "service_unavailable",
3006
+ "state_conflict",
3007
+ "revision_conflict",
3008
+ "test_to_live_escalation",
3009
+ ],
3010
+ request: billingPaymentMethodConfirmRequestSchema,
3011
+ requestExample: globalThis
3012
+ .GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
3013
+ ? {}
3014
+ : { checkoutSession: "cs_example_card_setup" },
3015
+ response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
3016
+ ? API_UNUSED_RESPONSE_SCHEMA
3017
+ : billingPaymentMethodSchema,
3018
+ scopes: ["billing:write"],
3019
+ sessionAuthority: "headers",
3020
+ summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
3021
+ ? ""
3022
+ : "Confirm a saved payment method",
3023
+ surfaces: ["api", "mock"],
3024
+ },
3025
+ {
3026
+ creates: false,
3027
+ description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
3028
+ ? ""
3029
+ : "Removes the verified organization's saved payment method, and with it everything that charges it. Removing it stops renewal: every project subscription is set to end at the end of the period already paid for, so paid projects keep running until then and then stop, with nothing refunded and nothing more charged; billing.projects shows each one's cancellationAt. The included free project is unaffected. Automatic top-up turns off immediately and forgets its payment method. A pending or declined project addition is ended, so nothing later starts a checkout or a charge, and no project can be added until a payment method is saved again. The method stops being the provider default and is detached from the organization's customer. The request must carry confirmed: true. Repeating the call is safe: with nothing on file it answers a null method and card and still makes sure nothing is left that could charge one. Saving a payment method through billing.paymentmethodsetup before the period ends keeps those projects: renewal resumes on the new method, except for any project the customer cancelled themselves. After the period ends, a paid project must be added again.",
3030
+ environments: ["live"],
3031
+ example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
3032
+ ? {}
3033
+ : { card: null, method: null },
3034
+ id: "billing.paymentmethodremove",
3035
+ idempotent: true,
3036
+ mcp: { destructive: true, kind: "tool", openWorld: false },
3037
+ method: "POST",
3038
+ mutates: true,
3039
+ path: "/v1/billing/payment-method/remove",
3040
+ principals: ["api-credential", "oauth", "session"],
3041
+ problems: [
3042
+ "invalid_request",
3043
+ "not_found",
3044
+ "service_unavailable",
3045
+ "state_conflict",
3046
+ "revision_conflict",
3047
+ "test_to_live_escalation",
3048
+ ],
3049
+ request: billingPaymentMethodRemoveRequestSchema,
3050
+ requestExample: globalThis
3051
+ .GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
3052
+ ? {}
3053
+ : { confirmed: true },
3054
+ response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
3055
+ ? API_UNUSED_RESPONSE_SCHEMA
3056
+ : billingPaymentMethodSchema,
3057
+ scopes: ["billing:write"],
3058
+ sessionAuthority: "headers",
3059
+ summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
3060
+ ? ""
3061
+ : "Remove the saved payment method",
3062
+ surfaces: ["api", "mock"],
3063
+ },
2698
3064
  {
2699
3065
  creates: false,
2700
3066
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
@@ -2711,7 +3077,16 @@ export const OPERATIONS = [
2711
3077
  mutates: true,
2712
3078
  path: "/v1/billing/reconcile",
2713
3079
  principals: ["api-credential", "oauth", "session"],
2714
- problems: ["service_unavailable", "test_to_live_escalation"],
3080
+ // `billing.reconcile` answers from the same summary read as
3081
+ // `billing.summary`, so it reaches the same not-provisioned refusal. It is
3082
+ // declared here because an integrator reading the published OpenAPI would
3083
+ // otherwise be told a 503 on this operation can only ever be
3084
+ // `service_unavailable`.
3085
+ problems: [
3086
+ "billing_not_ready",
3087
+ "service_unavailable",
3088
+ "test_to_live_escalation",
3089
+ ],
2715
3090
  response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
2716
3091
  ? API_UNUSED_RESPONSE_SCHEMA
2717
3092
  : billingSummarySchema,
@@ -2838,6 +3213,44 @@ export const OPERATIONS = [
2838
3213
  : "List immutable billing entries",
2839
3214
  surfaces: ["api", "mock"],
2840
3215
  },
3216
+ {
3217
+ creates: false,
3218
+ description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
3219
+ ? ""
3220
+ : "Read effective customer allowances for the verified organization. Deployment and organization revisions identify the policy used; infrastructure and other organizations' settings are excluded.",
3221
+ example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
3222
+ ? {}
3223
+ : {
3224
+ limits: {
3225
+ inlinePayloadBytes: 65536,
3226
+ forecastHorizonSeconds: 90000,
3227
+ usageWindowDays: 366,
3228
+ },
3229
+ provenance: {
3230
+ inlinePayloadBytes: "default",
3231
+ forecastHorizonSeconds: "default",
3232
+ usageWindowDays: "default",
3233
+ },
3234
+ revision: { global: 0, organization: 0 },
3235
+ },
3236
+ id: "limits.read",
3237
+ idempotent: true,
3238
+ mcp: { destructive: false, kind: "tool", openWorld: false },
3239
+ method: "GET",
3240
+ mutates: false,
3241
+ path: "/v1/limits",
3242
+ principals: ["api-credential", "oauth", "session"],
3243
+ problems: ["service_unavailable"],
3244
+ response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
3245
+ ? API_UNUSED_RESPONSE_SCHEMA
3246
+ : effectiveCustomerLimitsSchema,
3247
+ scopes: ["schedules:read"],
3248
+ sessionAuthority: "headers",
3249
+ summary: globalThis.GREATWAIT_API_REQUEST_REGISTRY
3250
+ ? ""
3251
+ : "Read effective customer limits",
3252
+ surfaces: ["api", "mock"],
3253
+ },
2841
3254
  {
2842
3255
  creates: false,
2843
3256
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
@@ -2972,7 +3385,7 @@ export const OPERATIONS = [
2972
3385
  // scheduled for removal, which is the opposite of what a tool list is for.
2973
3386
  mcp: {
2974
3387
  kind: "unavailable",
2975
- reason: "A transitional shape for the autoscaler migration, scheduled for withdrawal once W6-02 has cut over. forecast.read is the same data in the shape this product publishes, and it is the tool an agent should reach for.",
3388
+ reason: "A transitional shape for the autoscaler migration, withdrawn after its cutover. forecast.read is the same data in the shape this product publishes, and it is the tool an agent should reach for.",
2976
3389
  },
2977
3390
  method: "GET",
2978
3391
  mutates: false,
@@ -3127,6 +3540,8 @@ export const OPERATIONS = [
3127
3540
  {
3128
3541
  attemptNumber: 1,
3129
3542
  classifiedAt: "2026-07-28T15:00:00.071Z",
3543
+ dispatchRecoveries: 0,
3544
+ localReceiptRecoveries: 0,
3130
3545
  delivery: "dlv_01h8xyz9k2m4n6p8r0t2v4w6y8",
3131
3546
  diagnostic: "http_retryable",
3132
3547
  durationMs: 71,
@@ -3176,6 +3591,8 @@ export const OPERATIONS = [
3176
3591
  attempt: {
3177
3592
  attemptNumber: 2,
3178
3593
  classifiedAt: "2026-07-28T15:02:00.000Z",
3594
+ dispatchRecoveries: 2,
3595
+ localReceiptRecoveries: 1,
3179
3596
  delivery: "dlv_11h8xyz9k2m4n6p8r0t2v4w6y8",
3180
3597
  diagnostic: "network_ambiguous",
3181
3598
  durationMs: 10_000,
@@ -3220,6 +3637,8 @@ export const OPERATIONS = [
3220
3637
  : {
3221
3638
  attempt: {
3222
3639
  attemptNumber: 3,
3640
+ dispatchRecoveries: 0,
3641
+ localReceiptRecoveries: 0,
3223
3642
  delivery: "dlv_21h8xyz9k2m4n6p8r0t2v4w6y8",
3224
3643
  id: "att_21h8xyz9k2m4n6p8r0t2v4w6y8",
3225
3644
  occurrence: "occ_01h8xyz9k2m4n6p8r0t2v4w6y8",
@@ -3263,7 +3682,7 @@ export const OPERATIONS = [
3263
3682
  creates: false,
3264
3683
  description: globalThis.GREATWAIT_RUNTIME_CONTRACTS_ONLY
3265
3684
  ? ""
3266
- : "Replaces a schedule's definition, starting a new generation. Takes the same four ways of saying when as a create, so a one-shot can be replaced by a recurring definition and the other way round. An omitted callback endpoint/data pair preserves the stored callback; sending `data` alone replaces the encrypted data for the current endpoint, and sending `endpoint` selects a verified endpoint in the same authority tuple. The occurrence planned under the old definition is settled `skipped_stale` and can never fire unless it was already in flight, in which case its immutable attempt is allowed to settle honestly; a fresh occurrence is planned under the new definition, and the old definition's series stops advancing. `lateness` is resolved afresh against the replacement recurrence: omit it for that kind's default, or state `skipAhead`, `catchUp`, and an optional `maxStalenessSeconds` override. The policy applies only before an occurrence's first attempt; a retry already in progress remains on its retry and give-up ladder. Send `If-Match` with the version you read to make this conditional; without it the replace is unconditional and the last writer wins. A cancelled or completed schedule cannot be replaced. `partitionKey` is fixed when the schedule is created: omit it to preserve the stored value or echo that exact value in a GET → modify → PUT flow. Adding, changing, or clearing it is refused as `invalid_request` with `/partitionKey` identified. `latencyClass` remains derived from the replacement recurrence when the caller omits it.",
3685
+ : "Replaces a schedule's definition, starting a new generation. Takes the same four ways of saying when as a create, so a one-shot can be replaced by a recurring definition and the other way round. An omitted callback endpoint/data pair preserves the stored callback; sending `data` alone replaces the encrypted data for the current endpoint, and sending `endpoint` selects a verified endpoint in the same authority tuple. Sending `url` instead selects the endpoint at that address in the same tuple, creating one silently when there is none; creating needs `endpoints:write` as well, and the response's `endpointSigningSecret` says where its signing secret is revealed. Omitted `http` preserves HTTP settings. Its headers are a patch: `set` replaces a value, `keep` retains a configured value, `suppress` omits an endpoint default, and `remove` resumes inheritance. Explicit GET with no body clears a saved custom template; POST/PUT with `body: { mode: 'envelope' }` restores the structured callback. The occurrence planned under the old definition is settled `skipped_stale` and can never fire unless it was already in flight, in which case its immutable attempt is allowed to settle honestly; a fresh occurrence is planned under the new definition, and the old definition's series stops advancing. `lateness` is resolved afresh against the replacement recurrence: omit it for that kind's default, or state `skipAhead`, `catchUp`, and an optional `maxStalenessSeconds` override. The policy applies only before an occurrence's first attempt; a retry already in progress remains on its retry and give-up ladder. Send `If-Match` with the version you read to make this conditional; without it the replace is unconditional and the last writer wins. A cancelled or completed schedule cannot be replaced. `partitionKey` is fixed when the schedule is created: omit it to preserve the stored value or echo that exact value in a GET → modify → PUT flow. Adding, changing, or clearing it is refused as `invalid_request` with `/partitionKey` identified. `latencyClass` remains derived from the replacement recurrence when the caller omits it.",
3267
3686
  example: globalThis.GREATWAIT_RUNTIME_WITHOUT_EXAMPLES
3268
3687
  ? {}
3269
3688
  : {
@@ -3299,6 +3718,9 @@ export const OPERATIONS = [
3299
3718
  method: "PUT",
3300
3719
  mutates: true,
3301
3720
  path: "/v1/schedules/{scheduleId}",
3721
+ // Creating the endpoint a `url` names is an endpoint write (W9-44).
3722
+ conditionalScopes: ["endpoints:write"],
3723
+ conditionalScopesWhen: "the request names a `url` this project and environment has no endpoint at yet",
3302
3724
  principals: ["api-credential", "oauth", "session"],
3303
3725
  problems: [
3304
3726
  "invalid_request",
@@ -3307,6 +3729,8 @@ export const OPERATIONS = [
3307
3729
  // schedule and cannot change `partitionKey`, so neither counted ceiling
3308
3730
  // can move; what it can do is carry a larger body than the plan admits.
3309
3731
  "plan_limit_reached",
3732
+ "rate_limited",
3733
+ "scope_missing",
3310
3734
  "service_unavailable",
3311
3735
  "state_conflict",
3312
3736
  "version_conflict",
@@ -3328,7 +3752,7 @@ export const OPERATIONS = [
3328
3752
  requestHeaders: conditionalRequestHeaderSchema,
3329
3753
  response: globalThis.GREATWAIT_API_REQUEST_REGISTRY
3330
3754
  ? API_UNUSED_RESPONSE_SCHEMA
3331
- : scheduleViewSchema,
3755
+ : scheduleWrittenViewSchema,
3332
3756
  ...(globalThis.GREATWAIT_API_REQUEST_REGISTRY
3333
3757
  ? {}
3334
3758
  : { responseHeaders: versionResponseHeaderSchema }),
@@ -3652,6 +4076,16 @@ export function successStatusFor(operation) {
3652
4076
  * so an operation's own `problems` list stays about that operation.
3653
4077
  */
3654
4078
  export const UNIVERSAL_PROBLEMS = [
4079
+ // **Universal rather than per-operation, because its earliest raise sites
4080
+ // are before any operation exists.** Request admission runs as pre-route
4081
+ // middleware on every `/v1/*`, `/oauth/*` and `/mcp` path, and the Worker
4082
+ // refuses an unconfigured PostgreSQL authority before it builds an app at
4083
+ // all. Declaring it operation by operation would leave the published
4084
+ // contract, the mock and the SDK telling an integrator that a 503 on those
4085
+ // paths can only be `service_unavailable` — which is the mistake a review
4086
+ // round caught when `billing_not_ready` was declared on one of its two
4087
+ // operations and not the other.
4088
+ "capability_not_configured",
3655
4089
  "rate_limited",
3656
4090
  "service_unavailable",
3657
4091
  ];