@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.
- package/README.md +1 -1
- package/dist/billing.d.ts +231 -1
- package/dist/billing.js +150 -1
- package/dist/callback-safety.js +13 -3
- package/dist/configuration-bounds.d.ts +13 -0
- package/dist/configuration-bounds.js +13 -0
- package/dist/effective-limits.d.ts +40 -0
- package/dist/effective-limits.js +42 -0
- package/dist/endpoints.d.ts +5 -5
- package/dist/endpoints.js +5 -5
- package/dist/first-value-journey.d.ts +1 -1
- package/dist/first-value-journey.js +11 -7
- package/dist/forecast.d.ts +111 -21
- package/dist/forecast.js +87 -24
- package/dist/index.d.ts +5 -4
- package/dist/index.js +5 -4
- package/dist/mcp.js +1 -1
- package/dist/operational-config.d.ts +101 -0
- package/dist/operational-config.js +341 -0
- package/dist/operations.d.ts +597 -16
- package/dist/operations.js +384 -23
- package/dist/partition.d.ts +17 -9
- package/dist/partition.js +3 -3
- package/dist/problems.d.ts +25 -2
- package/dist/problems.js +49 -1
- package/dist/protocol.d.ts +5 -5
- package/dist/protocol.js +2 -1
- package/dist/scheduling-records.d.ts +6 -0
- package/dist/scheduling.d.ts +37 -1
- package/dist/scheduling.js +60 -4
- package/dist/usage.js +6 -21
- package/generated/v1/examples/attempts.list.response.json +2 -0
- package/generated/v1/examples/attempts.read.response.json +2 -0
- package/generated/v1/examples/billing.fundingconfirm.response.json +120 -0
- package/generated/v1/examples/billing.invoicehistory.response.json +6 -0
- package/generated/v1/examples/billing.invoices.response.json +15 -0
- package/generated/v1/examples/billing.paymenthistory.response.json +6 -0
- package/generated/v1/examples/billing.paymentmethod.response.json +16 -0
- package/generated/v1/examples/billing.paymentmethodconfirm.request.json +3 -0
- package/generated/v1/examples/billing.paymentmethodconfirm.response.json +16 -0
- package/generated/v1/examples/billing.paymentmethodremove.request.json +3 -0
- package/generated/v1/examples/billing.paymentmethodremove.response.json +4 -0
- package/generated/v1/examples/billing.paymentmethodsetup.request.json +1 -0
- package/generated/v1/examples/billing.paymentmethodsetup.response.json +3 -0
- package/generated/v1/examples/limits.read.response.json +16 -0
- package/generated/v1/examples/occurrences.redeliver.response.json +2 -0
- package/generated/v1/first-value-journey.json +24 -8
- package/generated/v1/manifest.json +342 -10
- package/generated/v1/openapi.json +12395 -6543
- package/generated/v1/policy-matrix.json +65 -2
- package/generated/v1/schemas/attempts.list.response.json +15 -0
- package/generated/v1/schemas/attempts.read.response.json +15 -0
- package/generated/v1/schemas/billing.fundingconfirm.response.json +552 -0
- package/generated/v1/schemas/billing.invoicehistory.query.json +16 -0
- package/generated/v1/schemas/billing.invoicehistory.response.json +88 -0
- package/generated/v1/schemas/billing.invoices.response.json +51 -0
- package/generated/v1/schemas/billing.ledger.response.json +5 -0
- package/generated/v1/schemas/billing.notificationsettingsupdate.request.json +24 -17
- package/generated/v1/schemas/billing.paymenthistory.query.json +16 -0
- package/generated/v1/schemas/billing.paymenthistory.response.json +182 -0
- package/generated/v1/schemas/billing.paymentmethod.response.json +137 -0
- package/generated/v1/schemas/billing.paymentmethodconfirm.request.json +14 -0
- package/generated/v1/schemas/billing.paymentmethodconfirm.response.json +137 -0
- package/generated/v1/schemas/billing.paymentmethodremove.request.json +12 -0
- package/generated/v1/schemas/billing.paymentmethodremove.response.json +137 -0
- package/generated/v1/schemas/billing.paymentmethodsetup.request.json +12 -0
- package/generated/v1/schemas/billing.paymentmethodsetup.response.json +11 -0
- package/generated/v1/schemas/billing.purchase.request.json +4 -0
- package/generated/v1/schemas/forecast.read.request-headers.json +10 -0
- package/generated/v1/schemas/forecast.read.response.json +148 -0
- package/generated/v1/schemas/limits.read.response.json +79 -0
- package/generated/v1/schemas/occurrences.redeliver.response.json +15 -0
- package/generated/v1/snippets/billing.fundingconfirm.json +6 -0
- package/generated/v1/snippets/billing.invoicehistory.json +6 -0
- package/generated/v1/snippets/billing.invoices.json +6 -0
- package/generated/v1/snippets/billing.notificationsettingsupdate.json +1 -1
- package/generated/v1/snippets/billing.paymenthistory.json +6 -0
- package/generated/v1/snippets/billing.paymentmethod.json +6 -0
- package/generated/v1/snippets/billing.paymentmethodconfirm.json +6 -0
- package/generated/v1/snippets/billing.paymentmethodremove.json +6 -0
- package/generated/v1/snippets/billing.paymentmethodsetup.json +6 -0
- package/generated/v1/snippets/forecast.windows.json +1 -1
- package/generated/v1/snippets/limits.read.json +6 -0
- package/package.json +7 -2
package/dist/partition.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ export declare const SINGLE_SHARD = "0";
|
|
|
53
53
|
* produced by two constants drifting apart. The test-gap audit named exactly
|
|
54
54
|
* that, and the fix is one declaration rather than a test comparing two.
|
|
55
55
|
*
|
|
56
|
-
* Thirty-two is one
|
|
56
|
+
* Thirty-two is one control-plane batch's worth of work and a few kilobytes of response.
|
|
57
57
|
* The caller comes back for the rest, and `RetainedProjections.pending` is how
|
|
58
58
|
* it knows to.
|
|
59
59
|
*/
|
|
@@ -93,8 +93,8 @@ export declare const MAX_PARTITION_SHARDS = 8;
|
|
|
93
93
|
* only under a precondition, and that is the most important thing to know about
|
|
94
94
|
* it.** A schedule's shard is derived from its identifier. Before W2-06 that was
|
|
95
95
|
* the only answer, so raising the count stranded every schedule already stored.
|
|
96
|
-
* Now the shard a schedule was actually stored in is *recorded* in the
|
|
97
|
-
* directory, and `resolveSchedule` falls back to it whenever the derived
|
|
96
|
+
* Now the shard a schedule was actually stored in is *recorded* in the
|
|
97
|
+
* control-plane directory, and `resolveSchedule` falls back to it whenever the derived
|
|
98
98
|
* partition has nothing — so a schedule created under an older count keeps
|
|
99
99
|
* working, because its route was written down rather than recomputed.
|
|
100
100
|
*
|
|
@@ -295,7 +295,7 @@ export interface DrainProjectionsQuery {
|
|
|
295
295
|
*
|
|
296
296
|
* **Nothing is deleted here.** The intents stay until `settleProjections` says
|
|
297
297
|
* the control plane has them, which is acceptance criterion 1: an intent
|
|
298
|
-
* survives a drain whose
|
|
298
|
+
* survives a drain whose control-plane write never landed, and a partition that has never
|
|
299
299
|
* been initialized answers an empty drain rather than a refusal — a shard nobody
|
|
300
300
|
* has written to owes the directory nothing.
|
|
301
301
|
*/
|
|
@@ -304,9 +304,10 @@ export type DrainProjectionsOutcome = PartitionRefused | RetainedProjections;
|
|
|
304
304
|
* Retire the intents the control plane accepted, and postpone the rest.
|
|
305
305
|
*
|
|
306
306
|
* Both halves in one call rather than two, because a drain has exactly one of
|
|
307
|
-
* these outcomes and the failing half must not need a healthy
|
|
308
|
-
* the deferral is what stops a control-plane outage from
|
|
309
|
-
* request pay a
|
|
307
|
+
* these outcomes and the failing half must not need a healthy control plane
|
|
308
|
+
* to be recorded: the deferral is what stops a control-plane outage from
|
|
309
|
+
* making every subsequent request pay a control-plane timeout for the same
|
|
310
|
+
* intent.
|
|
310
311
|
*/
|
|
311
312
|
export interface SettleProjectionsCommand {
|
|
312
313
|
/** Intents the control plane has durably applied, or cannot route. */
|
|
@@ -470,7 +471,7 @@ export interface CreateScheduleCommand {
|
|
|
470
471
|
readonly partitionKey?: string;
|
|
471
472
|
/**
|
|
472
473
|
* Authenticated encrypted customer JSON. The plaintext never crosses this
|
|
473
|
-
* seam and is never stored in a
|
|
474
|
+
* seam and is never stored in a control-plane projection.
|
|
474
475
|
*/
|
|
475
476
|
readonly payloadEnvelope?: string;
|
|
476
477
|
/** UTF-8 byte length of the plaintext JSON, before encryption. */
|
|
@@ -479,7 +480,7 @@ export interface CreateScheduleCommand {
|
|
|
479
480
|
* The verified endpoint URL captured for durable host routing.
|
|
480
481
|
*
|
|
481
482
|
* This is internal metadata, not a public response field. The Host Executor
|
|
482
|
-
* re-reads the
|
|
483
|
+
* re-reads the control-plane endpoint row before signing and reroutes if the URL has
|
|
483
484
|
* changed. It does not resolve or revalidate the address: that boundary was
|
|
484
485
|
* removed by FXO-1566 and FXO-1581, and this comment claimed it afterwards.
|
|
485
486
|
*/
|
|
@@ -700,6 +701,8 @@ export interface ForecastQuery {
|
|
|
700
701
|
readonly authority: Authority;
|
|
701
702
|
readonly bucketMs: number;
|
|
702
703
|
readonly fromMs: number;
|
|
704
|
+
/** Omit named-key cells when the public caller only needs totals/classes. */
|
|
705
|
+
readonly includePartitionKeys?: boolean;
|
|
703
706
|
readonly toMs: number;
|
|
704
707
|
}
|
|
705
708
|
/** One bucket, as one partition sees it. */
|
|
@@ -709,6 +712,8 @@ export interface ForecastPartitionBucket {
|
|
|
709
712
|
readonly count: number;
|
|
710
713
|
/** Occurrences here that are the next firing of their schedule. */
|
|
711
714
|
readonly nextFireCount: number;
|
|
715
|
+
/** Named-key counts folded into the public remainder after exact ranking. */
|
|
716
|
+
readonly omittedPartitionKeyCount?: number;
|
|
712
717
|
/**
|
|
713
718
|
* Named customer keys and their counts, ascending by key.
|
|
714
719
|
*
|
|
@@ -748,6 +753,9 @@ export type ForecastOutcome = PartitionRefused | {
|
|
|
748
753
|
*/
|
|
749
754
|
readonly asOfMs?: number;
|
|
750
755
|
readonly buckets: readonly ForecastPartitionBucket[];
|
|
756
|
+
/** Operator work budget that prevented a complete answer, never a count. */
|
|
757
|
+
readonly exhaustedBudget?: string;
|
|
758
|
+
readonly coverage?: import("./forecast.js").ForecastCoverage;
|
|
751
759
|
/**
|
|
752
760
|
* The instant this answer actually reached, when it is not the one asked
|
|
753
761
|
* for.
|
package/dist/partition.js
CHANGED
|
@@ -51,7 +51,7 @@ export const SINGLE_SHARD = "0";
|
|
|
51
51
|
* produced by two constants drifting apart. The test-gap audit named exactly
|
|
52
52
|
* that, and the fix is one declaration rather than a test comparing two.
|
|
53
53
|
*
|
|
54
|
-
* Thirty-two is one
|
|
54
|
+
* Thirty-two is one control-plane batch's worth of work and a few kilobytes of response.
|
|
55
55
|
* The caller comes back for the rest, and `RetainedProjections.pending` is how
|
|
56
56
|
* it knows to.
|
|
57
57
|
*/
|
|
@@ -110,8 +110,8 @@ function fnv1a32(input) {
|
|
|
110
110
|
* only under a precondition, and that is the most important thing to know about
|
|
111
111
|
* it.** A schedule's shard is derived from its identifier. Before W2-06 that was
|
|
112
112
|
* the only answer, so raising the count stranded every schedule already stored.
|
|
113
|
-
* Now the shard a schedule was actually stored in is *recorded* in the
|
|
114
|
-
* directory, and `resolveSchedule` falls back to it whenever the derived
|
|
113
|
+
* Now the shard a schedule was actually stored in is *recorded* in the
|
|
114
|
+
* control-plane directory, and `resolveSchedule` falls back to it whenever the derived
|
|
115
115
|
* partition has nothing — so a schedule created under an older count keeps
|
|
116
116
|
* working, because its route was written down rather than recomputed.
|
|
117
117
|
*
|
package/dist/problems.d.ts
CHANGED
|
@@ -12,12 +12,13 @@ import { z } from "./zod.js";
|
|
|
12
12
|
* `code` is the contract. `title` and `detail` are prose and may change without
|
|
13
13
|
* being a breaking change; clients must never branch on them.
|
|
14
14
|
*/
|
|
15
|
-
export declare const PROBLEM_CATEGORIES: readonly ["authentication", "authorization", "conflict", "invalid-request", "not-found", "rate-limited", "unavailable"];
|
|
15
|
+
export declare const PROBLEM_CATEGORIES: readonly ["authentication", "authorization", "conflict", "invalid-request", "not-configured", "not-found", "rate-limited", "unavailable"];
|
|
16
16
|
export declare const problemCategorySchema: import("zod").ZodEnum<{
|
|
17
17
|
authentication: "authentication";
|
|
18
18
|
authorization: "authorization";
|
|
19
19
|
conflict: "conflict";
|
|
20
20
|
"invalid-request": "invalid-request";
|
|
21
|
+
"not-configured": "not-configured";
|
|
21
22
|
"not-found": "not-found";
|
|
22
23
|
"rate-limited": "rate-limited";
|
|
23
24
|
unavailable: "unavailable";
|
|
@@ -32,6 +33,14 @@ export declare const PROBLEM_CODES: {
|
|
|
32
33
|
readonly category: "authentication";
|
|
33
34
|
readonly status: 401;
|
|
34
35
|
};
|
|
36
|
+
readonly billing_not_ready: {
|
|
37
|
+
readonly category: "unavailable";
|
|
38
|
+
readonly status: 503;
|
|
39
|
+
};
|
|
40
|
+
readonly capability_not_configured: {
|
|
41
|
+
readonly category: "not-configured";
|
|
42
|
+
readonly status: 503;
|
|
43
|
+
};
|
|
35
44
|
readonly credential_expired: {
|
|
36
45
|
readonly category: "authentication";
|
|
37
46
|
readonly status: 401;
|
|
@@ -96,6 +105,8 @@ export declare const PROBLEM_CODES: {
|
|
|
96
105
|
export type ProblemCode = keyof typeof PROBLEM_CODES;
|
|
97
106
|
export declare const problemCodeSchema: import("zod").ZodEnum<{
|
|
98
107
|
authentication_required: "authentication_required";
|
|
108
|
+
billing_not_ready: "billing_not_ready";
|
|
109
|
+
capability_not_configured: "capability_not_configured";
|
|
99
110
|
credential_expired: "credential_expired";
|
|
100
111
|
credential_revoked: "credential_revoked";
|
|
101
112
|
idempotency_key_reused: "idempotency_key_reused";
|
|
@@ -112,7 +123,17 @@ export declare const problemCodeSchema: import("zod").ZodEnum<{
|
|
|
112
123
|
test_to_live_escalation: "test_to_live_escalation";
|
|
113
124
|
version_conflict: "version_conflict";
|
|
114
125
|
}>;
|
|
115
|
-
/**
|
|
126
|
+
/**
|
|
127
|
+
* Whether repeating the identical request could succeed later.
|
|
128
|
+
*
|
|
129
|
+
* **Two 5xx categories, opposite answers, and that is the point.**
|
|
130
|
+
* `unavailable` is something that has gone wrong and will come back;
|
|
131
|
+
* `not-configured` is something that was never turned on and will not turn
|
|
132
|
+
* itself on. Reading the status alone cannot tell them apart, which is how a
|
|
133
|
+
* permanent refusal came to be published to customers as retryable — in the
|
|
134
|
+
* SDK's `retryable`, in the CLI's exit class, and as a "Try again" control the
|
|
135
|
+
* dashboard offered for a condition no amount of trying clears.
|
|
136
|
+
*/
|
|
116
137
|
export declare function isRetryable(code: ProblemCode): boolean;
|
|
117
138
|
export declare const fieldErrorSchema: import("zod").ZodObject<{
|
|
118
139
|
pointer: import("zod").ZodString;
|
|
@@ -122,6 +143,8 @@ export type FieldError = z.infer<typeof fieldErrorSchema>;
|
|
|
122
143
|
export declare const problemSchema: import("zod").ZodObject<{
|
|
123
144
|
code: import("zod").ZodEnum<{
|
|
124
145
|
authentication_required: "authentication_required";
|
|
146
|
+
billing_not_ready: "billing_not_ready";
|
|
147
|
+
capability_not_configured: "capability_not_configured";
|
|
125
148
|
credential_expired: "credential_expired";
|
|
126
149
|
credential_revoked: "credential_revoked";
|
|
127
150
|
idempotency_key_reused: "idempotency_key_reused";
|
package/dist/problems.js
CHANGED
|
@@ -17,6 +17,14 @@ export const PROBLEM_CATEGORIES = [
|
|
|
17
17
|
"authorization",
|
|
18
18
|
"conflict",
|
|
19
19
|
"invalid-request",
|
|
20
|
+
// **A capability this deployment was never given, which is not an outage.**
|
|
21
|
+
// Separate from `unavailable` for one reason: `isRetryable` is a function of
|
|
22
|
+
// the category, and these two answer the retry question oppositely. An
|
|
23
|
+
// outage clears by itself and repeating is the right move; an unconfigured
|
|
24
|
+
// capability clears when somebody changes configuration and never otherwise,
|
|
25
|
+
// so telling a client "the identical request is safe to repeat" is false and
|
|
26
|
+
// it is false forever. Both are 5xx because the caller's request was fine.
|
|
27
|
+
"not-configured",
|
|
20
28
|
"not-found",
|
|
21
29
|
"rate-limited",
|
|
22
30
|
"unavailable",
|
|
@@ -34,6 +42,36 @@ export const PROBLEM_CODES = {
|
|
|
34
42
|
// now. One code for both would make a missed rotation window indistinguishable
|
|
35
43
|
// from a security event, and the client's remedy differs — rotate again
|
|
36
44
|
// versus find out who revoked it.
|
|
45
|
+
// **"Still being set up" is not "broken", and a first screen should not say
|
|
46
|
+
// the second when it means the first.** An organization's billing account row
|
|
47
|
+
// is written by a projection that runs every minute rather than synchronously
|
|
48
|
+
// at sign-up, so a member who creates their project immediately can read
|
|
49
|
+
// billing before the row exists. That used to answer `service_unavailable`,
|
|
50
|
+
// which the dashboard renders as "The service is not answering right now" —
|
|
51
|
+
// the sentence W9-06 blocked the invited cohort over, and the one a new member
|
|
52
|
+
// met on first contact.
|
|
53
|
+
//
|
|
54
|
+
// Deliberately still `unavailable`, and therefore still retryable: repeating
|
|
55
|
+
// the request is exactly the right move, and it succeeds within about a
|
|
56
|
+
// minute. What changes is what the reader is told, not what a client does.
|
|
57
|
+
billing_not_ready: { category: "unavailable", status: 503 },
|
|
58
|
+
// **The environment was never given this capability.** A configuration fact,
|
|
59
|
+
// not a fault and not a fluctuation: the Worker holds no provider, no secret
|
|
60
|
+
// or no binding for the thing being asked about, and it will hold none until
|
|
61
|
+
// somebody deploys different configuration.
|
|
62
|
+
//
|
|
63
|
+
// It exists because `service_unavailable` was carrying both meanings, and
|
|
64
|
+
// the retry answer differs between them. W9-06 blocked the invited cohort
|
|
65
|
+
// over billing panels that said "The service is not answering right now" for
|
|
66
|
+
// capabilities production had deliberately not turned on; W9-08 found the
|
|
67
|
+
// other half still live — the same refusal reaching a customer as
|
|
68
|
+
// `retryable`, and the CLI printing "The identical request is safe to
|
|
69
|
+
// repeat" about a condition no repetition can clear.
|
|
70
|
+
//
|
|
71
|
+
// Deliberately **not** `billing_not_ready`, which is the opposite case: that
|
|
72
|
+
// one is provisioning already in flight, finishes on its own within a
|
|
73
|
+
// minute, and is correctly retryable.
|
|
74
|
+
capability_not_configured: { category: "not-configured", status: 503 },
|
|
37
75
|
credential_expired: { category: "authentication", status: 401 },
|
|
38
76
|
credential_revoked: { category: "authentication", status: 401 },
|
|
39
77
|
idempotency_key_reused: { category: "conflict", status: 409 },
|
|
@@ -61,7 +99,17 @@ export const PROBLEM_CODES = {
|
|
|
61
99
|
version_conflict: { category: "conflict", status: 409 },
|
|
62
100
|
};
|
|
63
101
|
export const problemCodeSchema = z.enum(Object.keys(PROBLEM_CODES));
|
|
64
|
-
/**
|
|
102
|
+
/**
|
|
103
|
+
* Whether repeating the identical request could succeed later.
|
|
104
|
+
*
|
|
105
|
+
* **Two 5xx categories, opposite answers, and that is the point.**
|
|
106
|
+
* `unavailable` is something that has gone wrong and will come back;
|
|
107
|
+
* `not-configured` is something that was never turned on and will not turn
|
|
108
|
+
* itself on. Reading the status alone cannot tell them apart, which is how a
|
|
109
|
+
* permanent refusal came to be published to customers as retryable — in the
|
|
110
|
+
* SDK's `retryable`, in the CLI's exit class, and as a "Try again" control the
|
|
111
|
+
* dashboard offered for a condition no amount of trying clears.
|
|
112
|
+
*/
|
|
65
113
|
export function isRetryable(code) {
|
|
66
114
|
const category = PROBLEM_CODES[code].category;
|
|
67
115
|
return category === "rate-limited" || category === "unavailable";
|
package/dist/protocol.d.ts
CHANGED
|
@@ -10,11 +10,11 @@ import type { FieldError } from "./problems.js";
|
|
|
10
10
|
* scheduling book changes constantly. The cursor is opaque: clients pass back
|
|
11
11
|
* exactly what they were given.
|
|
12
12
|
*/
|
|
13
|
-
export declare const PAGE_SIZE: {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
13
|
+
export declare const PAGE_SIZE: Readonly<{
|
|
14
|
+
default: 25;
|
|
15
|
+
max: 100;
|
|
16
|
+
min: 1;
|
|
17
|
+
}>;
|
|
18
18
|
export declare const pageRequestSchema: import("zod").ZodObject<{
|
|
19
19
|
cursor: import("zod").ZodOptional<import("zod").ZodString>;
|
|
20
20
|
limit: import("zod").ZodDefault<import("zod").ZodNumber>;
|
package/dist/protocol.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "./zod.js";
|
|
2
|
+
import { PUBLIC_PAGE_SIZE } from "./configuration-bounds.js";
|
|
2
3
|
import { endpointIdSchema, environmentIdSchema, organizationIdSchema, projectIdSchema, } from "./identifiers.js";
|
|
3
4
|
import { timestampSchema } from "./time.js";
|
|
4
5
|
/**
|
|
@@ -13,7 +14,7 @@ import { timestampSchema } from "./time.js";
|
|
|
13
14
|
* scheduling book changes constantly. The cursor is opaque: clients pass back
|
|
14
15
|
* exactly what they were given.
|
|
15
16
|
*/
|
|
16
|
-
export const PAGE_SIZE =
|
|
17
|
+
export const PAGE_SIZE = PUBLIC_PAGE_SIZE;
|
|
17
18
|
export const pageRequestSchema = z.object({
|
|
18
19
|
cursor: z.string().min(1).optional(),
|
|
19
20
|
limit: z
|
|
@@ -129,7 +129,9 @@ export declare const portableOccurrenceRecordSchema: import("zod").ZodObject<{
|
|
|
129
129
|
export type PortableOccurrenceRecord = z.infer<typeof portableOccurrenceRecordSchema>;
|
|
130
130
|
export declare const portableAttemptRecordSchema: import("zod").ZodObject<{
|
|
131
131
|
id: import("zod").ZodString;
|
|
132
|
+
localReceiptRecoveries: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
132
133
|
occurrence: import("zod").ZodString;
|
|
134
|
+
rescues: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
133
135
|
remediation: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
134
136
|
none: "none";
|
|
135
137
|
review_retry_policy: "review_retry_policy";
|
|
@@ -188,6 +190,7 @@ export declare const portableAttemptRecordSchema: import("zod").ZodObject<{
|
|
|
188
190
|
network_ambiguous: "network_ambiguous";
|
|
189
191
|
payload_unavailable: "payload_unavailable";
|
|
190
192
|
}>>;
|
|
193
|
+
dispatchRecoveries: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
191
194
|
durationMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
192
195
|
authority: import("zod").ZodObject<{
|
|
193
196
|
environment: import("zod").ZodString;
|
|
@@ -229,7 +232,9 @@ export type PortableEncryptedPayloadRecord = z.infer<typeof portableEncryptedPay
|
|
|
229
232
|
export declare const portableSchedulingRecordSetSchema: import("zod").ZodObject<{
|
|
230
233
|
attempts: import("zod").ZodArray<import("zod").ZodObject<{
|
|
231
234
|
id: import("zod").ZodString;
|
|
235
|
+
localReceiptRecoveries: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
232
236
|
occurrence: import("zod").ZodString;
|
|
237
|
+
rescues: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
233
238
|
remediation: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
234
239
|
none: "none";
|
|
235
240
|
review_retry_policy: "review_retry_policy";
|
|
@@ -288,6 +293,7 @@ export declare const portableSchedulingRecordSetSchema: import("zod").ZodObject<
|
|
|
288
293
|
network_ambiguous: "network_ambiguous";
|
|
289
294
|
payload_unavailable: "payload_unavailable";
|
|
290
295
|
}>>;
|
|
296
|
+
dispatchRecoveries: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
291
297
|
durationMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
292
298
|
authority: import("zod").ZodObject<{
|
|
293
299
|
environment: import("zod").ZodString;
|
package/dist/scheduling.d.ts
CHANGED
|
@@ -42,6 +42,33 @@ export declare const scheduleStatusSchema: import("zod").ZodEnum<{
|
|
|
42
42
|
cancelled: "cancelled";
|
|
43
43
|
}>;
|
|
44
44
|
export type ScheduleStatus = z.infer<typeof scheduleStatusSchema>;
|
|
45
|
+
/**
|
|
46
|
+
* The statuses a schedule never leaves, and from which it never fires again on
|
|
47
|
+
* its own.
|
|
48
|
+
*
|
|
49
|
+
* **"Never fires again on its own" rather than "never delivers again", and the
|
|
50
|
+
* distinction is real.** A member can still press Redeliver on a completed
|
|
51
|
+
* occurrence, and the repository admits that for a `completed` schedule as well
|
|
52
|
+
* as an `active` one. What is terminal here is the schedule's own timetable, not
|
|
53
|
+
* every possible future delivery.
|
|
54
|
+
*
|
|
55
|
+
* Exported for the same reason as {@link TERMINAL_OCCURRENCE_STATES}: so a
|
|
56
|
+
* caller enumerates them rather than writing the list out and quietly missing
|
|
57
|
+
* one if another is ever added. Three places had already written it out — the
|
|
58
|
+
* `archivedAt` validator in `scheduling-records.ts`, the dashboard's schedule
|
|
59
|
+
* controls, and the dashboard's pending-action rules — and the third had missed
|
|
60
|
+
* it entirely, which is the defect this list was extracted for.
|
|
61
|
+
*/
|
|
62
|
+
export declare const TERMINAL_SCHEDULE_STATUSES: readonly ["cancelled", "completed"];
|
|
63
|
+
/**
|
|
64
|
+
* Whether this schedule has finished, either on its own or because somebody
|
|
65
|
+
* stopped it.
|
|
66
|
+
*
|
|
67
|
+
* `paused` is deliberately not terminal: it is reversible, so a paused schedule
|
|
68
|
+
* pointed at a broken destination is still a problem worth telling somebody
|
|
69
|
+
* about.
|
|
70
|
+
*/
|
|
71
|
+
export declare function isTerminalScheduleStatus(status: ScheduleStatus): boolean;
|
|
45
72
|
/**
|
|
46
73
|
* How promptly an occurrence expects to be dispatched.
|
|
47
74
|
*
|
|
@@ -738,7 +765,7 @@ export type Schedule = z.infer<typeof scheduleSchema>;
|
|
|
738
765
|
* A page of schedules.
|
|
739
766
|
*
|
|
740
767
|
* Items are schedules rather than schedule *views*. A cross-partition listing is
|
|
741
|
-
* served from the
|
|
768
|
+
* served from the control-plane projection W2-06 built, and that projection holds a route
|
|
742
769
|
* and a summary rather than every partition's live occurrence — so a page that
|
|
743
770
|
* promised an occurrence would either lie about its freshness or force the
|
|
744
771
|
* listing back through every partition it spans. Detail is where the occurrence
|
|
@@ -895,7 +922,9 @@ export declare const attemptFailureSnippetSchema: import("zod").ZodObject<{
|
|
|
895
922
|
export type AttemptFailureSnippet = z.infer<typeof attemptFailureSnippetSchema>;
|
|
896
923
|
export declare const attemptSchema: import("zod").ZodObject<{
|
|
897
924
|
id: import("zod").ZodString;
|
|
925
|
+
localReceiptRecoveries: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
898
926
|
occurrence: import("zod").ZodString;
|
|
927
|
+
rescues: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
899
928
|
remediation: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
900
929
|
none: "none";
|
|
901
930
|
review_retry_policy: "review_retry_policy";
|
|
@@ -954,6 +983,7 @@ export declare const attemptSchema: import("zod").ZodObject<{
|
|
|
954
983
|
network_ambiguous: "network_ambiguous";
|
|
955
984
|
payload_unavailable: "payload_unavailable";
|
|
956
985
|
}>>;
|
|
986
|
+
dispatchRecoveries: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
957
987
|
durationMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
958
988
|
}, import("zod/v4/core").$strip>;
|
|
959
989
|
export type Attempt = z.infer<typeof attemptSchema>;
|
|
@@ -1074,7 +1104,9 @@ export type OccurrenceView = z.infer<typeof occurrenceViewSchema>;
|
|
|
1074
1104
|
export declare const attemptPageSchema: import("zod").ZodObject<{
|
|
1075
1105
|
data: import("zod").ZodArray<import("zod").ZodObject<{
|
|
1076
1106
|
id: import("zod").ZodString;
|
|
1107
|
+
localReceiptRecoveries: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
1077
1108
|
occurrence: import("zod").ZodString;
|
|
1109
|
+
rescues: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
1078
1110
|
remediation: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
1079
1111
|
none: "none";
|
|
1080
1112
|
review_retry_policy: "review_retry_policy";
|
|
@@ -1133,6 +1165,7 @@ export declare const attemptPageSchema: import("zod").ZodObject<{
|
|
|
1133
1165
|
network_ambiguous: "network_ambiguous";
|
|
1134
1166
|
payload_unavailable: "payload_unavailable";
|
|
1135
1167
|
}>>;
|
|
1168
|
+
dispatchRecoveries: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
1136
1169
|
durationMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
1137
1170
|
}, import("zod/v4/core").$strip>>;
|
|
1138
1171
|
nextCursor: import("zod").ZodOptional<import("zod").ZodString>;
|
|
@@ -1145,7 +1178,9 @@ export type AttemptPage = z.infer<typeof attemptPageSchema>;
|
|
|
1145
1178
|
export declare const attemptViewSchema: import("zod").ZodObject<{
|
|
1146
1179
|
attempt: import("zod").ZodObject<{
|
|
1147
1180
|
id: import("zod").ZodString;
|
|
1181
|
+
localReceiptRecoveries: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
1148
1182
|
occurrence: import("zod").ZodString;
|
|
1183
|
+
rescues: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
1149
1184
|
remediation: import("zod").ZodOptional<import("zod").ZodEnum<{
|
|
1150
1185
|
none: "none";
|
|
1151
1186
|
review_retry_policy: "review_retry_policy";
|
|
@@ -1204,6 +1239,7 @@ export declare const attemptViewSchema: import("zod").ZodObject<{
|
|
|
1204
1239
|
network_ambiguous: "network_ambiguous";
|
|
1205
1240
|
payload_unavailable: "payload_unavailable";
|
|
1206
1241
|
}>>;
|
|
1242
|
+
dispatchRecoveries: import("zod").ZodOptional<import("zod").ZodInt>;
|
|
1207
1243
|
durationMs: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
1208
1244
|
}, import("zod/v4/core").$strip>;
|
|
1209
1245
|
freshness: import("zod").ZodObject<{
|
package/dist/scheduling.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FIXED_INTERVAL_MIN_SECONDS, FIXED_INTERVAL_MAX_SECONDS, MAX_INLINE_PAYLOAD_BYTES, } from "./configuration-bounds.js";
|
|
1
2
|
import { z } from "./zod.js";
|
|
2
3
|
import { attemptIdSchema, deliveryIdSchema, endpointIdSchema, occurrenceIdSchema, scheduleIdSchema, } from "./identifiers.js";
|
|
3
4
|
import { CALLBACK_ATTEMPT_DIAGNOSTICS } from "./delivery.js";
|
|
@@ -46,6 +47,38 @@ export const SCHEDULE_STATUSES = [
|
|
|
46
47
|
"completed",
|
|
47
48
|
];
|
|
48
49
|
export const scheduleStatusSchema = z.enum(SCHEDULE_STATUSES);
|
|
50
|
+
/**
|
|
51
|
+
* The statuses a schedule never leaves, and from which it never fires again on
|
|
52
|
+
* its own.
|
|
53
|
+
*
|
|
54
|
+
* **"Never fires again on its own" rather than "never delivers again", and the
|
|
55
|
+
* distinction is real.** A member can still press Redeliver on a completed
|
|
56
|
+
* occurrence, and the repository admits that for a `completed` schedule as well
|
|
57
|
+
* as an `active` one. What is terminal here is the schedule's own timetable, not
|
|
58
|
+
* every possible future delivery.
|
|
59
|
+
*
|
|
60
|
+
* Exported for the same reason as {@link TERMINAL_OCCURRENCE_STATES}: so a
|
|
61
|
+
* caller enumerates them rather than writing the list out and quietly missing
|
|
62
|
+
* one if another is ever added. Three places had already written it out — the
|
|
63
|
+
* `archivedAt` validator in `scheduling-records.ts`, the dashboard's schedule
|
|
64
|
+
* controls, and the dashboard's pending-action rules — and the third had missed
|
|
65
|
+
* it entirely, which is the defect this list was extracted for.
|
|
66
|
+
*/
|
|
67
|
+
export const TERMINAL_SCHEDULE_STATUSES = [
|
|
68
|
+
"cancelled",
|
|
69
|
+
"completed",
|
|
70
|
+
];
|
|
71
|
+
/**
|
|
72
|
+
* Whether this schedule has finished, either on its own or because somebody
|
|
73
|
+
* stopped it.
|
|
74
|
+
*
|
|
75
|
+
* `paused` is deliberately not terminal: it is reversible, so a paused schedule
|
|
76
|
+
* pointed at a broken destination is still a problem worth telling somebody
|
|
77
|
+
* about.
|
|
78
|
+
*/
|
|
79
|
+
export function isTerminalScheduleStatus(status) {
|
|
80
|
+
return TERMINAL_SCHEDULE_STATUSES.includes(status);
|
|
81
|
+
}
|
|
49
82
|
/**
|
|
50
83
|
* How promptly an occurrence expects to be dispatched.
|
|
51
84
|
*
|
|
@@ -598,7 +631,7 @@ export const SCHEDULING_BOUNDS = {
|
|
|
598
631
|
* Widening a bound is additive by `classifyChange` and narrowing it is
|
|
599
632
|
* breaking, so this direction is the safe one to move in.
|
|
600
633
|
*/
|
|
601
|
-
everySecondsMax:
|
|
634
|
+
everySecondsMax: FIXED_INTERVAL_MAX_SECONDS,
|
|
602
635
|
/**
|
|
603
636
|
* The shortest fixed interval a recurring schedule may ask for, in seconds.
|
|
604
637
|
*
|
|
@@ -610,7 +643,7 @@ export const SCHEDULING_BOUNDS = {
|
|
|
610
643
|
* `classifyChange` and narrowing it is breaking, which is the direction to be
|
|
611
644
|
* conservative in.
|
|
612
645
|
*/
|
|
613
|
-
everySecondsMin:
|
|
646
|
+
everySecondsMin: FIXED_INTERVAL_MIN_SECONDS,
|
|
614
647
|
/**
|
|
615
648
|
* How long an idempotency receipt is honoured. A client retrying a create for
|
|
616
649
|
* longer than a day is not retrying, it is making a new request; keeping
|
|
@@ -662,7 +695,7 @@ export const SCHEDULING_BOUNDS = {
|
|
|
662
695
|
* command-shaped payloads this product is for, and refuses the ones that are
|
|
663
696
|
* really a file transfer.
|
|
664
697
|
*/
|
|
665
|
-
payloadBytes:
|
|
698
|
+
payloadBytes: MAX_INLINE_PAYLOAD_BYTES,
|
|
666
699
|
/**
|
|
667
700
|
* How soon a one-shot has to be for `realtime` to be the class it gets by
|
|
668
701
|
* default, in seconds.
|
|
@@ -908,7 +941,7 @@ export const scheduleSchema = z.object({
|
|
|
908
941
|
* A page of schedules.
|
|
909
942
|
*
|
|
910
943
|
* Items are schedules rather than schedule *views*. A cross-partition listing is
|
|
911
|
-
* served from the
|
|
944
|
+
* served from the control-plane projection W2-06 built, and that projection holds a route
|
|
912
945
|
* and a summary rather than every partition's live occurrence — so a page that
|
|
913
946
|
* promised an occurrence would either lie about its freshness or force the
|
|
914
947
|
* listing back through every partition it spans. Detail is where the occurrence
|
|
@@ -1037,6 +1070,12 @@ export const attemptSchema = z
|
|
|
1037
1070
|
delivery: deliveryIdSchema,
|
|
1038
1071
|
/** Safe classifier code; absent when durable evidence predates diagnostics. */
|
|
1039
1072
|
diagnostic: attemptDiagnosticSchema.optional(),
|
|
1073
|
+
/**
|
|
1074
|
+
* Instrumented re-drives of the same dispatching occurrence under a new
|
|
1075
|
+
* dispatch epoch. Includes deliberate admission deferrals; this is not a
|
|
1076
|
+
* count of database failures or callback sends. Absent on older responses.
|
|
1077
|
+
*/
|
|
1078
|
+
dispatchRecoveries: z.int().nonnegative().optional(),
|
|
1040
1079
|
/** Executor-observed elapsed time; absent when no durable timing survived. */
|
|
1041
1080
|
durationMs: z
|
|
1042
1081
|
.number()
|
|
@@ -1046,7 +1085,24 @@ export const attemptSchema = z
|
|
|
1046
1085
|
.optional(),
|
|
1047
1086
|
...timingEvidenceShape,
|
|
1048
1087
|
id: attemptIdSchema,
|
|
1088
|
+
/**
|
|
1089
|
+
* Instrumented send authorizations granted after a later local alarm
|
|
1090
|
+
* replayed the original wake receipt. Preserves the attempt and delivery
|
|
1091
|
+
* identity; excludes synchronous receipt hedges and repeated authorization
|
|
1092
|
+
* acknowledgements. A grant does not prove a callback left. Absent on
|
|
1093
|
+
* older responses.
|
|
1094
|
+
*/
|
|
1095
|
+
localReceiptRecoveries: z.int().nonnegative().optional(),
|
|
1049
1096
|
occurrence: occurrenceIdSchema,
|
|
1097
|
+
/**
|
|
1098
|
+
* How many times the watchdog took this attempt's send back and sent it
|
|
1099
|
+
* again: the send was authorized, and its outcome was never recorded
|
|
1100
|
+
* before its lease expired. Each re-send uses this attempt's `delivery` id,
|
|
1101
|
+
* so the receiver may have got the attempt more than once. `state` is the
|
|
1102
|
+
* outcome that was recorded. The timing evidence is the earliest send
|
|
1103
|
+
* known to have left. Absent when nothing was re-sent.
|
|
1104
|
+
*/
|
|
1105
|
+
rescues: z.int().positive().optional(),
|
|
1050
1106
|
/** Stable next-action code paired with a diagnostic when one is known. */
|
|
1051
1107
|
remediation: attemptRemediationSchema.optional(),
|
|
1052
1108
|
/**
|
package/dist/usage.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "./zod.js";
|
|
2
|
+
import { MAX_USAGE_WINDOW_DAYS } from "./configuration-bounds.js";
|
|
2
3
|
import { timestampSchema } from "./time.js";
|
|
3
4
|
/**
|
|
4
5
|
* A legacy operational aggregate of terminal occurrences.
|
|
@@ -67,7 +68,7 @@ export const USAGE_BOUNDS = {
|
|
|
67
68
|
* never older than that. It is a contract ceiling rather than a plan one: a
|
|
68
69
|
* plan may bring it closer and may never push it out.
|
|
69
70
|
*/
|
|
70
|
-
maxWindowDays:
|
|
71
|
+
maxWindowDays: MAX_USAGE_WINDOW_DAYS,
|
|
71
72
|
};
|
|
72
73
|
/** How a terminal occurrence ended. The four retained terminal states. */
|
|
73
74
|
export const BILLABLE_TERMINAL_STATES = [
|
|
@@ -202,26 +203,10 @@ export const usageSchema = z
|
|
|
202
203
|
*/
|
|
203
204
|
freshness: z.object({ kind: z.literal("authoritative") }),
|
|
204
205
|
/**
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* `dailyAttemptCeiling` attempts in a UTC day, and defers every schedule to
|
|
210
|
-
* the next day boundary rather than failing them. Nothing lost, nothing
|
|
211
|
-
* failed — and nothing running either, for up to a day, on a product whose
|
|
212
|
-
* whole job is to run things. The operator found his own account in that
|
|
213
|
-
* state during the W4-10 walk and no screen anywhere named it: the runs
|
|
214
|
-
* read "Delivering", the dashboard had no action waiting, and the only
|
|
215
|
-
* visible trace was an unremarkable number on the billing panel.
|
|
216
|
-
*
|
|
217
|
-
* The disposition, the ceiling and the count all lived inside
|
|
218
|
-
* `DialerWorker` and `EntitlementPolicy`; neither ever left
|
|
219
|
-
* `packages/application`, and `days` above counts settled *occurrences*
|
|
220
|
-
* rather than attempts, so it could not be derived either.
|
|
221
|
-
*
|
|
222
|
-
* Absent when this deployment sets no ceiling, which is the honest shape
|
|
223
|
-
* for "there is no allowance to be near the end of" — a surface must not
|
|
224
|
-
* render a limit nobody has.
|
|
206
|
+
* Legacy daily-allowance projection, retained for installed clients and
|
|
207
|
+
* mixed-version responses. W0-15 retires the daily quota; current authority
|
|
208
|
+
* readers omit this optional object rather than querying an obsolete count.
|
|
209
|
+
* Older servers can still explain parked work to compatible dashboards.
|
|
225
210
|
*/
|
|
226
211
|
plan: z
|
|
227
212
|
.object({
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
"classifiedAt": "2026-07-28T15:00:00.071Z",
|
|
6
6
|
"delivery": "dlv_01h8xyz9k2m4n6p8r0t2v4w6y8",
|
|
7
7
|
"diagnostic": "http_retryable",
|
|
8
|
+
"dispatchRecoveries": 0,
|
|
8
9
|
"durationMs": 71,
|
|
9
10
|
"firstAttemptLatenessMs": 0,
|
|
10
11
|
"firstAttemptStartedAt": "2026-07-28T15:00:00.000Z",
|
|
11
12
|
"timingEligibility": "eligible",
|
|
12
13
|
"timingPolicyVersion": "payg-v1",
|
|
13
14
|
"id": "att_01h8xyz9k2m4n6p8r0t2v4w6y8",
|
|
15
|
+
"localReceiptRecoveries": 0,
|
|
14
16
|
"occurrence": "occ_01h8xyz9k2m4n6p8r0t2v4w6y8",
|
|
15
17
|
"remediation": "review_retry_policy",
|
|
16
18
|
"responseStatus": 503,
|
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
"classifiedAt": "2026-07-28T15:02:00.000Z",
|
|
5
5
|
"delivery": "dlv_11h8xyz9k2m4n6p8r0t2v4w6y8",
|
|
6
6
|
"diagnostic": "network_ambiguous",
|
|
7
|
+
"dispatchRecoveries": 2,
|
|
7
8
|
"durationMs": 10000,
|
|
8
9
|
"firstAttemptLatenessMs": 0,
|
|
9
10
|
"firstAttemptStartedAt": "2026-07-28T15:00:00.000Z",
|
|
10
11
|
"timingEligibility": "eligible",
|
|
11
12
|
"timingPolicyVersion": "payg-v1",
|
|
12
13
|
"id": "att_11h8xyz9k2m4n6p8r0t2v4w6y8",
|
|
14
|
+
"localReceiptRecoveries": 1,
|
|
13
15
|
"occurrence": "occ_01h8xyz9k2m4n6p8r0t2v4w6y8",
|
|
14
16
|
"remediation": "review_before_redelivery",
|
|
15
17
|
"startedAt": "2026-07-28T15:01:50.000Z",
|