@sellable/mcp 0.1.554 → 0.1.555

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 (40) hide show
  1. package/dist/index-dev.js +0 -0
  2. package/dist/index.js +0 -0
  3. package/dist/refill-contract.d.ts +157 -0
  4. package/dist/refill-contract.js +487 -0
  5. package/dist/refill-run-client.d.ts +5 -0
  6. package/dist/refill-run-client.js +15 -0
  7. package/dist/refill-run-loop.d.ts +12 -1
  8. package/dist/refill-run-loop.js +158 -13
  9. package/dist/tools/campaign-message-preparation.d.ts +62 -0
  10. package/dist/tools/campaign-message-preparation.js +41 -0
  11. package/dist/tools/evergreen-refill-plan.d.ts +3 -0
  12. package/dist/tools/evergreen-refill-plan.js +29 -7
  13. package/dist/tools/prompts.js +9 -0
  14. package/dist/tools/refill-executors.d.ts +38 -0
  15. package/dist/tools/refill-executors.js +222 -3
  16. package/dist/tools/refill-sends-v2.d.ts +112 -1
  17. package/dist/tools/refill-sends-v2.js +302 -2
  18. package/dist/tools/refill-sends.d.ts +678 -32
  19. package/dist/tools/refill-sends.js +274 -13
  20. package/dist/tools/refill-target-plan.js +486 -14
  21. package/dist/tools/registry.d.ts +96 -27
  22. package/dist/tools/registry.js +1 -3
  23. package/dist/tools/scheduler-fill-capacity.js +1 -1
  24. package/dist/tools/scheduler-run.d.ts +71 -0
  25. package/dist/tools/scheduler-run.js +203 -1
  26. package/dist/tools/workspaces.d.ts +4 -6
  27. package/dist/tools/workspaces.js +11 -13
  28. package/package.json +1 -1
  29. package/skills/refill-sends/SKILL.md +91 -353
  30. package/skills/refill-sends-v2/SKILL.md +6 -6
  31. package/skills/refill-sends-v2-workflow/SKILL.md +5 -5
  32. package/skills/refill-sends-v2-workflow/core/flow.v1.json +8 -8
  33. package/skills/refill-sends-workflow/SKILL.md +100 -743
  34. package/skills/refill-sends-workflow/core/contract.v2.json +543 -0
  35. package/skills/refill-sends-workflow/core/flow.v1.json +185 -1
  36. package/dist/refill-date-window.d.ts +0 -34
  37. package/dist/refill-date-window.js +0 -210
  38. package/dist/tools/refill-sends-evergreen.d.ts +0 -28
  39. package/dist/tools/refill-sends-evergreen.js +0 -47
  40. package/skills/research/config.json +0 -9
package/dist/index-dev.js CHANGED
File without changes
package/dist/index.js CHANGED
File without changes
@@ -0,0 +1,157 @@
1
+ export declare const REFILL_CONTRACT_VERSION: "2.0.0";
2
+ export declare const REFILL_CONTRACT_CACHE_VERSION: "refill-contract-v1";
3
+ export declare const REFILL_CONTRACT_SUPPORTED_MAJOR: 2;
4
+ export declare const REFILL_CONTRACT_ERROR_CODES: readonly ["refill_contract_not_implemented", "unsupported_refill_contract_major", "refill_contract_hash_mismatch", "refill_contract_semantic_mismatch"];
5
+ export type RefillContractErrorCode = (typeof REFILL_CONTRACT_ERROR_CODES)[number];
6
+ export declare class RefillContractError extends Error {
7
+ readonly code: RefillContractErrorCode;
8
+ constructor(code: RefillContractErrorCode, message: string);
9
+ }
10
+ export declare const REFILL_SCOPE_IDS: readonly ["workspace_id", "target_date", "sender_selectors", "campaign_selectors", "approval_mode", "contract_identity", "installed_identity"];
11
+ export declare const REFILL_GATE_IDS: readonly ["workspace_access", "approval_packet", "source_family", "threshold", "scheduler", "campaign_lifecycle", "send_time", "no_direct_send", "one_primitive", "fresh_reread", "normalized_accounting", "prep_circuit", "terminal_truth"];
12
+ export declare const REFILL_STATE_IDS: readonly ["planning", "awaiting_approval", "executing", "settling", "replanning", "terminal"];
13
+ export declare const REFILL_ACTION_IDS: readonly ["prepare_messages", "approve_messages", "rerun_errored_cells", "start_paused_campaign", "run_scheduler_sweep", "scheduler_first_settle", "wait_for_scheduler", "wait_for_active_work", "wait_for_source_import", "copy_selected_source_rows", "continue_signal_discovery_source", "continue_sales_nav_source", "continue_prospeo_source", "manual_source_replenishment", "refresh_paid_inmail_credits", "lower_paid_inmail_threshold", "switch_to_connection_lane", "create_connection_campaign", "next_campaign", "done"];
14
+ export declare const REFILL_RECEIPT_IDS: readonly ["target_plan_receipt", "preparation_receipt", "scheduler_receipt", "run_receipt"];
15
+ export declare const REFILL_SIDE_EFFECT_CLASS_IDS: readonly ["read_only", "message_preparation", "message_approval", "source_replenishment", "credit_refresh", "campaign_start", "scheduler_placement"];
16
+ export declare const REFILL_FORBIDDEN_ACTION_IDS: readonly ["direct_send", "raw_scheduler_write", "campaign_create", "campaign_archive_delete", "threshold_lowering", "unselected_source_mutation", "unapproved_campaign_start", "sender_config_write"];
17
+ export declare const REFILL_TERMINAL_REASON_IDS: readonly ["projected_full", "concrete_blocker", "deadline_reached", "iteration_limit", "operator_stopped", "capped_by_scheduler", "loaded_awaiting_scheduler", "lanes_exhausted", "not_an_evergreen_workspace", "no_refillable_campaigns"];
18
+ export type RefillScopeId = (typeof REFILL_SCOPE_IDS)[number];
19
+ export type RefillGateId = (typeof REFILL_GATE_IDS)[number];
20
+ export type RefillStateId = (typeof REFILL_STATE_IDS)[number];
21
+ export type RefillActionId = (typeof REFILL_ACTION_IDS)[number];
22
+ export type RefillReceiptId = (typeof REFILL_RECEIPT_IDS)[number];
23
+ export type RefillSideEffectClassId = (typeof REFILL_SIDE_EFFECT_CLASS_IDS)[number];
24
+ export type RefillForbiddenActionId = (typeof REFILL_FORBIDDEN_ACTION_IDS)[number];
25
+ export type RefillTerminalReasonId = (typeof REFILL_TERMINAL_REASON_IDS)[number];
26
+ export type RefillAction = {
27
+ [Kind in RefillActionId]: {
28
+ kind: Kind;
29
+ actionKey: string;
30
+ sideEffectClass: RefillSideEffectClassId;
31
+ };
32
+ }[RefillActionId];
33
+ export type RefillReceipt = {
34
+ [Kind in RefillReceiptId]: {
35
+ kind: Kind;
36
+ actionKey: string;
37
+ recordedAt: string;
38
+ };
39
+ }[RefillReceiptId];
40
+ export type RefillTerminal = {
41
+ [Reason in RefillTerminalReasonId]: {
42
+ kind: "terminal";
43
+ reason: Reason;
44
+ evidence: Record<string, unknown>;
45
+ };
46
+ }[RefillTerminalReasonId];
47
+ export declare function canonicalizeRefillContract(value: unknown): string;
48
+ export declare function computeRefillContractHash(value: unknown): string;
49
+ export declare const REFILL_CONTRACT_HASH: string;
50
+ export declare const refillContract: {
51
+ readonly contractHash: string;
52
+ readonly contractVersion: "2.0.0";
53
+ readonly cacheVersion: "refill-contract-v1";
54
+ readonly supportedMajor: 2;
55
+ readonly semantics: {
56
+ readonly scope: {
57
+ id: "workspace_id" | "target_date" | "sender_selectors" | "campaign_selectors" | "approval_mode" | "contract_identity" | "installed_identity";
58
+ }[];
59
+ readonly gates: {
60
+ id: "workspace_access" | "approval_packet" | "source_family" | "threshold" | "scheduler" | "campaign_lifecycle" | "send_time" | "no_direct_send" | "one_primitive" | "fresh_reread" | "normalized_accounting" | "prep_circuit" | "terminal_truth";
61
+ }[];
62
+ readonly states: {
63
+ id: "planning" | "awaiting_approval" | "executing" | "settling" | "replanning" | "terminal";
64
+ }[];
65
+ readonly actions: {
66
+ id: "prepare_messages" | "approve_messages" | "rerun_errored_cells" | "start_paused_campaign" | "run_scheduler_sweep" | "scheduler_first_settle" | "wait_for_scheduler" | "wait_for_active_work" | "wait_for_source_import" | "copy_selected_source_rows" | "continue_signal_discovery_source" | "continue_sales_nav_source" | "continue_prospeo_source" | "manual_source_replenishment" | "refresh_paid_inmail_credits" | "lower_paid_inmail_threshold" | "switch_to_connection_lane" | "create_connection_campaign" | "next_campaign" | "done";
67
+ sideEffectClass: "read_only" | "message_preparation" | "message_approval" | "source_replenishment" | "credit_refresh" | "campaign_start" | "scheduler_placement";
68
+ }[];
69
+ readonly receipts: readonly [{
70
+ readonly id: "target_plan_receipt";
71
+ readonly requiredFields: readonly ["refillLaneKey", "branchMetrics", "ledger", "targetDate", "actionKey", "targetShapeRevision", "stateRevision"];
72
+ }, {
73
+ readonly id: "preparation_receipt";
74
+ readonly requiredFields: readonly ["dependency", "circuit", "batchCalibration", "cooperativeStop"];
75
+ }, {
76
+ readonly id: "scheduler_receipt";
77
+ readonly requiredFields: readonly ["receiptVersion", "diagnosticsVersion", "status", "trigger", "workspaceId", "runId", "leaseFence", "expectedTargetsHash", "maxPlacements", "readyCellsFound", "cellsConsidered", "cellsScheduled", "cellsSkipped", "cellsDeferred", "campaignScopeSummary", "expectedTargetSummary", "changedCounts", "summary", "nextAction", "errorCount", "error"];
78
+ }, {
79
+ readonly id: "run_receipt";
80
+ readonly requiredFields: readonly ["runId", "fence", "gate", "gateSeq", "events", "doneReason"];
81
+ }];
82
+ readonly sideEffectClasses: {
83
+ id: "read_only" | "message_preparation" | "message_approval" | "source_replenishment" | "credit_refresh" | "campaign_start" | "scheduler_placement";
84
+ }[];
85
+ readonly forbiddenActions: {
86
+ id: "direct_send" | "raw_scheduler_write" | "campaign_create" | "campaign_archive_delete" | "threshold_lowering" | "unselected_source_mutation" | "unapproved_campaign_start" | "sender_config_write";
87
+ }[];
88
+ readonly terminalReasons: {
89
+ id: "projected_full" | "concrete_blocker" | "deadline_reached" | "iteration_limit" | "operator_stopped" | "capped_by_scheduler" | "loaded_awaiting_scheduler" | "lanes_exhausted" | "not_an_evergreen_workspace" | "no_refillable_campaigns";
90
+ terminalKind: string;
91
+ }[];
92
+ readonly transitions: readonly [{
93
+ readonly from: "planning";
94
+ readonly to: "awaiting_approval";
95
+ }, {
96
+ readonly from: "awaiting_approval";
97
+ readonly to: "executing";
98
+ }, {
99
+ readonly from: "executing";
100
+ readonly to: "settling";
101
+ }, {
102
+ readonly from: "settling";
103
+ readonly to: "replanning";
104
+ }, {
105
+ readonly from: "replanning";
106
+ readonly to: "executing";
107
+ }, {
108
+ readonly from: "replanning";
109
+ readonly to: "terminal";
110
+ }];
111
+ };
112
+ readonly backendBindings: {
113
+ readonly planner: {
114
+ readonly actions: ("prepare_messages" | "approve_messages" | "rerun_errored_cells" | "start_paused_campaign" | "run_scheduler_sweep" | "scheduler_first_settle" | "wait_for_scheduler" | "wait_for_active_work" | "wait_for_source_import" | "copy_selected_source_rows" | "continue_signal_discovery_source" | "continue_sales_nav_source" | "continue_prospeo_source" | "manual_source_replenishment" | "refresh_paid_inmail_credits" | "lower_paid_inmail_threshold" | "switch_to_connection_lane" | "create_connection_campaign" | "next_campaign" | "done")[];
115
+ readonly receiptFields: readonly ["refillLaneKey", "branchMetrics", "ledger", "targetDate", "actionKey", "targetShapeRevision", "stateRevision"];
116
+ };
117
+ readonly preparation: {
118
+ readonly dependencyClasses: readonly ["active", "transient", "permanent", "changed", "exhausted"];
119
+ readonly dependencyReasons: readonly ["active_cells", "dependency_timeout", "rate_limited", "provider_unavailable", "authentication_failed", "validation_failed", "schema_invalid", "config_epoch_changed", "source_epoch_changed", "frontier_exhausted", "unknown_dependency"];
120
+ readonly circuitStates: readonly ["closed", "open", "half_open", "reset"];
121
+ readonly cooperativeStopReasons: readonly ["target_satisfied_during_prep"];
122
+ readonly receiptFields: readonly ["dependency", "circuit", "batchCalibration", "cooperativeStop"];
123
+ };
124
+ readonly scheduler: {
125
+ readonly targetOutcomes: readonly ["included", "omitted"];
126
+ readonly omissionReasons: readonly ["no_ready_cells", "not_scheduler_eligible", "sender_mismatch", "capacity_prefiltered", "outside_target_date", "receipt_error"];
127
+ readonly runStatuses: readonly ["ran", "window_closed_noop", "failed"];
128
+ readonly nextActions: readonly ["refresh_paid_inmail_credits_then_rerun", "wait_for_capacity_or_window", "inspect_sender_mismatch", "no_ready_cells_continue_refill_prep", "scheduled_cells", "investigate_deferred_reasons", "investigate_scheduler_failure"];
129
+ readonly receiptFields: readonly ["receiptVersion", "diagnosticsVersion", "status", "trigger", "workspaceId", "runId", "leaseFence", "expectedTargetsHash", "maxPlacements", "readyCellsFound", "cellsConsidered", "cellsScheduled", "cellsSkipped", "cellsDeferred", "campaignScopeSummary", "expectedTargetSummary", "changedCounts", "summary", "nextAction", "errorCount", "error"];
130
+ };
131
+ readonly run: {
132
+ readonly gates: readonly ["g0_bootstrap", "g1_plan", "g2_execute", "g3_verify", "g4_terminal"];
133
+ readonly states: readonly ["planning", "awaiting_approval", "executing", "settling", "replanning", "terminal"];
134
+ readonly resultKinds: readonly ["started", "awaiting_approval", "active_run_in_progress", "resumed", "lease_lost", "scope_drift", "approval_expired", "approval_fingerprint_mismatch"];
135
+ readonly terminalReasons: readonly ["complete", "capped_by_scheduler", "loaded_awaiting_scheduler", "lanes_exhausted", "blocked", "not_an_evergreen_workspace", "no_refillable_campaigns"];
136
+ readonly refusals: readonly ["scope_drift", "approval_expired", "approval_fingerprint_mismatch", "legacy_read_only", "expected_target_overflow", "scheduler_receipt_incomplete"];
137
+ readonly scopeFields: readonly ["workspaceId", "intent", "senderIds", "campaignIds", "tableIds", "actionIds", "approvalMode", "dateSelector", "senderTimezones", "expectedTargetsHash", "maxPlacements", "contract", "installed"];
138
+ readonly approvalFields: readonly ["scopeHash", "targetShapeRevision", "actionFingerprint", "expectedTargetsHash", "sideEffectEnvelope", "maxPlacements", "approvalExpiresAt", "approvalFingerprint"];
139
+ };
140
+ };
141
+ };
142
+ export type RefillContract = typeof refillContract;
143
+ export declare function assertSupportedRefillContractMajor(version: string): void;
144
+ export declare function validateRefillContractAsset(value: unknown): RefillContract;
145
+ export declare function refillContractSemanticProjection(): {
146
+ contractVersion: "2.0.0";
147
+ cacheVersion: "refill-contract-v1";
148
+ contractHash: string;
149
+ semanticIds: {
150
+ [k: string]: string[];
151
+ };
152
+ };
153
+ export declare function validateRefillFlowProjection(value: unknown): void;
154
+ export declare function renderRefillBootstrapGuidance(): string;
155
+ export declare function renderRefillSafetyGuidance(): string;
156
+ export declare function renderRefillTerminalGuidance(): string;
157
+ export declare function assertNeverRefillVariant(value: never): never;
@@ -0,0 +1,487 @@
1
+ import { createHash } from "node:crypto";
2
+ export const REFILL_CONTRACT_VERSION = "2.0.0";
3
+ export const REFILL_CONTRACT_CACHE_VERSION = "refill-contract-v1";
4
+ export const REFILL_CONTRACT_SUPPORTED_MAJOR = 2;
5
+ export const REFILL_CONTRACT_ERROR_CODES = [
6
+ "refill_contract_not_implemented",
7
+ "unsupported_refill_contract_major",
8
+ "refill_contract_hash_mismatch",
9
+ "refill_contract_semantic_mismatch",
10
+ ];
11
+ export class RefillContractError extends Error {
12
+ code;
13
+ constructor(code, message) {
14
+ super(message);
15
+ this.code = code;
16
+ this.name = "RefillContractError";
17
+ }
18
+ }
19
+ export const REFILL_SCOPE_IDS = [
20
+ "workspace_id",
21
+ "target_date",
22
+ "sender_selectors",
23
+ "campaign_selectors",
24
+ "approval_mode",
25
+ "contract_identity",
26
+ "installed_identity",
27
+ ];
28
+ export const REFILL_GATE_IDS = [
29
+ "workspace_access",
30
+ "approval_packet",
31
+ "source_family",
32
+ "threshold",
33
+ "scheduler",
34
+ "campaign_lifecycle",
35
+ "send_time",
36
+ "no_direct_send",
37
+ "one_primitive",
38
+ "fresh_reread",
39
+ "normalized_accounting",
40
+ "prep_circuit",
41
+ "terminal_truth",
42
+ ];
43
+ export const REFILL_STATE_IDS = [
44
+ "planning",
45
+ "awaiting_approval",
46
+ "executing",
47
+ "settling",
48
+ "replanning",
49
+ "terminal",
50
+ ];
51
+ export const REFILL_ACTION_IDS = [
52
+ "prepare_messages",
53
+ "approve_messages",
54
+ "rerun_errored_cells",
55
+ "start_paused_campaign",
56
+ "run_scheduler_sweep",
57
+ "scheduler_first_settle",
58
+ "wait_for_scheduler",
59
+ "wait_for_active_work",
60
+ "wait_for_source_import",
61
+ "copy_selected_source_rows",
62
+ "continue_signal_discovery_source",
63
+ "continue_sales_nav_source",
64
+ "continue_prospeo_source",
65
+ "manual_source_replenishment",
66
+ "refresh_paid_inmail_credits",
67
+ "lower_paid_inmail_threshold",
68
+ "switch_to_connection_lane",
69
+ "create_connection_campaign",
70
+ "next_campaign",
71
+ "done",
72
+ ];
73
+ export const REFILL_RECEIPT_IDS = [
74
+ "target_plan_receipt",
75
+ "preparation_receipt",
76
+ "scheduler_receipt",
77
+ "run_receipt",
78
+ ];
79
+ export const REFILL_SIDE_EFFECT_CLASS_IDS = [
80
+ "read_only",
81
+ "message_preparation",
82
+ "message_approval",
83
+ "source_replenishment",
84
+ "credit_refresh",
85
+ "campaign_start",
86
+ "scheduler_placement",
87
+ ];
88
+ export const REFILL_FORBIDDEN_ACTION_IDS = [
89
+ "direct_send",
90
+ "raw_scheduler_write",
91
+ "campaign_create",
92
+ "campaign_archive_delete",
93
+ "threshold_lowering",
94
+ "unselected_source_mutation",
95
+ "unapproved_campaign_start",
96
+ "sender_config_write",
97
+ ];
98
+ export const REFILL_TERMINAL_REASON_IDS = [
99
+ "projected_full",
100
+ "concrete_blocker",
101
+ "deadline_reached",
102
+ "iteration_limit",
103
+ "operator_stopped",
104
+ "capped_by_scheduler",
105
+ "loaded_awaiting_scheduler",
106
+ "lanes_exhausted",
107
+ "not_an_evergreen_workspace",
108
+ "no_refillable_campaigns",
109
+ ];
110
+ const plannerActions = [...REFILL_ACTION_IDS];
111
+ const plannerReceiptFields = [
112
+ "refillLaneKey",
113
+ "branchMetrics",
114
+ "ledger",
115
+ "targetDate",
116
+ "actionKey",
117
+ "targetShapeRevision",
118
+ "stateRevision",
119
+ ];
120
+ const preparationDependencyClasses = [
121
+ "active",
122
+ "transient",
123
+ "permanent",
124
+ "changed",
125
+ "exhausted",
126
+ ];
127
+ const preparationDependencyReasons = [
128
+ "active_cells",
129
+ "dependency_timeout",
130
+ "rate_limited",
131
+ "provider_unavailable",
132
+ "authentication_failed",
133
+ "validation_failed",
134
+ "schema_invalid",
135
+ "config_epoch_changed",
136
+ "source_epoch_changed",
137
+ "frontier_exhausted",
138
+ "unknown_dependency",
139
+ ];
140
+ const preparationCircuitStates = [
141
+ "closed",
142
+ "open",
143
+ "half_open",
144
+ "reset",
145
+ ];
146
+ const preparationCooperativeStopReasons = [
147
+ "target_satisfied_during_prep",
148
+ ];
149
+ const preparationReceiptFields = [
150
+ "dependency",
151
+ "circuit",
152
+ "batchCalibration",
153
+ "cooperativeStop",
154
+ ];
155
+ const schedulerTargetOutcomes = ["included", "omitted"];
156
+ const schedulerOmissionReasons = [
157
+ "no_ready_cells",
158
+ "not_scheduler_eligible",
159
+ "sender_mismatch",
160
+ "capacity_prefiltered",
161
+ "outside_target_date",
162
+ "receipt_error",
163
+ ];
164
+ const schedulerRunStatuses = [
165
+ "ran",
166
+ "window_closed_noop",
167
+ "failed",
168
+ ];
169
+ const schedulerNextActions = [
170
+ "refresh_paid_inmail_credits_then_rerun",
171
+ "wait_for_capacity_or_window",
172
+ "inspect_sender_mismatch",
173
+ "no_ready_cells_continue_refill_prep",
174
+ "scheduled_cells",
175
+ "investigate_deferred_reasons",
176
+ "investigate_scheduler_failure",
177
+ ];
178
+ const schedulerReceiptFields = [
179
+ "receiptVersion",
180
+ "diagnosticsVersion",
181
+ "status",
182
+ "trigger",
183
+ "workspaceId",
184
+ "runId",
185
+ "leaseFence",
186
+ "expectedTargetsHash",
187
+ "maxPlacements",
188
+ "readyCellsFound",
189
+ "cellsConsidered",
190
+ "cellsScheduled",
191
+ "cellsSkipped",
192
+ "cellsDeferred",
193
+ "campaignScopeSummary",
194
+ "expectedTargetSummary",
195
+ "changedCounts",
196
+ "summary",
197
+ "nextAction",
198
+ "errorCount",
199
+ "error",
200
+ ];
201
+ const runGates = [
202
+ "g0_bootstrap",
203
+ "g1_plan",
204
+ "g2_execute",
205
+ "g3_verify",
206
+ "g4_terminal",
207
+ ];
208
+ const runResultKinds = [
209
+ "started",
210
+ "awaiting_approval",
211
+ "active_run_in_progress",
212
+ "resumed",
213
+ "lease_lost",
214
+ "scope_drift",
215
+ "approval_expired",
216
+ "approval_fingerprint_mismatch",
217
+ ];
218
+ const runTerminalReasons = [
219
+ "complete",
220
+ "capped_by_scheduler",
221
+ "loaded_awaiting_scheduler",
222
+ "lanes_exhausted",
223
+ "blocked",
224
+ "not_an_evergreen_workspace",
225
+ "no_refillable_campaigns",
226
+ ];
227
+ const runRefusals = [
228
+ "scope_drift",
229
+ "approval_expired",
230
+ "approval_fingerprint_mismatch",
231
+ "legacy_read_only",
232
+ "expected_target_overflow",
233
+ "scheduler_receipt_incomplete",
234
+ ];
235
+ const runScopeFields = [
236
+ "workspaceId",
237
+ "intent",
238
+ "senderIds",
239
+ "campaignIds",
240
+ "tableIds",
241
+ "actionIds",
242
+ "approvalMode",
243
+ "dateSelector",
244
+ "senderTimezones",
245
+ "expectedTargetsHash",
246
+ "maxPlacements",
247
+ "contract",
248
+ "installed",
249
+ ];
250
+ const runApprovalFields = [
251
+ "scopeHash",
252
+ "targetShapeRevision",
253
+ "actionFingerprint",
254
+ "expectedTargetsHash",
255
+ "sideEffectEnvelope",
256
+ "maxPlacements",
257
+ "approvalExpiresAt",
258
+ "approvalFingerprint",
259
+ ];
260
+ const actionSideEffects = {
261
+ prepare_messages: "message_preparation",
262
+ approve_messages: "message_approval",
263
+ rerun_errored_cells: "message_preparation",
264
+ start_paused_campaign: "campaign_start",
265
+ run_scheduler_sweep: "scheduler_placement",
266
+ scheduler_first_settle: "read_only",
267
+ wait_for_scheduler: "read_only",
268
+ wait_for_active_work: "read_only",
269
+ wait_for_source_import: "read_only",
270
+ copy_selected_source_rows: "source_replenishment",
271
+ continue_signal_discovery_source: "source_replenishment",
272
+ continue_sales_nav_source: "source_replenishment",
273
+ continue_prospeo_source: "source_replenishment",
274
+ manual_source_replenishment: "source_replenishment",
275
+ refresh_paid_inmail_credits: "credit_refresh",
276
+ lower_paid_inmail_threshold: "read_only",
277
+ switch_to_connection_lane: "read_only",
278
+ create_connection_campaign: "read_only",
279
+ next_campaign: "read_only",
280
+ done: "read_only",
281
+ };
282
+ const semanticContract = {
283
+ scope: REFILL_SCOPE_IDS.map((id) => ({ id })),
284
+ gates: REFILL_GATE_IDS.map((id) => ({ id })),
285
+ states: REFILL_STATE_IDS.map((id) => ({ id })),
286
+ actions: REFILL_ACTION_IDS.map((id) => ({
287
+ id,
288
+ sideEffectClass: actionSideEffects[id],
289
+ })),
290
+ receipts: [
291
+ { id: "target_plan_receipt", requiredFields: plannerReceiptFields },
292
+ { id: "preparation_receipt", requiredFields: preparationReceiptFields },
293
+ { id: "scheduler_receipt", requiredFields: schedulerReceiptFields },
294
+ {
295
+ id: "run_receipt",
296
+ requiredFields: [
297
+ "runId",
298
+ "fence",
299
+ "gate",
300
+ "gateSeq",
301
+ "events",
302
+ "doneReason",
303
+ ],
304
+ },
305
+ ],
306
+ sideEffectClasses: REFILL_SIDE_EFFECT_CLASS_IDS.map((id) => ({ id })),
307
+ forbiddenActions: REFILL_FORBIDDEN_ACTION_IDS.map((id) => ({ id })),
308
+ terminalReasons: REFILL_TERMINAL_REASON_IDS.map((id) => ({
309
+ id,
310
+ terminalKind: id === "projected_full" ? "complete" : "stopped",
311
+ })),
312
+ transitions: [
313
+ { from: "planning", to: "awaiting_approval" },
314
+ { from: "awaiting_approval", to: "executing" },
315
+ { from: "executing", to: "settling" },
316
+ { from: "settling", to: "replanning" },
317
+ { from: "replanning", to: "executing" },
318
+ { from: "replanning", to: "terminal" },
319
+ ],
320
+ };
321
+ const backendBindings = {
322
+ planner: {
323
+ actions: plannerActions,
324
+ receiptFields: plannerReceiptFields,
325
+ },
326
+ preparation: {
327
+ dependencyClasses: preparationDependencyClasses,
328
+ dependencyReasons: preparationDependencyReasons,
329
+ circuitStates: preparationCircuitStates,
330
+ cooperativeStopReasons: preparationCooperativeStopReasons,
331
+ receiptFields: preparationReceiptFields,
332
+ },
333
+ scheduler: {
334
+ targetOutcomes: schedulerTargetOutcomes,
335
+ omissionReasons: schedulerOmissionReasons,
336
+ runStatuses: schedulerRunStatuses,
337
+ nextActions: schedulerNextActions,
338
+ receiptFields: schedulerReceiptFields,
339
+ },
340
+ run: {
341
+ gates: runGates,
342
+ states: REFILL_STATE_IDS,
343
+ resultKinds: runResultKinds,
344
+ terminalReasons: runTerminalReasons,
345
+ refusals: runRefusals,
346
+ scopeFields: runScopeFields,
347
+ approvalFields: runApprovalFields,
348
+ },
349
+ };
350
+ const contractWithoutHash = {
351
+ contractVersion: REFILL_CONTRACT_VERSION,
352
+ cacheVersion: REFILL_CONTRACT_CACHE_VERSION,
353
+ supportedMajor: REFILL_CONTRACT_SUPPORTED_MAJOR,
354
+ semantics: semanticContract,
355
+ backendBindings,
356
+ };
357
+ function canonicalValue(value) {
358
+ if (Array.isArray(value))
359
+ return value.map(canonicalValue);
360
+ if (value && typeof value === "object") {
361
+ return Object.fromEntries(Object.entries(value)
362
+ .filter(([key, entry]) => key !== "contractHash" &&
363
+ key !== "releaseIdentities" &&
364
+ entry !== undefined)
365
+ .sort(([left], [right]) => left.localeCompare(right))
366
+ .map(([key, entry]) => [key, canonicalValue(entry)]));
367
+ }
368
+ return value;
369
+ }
370
+ export function canonicalizeRefillContract(value) {
371
+ return JSON.stringify(canonicalValue(value));
372
+ }
373
+ export function computeRefillContractHash(value) {
374
+ return createHash("sha256")
375
+ .update(canonicalizeRefillContract(value))
376
+ .digest("hex");
377
+ }
378
+ export const REFILL_CONTRACT_HASH = computeRefillContractHash(contractWithoutHash);
379
+ export const refillContract = {
380
+ ...contractWithoutHash,
381
+ contractHash: REFILL_CONTRACT_HASH,
382
+ };
383
+ function objectRecord(value, path) {
384
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
385
+ throw new RefillContractError("refill_contract_semantic_mismatch", `${path} must be an object`);
386
+ }
387
+ return value;
388
+ }
389
+ function semanticDifference(path, actual, expected) {
390
+ if (canonicalizeRefillContract(actual) === canonicalizeRefillContract(expected)) {
391
+ return;
392
+ }
393
+ const actualIds = Array.isArray(actual)
394
+ ? actual.map((entry) => typeof entry === "string"
395
+ ? entry
396
+ : String(entry?.id ?? ""))
397
+ : [];
398
+ const expectedIds = Array.isArray(expected)
399
+ ? expected.map((entry) => typeof entry === "string"
400
+ ? entry
401
+ : String(entry?.id ?? ""))
402
+ : [];
403
+ const missing = expectedIds.filter((id) => !actualIds.includes(id));
404
+ const extra = actualIds.filter((id) => !expectedIds.includes(id));
405
+ const detail = [
406
+ missing.length ? `missing=${missing.join(",")}` : "",
407
+ extra.length ? `extra=${extra.join(",")}` : "",
408
+ ]
409
+ .filter(Boolean)
410
+ .join(" ");
411
+ throw new RefillContractError("refill_contract_semantic_mismatch", `${path} differs from the canonical refill contract${detail ? `: ${detail}` : ""}`);
412
+ }
413
+ export function assertSupportedRefillContractMajor(version) {
414
+ const major = Number.parseInt(version.split(".")[0] ?? "", 10);
415
+ if (major !== REFILL_CONTRACT_SUPPORTED_MAJOR) {
416
+ throw new RefillContractError("unsupported_refill_contract_major", `unsupported_refill_contract_major: expected ${REFILL_CONTRACT_SUPPORTED_MAJOR}, received ${version}`);
417
+ }
418
+ }
419
+ export function validateRefillContractAsset(value) {
420
+ const record = objectRecord(value, "contract");
421
+ const version = String(record.contractVersion ?? "");
422
+ assertSupportedRefillContractMajor(version);
423
+ if (version !== REFILL_CONTRACT_VERSION) {
424
+ throw new RefillContractError("refill_contract_semantic_mismatch", `contractVersion differs: expected ${REFILL_CONTRACT_VERSION}, received ${version}`);
425
+ }
426
+ if (record.cacheVersion !== REFILL_CONTRACT_CACHE_VERSION) {
427
+ throw new RefillContractError("refill_contract_semantic_mismatch", `cacheVersion differs: expected ${REFILL_CONTRACT_CACHE_VERSION}, received ${String(record.cacheVersion)}`);
428
+ }
429
+ const semantics = objectRecord(record.semantics, "semantics");
430
+ for (const [family, expected] of Object.entries(refillContract.semantics)) {
431
+ semanticDifference(`semantics.${family}`, semantics[family], expected);
432
+ }
433
+ semanticDifference("backendBindings", record.backendBindings, refillContract.backendBindings);
434
+ const computedHash = computeRefillContractHash(record);
435
+ if (record.contractHash !== computedHash) {
436
+ throw new RefillContractError("refill_contract_hash_mismatch", `refill_contract_hash_mismatch: expected ${computedHash}, received ${String(record.contractHash)}`);
437
+ }
438
+ return value;
439
+ }
440
+ export function refillContractSemanticProjection() {
441
+ return {
442
+ contractVersion: REFILL_CONTRACT_VERSION,
443
+ cacheVersion: REFILL_CONTRACT_CACHE_VERSION,
444
+ contractHash: REFILL_CONTRACT_HASH,
445
+ semanticIds: Object.fromEntries(Object.entries(refillContract.semantics)
446
+ .filter(([, entries]) => Array.isArray(entries))
447
+ .map(([family, entries]) => [
448
+ family,
449
+ entries.map((entry) => typeof entry === "string"
450
+ ? entry
451
+ : String(entry.id ?? "")),
452
+ ])),
453
+ };
454
+ }
455
+ export function validateRefillFlowProjection(value) {
456
+ const flow = objectRecord(value, "flow");
457
+ const projection = objectRecord(flow.refillContract, "flow.refillContract");
458
+ semanticDifference("flow.refillContract", projection, refillContractSemanticProjection());
459
+ }
460
+ function renderIds(label, ids) {
461
+ return `${label}: ${ids.join(", ")}`;
462
+ }
463
+ export function renderRefillBootstrapGuidance() {
464
+ return [
465
+ renderIds("scope", REFILL_SCOPE_IDS),
466
+ renderIds("gates", [
467
+ "approval_packet",
468
+ "one_primitive",
469
+ "fresh_reread",
470
+ "normalized_accounting",
471
+ "prep_circuit",
472
+ ]),
473
+ "release identities (independent of semantic hash): mcpPackageVersion, installPackageVersion, codexPluginVersion",
474
+ ].join("\n");
475
+ }
476
+ export function renderRefillSafetyGuidance() {
477
+ return renderIds("forbidden", REFILL_FORBIDDEN_ACTION_IDS);
478
+ }
479
+ export function renderRefillTerminalGuidance() {
480
+ return [
481
+ renderIds("terminal", REFILL_TERMINAL_REASON_IDS),
482
+ "ready_buffer_exists_is_not_complete",
483
+ ].join("\n");
484
+ }
485
+ export function assertNeverRefillVariant(value) {
486
+ throw new RefillContractError("refill_contract_semantic_mismatch", `Unhandled refill contract variant: ${String(value)}`);
487
+ }
@@ -5,6 +5,11 @@ export type RefillRunBlockerResult = {
5
5
  runId: string;
6
6
  gate?: string;
7
7
  gateSeq?: number;
8
+ } | {
9
+ blocker: "scope_drift" | "approval_expired" | "approval_fingerprint_mismatch";
10
+ runId: string;
11
+ expectedScopeHash: string | null;
12
+ receivedScopeHash: string | null;
8
13
  };
9
14
  export declare function startRefillRunRemote(input: {
10
15
  workspaceId?: string;