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

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 (84) hide show
  1. package/README.md +1 -1
  2. package/dist/billing.d.ts +231 -1
  3. package/dist/billing.js +150 -1
  4. package/dist/callback-safety.js +13 -3
  5. package/dist/configuration-bounds.d.ts +13 -0
  6. package/dist/configuration-bounds.js +13 -0
  7. package/dist/effective-limits.d.ts +40 -0
  8. package/dist/effective-limits.js +42 -0
  9. package/dist/endpoints.d.ts +5 -5
  10. package/dist/endpoints.js +5 -5
  11. package/dist/first-value-journey.d.ts +1 -1
  12. package/dist/first-value-journey.js +11 -7
  13. package/dist/forecast.d.ts +111 -21
  14. package/dist/forecast.js +87 -24
  15. package/dist/index.d.ts +5 -4
  16. package/dist/index.js +5 -4
  17. package/dist/mcp.js +1 -1
  18. package/dist/operational-config.d.ts +101 -0
  19. package/dist/operational-config.js +341 -0
  20. package/dist/operations.d.ts +597 -16
  21. package/dist/operations.js +384 -23
  22. package/dist/partition.d.ts +17 -9
  23. package/dist/partition.js +3 -3
  24. package/dist/problems.d.ts +25 -2
  25. package/dist/problems.js +49 -1
  26. package/dist/protocol.d.ts +5 -5
  27. package/dist/protocol.js +2 -1
  28. package/dist/scheduling-records.d.ts +6 -0
  29. package/dist/scheduling.d.ts +37 -1
  30. package/dist/scheduling.js +60 -4
  31. package/dist/usage.js +6 -21
  32. package/generated/v1/examples/attempts.list.response.json +2 -0
  33. package/generated/v1/examples/attempts.read.response.json +2 -0
  34. package/generated/v1/examples/billing.fundingconfirm.response.json +120 -0
  35. package/generated/v1/examples/billing.invoicehistory.response.json +6 -0
  36. package/generated/v1/examples/billing.invoices.response.json +15 -0
  37. package/generated/v1/examples/billing.paymenthistory.response.json +6 -0
  38. package/generated/v1/examples/billing.paymentmethod.response.json +16 -0
  39. package/generated/v1/examples/billing.paymentmethodconfirm.request.json +3 -0
  40. package/generated/v1/examples/billing.paymentmethodconfirm.response.json +16 -0
  41. package/generated/v1/examples/billing.paymentmethodremove.request.json +3 -0
  42. package/generated/v1/examples/billing.paymentmethodremove.response.json +4 -0
  43. package/generated/v1/examples/billing.paymentmethodsetup.request.json +1 -0
  44. package/generated/v1/examples/billing.paymentmethodsetup.response.json +3 -0
  45. package/generated/v1/examples/limits.read.response.json +16 -0
  46. package/generated/v1/examples/occurrences.redeliver.response.json +2 -0
  47. package/generated/v1/first-value-journey.json +24 -8
  48. package/generated/v1/manifest.json +342 -10
  49. package/generated/v1/openapi.json +12395 -6543
  50. package/generated/v1/policy-matrix.json +65 -2
  51. package/generated/v1/schemas/attempts.list.response.json +15 -0
  52. package/generated/v1/schemas/attempts.read.response.json +15 -0
  53. package/generated/v1/schemas/billing.fundingconfirm.response.json +552 -0
  54. package/generated/v1/schemas/billing.invoicehistory.query.json +16 -0
  55. package/generated/v1/schemas/billing.invoicehistory.response.json +88 -0
  56. package/generated/v1/schemas/billing.invoices.response.json +51 -0
  57. package/generated/v1/schemas/billing.ledger.response.json +5 -0
  58. package/generated/v1/schemas/billing.notificationsettingsupdate.request.json +24 -17
  59. package/generated/v1/schemas/billing.paymenthistory.query.json +16 -0
  60. package/generated/v1/schemas/billing.paymenthistory.response.json +182 -0
  61. package/generated/v1/schemas/billing.paymentmethod.response.json +137 -0
  62. package/generated/v1/schemas/billing.paymentmethodconfirm.request.json +14 -0
  63. package/generated/v1/schemas/billing.paymentmethodconfirm.response.json +137 -0
  64. package/generated/v1/schemas/billing.paymentmethodremove.request.json +12 -0
  65. package/generated/v1/schemas/billing.paymentmethodremove.response.json +137 -0
  66. package/generated/v1/schemas/billing.paymentmethodsetup.request.json +12 -0
  67. package/generated/v1/schemas/billing.paymentmethodsetup.response.json +11 -0
  68. package/generated/v1/schemas/billing.purchase.request.json +4 -0
  69. package/generated/v1/schemas/forecast.read.request-headers.json +10 -0
  70. package/generated/v1/schemas/forecast.read.response.json +148 -0
  71. package/generated/v1/schemas/limits.read.response.json +79 -0
  72. package/generated/v1/schemas/occurrences.redeliver.response.json +15 -0
  73. package/generated/v1/snippets/billing.fundingconfirm.json +6 -0
  74. package/generated/v1/snippets/billing.invoicehistory.json +6 -0
  75. package/generated/v1/snippets/billing.invoices.json +6 -0
  76. package/generated/v1/snippets/billing.notificationsettingsupdate.json +1 -1
  77. package/generated/v1/snippets/billing.paymenthistory.json +6 -0
  78. package/generated/v1/snippets/billing.paymentmethod.json +6 -0
  79. package/generated/v1/snippets/billing.paymentmethodconfirm.json +6 -0
  80. package/generated/v1/snippets/billing.paymentmethodremove.json +6 -0
  81. package/generated/v1/snippets/billing.paymentmethodsetup.json +6 -0
  82. package/generated/v1/snippets/forecast.windows.json +1 -1
  83. package/generated/v1/snippets/limits.read.json +6 -0
  84. package/package.json +7 -2
@@ -6,7 +6,7 @@ import type { ProblemCode } from "./problems.js";
6
6
  *
7
7
  * **Declared once, here, because W9-03 is not the only story that has to tell
8
8
  * it.** The curl quickstart, the JavaScript quickstart, the website journey
9
- * W9-01 owns, the DocsAlot pages W9-04 publishes, and the command-line
9
+ * W9-01 owns, the documentation pages W9-04 publishes, and the command-line
10
10
  * ergonomics W10 owns are all the *same* sequence rendered for a different
11
11
  * reader. Written separately they diverge silently — the legacy scheduler's
12
12
  * hand-maintained client and documentation are the worked example, and the
@@ -109,20 +109,20 @@ export const CURL_JOURNEY_TOOLS = [
109
109
  ];
110
110
  export const FIRST_VALUE_PREREQUISITES = [
111
111
  {
112
- action: "Accept your Greatwait invitation, sign in, and create a project in the dashboard.",
112
+ action: "Accept your GreatWait invitation, sign in, and create a project in the dashboard.",
113
113
  because: "projects.create accepts only a signed-in member, so a project is created by a person rather than by an API credential.",
114
114
  id: "project",
115
115
  title: "A project",
116
116
  },
117
117
  {
118
- action: "In that project, create an API credential and copy the secret it shows once.",
118
+ action: "In that project, create an API credential with endpoints:write, occurrences:read, schedules:read and schedules:write, and copy the secret it shows once. The key picker starts with nothing selected and refuses an empty one, so those four are the boxes to tick.",
119
119
  because: "credentials.create accepts only a signed-in member: a credential that could mint another credential would make revoking one meaningless.",
120
120
  id: "credential",
121
121
  title: "An API credential",
122
122
  },
123
123
  {
124
124
  action: "Have an HTTPS URL of your own that answers POST with a 2xx status, and can be reached from the public internet.",
125
- because: "Greatwait delivers your callback to an address you control. It does not offer a shared receiver to try, and it will not send your payload to a third-party inspection service on your behalf.",
125
+ because: "GreatWait delivers your callback to an address you control. It does not offer a shared receiver to try, and it will not send your payload to a third-party inspection service on your behalf.",
126
126
  id: "receiver",
127
127
  title: "An HTTPS receiver you control",
128
128
  },
@@ -190,7 +190,7 @@ export const FIRST_VALUE_STEPS = [
190
190
  key: "check-service",
191
191
  observe: "The service name and the environment you meant to work in. If the environment is not the one you expect, stop and fix GREATWAIT_API_URL before creating anything.",
192
192
  operationId: "meta.version",
193
- purpose: "Confirms the origin you are pointed at is a Greatwait API and says which environment it serves. It needs no credential, so it separates 'wrong URL' from 'wrong key'.",
193
+ purpose: "Confirms the origin you are pointed at is a GreatWait API and says which environment it serves. It needs no credential, so it separates 'wrong URL' from 'wrong key'.",
194
194
  recovery: [
195
195
  {
196
196
  nextMove: "Something answered, but not this service. Check GREATWAIT_API_URL — a 404 here comes from a proxy in front of the API rather than from the API, so it carries no problem document to read.",
@@ -235,7 +235,7 @@ export const FIRST_VALUE_STEPS = [
235
235
  { from: "id", variable: "GREATWAIT_ENDPOINTID" },
236
236
  { from: "secret", secret: true, variable: "GREATWAIT_ENDPOINT_SECRET" },
237
237
  ],
238
- observe: "An endpoint identifier, and a signing secret returned by this call and by no other. Store the secret now: reading the endpoint back later will not show it again.",
238
+ observe: "An endpoint identifier, and a signing secret. Store it now: this is the only call that returns it, and reading the endpoint back shows a redacted prefix instead. It is not gone if you lose it — a signed-in member can read it again on the endpoint's own page in the dashboard, which is the one caller `endpoints.revealSigningSecret` accepts.",
239
239
  operationId: "endpoints.create",
240
240
  purpose: "Registers the address every occurrence of this schedule is delivered to, and mints the per-endpoint signing key your receiver verifies callbacks with.",
241
241
  recovery: [
@@ -247,6 +247,10 @@ export const FIRST_VALUE_STEPS = [
247
247
  nextMove: "This project is at its destination ceiling. Disable a destination you no longer deliver to; disabled ones still count, because they stay readable for audit.",
248
248
  when: "plan_limit_reached",
249
249
  },
250
+ {
251
+ nextMove: "An active destination already delivers to this address in this project — usually one a previous run of this journey created. Reuse that destination, disable it first, or give the new one a name of its own.",
252
+ when: "state_conflict",
253
+ },
250
254
  ],
251
255
  request: { url: "{{GREATWAIT_RECEIVER_URL}}" },
252
256
  title: "Create the destination",
@@ -278,7 +282,7 @@ export const FIRST_VALUE_STEPS = [
278
282
  when: "invalid_request",
279
283
  },
280
284
  {
281
- nextMove: "This organization is at a plan ceiling — live schedules, distinct partition keys, or payload size. Nothing was created; reduce the payload or archive a schedule and retry.",
285
+ nextMove: "This organization is at a plan ceiling — the payload is larger than its plan carries, or the schedule names a new partition key when the organization's keys are full. Nothing was created; send a smaller payload or reuse a partition key that is already live, and retry.",
282
286
  when: "plan_limit_reached",
283
287
  },
284
288
  {
@@ -375,7 +379,7 @@ export const FIRST_VALUE_STEPS = [
375
379
  when: "attempt-failed",
376
380
  },
377
381
  {
378
- nextMove: "Nothing reached your receiver. Confirm the URL answers a POST from the public internet, and that it is not behind an allowlist Greatwait is not on.",
382
+ nextMove: "Nothing reached your receiver. Confirm the URL answers a POST from the public internet, and that it is not behind an allowlist GreatWait is not on.",
379
383
  when: "receiver-unreachable",
380
384
  },
381
385
  ],
@@ -53,10 +53,11 @@ export declare const FORECAST_BOUNDS: {
53
53
  * argument for refusing rather than under-reporting collapses if staleness is
54
54
  * the one degradation that gets through as a number.
55
55
  */
56
- readonly maxLagSeconds: 600;
56
+ readonly maxLagSeconds: number;
57
57
  /**
58
- * Instants one partition may project into a single snapshot before it reports
59
- * the answer as short.
58
+ * Actual recurrence work units (shared cron advances or interval-series
59
+ * calculations) before a partition reports the answer as short. Output-cell
60
+ * allocation is bounded independently by maxGroupsPerPartition.
60
61
  *
61
62
  * Published rather than kept internal so a refusal is classifiable: a shadow
62
63
  * comparison that sees a refusal needs to be able to tell "we are near a
@@ -83,7 +84,7 @@ export declare const FORECAST_BOUNDS: {
83
84
  * an incident. `freshness.lagSeconds` reports the actual age on every answer;
84
85
  * this is the bound it lives inside.
85
86
  */
86
- readonly refreshCeilingSeconds: 300;
87
+ readonly refreshCeilingSeconds: number;
87
88
  /**
88
89
  * Shortest gap between refreshes once something *has* been written.
89
90
  *
@@ -92,7 +93,7 @@ export declare const FORECAST_BOUNDS: {
92
93
  * projection that rebuilt on every poll would be the cost this whole design
93
94
  * exists to avoid.
94
95
  */
95
- readonly refreshFloorSeconds: 30;
96
+ readonly refreshFloorSeconds: number;
96
97
  /**
97
98
  * How far below `now` a window may begin.
98
99
  *
@@ -102,7 +103,7 @@ export declare const FORECAST_BOUNDS: {
102
103
  * because the caller's `now` is a second behind. Further back than that is a
103
104
  * question about the past, which a forecast does not answer.
104
105
  */
105
- readonly slackSeconds: 120;
106
+ readonly slackSeconds: number;
106
107
  /**
107
108
  * Customer keys named individually in one bucket before the rest are summed.
108
109
  *
@@ -214,7 +215,106 @@ export declare const forecastBucketSchema: import("zod").ZodObject<{
214
215
  start: import("zod").ZodString;
215
216
  }, import("zod/v4/core").$strip>;
216
217
  export type ForecastBucket = z.infer<typeof forecastBucketSchema>;
218
+ /** Capability opt-in prevents old clients that read only counts from mistaking
219
+ * a lower bound for complete work. Older servers safely ignore this header. */
220
+ export declare const FORECAST_PARTIAL_ACCEPT_HEADER = "X-Greatwait-Accept-Partial-Forecast";
221
+ export declare const forecastRequestHeadersSchema: import("zod").ZodObject<{
222
+ "X-Greatwait-Accept-Partial-Forecast": import("zod").ZodOptional<import("zod").ZodLiteral<"true">>;
223
+ }, import("zod/v4/core").$strip>;
224
+ export declare const forecastCoverageSchema: import("zod").ZodObject<{
225
+ complete: import("zod").ZodBoolean;
226
+ countMeaning: import("zod").ZodEnum<{
227
+ "complete-total": "complete-total";
228
+ "lower-bound": "lower-bound";
229
+ }>;
230
+ projectedWindow: import("zod").ZodObject<{
231
+ from: import("zod").ZodString;
232
+ to: import("zod").ZodString;
233
+ }, import("zod/v4/core").$strip>;
234
+ completeThrough: import("zod").ZodString;
235
+ heads: import("zod").ZodObject<{
236
+ groupsRead: import("zod").ZodNumber;
237
+ occurrencesCounted: import("zod").ZodNumber;
238
+ complete: import("zod").ZodBoolean;
239
+ selection: import("zod").ZodLiteral<"earliest bucket, latency class, partition key groups">;
240
+ lastGroup: import("zod").ZodOptional<import("zod").ZodObject<{
241
+ start: import("zod").ZodString;
242
+ latencyClass: import("zod").ZodEnum<{
243
+ realtime: "realtime";
244
+ bulk: "bulk";
245
+ }>;
246
+ partitionKey: import("zod").ZodString;
247
+ }, import("zod/v4/core").$strip>>;
248
+ }, import("zod/v4/core").$strip>;
249
+ recurring: import("zod").ZodObject<{
250
+ schedulesRead: import("zod").ZodNumber;
251
+ populationComplete: import("zod").ZodBoolean;
252
+ selection: import("zod").ZodLiteral<"oldest eligible active recurring schedules by createdAt and scheduleId">;
253
+ firstScheduleId: import("zod").ZodOptional<import("zod").ZodString>;
254
+ lastScheduleId: import("zod").ZodOptional<import("zod").ZodString>;
255
+ }, import("zod/v4/core").$strip>;
256
+ work: import("zod").ZodObject<{
257
+ usedUnits: import("zod").ZodNumber;
258
+ limitUnits: import("zod").ZodNumber;
259
+ }, import("zod/v4/core").$strip>;
260
+ boundsReached: import("zod").ZodArray<import("zod").ZodObject<{
261
+ kind: import("zod").ZodEnum<{
262
+ "head-cells": "head-cells";
263
+ "recurring-series": "recurring-series";
264
+ "projection-work": "projection-work";
265
+ "projection-cells": "projection-cells";
266
+ }>;
267
+ limit: import("zod").ZodNumber;
268
+ }, import("zod/v4/core").$strip>>;
269
+ }, import("zod/v4/core").$strip>;
270
+ export type ForecastCoverage = z.infer<typeof forecastCoverageSchema>;
217
271
  export declare const forecastSchema: import("zod").ZodObject<{
272
+ coverage: import("zod").ZodOptional<import("zod").ZodObject<{
273
+ complete: import("zod").ZodBoolean;
274
+ countMeaning: import("zod").ZodEnum<{
275
+ "complete-total": "complete-total";
276
+ "lower-bound": "lower-bound";
277
+ }>;
278
+ projectedWindow: import("zod").ZodObject<{
279
+ from: import("zod").ZodString;
280
+ to: import("zod").ZodString;
281
+ }, import("zod/v4/core").$strip>;
282
+ completeThrough: import("zod").ZodString;
283
+ heads: import("zod").ZodObject<{
284
+ groupsRead: import("zod").ZodNumber;
285
+ occurrencesCounted: import("zod").ZodNumber;
286
+ complete: import("zod").ZodBoolean;
287
+ selection: import("zod").ZodLiteral<"earliest bucket, latency class, partition key groups">;
288
+ lastGroup: import("zod").ZodOptional<import("zod").ZodObject<{
289
+ start: import("zod").ZodString;
290
+ latencyClass: import("zod").ZodEnum<{
291
+ realtime: "realtime";
292
+ bulk: "bulk";
293
+ }>;
294
+ partitionKey: import("zod").ZodString;
295
+ }, import("zod/v4/core").$strip>>;
296
+ }, import("zod/v4/core").$strip>;
297
+ recurring: import("zod").ZodObject<{
298
+ schedulesRead: import("zod").ZodNumber;
299
+ populationComplete: import("zod").ZodBoolean;
300
+ selection: import("zod").ZodLiteral<"oldest eligible active recurring schedules by createdAt and scheduleId">;
301
+ firstScheduleId: import("zod").ZodOptional<import("zod").ZodString>;
302
+ lastScheduleId: import("zod").ZodOptional<import("zod").ZodString>;
303
+ }, import("zod/v4/core").$strip>;
304
+ work: import("zod").ZodObject<{
305
+ usedUnits: import("zod").ZodNumber;
306
+ limitUnits: import("zod").ZodNumber;
307
+ }, import("zod/v4/core").$strip>;
308
+ boundsReached: import("zod").ZodArray<import("zod").ZodObject<{
309
+ kind: import("zod").ZodEnum<{
310
+ "head-cells": "head-cells";
311
+ "recurring-series": "recurring-series";
312
+ "projection-work": "projection-work";
313
+ "projection-cells": "projection-cells";
314
+ }>;
315
+ limit: import("zod").ZodNumber;
316
+ }, import("zod/v4/core").$strip>>;
317
+ }, import("zod/v4/core").$strip>>;
218
318
  buckets: import("zod").ZodArray<import("zod").ZodObject<{
219
319
  byLatencyClass: import("zod").ZodObject<{
220
320
  bulk: import("zod").ZodNumber;
@@ -245,6 +345,7 @@ export interface ForecastMergedBucket {
245
345
  readonly byPartitionKey: Record<string, number>;
246
346
  count: number;
247
347
  nextFireCount: number;
348
+ omittedPartitionKeyCount?: number;
248
349
  unkeyedCount: number;
249
350
  }
250
351
  /**
@@ -301,26 +402,15 @@ export type ForecastAnswerDecision = {
301
402
  /**
302
403
  * Whether a gathered forecast may be published, and how old it is.
303
404
  *
304
- * **Every degradation this operation can suffer ends here, and every one of
305
- * them is a refusal.** That is the whole safety argument of the shape, and it
306
- * follows from a measured fact about the consumer it exists for: it reads the
307
- * bucket total and nothing else — not a degraded flag, not `freshness` — so a
308
- * degraded answer reads to it as a quiet book, and a quiet book makes it
309
- * release capacity. Its own failure path is fail-safe: a request that errors
310
- * makes it hold its last good reading. So the honest degradation is the one
311
- * that errors.
312
- *
313
- * The three are distinct because they mean different things to whoever is
314
- * looking: a partition that did not answer is an availability problem, a book
315
- * past the projection bound is a capacity problem with a published number
316
- * beside it, and an answer older than the bound is a partition that has stopped
317
- * refreshing.
405
+ * Unavailable and stale sources always refuse. Work-bound partial answers are
406
+ * permitted only for a reader that explicitly understands coverage; the
407
+ * default retains the count-only legacy consumer's safe failure behavior.
318
408
  *
319
409
  * `asOfMs` is the **oldest** across the shards, for the reason
320
410
  * `projectionCoverage` takes the oldest checkpoint: one busy shard must not be
321
411
  * allowed to vouch for three quiet ones.
322
412
  */
323
- export declare function decideForecastAnswer(answers: readonly ForecastShardAnswer[], nowMs: number): ForecastAnswerDecision;
413
+ export declare function decideForecastAnswer(answers: readonly ForecastShardAnswer[], nowMs: number, acceptPartial?: boolean): ForecastAnswerDecision;
324
414
  /**
325
415
  * The version of the transitional window shape.
326
416
  *
package/dist/forecast.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { MAX_FORECAST_HORIZON_SECONDS } from "./configuration-bounds.js";
2
+ import { OPERATIONAL_TIMING } from "./operational-config.js";
1
3
  import { z } from "./zod.js";
2
4
  import { freshnessSchema, projectedFreshnessSchema, } from "./protocol.js";
3
5
  import { timestampSchema } from "./time.js";
@@ -55,10 +57,11 @@ export const FORECAST_BOUNDS = {
55
57
  * argument for refusing rather than under-reporting collapses if staleness is
56
58
  * the one degradation that gets through as a number.
57
59
  */
58
- maxLagSeconds: 600,
60
+ maxLagSeconds: (OPERATIONAL_TIMING.forecastRefreshMaximumMs * 2) / 1000,
59
61
  /**
60
- * Instants one partition may project into a single snapshot before it reports
61
- * the answer as short.
62
+ * Actual recurrence work units (shared cron advances or interval-series
63
+ * calculations) before a partition reports the answer as short. Output-cell
64
+ * allocation is bounded independently by maxGroupsPerPartition.
62
65
  *
63
66
  * Published rather than kept internal so a refusal is classifiable: a shadow
64
67
  * comparison that sees a refusal needs to be able to tell "we are near a
@@ -75,7 +78,7 @@ export const FORECAST_BOUNDS = {
75
78
  * legacy service's seven-day ceiling bounded the *query* with no snapshot
76
79
  * behind it at all.
77
80
  */
78
- maxWindowSeconds: 25 * 60 * 60,
81
+ maxWindowSeconds: MAX_FORECAST_HORIZON_SECONDS,
79
82
  minBucketSeconds: 60,
80
83
  /**
81
84
  * Longest a partition lets its snapshot stand when nothing has been written.
@@ -85,7 +88,7 @@ export const FORECAST_BOUNDS = {
85
88
  * an incident. `freshness.lagSeconds` reports the actual age on every answer;
86
89
  * this is the bound it lives inside.
87
90
  */
88
- refreshCeilingSeconds: 300,
91
+ refreshCeilingSeconds: OPERATIONAL_TIMING.forecastRefreshMaximumMs / 1000,
89
92
  /**
90
93
  * Shortest gap between refreshes once something *has* been written.
91
94
  *
@@ -94,7 +97,7 @@ export const FORECAST_BOUNDS = {
94
97
  * projection that rebuilt on every poll would be the cost this whole design
95
98
  * exists to avoid.
96
99
  */
97
- refreshFloorSeconds: 30,
100
+ refreshFloorSeconds: OPERATIONAL_TIMING.forecastRefreshFloorMs / 1000,
98
101
  /**
99
102
  * How far below `now` a window may begin.
100
103
  *
@@ -104,7 +107,7 @@ export const FORECAST_BOUNDS = {
104
107
  * because the caller's `now` is a second behind. Further back than that is a
105
108
  * question about the past, which a forecast does not answer.
106
109
  */
107
- slackSeconds: 120,
110
+ slackSeconds: OPERATIONAL_TIMING.forecastCoverageSlackMs / 1000,
108
111
  /**
109
112
  * Customer keys named individually in one bucket before the rest are summed.
110
113
  *
@@ -337,7 +340,73 @@ export const forecastBucketSchema = z.object({
337
340
  /** The bucket's epoch-aligned start. May precede the requested `from`. */
338
341
  start: timestampSchema,
339
342
  });
343
+ /** Capability opt-in prevents old clients that read only counts from mistaking
344
+ * a lower bound for complete work. Older servers safely ignore this header. */
345
+ export const FORECAST_PARTIAL_ACCEPT_HEADER = "X-Greatwait-Accept-Partial-Forecast";
346
+ export const forecastRequestHeadersSchema = z.object({
347
+ [FORECAST_PARTIAL_ACCEPT_HEADER]: z.literal("true").optional(),
348
+ });
349
+ export const forecastCoverageSchema = z
350
+ .object({
351
+ complete: z.boolean(),
352
+ countMeaning: z.enum(["complete-total", "lower-bound"]),
353
+ projectedWindow: z.object({ from: timestampSchema, to: timestampSchema }),
354
+ /** No interval after this can be assumed quiet from absent buckets. */
355
+ completeThrough: timestampSchema,
356
+ heads: z.object({
357
+ groupsRead: z.number().int().nonnegative(),
358
+ occurrencesCounted: z.number().int().nonnegative(),
359
+ complete: z.boolean(),
360
+ selection: z.literal("earliest bucket, latency class, partition key groups"),
361
+ lastGroup: z
362
+ .object({
363
+ start: timestampSchema,
364
+ latencyClass: z.enum(["realtime", "bulk"]),
365
+ partitionKey: z.string(),
366
+ })
367
+ .optional(),
368
+ }),
369
+ recurring: z.object({
370
+ schedulesRead: z.number().int().nonnegative(),
371
+ /** The selected population is complete, not necessarily its expansion. */
372
+ populationComplete: z.boolean(),
373
+ selection: z.literal("oldest eligible active recurring schedules by createdAt and scheduleId"),
374
+ firstScheduleId: z.string().optional(),
375
+ lastScheduleId: z.string().optional(),
376
+ }),
377
+ work: z.object({
378
+ usedUnits: z.number().int().nonnegative(),
379
+ limitUnits: z.number().int().nonnegative(),
380
+ }),
381
+ boundsReached: z.array(z.object({
382
+ kind: z.enum([
383
+ "head-cells",
384
+ "recurring-series",
385
+ "projection-work",
386
+ "projection-cells",
387
+ ]),
388
+ limit: z.number().int().nonnegative(),
389
+ })),
390
+ })
391
+ .superRefine((coverage, context) => {
392
+ if ((coverage.countMeaning === "complete-total") !== coverage.complete ||
393
+ (coverage.complete &&
394
+ (coverage.boundsReached.length !== 0 ||
395
+ !coverage.heads.complete ||
396
+ !coverage.recurring.populationComplete ||
397
+ coverage.completeThrough !== coverage.projectedWindow.to)) ||
398
+ (!coverage.complete &&
399
+ (coverage.boundsReached.length === 0 ||
400
+ coverage.completeThrough !== coverage.projectedWindow.from))) {
401
+ context.addIssue({
402
+ code: "custom",
403
+ message: "Coverage must distinguish complete totals from lower bounds without claiming an unproven time prefix",
404
+ });
405
+ }
406
+ });
340
407
  export const forecastSchema = z.object({
408
+ /** Optional for older servers and callers without the coverage capability. */
409
+ coverage: forecastCoverageSchema.optional(),
341
410
  /** Ascending by `start`. A bucket with no occurrences is omitted. */
342
411
  buckets: z.array(forecastBucketSchema),
343
412
  /**
@@ -391,6 +460,10 @@ export function mergeForecastBuckets(buckets) {
391
460
  }
392
461
  into.count += bucket.count;
393
462
  into.nextFireCount += bucket.nextFireCount;
463
+ if (bucket.omittedPartitionKeyCount !== undefined) {
464
+ into.omittedPartitionKeyCount =
465
+ (into.omittedPartitionKeyCount ?? 0) + bucket.omittedPartitionKeyCount;
466
+ }
394
467
  into.unkeyedCount += bucket.unkeyedCount;
395
468
  }
396
469
  return [...merged.values()].sort((left, right) => left.bucketStartMs - right.bucketStartMs);
@@ -412,7 +485,7 @@ export function mergeForecastBuckets(buckets) {
412
485
  export function topPartitionKeys(bucket) {
413
486
  const ranked = Object.entries(bucket.byPartitionKey).sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0]));
414
487
  const byPartitionKey = Object.create(null);
415
- let otherPartitionKeyCount = bucket.unkeyedCount;
488
+ let otherPartitionKeyCount = bucket.unkeyedCount + (bucket.omittedPartitionKeyCount ?? 0);
416
489
  ranked.forEach(([key, n], index) => {
417
490
  if (index < FORECAST_BOUNDS.topPartitionKeys) {
418
491
  byPartitionKey[key] = n;
@@ -426,30 +499,20 @@ export function topPartitionKeys(bucket) {
426
499
  /**
427
500
  * Whether a gathered forecast may be published, and how old it is.
428
501
  *
429
- * **Every degradation this operation can suffer ends here, and every one of
430
- * them is a refusal.** That is the whole safety argument of the shape, and it
431
- * follows from a measured fact about the consumer it exists for: it reads the
432
- * bucket total and nothing else — not a degraded flag, not `freshness` — so a
433
- * degraded answer reads to it as a quiet book, and a quiet book makes it
434
- * release capacity. Its own failure path is fail-safe: a request that errors
435
- * makes it hold its last good reading. So the honest degradation is the one
436
- * that errors.
437
- *
438
- * The three are distinct because they mean different things to whoever is
439
- * looking: a partition that did not answer is an availability problem, a book
440
- * past the projection bound is a capacity problem with a published number
441
- * beside it, and an answer older than the bound is a partition that has stopped
442
- * refreshing.
502
+ * Unavailable and stale sources always refuse. Work-bound partial answers are
503
+ * permitted only for a reader that explicitly understands coverage; the
504
+ * default retains the count-only legacy consumer's safe failure behavior.
443
505
  *
444
506
  * `asOfMs` is the **oldest** across the shards, for the reason
445
507
  * `projectionCoverage` takes the oldest checkpoint: one busy shard must not be
446
508
  * allowed to vouch for three quiet ones.
447
509
  */
448
- export function decideForecastAnswer(answers, nowMs) {
510
+ export function decideForecastAnswer(answers, nowMs, acceptPartial = false) {
449
511
  if (answers.some((answer) => "refused" in answer)) {
450
512
  return { ok: false, refusal: "partition-unavailable" };
451
513
  }
452
- if (answers.some((answer) => "truncated" in answer && answer.truncated)) {
514
+ if (!acceptPartial &&
515
+ answers.some((answer) => "truncated" in answer && answer.truncated)) {
453
516
  return { ok: false, refusal: "book-too-large" };
454
517
  }
455
518
  // **Only a partition that built a snapshot vouches for freshness.** One that
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export { CHANGE_KINDS, CHANGE_OPERATIONS, CHANGE_SUBJECTS, CONTRACT_VERSION, ass
14
14
  export { WORKSPACE_LAYERS, scaffoldProblemSchema, scaffoldVersionSchema, toolDescriptorSchema, toolListSchema, workspaceIdentitySchema, workspaceLayerSchema, workspaceScaffoldSchema, type ScaffoldProblem, type ScaffoldVersion, type ToolDescriptor, type ToolList, type WorkspaceIdentity, type WorkspaceLayer, type WorkspaceScaffold, } from "./workspace.js";
15
15
  export { MOCK_BEHAVIORS, MOCK_HEADERS, OPERATIONS, UNIVERSAL_PROBLEMS, AUTHENTICATED_PROBLEMS, SCOPED_PROBLEMS, findOperation, fixtureListSchema, mockBehaviorSchema, mockScenarioRequestSchema, mockScenarioResponseSchema, operationsFor, problemsFor, requestSchemaFor, responseSchemaFor, successStatusFor, type FixtureList, type McpDisposition, type MockBehavior, type MockScenarioRequest, type MockScenarioResponse, type OperationDefinition, type OperationId, type OperationSurface, } from "./operations.js";
16
16
  export { PROJECT_LIST_LIMIT, PROJECT_STATUSES, environmentSchema, organizationSchema, projectCreateRequestSchema, projectArchiveRequestSchema, projectDeletedSchema, projectDeletionCountsSchema, projectListSchema, projectNameKey, projectNameSchema, projectSchema, projectStatusSchema, projectSummarySchema, projectUpdateRequestSchema, provisionedProjectSchema, type Environment, type Organization, type Project, type ProjectCreateRequest, type ProjectArchiveRequest, type ProjectDeleted, type ProjectDeletionCounts, type ProjectList, type ProjectStatus, type ProjectSummary, type ProjectUpdateRequest, type ProvisionedProject, } from "./tenancy.js";
17
- export { ATTEMPT_DURATION_MAX_MS, ATTEMPT_FAILURE_SNIPPET_MAX_LENGTH, ATTEMPT_REMEDIATIONS, ATTEMPT_RESPONSE_HEADER_MAX_LENGTH, ATTEMPT_STATES, CRON_EXPRESSION_MAX_LENGTH, LATENCY_CLASSES, OCCURRENCE_STATES, PARTITION_KEY_MAX_LENGTH, RECURRENCE_REQUEST_FIELDS, SCHEDULE_STATUSES, SCHEDULING_BOUNDS, TERMINAL_OCCURRENCE_STATES, attemptFailureSnippetSchema, attemptResponseHeaderSchema, attemptSchema, attemptDiagnosticSchema, attemptPageSchema, attemptRemediationSchema, attemptStateForResponse, attemptStateSchema, attemptTriggerSchema, attemptViewSchema, cronExpressionSchema, DELIVERY_COMPLETION_MODES, DELIVERY_DURATION_TIERS, MAX_DELIVERY_DURATION_SECONDS, RESPONSE_DELIVERY_MAX_DURATION_SECONDS, DELIVERY_OVERLAP_POLICIES, DEFAULT_DELIVERY_DURATION_SECONDS, DEFAULT_DELIVERY_OVERLAP_POLICY, FREE_DELIVERY_DURATION_SECONDS, DEFAULT_ONE_SHOT_MAX_STALENESS_SECONDS, LATENESS_POLICIES, isLongRunningDuration, deliveryCompletionModeSchema, deliveryDurationSecondsSchema, deliveryOverlapPolicySchema, type DeliveryCompletionMode, type DeliveryOverlapPolicy, deriveDeliverySettings, deriveLatencyClass, deriveLatenessSettings, defaultLatenessPolicyForRecurrence, generationSchema, isTerminalOccurrenceState, latencyClassSchema, latenessPolicySchema, occurrenceSchema, occurrencePageSchema, parseProjectOccurrenceListRequest, projectOccurrenceCursorBinding, projectOccurrenceListRequestSchema, projectOccurrencePageSchema, occurrenceStateSchema, occurrenceViewSchema, partitionKeySchema, remediationForAttempt, recurrenceSchema, scheduleNameSchema, scheduleLatenessRequestSchema, scheduleLatenessSchema, schedulePageSchema, scheduleRequestSchema, scheduleSchema, scheduleStatusSchema, scheduleViewSchema, type Attempt, type AttemptFailureSnippet, type AttemptResponseHeader, type AttemptDiagnostic, type AttemptPage, type AttemptRemediation, type AttemptState, type AttemptTrigger, type AttemptView, type CronExpression, type Generation, type DeliverySettings, type LatencyClass, type LatenessPolicy, type LatenessSettings, type Occurrence, type OccurrencePage, type ProjectOccurrenceListRequest, type ProjectOccurrenceListRequestParse, type ProjectOccurrencePage, type OccurrenceState, type OccurrenceView, type PartitionKey, type Recurrence, type Schedule, type ScheduleLatenessRequest, type SchedulePage, type ScheduleRequest, type ScheduleStatus, type ScheduleView, } from "./scheduling.js";
17
+ export { ATTEMPT_DURATION_MAX_MS, ATTEMPT_FAILURE_SNIPPET_MAX_LENGTH, ATTEMPT_REMEDIATIONS, ATTEMPT_RESPONSE_HEADER_MAX_LENGTH, ATTEMPT_STATES, CRON_EXPRESSION_MAX_LENGTH, LATENCY_CLASSES, OCCURRENCE_STATES, PARTITION_KEY_MAX_LENGTH, RECURRENCE_REQUEST_FIELDS, SCHEDULE_STATUSES, SCHEDULING_BOUNDS, TERMINAL_OCCURRENCE_STATES, TERMINAL_SCHEDULE_STATUSES, attemptFailureSnippetSchema, attemptResponseHeaderSchema, attemptSchema, attemptDiagnosticSchema, attemptPageSchema, attemptRemediationSchema, attemptStateForResponse, attemptStateSchema, attemptTriggerSchema, attemptViewSchema, cronExpressionSchema, DELIVERY_COMPLETION_MODES, DELIVERY_DURATION_TIERS, MAX_DELIVERY_DURATION_SECONDS, RESPONSE_DELIVERY_MAX_DURATION_SECONDS, DELIVERY_OVERLAP_POLICIES, DEFAULT_DELIVERY_DURATION_SECONDS, DEFAULT_DELIVERY_OVERLAP_POLICY, FREE_DELIVERY_DURATION_SECONDS, DEFAULT_ONE_SHOT_MAX_STALENESS_SECONDS, LATENESS_POLICIES, isLongRunningDuration, deliveryCompletionModeSchema, deliveryDurationSecondsSchema, deliveryOverlapPolicySchema, type DeliveryCompletionMode, type DeliveryOverlapPolicy, deriveDeliverySettings, deriveLatencyClass, deriveLatenessSettings, defaultLatenessPolicyForRecurrence, generationSchema, isTerminalOccurrenceState, isTerminalScheduleStatus, latencyClassSchema, latenessPolicySchema, occurrenceSchema, occurrencePageSchema, parseProjectOccurrenceListRequest, projectOccurrenceCursorBinding, projectOccurrenceListRequestSchema, projectOccurrencePageSchema, occurrenceStateSchema, occurrenceViewSchema, partitionKeySchema, remediationForAttempt, recurrenceSchema, scheduleNameSchema, scheduleLatenessRequestSchema, scheduleLatenessSchema, schedulePageSchema, scheduleRequestSchema, scheduleSchema, scheduleStatusSchema, scheduleViewSchema, type Attempt, type AttemptFailureSnippet, type AttemptResponseHeader, type AttemptDiagnostic, type AttemptPage, type AttemptRemediation, type AttemptState, type AttemptTrigger, type AttemptView, type CronExpression, type Generation, type DeliverySettings, type LatencyClass, type LatenessPolicy, type LatenessSettings, type Occurrence, type OccurrencePage, type ProjectOccurrenceListRequest, type ProjectOccurrenceListRequestParse, type ProjectOccurrencePage, type OccurrenceState, type OccurrenceView, type PartitionKey, type Recurrence, type Schedule, type ScheduleLatenessRequest, type SchedulePage, type ScheduleRequest, type ScheduleStatus, type ScheduleView, } from "./scheduling.js";
18
18
  export { portableAttemptRecordSchema, portableEncryptedPayloadRecordSchema, portableOccurrenceRecordSchema, portableReceiptRecordSchema, portableScheduleRecordSchema, portableSchedulingRecordSetSchema, type PortableAttemptRecord, type PortableEncryptedPayloadRecord, type PortableOccurrenceRecord, type PortableReceiptRecord, type PortableScheduleRecord, type PortableSchedulingRecordSet, } from "./scheduling-records.js";
19
19
  export { ROLE_SCOPE_CEILINGS, capScopesToRole, ceilingForRole, credentialScopes, grantableScopes, policyMatrix, roleAllows, roleCanPerform, type PolicyMatrixRow, } from "./policy.js";
20
20
  export { ACCESS_TOKEN_PATTERN, ACCESS_TOKEN_TTL_SECONDS, AUTHORIZATION_CODE_PATTERN, AUTHORIZATION_CODE_TTL_SECONDS, AUTHORIZATION_REQUEST_TTL_SECONDS, MAX_REDIRECT_URIS, OAUTH_ERRORS, OAUTH_ERROR_STATUS, OAUTH_GRANT_STATUSES, OAUTH_GRANT_TYPES, OAUTH_RESPONSE_TYPES, OAUTH_REVOCATION_REASONS, OAUTH_ROUTES, OAUTH_SECRET_PATTERN, OAUTH_TOKEN_NAMESPACE_LENGTH, OAUTH_TOKEN_SECRET_LENGTH, PKCE_CHALLENGE_PATTERN, PKCE_METHODS, PKCE_VERIFIER_PATTERN, REFRESH_TOKEN_PATTERN, REFRESH_TOKEN_TTL_SECONDS, TOKEN_ENDPOINT_AUTH_METHODS, authorizationParametersSchema, authorizationServerMetadataSchema, bearerChallenge, clientRegistrationRequestSchema, clientRegistrationSchema, consentDecisionSchema, consentOutcomeSchema, consentPromptSchema, formatScopeString, isLoopbackRedirect, oauthError, oauthErrorCodeSchema, oauthErrorSchema, oauthGrantListSchema, oauthGrantRevokedSchema, oauthGrantSchema, oauthGrantStatusSchema, oauthGrantTypeSchema, oauthRevocationReasonSchema, parseScopeString, pkceMethodSchema, protectedResourceMetadataSchema, redirectUriSchema, revocationRequestSchema, tokenRequestSchema, tokenResponseSchema, type AuthorizationParameters, type AuthorizationServerMetadata, type ClientRegistration, type ClientRegistrationRequest, type ConsentDecision, type ConsentOutcome, type ConsentPrompt, type OAuthErrorBody, type OAuthErrorCode, type OAuthGrant, type OAuthGrantList, type OAuthGrantRevoked, type OAuthGrantStatus, type OAuthGrantType, type OAuthRevocationReason, type ProtectedResourceMetadata, type RevocationRequest, type TokenRequest, type TokenResponse, } from "./oauth.js";
@@ -22,10 +22,11 @@ export { CALLBACK_ENVELOPE_HEADROOM_BYTES, CALLBACK_RECEIVER_MAX_BODY_BYTES, } f
22
22
  export { CALLBACK_ENDPOINT_SECRET_PATTERN, CALLBACK_URL_REJECTION_REASONS, evaluateCallbackUrl, isPublicCallbackAddress, type CallbackUrlRejectionReason, } from "./callback-safety.js";
23
23
  export { CALLBACK_ENDPOINT_LIMIT_PER_ENVIRONMENT, CALLBACK_ENDPOINT_STATUSES, CALLBACK_SIGNING_KEY_ROTATION_OVERLAP_SECONDS, CALLBACK_EGRESS_FAILURES, CALLBACK_ADMISSION_RATE_LIMITS, callbackEndpointCreatedSchema, callbackEndpointNameSchema, callbackEndpointPageSchema, callbackEndpointRequestSchema, callbackEndpointRotatedSchema, callbackEndpointSchema, callbackEndpointSigningSecretsSchema, callbackEndpointStatusSchema, callbackSigningKeyRotationRequestSchema, callbackSigningKeysSchema, callbackEgressFailureSchema, type CallbackEndpoint, type CallbackEndpointCreated, type CallbackEndpointPage, type CallbackEndpointRequest, type CallbackEndpointRotated, type CallbackEndpointSigningSecrets, type CallbackEndpointStatus, type CallbackSigningKeyRotationRequest, type CallbackSigningKeys, type CallbackEgressFailure, } from "./endpoints.js";
24
24
  export { compactInterval, cronWords, generatedEndpointName, generatedScheduleName, periodWords, targetDomain, } from "./naming.js";
25
- export { FORECAST_BOUNDS, FORECAST_BREAKDOWNS, FORECAST_COMPATIBILITY, FORECAST_RULES, FORECAST_WINDOW_VERSION, decideForecastAnswer, forecastBreakdownSchema, forecastBucketSchema, forecastBucketStartMs, forecastLatencyCountsSchema, forecastRequestSchema, forecastSchema, forecastViolations, forecastWindowBucketSchema, forecastWindowViolations, forecastWindowsSchema, mergeForecastBuckets, parseForecastRequest, resolveForecastWindow, topPartitionKeys, type Forecast, type ForecastAnswerDecision, type ForecastAnswerRefusal, type ForecastBreakdown, type ForecastBucket, type ForecastMergedBucket, type ForecastShardAnswer, type ForecastLatencyCounts, type ForecastRequest, type ForecastRequestParse, type ForecastWindow, type ForecastWindowBucket, type ForecastWindowRefusal, type ForecastWindowResolution, type ForecastWindows, } from "./forecast.js";
25
+ export { FORECAST_BOUNDS, FORECAST_PARTIAL_ACCEPT_HEADER, forecastRequestHeadersSchema, forecastCoverageSchema, type ForecastCoverage, FORECAST_BREAKDOWNS, FORECAST_COMPATIBILITY, FORECAST_RULES, FORECAST_WINDOW_VERSION, decideForecastAnswer, forecastBreakdownSchema, forecastBucketSchema, forecastBucketStartMs, forecastLatencyCountsSchema, forecastRequestSchema, forecastSchema, forecastViolations, forecastWindowBucketSchema, forecastWindowViolations, forecastWindowsSchema, mergeForecastBuckets, parseForecastRequest, resolveForecastWindow, topPartitionKeys, type Forecast, type ForecastAnswerDecision, type ForecastAnswerRefusal, type ForecastBreakdown, type ForecastBucket, type ForecastMergedBucket, type ForecastShardAnswer, type ForecastLatencyCounts, type ForecastRequest, type ForecastRequestParse, type ForecastWindow, type ForecastWindowBucket, type ForecastWindowRefusal, type ForecastWindowResolution, type ForecastWindows, } from "./forecast.js";
26
26
  export { CURL_JOURNEY_TOOLS, FIRST_VALUE_JOURNEY, FIRST_VALUE_PREREQUISITES, FIRST_VALUE_STEPS, FIRST_VALUE_VARIABLES, JOURNEY_ACTIVATION_DURATIONS, JOURNEY_ACTIVATION_OUTCOMES, JOURNEY_CONDITIONS, MINIMUM_CURL_VERSION, WEBSITE_JOURNEY_STEPS, WEBSITE_JOURNEY_STEP_KEYS, journeyActivationDuration, journeyCapturedVariables, journeyPathVariables, journeyPoll, journeyPrerequisite, journeyReferences, journeyStepSchema, journeyStepVariables, journeyVariable, journeyVariableName, journeyVariableSchema, parseWebsiteActivationEvent, pathParameterNames, resolveJourneyReferences, websiteActivationEventSchema, websiteJourneySteps, type FirstValueJourney, type JourneyActivationDuration, type JourneyActivationOutcome, type JourneyCapture, type JourneyCondition, type JourneyExpectation, type JourneyPoll, type JourneyPrerequisite, type JourneyRecovery, type JourneyStep, type JourneyVariable, type WebsiteActivationEvent, } from "./first-value-journey.js";
27
27
  export { BILLABLE_TERMINAL_STATES, USAGE_BOUNDS, USAGE_WINDOW_REASONS, billableTerminalStateSchema, parseUsageRequest, resolveUsageWindow, usageDaySchema, usageRequestSchema, usageSchema, utcMidnightMs, type BillableTerminalStateName, type ResolvedUsageWindow, type UsageDayView, type UsageRequest, type UsageRequestParse, type UsageView, type UsageWindowRefusal, } from "./usage.js";
28
- export { BILLING_ACTIVATION_MODES, BILLING_AMOUNT_SCALE, BILLING_BLOCK_REASONS, BILLING_CURRENCY, BILLING_ENTRY_KINDS, BILLING_PAYMENT_KINDS, BILLING_PAYMENT_STATES, BILLING_NOTICE_KINDS, billingAutoTopUpApplyRequestSchema, billingAutoTopUpConfigurationSchema, billingAutoTopUpPreviewRequestSchema, billingAutoTopUpPreviewSchema, billingAutoTopUpRuleSchema, billingBudgetPolicySchema, billingBudgetUpdateRequestHeadersSchema, billingBudgetUpdateRequestSchema, billingBudgetUpdateResponseSchema, billingCeilingUpdateRequestSchema, billingFundingQuoteRequestSchema, billingFundingQuoteSchema, billingFundingViewSchema, billingNoticePageSchema, billingNoticeRecoveryPathSchema, billingNoticeSchema, billingNotificationSettingsSchema, billingNotificationSettingsUpdateRequestSchema, billingLedgerEntrySchema, billingLedgerPageSchema, billingLedgerRequestSchema, billingPaymentOperationSchema, billingPeriodSummarySchema, billingPurchaseRequestSchema, billingRefundRequestCreateSchema, billingRefundResolutionRequestSchema, billingRefundRequestViewSchema, billingSummarySchema, exactCentMoneySchema, manualFundingCreditSchema, microdollarAmountSchema, nonnegativeMicrodollarAmountSchema, type BillingAutoTopUpApplyRequest, type BillingAutoTopUpConfiguration, type BillingAutoTopUpPreview, type BillingAutoTopUpPreviewRequest, type BillingAutoTopUpRule, type BillingCeilingUpdateRequest, type BillingFundingQuote, type BillingFundingQuoteRequest, type BillingFundingView, type BillingNotice, type BillingNoticePage, type BillingNotificationSettings, type BillingNotificationSettingsUpdateRequest, type BillingLedgerEntryView, type BillingLedgerPage, type BillingLedgerRequest, type BillingBudgetUpdateRequest, type BillingBudgetUpdateResponse, type BillingPaymentOperation, type BillingPurchaseRequest, type BillingRefundRequestCreate, type BillingRefundResolutionRequest, type BillingRefundRequestView, type BillingSummaryView, } from "./billing.js";
28
+ export { BILLING_ACTIVATION_MODES, BILLING_AMOUNT_SCALE, BILLING_BLOCK_REASONS, BILLING_CURRENCY, BILLING_ENTRY_KINDS, BILLING_LEDGER_ENTRY_NOTES, BILLING_PAYMENT_KINDS, BILLING_PAYMENT_STATES, BILLING_NOTICE_KINDS, billingAutoTopUpApplyRequestSchema, billingAutoTopUpConfigurationSchema, billingAutoTopUpPreviewRequestSchema, billingAutoTopUpPreviewSchema, billingAutoTopUpRuleSchema, billingBudgetPolicySchema, billingBudgetUpdateRequestHeadersSchema, billingBudgetUpdateRequestSchema, billingBudgetUpdateResponseSchema, billingCeilingUpdateRequestSchema, billingFundingQuoteRequestSchema, billingFundingQuoteSchema, billingFundingViewSchema, billingNoticePageSchema, billingNoticeRecoveryPathSchema, billingNoticeSchema, billingNotificationSettingsSchema, billingNotificationSettingsUpdateRequestSchema, billingLedgerEntrySchema, billingLedgerPageSchema, billingLedgerRequestSchema, billingPaymentOperationSchema, billingPeriodSummarySchema, billingPurchaseRequestSchema, billingRefundRequestCreateSchema, billingRefundResolutionRequestSchema, billingRefundRequestViewSchema, billingSummarySchema, exactCentMoneySchema, manualFundingCreditSchema, microdollarAmountSchema, nonnegativeMicrodollarAmountSchema, type BillingAutoTopUpApplyRequest, type BillingAutoTopUpConfiguration, type BillingAutoTopUpPreview, type BillingAutoTopUpPreviewRequest, type BillingAutoTopUpRule, type BillingCeilingUpdateRequest, type BillingFundingQuote, type BillingFundingQuoteRequest, type BillingFundingView, type BillingNotice, type BillingNoticePage, type BillingNotificationSettings, type BillingNotificationSettingsUpdateRequest, type BillingLedgerEntryView, type BillingLedgerPage, type BillingLedgerRequest, type BillingBudgetUpdateRequest, type BillingBudgetUpdateResponse, type BillingPaymentOperation, type BillingPurchaseRequest, type BillingRefundRequestCreate, type BillingRefundResolutionRequest, type BillingRefundRequestView, type BillingSummaryView, } from "./billing.js";
29
29
  export { DELIVERY_TIMING_TARGETS_MS, DELIVERY_TIMING_VERDICTS, deliveryTimingSummarySchema, timingThresholdSummarySchema, type DeliveryTimingSummaryView, type TimingThresholdView, } from "./timing.js";
30
30
  export { CALLBACK_RECEIVER_DISPOSITIONS, CALLBACK_RECEIVER_PROTOCOL, CALLBACK_RECEIVER_STATUS, TEST_SINK_BEHAVIORS, TEST_SINK_BEHAVIOR_FACTS, TEST_SINK_BOUNDS, TEST_SINK_CLIENT_ERROR_STATUSES, TEST_SINK_DISPOSITIONS, TEST_SINK_PROTOCOL_VERSION, TEST_SINK_SERVER_ERROR_STATUSES, callbackReceiverAcknowledgementSchema, callbackReceiverDispositionSchema, resolveTestSinkAction, testSinkBehaviorSchema, testSinkCreateRequestSchema, testSinkDeliveryBodySchema, testSinkDispositionSchema, testSinkDeliveryPageSchema, testSinkDeliverySchema, testSinkPageSchema, testSinkProgramSchema, testSinkSchema, type CallbackReceiverAcknowledgement, type CallbackReceiverDisposition, type TestSink, type TestSinkAction, type TestSinkBehavior, type TestSinkCreateRequest, type TestSinkDelivery, type TestSinkDeliveryBody, type TestSinkDeliveryPage, type TestSinkDisposition, type TestSinkPage, type TestSinkProgram, } from "./test-sink.js";
31
- export { PROJECT_BILLING_ACTIONS, projectBillingQuoteRequestSchema, projectBillingQuoteSchema, projectBillingChangeRequestSchema, projectBillingStateSchema, billingPortalSchema, type ProjectBillingQuoteRequest, type ProjectBillingQuote, type ProjectBillingChangeRequest, type ProjectBillingState, } from "./billing.js";
31
+ export { PROJECT_BILLING_ACTIONS, projectBillingQuoteRequestSchema, projectBillingQuoteSchema, projectBillingChangeRequestSchema, projectBillingStateSchema, billingPortalSchema, BILLING_PAYMENT_METHOD_REQUIRED_TITLE, billingPaymentMethodSchema, billingPaymentMethodSetupRequestSchema, billingPaymentMethodConfirmRequestSchema, billingPaymentMethodRemoveRequestSchema, billingInvoiceSchema, billingInvoiceListSchema, billingPaymentHistoryPageSchema, billingInvoiceHistoryPageSchema, type BillingPaymentHistoryPage, type BillingInvoiceHistoryPage, type BillingInvoice, type BillingInvoiceList, type BillingPaymentMethod, type BillingPaymentMethodSetupRequest, type BillingPaymentMethodConfirmRequest, type BillingPaymentMethodRemoveRequest, type ProjectBillingQuoteRequest, type ProjectBillingQuote, type ProjectBillingChangeRequest, type ProjectBillingState, } from "./billing.js";
32
+ export { effectiveCustomerLimitsSchema, type EffectiveCustomerLimits, } from "./effective-limits.js";
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ export { CHANGE_KINDS, CHANGE_OPERATIONS, CHANGE_SUBJECTS, CONTRACT_VERSION, ass
14
14
  export { WORKSPACE_LAYERS, scaffoldProblemSchema, scaffoldVersionSchema, toolDescriptorSchema, toolListSchema, workspaceIdentitySchema, workspaceLayerSchema, workspaceScaffoldSchema, } from "./workspace.js";
15
15
  export { MOCK_BEHAVIORS, MOCK_HEADERS, OPERATIONS, UNIVERSAL_PROBLEMS, AUTHENTICATED_PROBLEMS, SCOPED_PROBLEMS, findOperation, fixtureListSchema, mockBehaviorSchema, mockScenarioRequestSchema, mockScenarioResponseSchema, operationsFor, problemsFor, requestSchemaFor, responseSchemaFor, successStatusFor, } from "./operations.js";
16
16
  export { PROJECT_LIST_LIMIT, PROJECT_STATUSES, environmentSchema, organizationSchema, projectCreateRequestSchema, projectArchiveRequestSchema, projectDeletedSchema, projectDeletionCountsSchema, projectListSchema, projectNameKey, projectNameSchema, projectSchema, projectStatusSchema, projectSummarySchema, projectUpdateRequestSchema, provisionedProjectSchema, } from "./tenancy.js";
17
- export { ATTEMPT_DURATION_MAX_MS, ATTEMPT_FAILURE_SNIPPET_MAX_LENGTH, ATTEMPT_REMEDIATIONS, ATTEMPT_RESPONSE_HEADER_MAX_LENGTH, ATTEMPT_STATES, CRON_EXPRESSION_MAX_LENGTH, LATENCY_CLASSES, OCCURRENCE_STATES, PARTITION_KEY_MAX_LENGTH, RECURRENCE_REQUEST_FIELDS, SCHEDULE_STATUSES, SCHEDULING_BOUNDS, TERMINAL_OCCURRENCE_STATES, attemptFailureSnippetSchema, attemptResponseHeaderSchema, attemptSchema, attemptDiagnosticSchema, attemptPageSchema, attemptRemediationSchema, attemptStateForResponse, attemptStateSchema, attemptTriggerSchema, attemptViewSchema, cronExpressionSchema, DELIVERY_COMPLETION_MODES, DELIVERY_DURATION_TIERS, MAX_DELIVERY_DURATION_SECONDS, RESPONSE_DELIVERY_MAX_DURATION_SECONDS, DELIVERY_OVERLAP_POLICIES, DEFAULT_DELIVERY_DURATION_SECONDS, DEFAULT_DELIVERY_OVERLAP_POLICY, FREE_DELIVERY_DURATION_SECONDS, DEFAULT_ONE_SHOT_MAX_STALENESS_SECONDS, LATENESS_POLICIES, isLongRunningDuration, deliveryCompletionModeSchema, deliveryDurationSecondsSchema, deliveryOverlapPolicySchema, deriveDeliverySettings, deriveLatencyClass, deriveLatenessSettings, defaultLatenessPolicyForRecurrence, generationSchema, isTerminalOccurrenceState, latencyClassSchema, latenessPolicySchema, occurrenceSchema, occurrencePageSchema, parseProjectOccurrenceListRequest, projectOccurrenceCursorBinding, projectOccurrenceListRequestSchema, projectOccurrencePageSchema, occurrenceStateSchema, occurrenceViewSchema, partitionKeySchema, remediationForAttempt, recurrenceSchema, scheduleNameSchema, scheduleLatenessRequestSchema, scheduleLatenessSchema, schedulePageSchema, scheduleRequestSchema, scheduleSchema, scheduleStatusSchema, scheduleViewSchema, } from "./scheduling.js";
17
+ export { ATTEMPT_DURATION_MAX_MS, ATTEMPT_FAILURE_SNIPPET_MAX_LENGTH, ATTEMPT_REMEDIATIONS, ATTEMPT_RESPONSE_HEADER_MAX_LENGTH, ATTEMPT_STATES, CRON_EXPRESSION_MAX_LENGTH, LATENCY_CLASSES, OCCURRENCE_STATES, PARTITION_KEY_MAX_LENGTH, RECURRENCE_REQUEST_FIELDS, SCHEDULE_STATUSES, SCHEDULING_BOUNDS, TERMINAL_OCCURRENCE_STATES, TERMINAL_SCHEDULE_STATUSES, attemptFailureSnippetSchema, attemptResponseHeaderSchema, attemptSchema, attemptDiagnosticSchema, attemptPageSchema, attemptRemediationSchema, attemptStateForResponse, attemptStateSchema, attemptTriggerSchema, attemptViewSchema, cronExpressionSchema, DELIVERY_COMPLETION_MODES, DELIVERY_DURATION_TIERS, MAX_DELIVERY_DURATION_SECONDS, RESPONSE_DELIVERY_MAX_DURATION_SECONDS, DELIVERY_OVERLAP_POLICIES, DEFAULT_DELIVERY_DURATION_SECONDS, DEFAULT_DELIVERY_OVERLAP_POLICY, FREE_DELIVERY_DURATION_SECONDS, DEFAULT_ONE_SHOT_MAX_STALENESS_SECONDS, LATENESS_POLICIES, isLongRunningDuration, deliveryCompletionModeSchema, deliveryDurationSecondsSchema, deliveryOverlapPolicySchema, deriveDeliverySettings, deriveLatencyClass, deriveLatenessSettings, defaultLatenessPolicyForRecurrence, generationSchema, isTerminalOccurrenceState, isTerminalScheduleStatus, latencyClassSchema, latenessPolicySchema, occurrenceSchema, occurrencePageSchema, parseProjectOccurrenceListRequest, projectOccurrenceCursorBinding, projectOccurrenceListRequestSchema, projectOccurrencePageSchema, occurrenceStateSchema, occurrenceViewSchema, partitionKeySchema, remediationForAttempt, recurrenceSchema, scheduleNameSchema, scheduleLatenessRequestSchema, scheduleLatenessSchema, schedulePageSchema, scheduleRequestSchema, scheduleSchema, scheduleStatusSchema, scheduleViewSchema, } from "./scheduling.js";
18
18
  export { portableAttemptRecordSchema, portableEncryptedPayloadRecordSchema, portableOccurrenceRecordSchema, portableReceiptRecordSchema, portableScheduleRecordSchema, portableSchedulingRecordSetSchema, } from "./scheduling-records.js";
19
19
  export { ROLE_SCOPE_CEILINGS, capScopesToRole, ceilingForRole, credentialScopes, grantableScopes, policyMatrix, roleAllows, roleCanPerform, } from "./policy.js";
20
20
  export { ACCESS_TOKEN_PATTERN, ACCESS_TOKEN_TTL_SECONDS, AUTHORIZATION_CODE_PATTERN, AUTHORIZATION_CODE_TTL_SECONDS, AUTHORIZATION_REQUEST_TTL_SECONDS, MAX_REDIRECT_URIS, OAUTH_ERRORS, OAUTH_ERROR_STATUS, OAUTH_GRANT_STATUSES, OAUTH_GRANT_TYPES, OAUTH_RESPONSE_TYPES, OAUTH_REVOCATION_REASONS, OAUTH_ROUTES, OAUTH_SECRET_PATTERN, OAUTH_TOKEN_NAMESPACE_LENGTH, OAUTH_TOKEN_SECRET_LENGTH, PKCE_CHALLENGE_PATTERN, PKCE_METHODS, PKCE_VERIFIER_PATTERN, REFRESH_TOKEN_PATTERN, REFRESH_TOKEN_TTL_SECONDS, TOKEN_ENDPOINT_AUTH_METHODS, authorizationParametersSchema, authorizationServerMetadataSchema, bearerChallenge, clientRegistrationRequestSchema, clientRegistrationSchema, consentDecisionSchema, consentOutcomeSchema, consentPromptSchema, formatScopeString, isLoopbackRedirect, oauthError, oauthErrorCodeSchema, oauthErrorSchema, oauthGrantListSchema, oauthGrantRevokedSchema, oauthGrantSchema, oauthGrantStatusSchema, oauthGrantTypeSchema, oauthRevocationReasonSchema, parseScopeString, pkceMethodSchema, protectedResourceMetadataSchema, redirectUriSchema, revocationRequestSchema, tokenRequestSchema, tokenResponseSchema, } from "./oauth.js";
@@ -22,10 +22,11 @@ export { CALLBACK_ENVELOPE_HEADROOM_BYTES, CALLBACK_RECEIVER_MAX_BODY_BYTES, } f
22
22
  export { CALLBACK_ENDPOINT_SECRET_PATTERN, CALLBACK_URL_REJECTION_REASONS, evaluateCallbackUrl, isPublicCallbackAddress, } from "./callback-safety.js";
23
23
  export { CALLBACK_ENDPOINT_LIMIT_PER_ENVIRONMENT, CALLBACK_ENDPOINT_STATUSES, CALLBACK_SIGNING_KEY_ROTATION_OVERLAP_SECONDS, CALLBACK_EGRESS_FAILURES, CALLBACK_ADMISSION_RATE_LIMITS, callbackEndpointCreatedSchema, callbackEndpointNameSchema, callbackEndpointPageSchema, callbackEndpointRequestSchema, callbackEndpointRotatedSchema, callbackEndpointSchema, callbackEndpointSigningSecretsSchema, callbackEndpointStatusSchema, callbackSigningKeyRotationRequestSchema, callbackSigningKeysSchema, callbackEgressFailureSchema, } from "./endpoints.js";
24
24
  export { compactInterval, cronWords, generatedEndpointName, generatedScheduleName, periodWords, targetDomain, } from "./naming.js";
25
- export { FORECAST_BOUNDS, FORECAST_BREAKDOWNS, FORECAST_COMPATIBILITY, FORECAST_RULES, FORECAST_WINDOW_VERSION, decideForecastAnswer, forecastBreakdownSchema, forecastBucketSchema, forecastBucketStartMs, forecastLatencyCountsSchema, forecastRequestSchema, forecastSchema, forecastViolations, forecastWindowBucketSchema, forecastWindowViolations, forecastWindowsSchema, mergeForecastBuckets, parseForecastRequest, resolveForecastWindow, topPartitionKeys, } from "./forecast.js";
25
+ export { FORECAST_BOUNDS, FORECAST_PARTIAL_ACCEPT_HEADER, forecastRequestHeadersSchema, forecastCoverageSchema, FORECAST_BREAKDOWNS, FORECAST_COMPATIBILITY, FORECAST_RULES, FORECAST_WINDOW_VERSION, decideForecastAnswer, forecastBreakdownSchema, forecastBucketSchema, forecastBucketStartMs, forecastLatencyCountsSchema, forecastRequestSchema, forecastSchema, forecastViolations, forecastWindowBucketSchema, forecastWindowViolations, forecastWindowsSchema, mergeForecastBuckets, parseForecastRequest, resolveForecastWindow, topPartitionKeys, } from "./forecast.js";
26
26
  export { CURL_JOURNEY_TOOLS, FIRST_VALUE_JOURNEY, FIRST_VALUE_PREREQUISITES, FIRST_VALUE_STEPS, FIRST_VALUE_VARIABLES, JOURNEY_ACTIVATION_DURATIONS, JOURNEY_ACTIVATION_OUTCOMES, JOURNEY_CONDITIONS, MINIMUM_CURL_VERSION, WEBSITE_JOURNEY_STEPS, WEBSITE_JOURNEY_STEP_KEYS, journeyActivationDuration, journeyCapturedVariables, journeyPathVariables, journeyPoll, journeyPrerequisite, journeyReferences, journeyStepSchema, journeyStepVariables, journeyVariable, journeyVariableName, journeyVariableSchema, parseWebsiteActivationEvent, pathParameterNames, resolveJourneyReferences, websiteActivationEventSchema, websiteJourneySteps, } from "./first-value-journey.js";
27
27
  export { BILLABLE_TERMINAL_STATES, USAGE_BOUNDS, USAGE_WINDOW_REASONS, billableTerminalStateSchema, parseUsageRequest, resolveUsageWindow, usageDaySchema, usageRequestSchema, usageSchema, utcMidnightMs, } from "./usage.js";
28
- export { BILLING_ACTIVATION_MODES, BILLING_AMOUNT_SCALE, BILLING_BLOCK_REASONS, BILLING_CURRENCY, BILLING_ENTRY_KINDS, BILLING_PAYMENT_KINDS, BILLING_PAYMENT_STATES, BILLING_NOTICE_KINDS, billingAutoTopUpApplyRequestSchema, billingAutoTopUpConfigurationSchema, billingAutoTopUpPreviewRequestSchema, billingAutoTopUpPreviewSchema, billingAutoTopUpRuleSchema, billingBudgetPolicySchema, billingBudgetUpdateRequestHeadersSchema, billingBudgetUpdateRequestSchema, billingBudgetUpdateResponseSchema, billingCeilingUpdateRequestSchema, billingFundingQuoteRequestSchema, billingFundingQuoteSchema, billingFundingViewSchema, billingNoticePageSchema, billingNoticeRecoveryPathSchema, billingNoticeSchema, billingNotificationSettingsSchema, billingNotificationSettingsUpdateRequestSchema, billingLedgerEntrySchema, billingLedgerPageSchema, billingLedgerRequestSchema, billingPaymentOperationSchema, billingPeriodSummarySchema, billingPurchaseRequestSchema, billingRefundRequestCreateSchema, billingRefundResolutionRequestSchema, billingRefundRequestViewSchema, billingSummarySchema, exactCentMoneySchema, manualFundingCreditSchema, microdollarAmountSchema, nonnegativeMicrodollarAmountSchema, } from "./billing.js";
28
+ export { BILLING_ACTIVATION_MODES, BILLING_AMOUNT_SCALE, BILLING_BLOCK_REASONS, BILLING_CURRENCY, BILLING_ENTRY_KINDS, BILLING_LEDGER_ENTRY_NOTES, BILLING_PAYMENT_KINDS, BILLING_PAYMENT_STATES, BILLING_NOTICE_KINDS, billingAutoTopUpApplyRequestSchema, billingAutoTopUpConfigurationSchema, billingAutoTopUpPreviewRequestSchema, billingAutoTopUpPreviewSchema, billingAutoTopUpRuleSchema, billingBudgetPolicySchema, billingBudgetUpdateRequestHeadersSchema, billingBudgetUpdateRequestSchema, billingBudgetUpdateResponseSchema, billingCeilingUpdateRequestSchema, billingFundingQuoteRequestSchema, billingFundingQuoteSchema, billingFundingViewSchema, billingNoticePageSchema, billingNoticeRecoveryPathSchema, billingNoticeSchema, billingNotificationSettingsSchema, billingNotificationSettingsUpdateRequestSchema, billingLedgerEntrySchema, billingLedgerPageSchema, billingLedgerRequestSchema, billingPaymentOperationSchema, billingPeriodSummarySchema, billingPurchaseRequestSchema, billingRefundRequestCreateSchema, billingRefundResolutionRequestSchema, billingRefundRequestViewSchema, billingSummarySchema, exactCentMoneySchema, manualFundingCreditSchema, microdollarAmountSchema, nonnegativeMicrodollarAmountSchema, } from "./billing.js";
29
29
  export { DELIVERY_TIMING_TARGETS_MS, DELIVERY_TIMING_VERDICTS, deliveryTimingSummarySchema, timingThresholdSummarySchema, } from "./timing.js";
30
30
  export { CALLBACK_RECEIVER_DISPOSITIONS, CALLBACK_RECEIVER_PROTOCOL, CALLBACK_RECEIVER_STATUS, TEST_SINK_BEHAVIORS, TEST_SINK_BEHAVIOR_FACTS, TEST_SINK_BOUNDS, TEST_SINK_CLIENT_ERROR_STATUSES, TEST_SINK_DISPOSITIONS, TEST_SINK_PROTOCOL_VERSION, TEST_SINK_SERVER_ERROR_STATUSES, callbackReceiverAcknowledgementSchema, callbackReceiverDispositionSchema, resolveTestSinkAction, testSinkBehaviorSchema, testSinkCreateRequestSchema, testSinkDeliveryBodySchema, testSinkDispositionSchema, testSinkDeliveryPageSchema, testSinkDeliverySchema, testSinkPageSchema, testSinkProgramSchema, testSinkSchema, } from "./test-sink.js";
31
- export { PROJECT_BILLING_ACTIONS, projectBillingQuoteRequestSchema, projectBillingQuoteSchema, projectBillingChangeRequestSchema, projectBillingStateSchema, billingPortalSchema, } from "./billing.js";
31
+ export { PROJECT_BILLING_ACTIONS, projectBillingQuoteRequestSchema, projectBillingQuoteSchema, projectBillingChangeRequestSchema, projectBillingStateSchema, billingPortalSchema, BILLING_PAYMENT_METHOD_REQUIRED_TITLE, billingPaymentMethodSchema, billingPaymentMethodSetupRequestSchema, billingPaymentMethodConfirmRequestSchema, billingPaymentMethodRemoveRequestSchema, billingInvoiceSchema, billingInvoiceListSchema, billingPaymentHistoryPageSchema, billingInvoiceHistoryPageSchema, } from "./billing.js";
32
+ export { effectiveCustomerLimitsSchema, } from "./effective-limits.js";
package/dist/mcp.js CHANGED
@@ -53,7 +53,7 @@ export const MCP_ROUTES = {
53
53
  * instruction like "create this in production" is even expressible.
54
54
  */
55
55
  export const MCP_INSTRUCTIONS = [
56
- "Greatwait schedules work and delivers it to an endpoint at the time asked for.",
56
+ "GreatWait schedules work and delivers it to an endpoint at the time asked for.",
57
57
  "Every tool acts inside one organization, project and environment, fixed by the credential this connection was authorized with; no argument can name another, and there is no tool that moves between them.",
58
58
  "Reads are safe to repeat. Writes are annotated, and the ones marked destructive settle or discard an occurrence that would otherwise have fired.",
59
59
  "A refusal comes back as a problem document with a stable `code`: act on the code, not on the wording.",