@haaaiawd/second-nature 0.1.43 → 0.1.51

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.
@@ -1,111 +1,111 @@
1
- import type { CredentialContext, CredentialState } from "../../shared/types/credential.js";
2
- import { type FailureClass } from "./failure-taxonomy.js";
3
- export declare const CHANNEL_TYPES: readonly ["api_rest", "api_rpc", "a2a", "mcp", "cli", "skill", "browser"];
4
- export type ChannelType = (typeof CHANNEL_TYPES)[number];
5
- export declare const CAPABILITY_INTENTS: readonly ["feed.read", "post.publish", "comment.reply", "notification.list", "message.send", "agent.register", "agent.heartbeat", "work.discover", "task.claim"];
6
- export type BuiltInCapabilityIntent = (typeof CAPABILITY_INTENTS)[number];
7
- export type CapabilityIntent = BuiltInCapabilityIntent | (string & {});
8
- export declare function isKnownCapabilityIntent(intent: string): intent is BuiltInCapabilityIntent;
9
- export interface ConnectorRequestIdentity {
10
- /** Platform handle for the target platform (readable, no credential). */
11
- platformHandle?: string;
12
- /** Canonical name across all platforms. */
13
- canonicalName?: string;
14
- }
15
- export interface ConnectorRequest {
16
- platformId: string;
17
- intent: CapabilityIntent;
18
- payload: Record<string, unknown>;
19
- preferredChannel?: ChannelType;
20
- timeoutMs?: number;
21
- idempotencyKey?: string;
22
- decisionId?: string;
23
- intentId?: string;
24
- /** T-V7C.C.4: identity for connector request (readable, no credential). */
25
- identity?: ConnectorRequestIdentity;
26
- }
27
- export interface ExecutionPlan {
28
- platformId: string;
29
- intent: CapabilityIntent;
30
- channel: ChannelType;
31
- endpointMode: "rest_json" | "a2a_envelope" | "cli_stdout" | "skill_call";
32
- idempotencyKey?: string;
33
- /** True when selected channel is manifest-marked degraded (cli/skill/browser). */
34
- degraded?: boolean;
35
- }
36
- export interface ConnectorResult<T> {
37
- status: "success" | "retryable_failure" | "terminal_failure";
38
- data?: T;
39
- failureClass?: FailureClass;
40
- retryAfterMs?: number;
41
- executionId?: string;
42
- metadata: {
43
- platformId: string;
44
- channel: ChannelType;
45
- latencyMs: number;
46
- degraded?: boolean;
47
- detail?: string;
48
- };
49
- }
50
- export interface RawAttempt {
51
- platformId: string;
52
- channel: ChannelType;
53
- latencyMs: number;
54
- degraded?: boolean;
55
- success: boolean;
56
- payload?: unknown;
57
- error?: unknown;
58
- }
59
- export interface CredentialContextPort {
60
- loadCredentialState(platformId: string): Promise<CredentialContext>;
61
- }
62
- export interface CooldownLedgerPort {
63
- loadCooldownState(platformId: string, intent: CapabilityIntent): Promise<{
64
- blocked: boolean;
65
- retryAfterMs?: number;
66
- }>;
67
- }
68
- export interface RouteContextPort extends CredentialContextPort, CooldownLedgerPort {
69
- }
70
- export interface ConnectorManifestLike {
71
- platformId: string;
72
- supportedCapabilities: CapabilityIntent[];
73
- channelPriority: ChannelType[];
74
- credentialTypes: string[];
75
- degradedChannels?: ChannelType[];
76
- sourceRefPolicy?: {
77
- minSourceRefs?: number;
78
- rejectInlineSensitivePayload?: boolean;
79
- };
80
- }
81
- export interface ConnectorManifestLoader {
82
- loadManifest(platformId: string): ConnectorManifestLike;
83
- }
84
- export interface RoutePlanner {
85
- planRoute(intent: CapabilityIntent, request: ConnectorRequest): Promise<ExecutionPlan>;
86
- }
87
- export interface ExecutionRunner {
88
- run(plan: ExecutionPlan, request: ConnectorRequest): Promise<RawAttempt>;
89
- }
90
- export interface ConnectorExecutionPort {
91
- executeCapability(intent: CapabilityIntent, request: ConnectorRequest): Promise<ConnectorResult<unknown>>;
92
- }
93
- export interface ConnectorExecutor {
94
- executeEffect(input: {
95
- platformId: string;
96
- intent: CapabilityIntent;
97
- payload: Record<string, unknown>;
98
- decisionId: string;
99
- intentId: string;
100
- idempotencyKey: string;
101
- /** T-V7C.C.4: identity for connector request (readable, no credential). */
102
- identity?: ConnectorRequestIdentity;
103
- }): Promise<ConnectorResult<unknown>>;
104
- }
105
- export declare function normalizeOutcome(attempt: RawAttempt): ConnectorResult<unknown>;
106
- export declare function createConnectorContractCore(input: {
107
- manifestLoader: ConnectorManifestLoader;
108
- routePlanner: RoutePlanner;
109
- executionRunner: ExecutionRunner;
110
- }): ConnectorExecutionPort;
111
- export declare function isCredentialActive(state: CredentialState): boolean;
1
+ import type { CredentialContext, CredentialState } from "../../shared/types/credential.js";
2
+ import { type FailureClass } from "./failure-taxonomy.js";
3
+ export declare const CHANNEL_TYPES: readonly ["api_rest", "api_rpc", "a2a", "mcp", "cli", "skill", "browser"];
4
+ export type ChannelType = (typeof CHANNEL_TYPES)[number];
5
+ export declare const CAPABILITY_INTENTS: readonly ["feed.read", "post.publish", "comment.reply", "notification.list", "message.send", "agent.register", "agent.heartbeat", "work.discover", "task.claim"];
6
+ export type BuiltInCapabilityIntent = (typeof CAPABILITY_INTENTS)[number];
7
+ export type CapabilityIntent = BuiltInCapabilityIntent | (string & {});
8
+ export declare function isKnownCapabilityIntent(intent: string): intent is BuiltInCapabilityIntent;
9
+ export interface ConnectorRequestIdentity {
10
+ /** Platform handle for the target platform (readable, no credential). */
11
+ platformHandle?: string;
12
+ /** Canonical name across all platforms. */
13
+ canonicalName?: string;
14
+ }
15
+ export interface ConnectorRequest {
16
+ platformId: string;
17
+ intent: CapabilityIntent;
18
+ payload: Record<string, unknown>;
19
+ preferredChannel?: ChannelType;
20
+ timeoutMs?: number;
21
+ idempotencyKey?: string;
22
+ decisionId?: string;
23
+ intentId?: string;
24
+ /** T-V7C.C.4: identity for connector request (readable, no credential). */
25
+ identity?: ConnectorRequestIdentity;
26
+ }
27
+ export interface ExecutionPlan {
28
+ platformId: string;
29
+ intent: CapabilityIntent;
30
+ channel: ChannelType;
31
+ endpointMode: "rest_json" | "a2a_envelope" | "cli_stdout" | "skill_call";
32
+ idempotencyKey?: string;
33
+ /** True when selected channel is manifest-marked degraded (cli/skill/browser). */
34
+ degraded?: boolean;
35
+ }
36
+ export interface ConnectorResult<T> {
37
+ status: "success" | "retryable_failure" | "terminal_failure";
38
+ data?: T;
39
+ failureClass?: FailureClass;
40
+ retryAfterMs?: number;
41
+ executionId?: string;
42
+ metadata: {
43
+ platformId: string;
44
+ channel: ChannelType;
45
+ latencyMs: number;
46
+ degraded?: boolean;
47
+ detail?: string;
48
+ };
49
+ }
50
+ export interface RawAttempt {
51
+ platformId: string;
52
+ channel: ChannelType;
53
+ latencyMs: number;
54
+ degraded?: boolean;
55
+ success: boolean;
56
+ payload?: unknown;
57
+ error?: unknown;
58
+ }
59
+ export interface CredentialContextPort {
60
+ loadCredentialState(platformId: string): Promise<CredentialContext>;
61
+ }
62
+ export interface CooldownLedgerPort {
63
+ loadCooldownState(platformId: string, intent: CapabilityIntent): Promise<{
64
+ blocked: boolean;
65
+ retryAfterMs?: number;
66
+ }>;
67
+ }
68
+ export interface RouteContextPort extends CredentialContextPort, CooldownLedgerPort {
69
+ }
70
+ export interface ConnectorManifestLike {
71
+ platformId: string;
72
+ supportedCapabilities: CapabilityIntent[];
73
+ channelPriority: ChannelType[];
74
+ credentialTypes: string[];
75
+ degradedChannels?: ChannelType[];
76
+ sourceRefPolicy?: {
77
+ minSourceRefs?: number;
78
+ rejectInlineSensitivePayload?: boolean;
79
+ };
80
+ }
81
+ export interface ConnectorManifestLoader {
82
+ loadManifest(platformId: string): ConnectorManifestLike;
83
+ }
84
+ export interface RoutePlanner {
85
+ planRoute(intent: CapabilityIntent, request: ConnectorRequest): Promise<ExecutionPlan>;
86
+ }
87
+ export interface ExecutionRunner {
88
+ run(plan: ExecutionPlan, request: ConnectorRequest): Promise<RawAttempt>;
89
+ }
90
+ export interface ConnectorExecutionPort {
91
+ executeCapability(intent: CapabilityIntent, request: ConnectorRequest): Promise<ConnectorResult<unknown>>;
92
+ }
93
+ export interface ConnectorExecutor {
94
+ executeEffect(input: {
95
+ platformId: string;
96
+ intent: CapabilityIntent;
97
+ payload: Record<string, unknown>;
98
+ decisionId: string;
99
+ intentId: string;
100
+ idempotencyKey: string;
101
+ /** T-V7C.C.4: identity for connector request (readable, no credential). */
102
+ identity?: ConnectorRequestIdentity;
103
+ }): Promise<ConnectorResult<unknown>>;
104
+ }
105
+ export declare function normalizeOutcome(attempt: RawAttempt): ConnectorResult<unknown>;
106
+ export declare function createConnectorContractCore(input: {
107
+ manifestLoader: ConnectorManifestLoader;
108
+ routePlanner: RoutePlanner;
109
+ executionRunner: ExecutionRunner;
110
+ }): ConnectorExecutionPort;
111
+ export declare function isCredentialActive(state: CredentialState): boolean;
@@ -1,13 +1,13 @@
1
- export declare const FAILURE_CLASSES: readonly ["transport_failure", "auth_failure", "credential_expired", "verification_required", "rate_limited", "cooldown_blocked", "parse_failure", "protocol_mismatch", "semantic_rejection", "idempotency_conflict", "concurrency_conflict", "permanent_input_error", "platform_unavailable", "configuration_missing", "script_error", "timeout", "unknown_platform_change"];
2
- export type FailureClass = (typeof FAILURE_CLASSES)[number];
3
- export interface FailureClassification {
4
- class: FailureClass;
5
- retryable: boolean;
6
- retryAfterMs?: number;
7
- }
8
- export declare class ConnectorPolicyError extends Error {
9
- readonly failureClass: FailureClass;
10
- readonly retryAfterMs?: number | undefined;
11
- constructor(failureClass: FailureClass, message: string, retryAfterMs?: number | undefined);
12
- }
13
- export declare function classifyFailure(error: unknown): FailureClassification;
1
+ export declare const FAILURE_CLASSES: readonly ["transport_failure", "auth_failure", "credential_expired", "verification_required", "rate_limited", "cooldown_blocked", "parse_failure", "protocol_mismatch", "semantic_rejection", "idempotency_conflict", "concurrency_conflict", "permanent_input_error", "platform_unavailable", "configuration_missing", "script_error", "timeout", "unknown_platform_change"];
2
+ export type FailureClass = (typeof FAILURE_CLASSES)[number];
3
+ export interface FailureClassification {
4
+ class: FailureClass;
5
+ retryable: boolean;
6
+ retryAfterMs?: number;
7
+ }
8
+ export declare class ConnectorPolicyError extends Error {
9
+ readonly failureClass: FailureClass;
10
+ readonly retryAfterMs?: number | undefined;
11
+ constructor(failureClass: FailureClass, message: string, retryAfterMs?: number | undefined);
12
+ }
13
+ export declare function classifyFailure(error: unknown): FailureClassification;
@@ -1,186 +1,186 @@
1
- export const FAILURE_CLASSES = [
2
- "transport_failure",
3
- "auth_failure",
4
- "credential_expired",
5
- "verification_required",
6
- "rate_limited",
7
- "cooldown_blocked",
8
- "parse_failure",
9
- "protocol_mismatch",
10
- "semantic_rejection",
11
- "idempotency_conflict",
12
- "concurrency_conflict",
13
- "permanent_input_error",
14
- "platform_unavailable",
15
- "configuration_missing",
16
- "script_error",
17
- "timeout",
18
- "unknown_platform_change",
19
- ];
20
- const RETRYABLE_BY_CLASS = {
21
- transport_failure: true,
22
- auth_failure: false,
23
- credential_expired: false,
24
- verification_required: false,
25
- rate_limited: true,
26
- cooldown_blocked: false,
27
- parse_failure: false,
28
- protocol_mismatch: false,
29
- semantic_rejection: false,
30
- idempotency_conflict: false,
31
- concurrency_conflict: true,
32
- permanent_input_error: false,
33
- platform_unavailable: false,
34
- configuration_missing: false,
35
- script_error: false,
36
- timeout: true,
37
- unknown_platform_change: false,
38
- };
39
- export class ConnectorPolicyError extends Error {
40
- failureClass;
41
- retryAfterMs;
42
- constructor(failureClass, message, retryAfterMs) {
43
- super(message);
44
- this.failureClass = failureClass;
45
- this.retryAfterMs = retryAfterMs;
46
- this.name = "ConnectorPolicyError";
47
- }
48
- }
49
- function readRetryAfterMs(input) {
50
- const retryAfterMs = input.retryAfterMs;
51
- if (typeof retryAfterMs === "number" &&
52
- Number.isFinite(retryAfterMs) &&
53
- retryAfterMs > 0) {
54
- return retryAfterMs;
55
- }
56
- const retryAfterSeconds = input.retryAfterSeconds;
57
- if (typeof retryAfterSeconds === "number" &&
58
- Number.isFinite(retryAfterSeconds) &&
59
- retryAfterSeconds > 0) {
60
- return retryAfterSeconds * 1000;
61
- }
62
- return undefined;
63
- }
64
- export function classifyFailure(error) {
65
- if (error instanceof ConnectorPolicyError) {
66
- return {
67
- class: error.failureClass,
68
- retryable: RETRYABLE_BY_CLASS[error.failureClass],
69
- retryAfterMs: error.retryAfterMs,
70
- };
71
- }
72
- if (error instanceof SyntaxError) {
73
- return { class: "parse_failure", retryable: false };
74
- }
75
- if (error && typeof error === "object") {
76
- const record = error;
77
- const code = record.code;
78
- if (typeof code === "string") {
79
- if (code === "auth_failure")
80
- return {
81
- class: "auth_failure",
82
- retryable: RETRYABLE_BY_CLASS.auth_failure,
83
- };
84
- if (code === "verification_required")
85
- return {
86
- class: "verification_required",
87
- retryable: RETRYABLE_BY_CLASS.verification_required,
88
- };
89
- if (code === "credential_expired")
90
- return {
91
- class: "credential_expired",
92
- retryable: RETRYABLE_BY_CLASS.credential_expired,
93
- };
94
- if (code === "cooldown_blocked")
95
- return {
96
- class: "cooldown_blocked",
97
- retryable: RETRYABLE_BY_CLASS.cooldown_blocked,
98
- };
99
- if (code === "idempotency_conflict")
100
- return {
101
- class: "idempotency_conflict",
102
- retryable: RETRYABLE_BY_CLASS.idempotency_conflict,
103
- };
104
- if (code === "concurrency_conflict")
105
- return {
106
- class: "concurrency_conflict",
107
- retryable: RETRYABLE_BY_CLASS.concurrency_conflict,
108
- };
109
- if (code === "protocol_mismatch")
110
- return {
111
- class: "protocol_mismatch",
112
- retryable: RETRYABLE_BY_CLASS.protocol_mismatch,
113
- };
114
- if (code === "semantic_rejection")
115
- return {
116
- class: "semantic_rejection",
117
- retryable: RETRYABLE_BY_CLASS.semantic_rejection,
118
- };
119
- if (code === "transport_failure")
120
- return {
121
- class: "transport_failure",
122
- retryable: RETRYABLE_BY_CLASS.transport_failure,
123
- };
124
- if (code === "permanent_input_error")
125
- return {
126
- class: "permanent_input_error",
127
- retryable: RETRYABLE_BY_CLASS.permanent_input_error,
128
- };
129
- if (code === "platform_unavailable")
130
- return {
131
- class: "platform_unavailable",
132
- retryable: RETRYABLE_BY_CLASS.platform_unavailable,
133
- };
134
- if (code === "configuration_missing")
135
- return {
136
- class: "configuration_missing",
137
- retryable: RETRYABLE_BY_CLASS.configuration_missing,
138
- };
139
- if (code === "script_error")
140
- return {
141
- class: "script_error",
142
- retryable: RETRYABLE_BY_CLASS.script_error,
143
- };
144
- if (code === "timeout")
145
- return {
146
- class: "timeout",
147
- retryable: RETRYABLE_BY_CLASS.timeout,
148
- };
149
- if (code === "unknown_platform" || code === "unknown_platform_change")
150
- return {
151
- class: "unknown_platform_change",
152
- retryable: RETRYABLE_BY_CLASS.unknown_platform_change,
153
- };
154
- }
155
- const status = record.status;
156
- if (status === 429) {
157
- return {
158
- class: "rate_limited",
159
- retryable: RETRYABLE_BY_CLASS.rate_limited,
160
- retryAfterMs: readRetryAfterMs(record),
161
- };
162
- }
163
- if (status === 401 || status === 403) {
164
- return {
165
- class: "auth_failure",
166
- retryable: RETRYABLE_BY_CLASS.auth_failure,
167
- };
168
- }
169
- if (status === 400 || status === 404 || status === 422) {
170
- return {
171
- class: "permanent_input_error",
172
- retryable: RETRYABLE_BY_CLASS.permanent_input_error,
173
- };
174
- }
175
- if (status === 500 || status === 502 || status === 503 || status === 504) {
176
- return {
177
- class: "transport_failure",
178
- retryable: RETRYABLE_BY_CLASS.transport_failure,
179
- };
180
- }
181
- }
182
- return {
183
- class: "unknown_platform_change",
184
- retryable: RETRYABLE_BY_CLASS.unknown_platform_change,
185
- };
186
- }
1
+ export const FAILURE_CLASSES = [
2
+ "transport_failure",
3
+ "auth_failure",
4
+ "credential_expired",
5
+ "verification_required",
6
+ "rate_limited",
7
+ "cooldown_blocked",
8
+ "parse_failure",
9
+ "protocol_mismatch",
10
+ "semantic_rejection",
11
+ "idempotency_conflict",
12
+ "concurrency_conflict",
13
+ "permanent_input_error",
14
+ "platform_unavailable",
15
+ "configuration_missing",
16
+ "script_error",
17
+ "timeout",
18
+ "unknown_platform_change",
19
+ ];
20
+ const RETRYABLE_BY_CLASS = {
21
+ transport_failure: true,
22
+ auth_failure: false,
23
+ credential_expired: false,
24
+ verification_required: false,
25
+ rate_limited: true,
26
+ cooldown_blocked: false,
27
+ parse_failure: false,
28
+ protocol_mismatch: false,
29
+ semantic_rejection: false,
30
+ idempotency_conflict: false,
31
+ concurrency_conflict: true,
32
+ permanent_input_error: false,
33
+ platform_unavailable: false,
34
+ configuration_missing: false,
35
+ script_error: false,
36
+ timeout: true,
37
+ unknown_platform_change: false,
38
+ };
39
+ export class ConnectorPolicyError extends Error {
40
+ failureClass;
41
+ retryAfterMs;
42
+ constructor(failureClass, message, retryAfterMs) {
43
+ super(message);
44
+ this.failureClass = failureClass;
45
+ this.retryAfterMs = retryAfterMs;
46
+ this.name = "ConnectorPolicyError";
47
+ }
48
+ }
49
+ function readRetryAfterMs(input) {
50
+ const retryAfterMs = input.retryAfterMs;
51
+ if (typeof retryAfterMs === "number" &&
52
+ Number.isFinite(retryAfterMs) &&
53
+ retryAfterMs > 0) {
54
+ return retryAfterMs;
55
+ }
56
+ const retryAfterSeconds = input.retryAfterSeconds;
57
+ if (typeof retryAfterSeconds === "number" &&
58
+ Number.isFinite(retryAfterSeconds) &&
59
+ retryAfterSeconds > 0) {
60
+ return retryAfterSeconds * 1000;
61
+ }
62
+ return undefined;
63
+ }
64
+ export function classifyFailure(error) {
65
+ if (error instanceof ConnectorPolicyError) {
66
+ return {
67
+ class: error.failureClass,
68
+ retryable: RETRYABLE_BY_CLASS[error.failureClass],
69
+ retryAfterMs: error.retryAfterMs,
70
+ };
71
+ }
72
+ if (error instanceof SyntaxError) {
73
+ return { class: "parse_failure", retryable: false };
74
+ }
75
+ if (error && typeof error === "object") {
76
+ const record = error;
77
+ const code = record.code;
78
+ if (typeof code === "string") {
79
+ if (code === "auth_failure")
80
+ return {
81
+ class: "auth_failure",
82
+ retryable: RETRYABLE_BY_CLASS.auth_failure,
83
+ };
84
+ if (code === "verification_required")
85
+ return {
86
+ class: "verification_required",
87
+ retryable: RETRYABLE_BY_CLASS.verification_required,
88
+ };
89
+ if (code === "credential_expired")
90
+ return {
91
+ class: "credential_expired",
92
+ retryable: RETRYABLE_BY_CLASS.credential_expired,
93
+ };
94
+ if (code === "cooldown_blocked")
95
+ return {
96
+ class: "cooldown_blocked",
97
+ retryable: RETRYABLE_BY_CLASS.cooldown_blocked,
98
+ };
99
+ if (code === "idempotency_conflict")
100
+ return {
101
+ class: "idempotency_conflict",
102
+ retryable: RETRYABLE_BY_CLASS.idempotency_conflict,
103
+ };
104
+ if (code === "concurrency_conflict")
105
+ return {
106
+ class: "concurrency_conflict",
107
+ retryable: RETRYABLE_BY_CLASS.concurrency_conflict,
108
+ };
109
+ if (code === "protocol_mismatch")
110
+ return {
111
+ class: "protocol_mismatch",
112
+ retryable: RETRYABLE_BY_CLASS.protocol_mismatch,
113
+ };
114
+ if (code === "semantic_rejection")
115
+ return {
116
+ class: "semantic_rejection",
117
+ retryable: RETRYABLE_BY_CLASS.semantic_rejection,
118
+ };
119
+ if (code === "transport_failure")
120
+ return {
121
+ class: "transport_failure",
122
+ retryable: RETRYABLE_BY_CLASS.transport_failure,
123
+ };
124
+ if (code === "permanent_input_error")
125
+ return {
126
+ class: "permanent_input_error",
127
+ retryable: RETRYABLE_BY_CLASS.permanent_input_error,
128
+ };
129
+ if (code === "platform_unavailable")
130
+ return {
131
+ class: "platform_unavailable",
132
+ retryable: RETRYABLE_BY_CLASS.platform_unavailable,
133
+ };
134
+ if (code === "configuration_missing")
135
+ return {
136
+ class: "configuration_missing",
137
+ retryable: RETRYABLE_BY_CLASS.configuration_missing,
138
+ };
139
+ if (code === "script_error")
140
+ return {
141
+ class: "script_error",
142
+ retryable: RETRYABLE_BY_CLASS.script_error,
143
+ };
144
+ if (code === "timeout")
145
+ return {
146
+ class: "timeout",
147
+ retryable: RETRYABLE_BY_CLASS.timeout,
148
+ };
149
+ if (code === "unknown_platform" || code === "unknown_platform_change")
150
+ return {
151
+ class: "unknown_platform_change",
152
+ retryable: RETRYABLE_BY_CLASS.unknown_platform_change,
153
+ };
154
+ }
155
+ const status = record.status;
156
+ if (status === 429) {
157
+ return {
158
+ class: "rate_limited",
159
+ retryable: RETRYABLE_BY_CLASS.rate_limited,
160
+ retryAfterMs: readRetryAfterMs(record),
161
+ };
162
+ }
163
+ if (status === 401 || status === 403) {
164
+ return {
165
+ class: "auth_failure",
166
+ retryable: RETRYABLE_BY_CLASS.auth_failure,
167
+ };
168
+ }
169
+ if (status === 400 || status === 404 || status === 422) {
170
+ return {
171
+ class: "permanent_input_error",
172
+ retryable: RETRYABLE_BY_CLASS.permanent_input_error,
173
+ };
174
+ }
175
+ if (status === 500 || status === 502 || status === 503 || status === 504) {
176
+ return {
177
+ class: "transport_failure",
178
+ retryable: RETRYABLE_BY_CLASS.transport_failure,
179
+ };
180
+ }
181
+ }
182
+ return {
183
+ class: "unknown_platform_change",
184
+ retryable: RETRYABLE_BY_CLASS.unknown_platform_change,
185
+ };
186
+ }