@sellable/mcp 0.1.745 → 0.1.747

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.
@@ -214,6 +214,8 @@ export type SchedulerChangedCounts = {
214
214
  }>;
215
215
  };
216
216
  export declare function normalizeSchedulerChangedCounts(value: unknown): SchedulerChangedCounts | null;
217
+ export declare function setSweepSettlePollDelayMsForTests(ms: number): void;
218
+ export declare function resetSweepSettlePollDelayMsForTests(): void;
217
219
  export declare function schedulerEnvelopeIsTerminal(schedulerStatus: string, receipt?: Record<string, unknown> | null): boolean;
218
220
  export declare function normalizeSchedulerPrimitiveResult(value: unknown, expected?: {
219
221
  expectedTargets: SchedulerExpectedTargetInput[];
@@ -294,6 +294,34 @@ function hasTerminalSchedulerReceipt(receipt) {
294
294
  const status = receipt ? stringValue(receipt.status) : null;
295
295
  return Boolean(status && SCHEDULER_TERMINAL_RECEIPT_STATUSES.has(status));
296
296
  }
297
+ // fix(112ap): poll ONLY a genuinely in-flight attach. `!terminal` is the wrong
298
+ // test — it is also true for `backoff` and `failed`, and re-polling those would
299
+ // both waste the budget and misrepresent a refused dispatch as a pending one.
300
+ // In-flight means an attaching envelope (accepted|attached) that has NOT yet
301
+ // yielded a terminal receipt, matching the 112ao-2b contract exactly.
302
+ function schedulerDispatchIsStillRunning(value) {
303
+ const response = recordValue(value);
304
+ if (!response)
305
+ return false;
306
+ const status = stringValue(response.status) ?? "";
307
+ if (!SCHEDULER_ATTACHING_ENVELOPE_STATUSES.has(status))
308
+ return false;
309
+ return !hasTerminalSchedulerReceipt(recordValue(response.receipt));
310
+ }
311
+ // fix(112ap): bounded self-settle for a dispatched sweep. 4 x 8s = 32s, just past
312
+ // the scheduler's own ~28s observed pass duration and its 30s retryAfterMs hint,
313
+ // while staying well inside the coordinator's per-call budget.
314
+ const SWEEP_SETTLE_POLL_ATTEMPTS = 4;
315
+ const SWEEP_SETTLE_POLL_DEFAULT_DELAY_MS = 8_000;
316
+ // Injectable so pins can exercise the settle loop without real wall-clock waits.
317
+ // Production never calls the setter; the default is what ships.
318
+ let sweepSettlePollDelayMs = SWEEP_SETTLE_POLL_DEFAULT_DELAY_MS;
319
+ export function setSweepSettlePollDelayMsForTests(ms) {
320
+ sweepSettlePollDelayMs = ms;
321
+ }
322
+ export function resetSweepSettlePollDelayMsForTests() {
323
+ sweepSettlePollDelayMs = SWEEP_SETTLE_POLL_DEFAULT_DELAY_MS;
324
+ }
297
325
  export function schedulerEnvelopeIsTerminal(schedulerStatus, receipt = null) {
298
326
  if (SCHEDULER_TERMINAL_ENVELOPE_STATUSES.has(schedulerStatus))
299
327
  return true;
@@ -3052,7 +3080,7 @@ export async function executeOneYoloPrimitive(action, workspaceId) {
3052
3080
  },
3053
3081
  };
3054
3082
  }
3055
- const result = await runSchedulerSweep({
3083
+ let result = await runSchedulerSweep({
3056
3084
  workspaceId,
3057
3085
  action: "run",
3058
3086
  targetDate,
@@ -3062,6 +3090,56 @@ export async function executeOneYoloPrimitive(action, workspaceId) {
3062
3090
  expectedTargetsHash,
3063
3091
  maxPlacements,
3064
3092
  });
3093
+ // fix(112ap): settle our OWN dispatch before returning.
3094
+ //
3095
+ // The route holds a sweep for SCHEDULER_RUN_RESPONSE_BUDGET_MS (1s,
3096
+ // route.ts:20) and then returns `attached` with the real pass still running
3097
+ // in the background. We used to return that immediately, so the coordinator
3098
+ // replanned; concurrent approve/prepare churned readyCounts, which churns
3099
+ // stateRevision, which is hashed into actionKey/requestKey — so the NEXT
3100
+ // iteration minted a BRAND NEW key and polled a run that had never been
3101
+ // dispatched. scopeMatches was correctly false, and it dispatched again.
3102
+ //
3103
+ // Dotwork 2026-07-29 receipts: 12 DISTINCT run_scheduler_sweep keys, each
3104
+ // dispatched exactly once, every one returning exact_action_complete with
3105
+ // `lanesTouched: []`, coverage frozen at {sent:0, scheduled:0, ready:20}.
3106
+ // approve_messages/prepare_messages in the same runs DID report lanesTouched.
3107
+ // Meanwhile the scheduler itself was healthy — its own on-demand receipt
3108
+ // placed 12 ready / 12 considered / 12 scheduled with zero skips, zero
3109
+ // defers, zero prefilters. The sweeps simply never became scheduler runs.
3110
+ //
3111
+ // The key we just dispatched is in scope RIGHT HERE, so poll it here instead
3112
+ // of trying to remember it across a replan. That matters: per-fence runState
3113
+ // does NOT survive next_exact_target (it reset 112e's cohort guard, 112aj's
3114
+ // counter and 112an's stall bound), so a cross-fence memory would have needed
3115
+ // the WORKSPACE_ATTEMPT_LEDGER_KEYS allowlist. Polling in-scope needs none of
3116
+ // that. Bounded so a slow pass still degrades to the existing in-flight
3117
+ // handling rather than holding the tool call open.
3118
+ for (let attempt = 0; attempt < SWEEP_SETTLE_POLL_ATTEMPTS &&
3119
+ schedulerDispatchIsStillRunning(result); attempt += 1) {
3120
+ await sleep(sweepSettlePollDelayMs);
3121
+ const settled = await runSchedulerSweep({
3122
+ workspaceId,
3123
+ action: "status",
3124
+ targetDate,
3125
+ requestKey,
3126
+ targetShapeRevision,
3127
+ expectedTargetsHash,
3128
+ maxPlacements,
3129
+ });
3130
+ // Adopt the polled response ONLY when it actually settled. A status
3131
+ // probe returns a DIFFERENT shape ({scopeMatches, running}) than a
3132
+ // dispatch envelope ({status, receipt}); overwriting unconditionally
3133
+ // destroyed the in-flight envelope and with it
3134
+ // matching_scheduler_active / bounded_reread_wait / retryAfterMs, which
3135
+ // is the handling the coordinator relies on when a run is still going.
3136
+ // Keep the dispatch envelope until a terminal receipt exists.
3137
+ const settledRecord = recordValue(settled);
3138
+ if (settledRecord &&
3139
+ hasTerminalSchedulerReceipt(recordValue(settledRecord.receipt))) {
3140
+ result = settled;
3141
+ }
3142
+ }
3065
3143
  return {
3066
3144
  status: "executed_and_reread",
3067
3145
  result: normalizeSchedulerPrimitiveResult(result, {
@@ -649,6 +649,9 @@ export declare function refillSendsCommand(input?: RefillSendsCommandInput): {
649
649
  subskillName: string;
650
650
  assetPath: string;
651
651
  expectedVersion: string;
652
+ minimumVersion: string;
653
+ compatibleMajor: string;
654
+ versionPolicy: string;
652
655
  };
653
656
  yolo: boolean;
654
657
  executionMode: RefillSendsExecutionMode;
@@ -656,6 +659,19 @@ export declare function refillSendsCommand(input?: RefillSendsCommandInput): {
656
659
  workspaceResolution: string;
657
660
  intent: RefillSendsIntent;
658
661
  };
662
+ export declare const REFILL_FLOW_MINIMUM_VERSION = "v1.8";
663
+ export declare const REFILL_FLOW_COMPATIBLE_MAJOR = "v1";
664
+ /**
665
+ * Whether an observed flow-asset version satisfies the consumer's contract.
666
+ *
667
+ * Compatible when the major matches and the minor is >= the minimum. An
668
+ * unparseable or absent version stays a mismatch: this widens the accepted
669
+ * range, it never weakens the requirement that a version be verified at all.
670
+ */
671
+ export declare function isCompatibleRefillFlowVersion(actualVersion: unknown, bounds?: {
672
+ minimumVersion?: string;
673
+ compatibleMajor?: string;
674
+ }): boolean;
659
675
  type WorkspaceExactTarget = {
660
676
  campaignId: string;
661
677
  tableId: string;
@@ -809,6 +825,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
809
825
  subskillName: string;
810
826
  assetPath: string;
811
827
  expectedVersion: string;
828
+ minimumVersion: string;
829
+ compatibleMajor: string;
830
+ versionPolicy: string;
812
831
  };
813
832
  yolo: boolean;
814
833
  executionMode: RefillSendsExecutionMode;
@@ -912,6 +931,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
912
931
  subskillName: string;
913
932
  assetPath: string;
914
933
  expectedVersion: string;
934
+ minimumVersion: string;
935
+ compatibleMajor: string;
936
+ versionPolicy: string;
915
937
  };
916
938
  yolo: boolean;
917
939
  executionMode: RefillSendsExecutionMode;
@@ -1020,6 +1042,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
1020
1042
  subskillName: string;
1021
1043
  assetPath: string;
1022
1044
  expectedVersion: string;
1045
+ minimumVersion: string;
1046
+ compatibleMajor: string;
1047
+ versionPolicy: string;
1023
1048
  };
1024
1049
  yolo: boolean;
1025
1050
  executionMode: RefillSendsExecutionMode;
@@ -1182,6 +1207,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
1182
1207
  subskillName: string;
1183
1208
  assetPath: string;
1184
1209
  expectedVersion: string;
1210
+ minimumVersion: string;
1211
+ compatibleMajor: string;
1212
+ versionPolicy: string;
1185
1213
  };
1186
1214
  yolo: boolean;
1187
1215
  executionMode: RefillSendsExecutionMode;
@@ -1349,6 +1377,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
1349
1377
  subskillName: string;
1350
1378
  assetPath: string;
1351
1379
  expectedVersion: string;
1380
+ minimumVersion: string;
1381
+ compatibleMajor: string;
1382
+ versionPolicy: string;
1352
1383
  };
1353
1384
  yolo: boolean;
1354
1385
  executionMode: RefillSendsExecutionMode;
@@ -1465,6 +1496,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
1465
1496
  subskillName: string;
1466
1497
  assetPath: string;
1467
1498
  expectedVersion: string;
1499
+ minimumVersion: string;
1500
+ compatibleMajor: string;
1501
+ versionPolicy: string;
1468
1502
  };
1469
1503
  yolo: boolean;
1470
1504
  executionMode: RefillSendsExecutionMode;
@@ -1584,6 +1618,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
1584
1618
  subskillName: string;
1585
1619
  assetPath: string;
1586
1620
  expectedVersion: string;
1621
+ minimumVersion: string;
1622
+ compatibleMajor: string;
1623
+ versionPolicy: string;
1587
1624
  };
1588
1625
  yolo: boolean;
1589
1626
  executionMode: RefillSendsExecutionMode;
@@ -1702,6 +1739,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
1702
1739
  subskillName: string;
1703
1740
  assetPath: string;
1704
1741
  expectedVersion: string;
1742
+ minimumVersion: string;
1743
+ compatibleMajor: string;
1744
+ versionPolicy: string;
1705
1745
  };
1706
1746
  yolo: boolean;
1707
1747
  executionMode: RefillSendsExecutionMode;
@@ -1823,6 +1863,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
1823
1863
  subskillName: string;
1824
1864
  assetPath: string;
1825
1865
  expectedVersion: string;
1866
+ minimumVersion: string;
1867
+ compatibleMajor: string;
1868
+ versionPolicy: string;
1826
1869
  };
1827
1870
  yolo: boolean;
1828
1871
  executionMode: RefillSendsExecutionMode;
@@ -1985,6 +2028,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
1985
2028
  subskillName: string;
1986
2029
  assetPath: string;
1987
2030
  expectedVersion: string;
2031
+ minimumVersion: string;
2032
+ compatibleMajor: string;
2033
+ versionPolicy: string;
1988
2034
  };
1989
2035
  yolo: boolean;
1990
2036
  executionMode: RefillSendsExecutionMode;
@@ -2093,6 +2139,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
2093
2139
  subskillName: string;
2094
2140
  assetPath: string;
2095
2141
  expectedVersion: string;
2142
+ minimumVersion: string;
2143
+ compatibleMajor: string;
2144
+ versionPolicy: string;
2096
2145
  };
2097
2146
  yolo: boolean;
2098
2147
  executionMode: RefillSendsExecutionMode;
@@ -2259,6 +2308,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
2259
2308
  subskillName: string;
2260
2309
  assetPath: string;
2261
2310
  expectedVersion: string;
2311
+ minimumVersion: string;
2312
+ compatibleMajor: string;
2313
+ versionPolicy: string;
2262
2314
  };
2263
2315
  yolo: boolean;
2264
2316
  executionMode: RefillSendsExecutionMode;
@@ -2381,6 +2433,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
2381
2433
  subskillName: string;
2382
2434
  assetPath: string;
2383
2435
  expectedVersion: string;
2436
+ minimumVersion: string;
2437
+ compatibleMajor: string;
2438
+ versionPolicy: string;
2384
2439
  };
2385
2440
  yolo: boolean;
2386
2441
  executionMode: RefillSendsExecutionMode;
@@ -2516,6 +2571,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
2516
2571
  subskillName: string;
2517
2572
  assetPath: string;
2518
2573
  expectedVersion: string;
2574
+ minimumVersion: string;
2575
+ compatibleMajor: string;
2576
+ versionPolicy: string;
2519
2577
  };
2520
2578
  yolo: boolean;
2521
2579
  executionMode: RefillSendsExecutionMode;
@@ -2641,6 +2699,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
2641
2699
  subskillName: string;
2642
2700
  assetPath: string;
2643
2701
  expectedVersion: string;
2702
+ minimumVersion: string;
2703
+ compatibleMajor: string;
2704
+ versionPolicy: string;
2644
2705
  };
2645
2706
  yolo: boolean;
2646
2707
  executionMode: RefillSendsExecutionMode;
@@ -2765,6 +2826,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
2765
2826
  subskillName: string;
2766
2827
  assetPath: string;
2767
2828
  expectedVersion: string;
2829
+ minimumVersion: string;
2830
+ compatibleMajor: string;
2831
+ versionPolicy: string;
2768
2832
  };
2769
2833
  yolo: boolean;
2770
2834
  executionMode: RefillSendsExecutionMode;
@@ -2922,6 +2986,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
2922
2986
  subskillName: string;
2923
2987
  assetPath: string;
2924
2988
  expectedVersion: string;
2989
+ minimumVersion: string;
2990
+ compatibleMajor: string;
2991
+ versionPolicy: string;
2925
2992
  };
2926
2993
  yolo: boolean;
2927
2994
  executionMode: RefillSendsExecutionMode;
@@ -3042,6 +3109,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
3042
3109
  subskillName: string;
3043
3110
  assetPath: string;
3044
3111
  expectedVersion: string;
3112
+ minimumVersion: string;
3113
+ compatibleMajor: string;
3114
+ versionPolicy: string;
3045
3115
  };
3046
3116
  yolo: boolean;
3047
3117
  executionMode: RefillSendsExecutionMode;
@@ -3136,6 +3206,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
3136
3206
  subskillName: string;
3137
3207
  assetPath: string;
3138
3208
  expectedVersion: string;
3209
+ minimumVersion: string;
3210
+ compatibleMajor: string;
3211
+ versionPolicy: string;
3139
3212
  };
3140
3213
  yolo: boolean;
3141
3214
  executionMode: RefillSendsExecutionMode;
@@ -3226,6 +3299,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
3226
3299
  subskillName: string;
3227
3300
  assetPath: string;
3228
3301
  expectedVersion: string;
3302
+ minimumVersion: string;
3303
+ compatibleMajor: string;
3304
+ versionPolicy: string;
3229
3305
  };
3230
3306
  yolo: boolean;
3231
3307
  executionMode: RefillSendsExecutionMode;
@@ -3343,6 +3419,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
3343
3419
  subskillName: string;
3344
3420
  assetPath: string;
3345
3421
  expectedVersion: string;
3422
+ minimumVersion: string;
3423
+ compatibleMajor: string;
3424
+ versionPolicy: string;
3346
3425
  };
3347
3426
  yolo: boolean;
3348
3427
  executionMode: RefillSendsExecutionMode;
@@ -3572,6 +3651,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
3572
3651
  subskillName: string;
3573
3652
  assetPath: string;
3574
3653
  expectedVersion: string;
3654
+ minimumVersion: string;
3655
+ compatibleMajor: string;
3656
+ versionPolicy: string;
3575
3657
  };
3576
3658
  yolo: boolean;
3577
3659
  executionMode: RefillSendsExecutionMode;
@@ -3807,6 +3889,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
3807
3889
  subskillName: string;
3808
3890
  assetPath: string;
3809
3891
  expectedVersion: string;
3892
+ minimumVersion: string;
3893
+ compatibleMajor: string;
3894
+ versionPolicy: string;
3810
3895
  };
3811
3896
  yolo: boolean;
3812
3897
  executionMode: RefillSendsExecutionMode;
@@ -4040,6 +4125,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
4040
4125
  subskillName: string;
4041
4126
  assetPath: string;
4042
4127
  expectedVersion: string;
4128
+ minimumVersion: string;
4129
+ compatibleMajor: string;
4130
+ versionPolicy: string;
4043
4131
  };
4044
4132
  yolo: boolean;
4045
4133
  executionMode: RefillSendsExecutionMode;
@@ -4269,6 +4357,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
4269
4357
  subskillName: string;
4270
4358
  assetPath: string;
4271
4359
  expectedVersion: string;
4360
+ minimumVersion: string;
4361
+ compatibleMajor: string;
4362
+ versionPolicy: string;
4272
4363
  };
4273
4364
  yolo: boolean;
4274
4365
  executionMode: RefillSendsExecutionMode;
@@ -4503,6 +4594,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
4503
4594
  subskillName: string;
4504
4595
  assetPath: string;
4505
4596
  expectedVersion: string;
4597
+ minimumVersion: string;
4598
+ compatibleMajor: string;
4599
+ versionPolicy: string;
4506
4600
  };
4507
4601
  yolo: boolean;
4508
4602
  executionMode: RefillSendsExecutionMode;
@@ -4739,6 +4833,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
4739
4833
  subskillName: string;
4740
4834
  assetPath: string;
4741
4835
  expectedVersion: string;
4836
+ minimumVersion: string;
4837
+ compatibleMajor: string;
4838
+ versionPolicy: string;
4742
4839
  };
4743
4840
  yolo: boolean;
4744
4841
  executionMode: RefillSendsExecutionMode;
@@ -4974,6 +5071,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
4974
5071
  subskillName: string;
4975
5072
  assetPath: string;
4976
5073
  expectedVersion: string;
5074
+ minimumVersion: string;
5075
+ compatibleMajor: string;
5076
+ versionPolicy: string;
4977
5077
  };
4978
5078
  yolo: boolean;
4979
5079
  executionMode: RefillSendsExecutionMode;
@@ -5213,6 +5313,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
5213
5313
  subskillName: string;
5214
5314
  assetPath: string;
5215
5315
  expectedVersion: string;
5316
+ minimumVersion: string;
5317
+ compatibleMajor: string;
5318
+ versionPolicy: string;
5216
5319
  };
5217
5320
  yolo: boolean;
5218
5321
  executionMode: RefillSendsExecutionMode;
@@ -5445,6 +5548,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
5445
5548
  subskillName: string;
5446
5549
  assetPath: string;
5447
5550
  expectedVersion: string;
5551
+ minimumVersion: string;
5552
+ compatibleMajor: string;
5553
+ versionPolicy: string;
5448
5554
  };
5449
5555
  yolo: boolean;
5450
5556
  executionMode: RefillSendsExecutionMode;
@@ -5683,6 +5789,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
5683
5789
  subskillName: string;
5684
5790
  assetPath: string;
5685
5791
  expectedVersion: string;
5792
+ minimumVersion: string;
5793
+ compatibleMajor: string;
5794
+ versionPolicy: string;
5686
5795
  };
5687
5796
  yolo: boolean;
5688
5797
  executionMode: RefillSendsExecutionMode;
@@ -5919,6 +6028,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
5919
6028
  subskillName: string;
5920
6029
  assetPath: string;
5921
6030
  expectedVersion: string;
6031
+ minimumVersion: string;
6032
+ compatibleMajor: string;
6033
+ versionPolicy: string;
5922
6034
  };
5923
6035
  yolo: boolean;
5924
6036
  executionMode: RefillSendsExecutionMode;
@@ -6151,6 +6263,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
6151
6263
  subskillName: string;
6152
6264
  assetPath: string;
6153
6265
  expectedVersion: string;
6266
+ minimumVersion: string;
6267
+ compatibleMajor: string;
6268
+ versionPolicy: string;
6154
6269
  };
6155
6270
  yolo: boolean;
6156
6271
  executionMode: RefillSendsExecutionMode;
@@ -6388,6 +6503,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
6388
6503
  subskillName: string;
6389
6504
  assetPath: string;
6390
6505
  expectedVersion: string;
6506
+ minimumVersion: string;
6507
+ compatibleMajor: string;
6508
+ versionPolicy: string;
6391
6509
  };
6392
6510
  yolo: boolean;
6393
6511
  executionMode: RefillSendsExecutionMode;
@@ -6627,6 +6745,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
6627
6745
  subskillName: string;
6628
6746
  assetPath: string;
6629
6747
  expectedVersion: string;
6748
+ minimumVersion: string;
6749
+ compatibleMajor: string;
6750
+ versionPolicy: string;
6630
6751
  };
6631
6752
  yolo: boolean;
6632
6753
  executionMode: RefillSendsExecutionMode;
@@ -6864,6 +6985,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
6864
6985
  subskillName: string;
6865
6986
  assetPath: string;
6866
6987
  expectedVersion: string;
6988
+ minimumVersion: string;
6989
+ compatibleMajor: string;
6990
+ versionPolicy: string;
6867
6991
  };
6868
6992
  yolo: boolean;
6869
6993
  executionMode: RefillSendsExecutionMode;
@@ -7095,6 +7219,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
7095
7219
  subskillName: string;
7096
7220
  assetPath: string;
7097
7221
  expectedVersion: string;
7222
+ minimumVersion: string;
7223
+ compatibleMajor: string;
7224
+ versionPolicy: string;
7098
7225
  };
7099
7226
  yolo: boolean;
7100
7227
  executionMode: RefillSendsExecutionMode;
@@ -7332,6 +7459,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
7332
7459
  subskillName: string;
7333
7460
  assetPath: string;
7334
7461
  expectedVersion: string;
7462
+ minimumVersion: string;
7463
+ compatibleMajor: string;
7464
+ versionPolicy: string;
7335
7465
  };
7336
7466
  yolo: boolean;
7337
7467
  executionMode: RefillSendsExecutionMode;
@@ -7567,6 +7697,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
7567
7697
  subskillName: string;
7568
7698
  assetPath: string;
7569
7699
  expectedVersion: string;
7700
+ minimumVersion: string;
7701
+ compatibleMajor: string;
7702
+ versionPolicy: string;
7570
7703
  };
7571
7704
  yolo: boolean;
7572
7705
  executionMode: RefillSendsExecutionMode;
@@ -7798,6 +7931,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
7798
7931
  subskillName: string;
7799
7932
  assetPath: string;
7800
7933
  expectedVersion: string;
7934
+ minimumVersion: string;
7935
+ compatibleMajor: string;
7936
+ versionPolicy: string;
7801
7937
  };
7802
7938
  yolo: boolean;
7803
7939
  executionMode: RefillSendsExecutionMode;
@@ -8034,6 +8170,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
8034
8170
  subskillName: string;
8035
8171
  assetPath: string;
8036
8172
  expectedVersion: string;
8173
+ minimumVersion: string;
8174
+ compatibleMajor: string;
8175
+ versionPolicy: string;
8037
8176
  };
8038
8177
  yolo: boolean;
8039
8178
  executionMode: RefillSendsExecutionMode;
@@ -8272,6 +8411,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
8272
8411
  subskillName: string;
8273
8412
  assetPath: string;
8274
8413
  expectedVersion: string;
8414
+ minimumVersion: string;
8415
+ compatibleMajor: string;
8416
+ versionPolicy: string;
8275
8417
  };
8276
8418
  yolo: boolean;
8277
8419
  executionMode: RefillSendsExecutionMode;
@@ -8508,6 +8650,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
8508
8650
  subskillName: string;
8509
8651
  assetPath: string;
8510
8652
  expectedVersion: string;
8653
+ minimumVersion: string;
8654
+ compatibleMajor: string;
8655
+ versionPolicy: string;
8511
8656
  };
8512
8657
  yolo: boolean;
8513
8658
  executionMode: RefillSendsExecutionMode;
@@ -8775,6 +8920,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
8775
8920
  subskillName: string;
8776
8921
  assetPath: string;
8777
8922
  expectedVersion: string;
8923
+ minimumVersion: string;
8924
+ compatibleMajor: string;
8925
+ versionPolicy: string;
8778
8926
  };
8779
8927
  yolo: boolean;
8780
8928
  executionMode: RefillSendsExecutionMode;
@@ -9007,6 +9155,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
9007
9155
  subskillName: string;
9008
9156
  assetPath: string;
9009
9157
  expectedVersion: string;
9158
+ minimumVersion: string;
9159
+ compatibleMajor: string;
9160
+ versionPolicy: string;
9010
9161
  };
9011
9162
  yolo: boolean;
9012
9163
  executionMode: RefillSendsExecutionMode;
@@ -9245,6 +9396,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
9245
9396
  subskillName: string;
9246
9397
  assetPath: string;
9247
9398
  expectedVersion: string;
9399
+ minimumVersion: string;
9400
+ compatibleMajor: string;
9401
+ versionPolicy: string;
9248
9402
  };
9249
9403
  yolo: boolean;
9250
9404
  executionMode: RefillSendsExecutionMode;
@@ -9481,6 +9635,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
9481
9635
  subskillName: string;
9482
9636
  assetPath: string;
9483
9637
  expectedVersion: string;
9638
+ minimumVersion: string;
9639
+ compatibleMajor: string;
9640
+ versionPolicy: string;
9484
9641
  };
9485
9642
  yolo: boolean;
9486
9643
  executionMode: RefillSendsExecutionMode;
@@ -9713,6 +9870,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
9713
9870
  subskillName: string;
9714
9871
  assetPath: string;
9715
9872
  expectedVersion: string;
9873
+ minimumVersion: string;
9874
+ compatibleMajor: string;
9875
+ versionPolicy: string;
9716
9876
  };
9717
9877
  yolo: boolean;
9718
9878
  executionMode: RefillSendsExecutionMode;
@@ -9950,6 +10110,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
9950
10110
  subskillName: string;
9951
10111
  assetPath: string;
9952
10112
  expectedVersion: string;
10113
+ minimumVersion: string;
10114
+ compatibleMajor: string;
10115
+ versionPolicy: string;
9953
10116
  };
9954
10117
  yolo: boolean;
9955
10118
  executionMode: RefillSendsExecutionMode;
@@ -10189,6 +10352,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
10189
10352
  subskillName: string;
10190
10353
  assetPath: string;
10191
10354
  expectedVersion: string;
10355
+ minimumVersion: string;
10356
+ compatibleMajor: string;
10357
+ versionPolicy: string;
10192
10358
  };
10193
10359
  yolo: boolean;
10194
10360
  executionMode: RefillSendsExecutionMode;
@@ -10426,6 +10592,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
10426
10592
  subskillName: string;
10427
10593
  assetPath: string;
10428
10594
  expectedVersion: string;
10595
+ minimumVersion: string;
10596
+ compatibleMajor: string;
10597
+ versionPolicy: string;
10429
10598
  };
10430
10599
  yolo: boolean;
10431
10600
  executionMode: RefillSendsExecutionMode;
@@ -10705,6 +10874,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
10705
10874
  subskillName: string;
10706
10875
  assetPath: string;
10707
10876
  expectedVersion: string;
10877
+ minimumVersion: string;
10878
+ compatibleMajor: string;
10879
+ versionPolicy: string;
10708
10880
  };
10709
10881
  yolo: boolean;
10710
10882
  executionMode: RefillSendsExecutionMode;
@@ -10928,6 +11100,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
10928
11100
  subskillName: string;
10929
11101
  assetPath: string;
10930
11102
  expectedVersion: string;
11103
+ minimumVersion: string;
11104
+ compatibleMajor: string;
11105
+ versionPolicy: string;
10931
11106
  };
10932
11107
  yolo: boolean;
10933
11108
  executionMode: RefillSendsExecutionMode;
@@ -11186,6 +11361,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
11186
11361
  subskillName: string;
11187
11362
  assetPath: string;
11188
11363
  expectedVersion: string;
11364
+ minimumVersion: string;
11365
+ compatibleMajor: string;
11366
+ versionPolicy: string;
11189
11367
  };
11190
11368
  yolo: boolean;
11191
11369
  executionMode: RefillSendsExecutionMode;
@@ -11348,6 +11526,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
11348
11526
  subskillName: string;
11349
11527
  assetPath: string;
11350
11528
  expectedVersion: string;
11529
+ minimumVersion: string;
11530
+ compatibleMajor: string;
11531
+ versionPolicy: string;
11351
11532
  };
11352
11533
  yolo: boolean;
11353
11534
  executionMode: RefillSendsExecutionMode;
@@ -11516,6 +11697,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
11516
11697
  subskillName: string;
11517
11698
  assetPath: string;
11518
11699
  expectedVersion: string;
11700
+ minimumVersion: string;
11701
+ compatibleMajor: string;
11702
+ versionPolicy: string;
11519
11703
  };
11520
11704
  yolo: boolean;
11521
11705
  executionMode: RefillSendsExecutionMode;
@@ -11682,6 +11866,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
11682
11866
  subskillName: string;
11683
11867
  assetPath: string;
11684
11868
  expectedVersion: string;
11869
+ minimumVersion: string;
11870
+ compatibleMajor: string;
11871
+ versionPolicy: string;
11685
11872
  };
11686
11873
  yolo: boolean;
11687
11874
  executionMode: RefillSendsExecutionMode;
@@ -11844,6 +12031,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
11844
12031
  subskillName: string;
11845
12032
  assetPath: string;
11846
12033
  expectedVersion: string;
12034
+ minimumVersion: string;
12035
+ compatibleMajor: string;
12036
+ versionPolicy: string;
11847
12037
  };
11848
12038
  yolo: boolean;
11849
12039
  executionMode: RefillSendsExecutionMode;
@@ -12011,6 +12201,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
12011
12201
  subskillName: string;
12012
12202
  assetPath: string;
12013
12203
  expectedVersion: string;
12204
+ minimumVersion: string;
12205
+ compatibleMajor: string;
12206
+ versionPolicy: string;
12014
12207
  };
12015
12208
  yolo: boolean;
12016
12209
  executionMode: RefillSendsExecutionMode;
@@ -12180,6 +12373,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
12180
12373
  subskillName: string;
12181
12374
  assetPath: string;
12182
12375
  expectedVersion: string;
12376
+ minimumVersion: string;
12377
+ compatibleMajor: string;
12378
+ versionPolicy: string;
12183
12379
  };
12184
12380
  yolo: boolean;
12185
12381
  executionMode: RefillSendsExecutionMode;
@@ -12348,6 +12544,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
12348
12544
  subskillName: string;
12349
12545
  assetPath: string;
12350
12546
  expectedVersion: string;
12547
+ minimumVersion: string;
12548
+ compatibleMajor: string;
12549
+ versionPolicy: string;
12351
12550
  };
12352
12551
  yolo: boolean;
12353
12552
  executionMode: RefillSendsExecutionMode;
@@ -12456,6 +12655,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
12456
12655
  subskillName: string;
12457
12656
  assetPath: string;
12458
12657
  expectedVersion: string;
12658
+ minimumVersion: string;
12659
+ compatibleMajor: string;
12660
+ versionPolicy: string;
12459
12661
  };
12460
12662
  yolo: boolean;
12461
12663
  executionMode: RefillSendsExecutionMode;
@@ -12577,6 +12779,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
12577
12779
  subskillName: string;
12578
12780
  assetPath: string;
12579
12781
  expectedVersion: string;
12782
+ minimumVersion: string;
12783
+ compatibleMajor: string;
12784
+ versionPolicy: string;
12580
12785
  };
12581
12786
  yolo: boolean;
12582
12787
  executionMode: RefillSendsExecutionMode;
@@ -12785,6 +12990,9 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
12785
12990
  subskillName: string;
12786
12991
  assetPath: string;
12787
12992
  expectedVersion: string;
12993
+ minimumVersion: string;
12994
+ compatibleMajor: string;
12995
+ versionPolicy: string;
12788
12996
  };
12789
12997
  yolo: boolean;
12790
12998
  executionMode: RefillSendsExecutionMode;
@@ -423,6 +423,49 @@ export const refillSendsToolDefinitions = [
423
423
  export function refillSendsCommand(input = {}) {
424
424
  return buildRefillSendsCommand(normalizeRefillSendsInput(input));
425
425
  }
426
+ // fix(112ao-4): the refill flow contract was matched by EXACT STRING across a
427
+ // release boundary — the flow asset ships in the npm package (@sellable/mcp)
428
+ // while the skill that verifies it is installed separately into
429
+ // ~/.codex/plugins/cache. Exact equality makes EVERY contract change breaking:
430
+ // bumping v1.8 -> v1.9 halted every customer-real run with
431
+ // workflow_version_mismatch, and a full repo sweep could not have caught it
432
+ // because the authoritative consumer is not in this repo.
433
+ //
434
+ // The version value itself is deliberately NOT changed here. What changes is
435
+ // the comparison: consumers accept any same-major version at or above the
436
+ // minimum, so additive flow changes ship without a coordinated skill release.
437
+ // A breaking change still gets a major bump (v2), which correctly fails closed.
438
+ export const REFILL_FLOW_MINIMUM_VERSION = "v1.8";
439
+ export const REFILL_FLOW_COMPATIBLE_MAJOR = "v1";
440
+ function parseFlowVersion(value) {
441
+ if (typeof value !== "string")
442
+ return null;
443
+ const match = /^v(\d+)\.(\d+)$/.exec(value.trim());
444
+ if (!match)
445
+ return null;
446
+ const major = Number(match[1]);
447
+ const minor = Number(match[2]);
448
+ return Number.isInteger(major) && Number.isInteger(minor)
449
+ ? { major, minor }
450
+ : null;
451
+ }
452
+ /**
453
+ * Whether an observed flow-asset version satisfies the consumer's contract.
454
+ *
455
+ * Compatible when the major matches and the minor is >= the minimum. An
456
+ * unparseable or absent version stays a mismatch: this widens the accepted
457
+ * range, it never weakens the requirement that a version be verified at all.
458
+ */
459
+ export function isCompatibleRefillFlowVersion(actualVersion, bounds = {}) {
460
+ const minimum = parseFlowVersion(bounds.minimumVersion ?? REFILL_FLOW_MINIMUM_VERSION);
461
+ const actual = parseFlowVersion(actualVersion);
462
+ if (!minimum || !actual)
463
+ return false;
464
+ const expectedMajor = parseFlowVersion(`${bounds.compatibleMajor ?? REFILL_FLOW_COMPATIBLE_MAJOR}.0`);
465
+ if (!expectedMajor || actual.major !== expectedMajor.major)
466
+ return false;
467
+ return actual.minor >= minimum.minor;
468
+ }
426
469
  function buildRefillSendsCommand(input) {
427
470
  const workspaceId = normalizeExplicitWorkspaceId(input.workspaceId);
428
471
  const senders = normalizeStrings(input.senders);
@@ -454,7 +497,13 @@ function buildRefillSendsCommand(input) {
454
497
  workflowAsset: {
455
498
  subskillName: "refill-sends-workflow",
456
499
  assetPath: "core/flow.v1.json",
457
- expectedVersion: "v1.8",
500
+ // fix(112ao-4): `expectedVersion` is retained verbatim so consumers
501
+ // already installed against the exact-match contract keep working. New
502
+ // consumers read the range fields instead. See REFILL_FLOW_VERSION_RANGE.
503
+ expectedVersion: REFILL_FLOW_MINIMUM_VERSION,
504
+ minimumVersion: REFILL_FLOW_MINIMUM_VERSION,
505
+ compatibleMajor: REFILL_FLOW_COMPATIBLE_MAJOR,
506
+ versionPolicy: "compatible_range",
458
507
  },
459
508
  yolo,
460
509
  executionMode,
@@ -502,7 +551,7 @@ function buildRefillSendsCommand(input) {
502
551
  },
503
552
  firstOperationalSteps: [
504
553
  'Load get_subskill_prompt({ subskillName: "refill-sends-workflow" }) before any product operation.',
505
- 'Load get_subskill_asset({ subskillName: "refill-sends-workflow", assetPath: "core/flow.v1.json" }) before any product operation; continue chunks until hasMore is false, parse JSON, and require exactly workflow:"refill-sends-workflow" and version:"v1.8". Report the verified version before D1. Any other or unverified version is workflow_version_mismatch and must stop before get_refill_target_plan or mutation.',
554
+ 'Load get_subskill_asset({ subskillName: "refill-sends-workflow", assetPath: "core/flow.v1.json" }) before any product operation; continue chunks until hasMore is false, parse JSON, and require workflow:"refill-sends-workflow" plus a COMPATIBLE version: same major (v1) with minor at or above the v1.8 minimum, so v1.8, v1.9, and v1.10 all pass while v2.x does not. Report the verified version before D1. A missing, unparseable, wrong-major, or below-minimum version is workflow_version_mismatch and must stop before get_refill_target_plan or mutation. Do not compare the version by exact string equality.',
506
555
  "A skill cannot create or invoke /goal by itself. If this refill is already running inside an active Codex goal, keep that goal open until every selected sender lane is horizon-filled by projected coverage (sent + scheduled), Christian explicitly stops/statuses the run, or a concrete non-scheduler blocker appears.",
507
556
  `Call get_refill_target_plan({ intent: "${intent}"${workspaceId ? `, workspaceId: "${workspaceId}"` : ""}${input.campaignId ? `, campaignId: "${input.campaignId}"` : ""}${input.tableId ? `, tableId: "${input.tableId}"` : ""}${senderIds.length > 0 ? `, senderIds: ${JSON.stringify(senderIds)}` : ""}${senderNames.length > 0
508
557
  ? `, senderNames: ${JSON.stringify(senderNames)}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.745",
3
+ "version": "0.1.747",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code, Codex, and Hermes campaign workflows",
6
6
  "main": "dist/index.js",
@@ -74,10 +74,14 @@ get_subskill_prompt({ subskillName: "refill-sends-workflow" })
74
74
  get_subskill_asset({ subskillName: "refill-sends-workflow", assetPath: "core/flow.v1.json" })
75
75
  ```
76
76
 
77
- Continue chunks until `hasMore:false`; require
78
- exactly `workflow:"refill-sends-workflow"` and `version:"v1.8"`, then report
79
- that verified version before D1. Any other or unverified version is
80
- `workflow_version_mismatch`: stop before `get_refill_target_plan` or mutation.
77
+ Continue chunks until `hasMore:false`; require `workflow:"refill-sends-workflow"`
78
+ and a COMPATIBLE version: same major (`v1`) and minor at or above the minimum
79
+ `v1.8` so `v1.8`, `v1.9`, `v1.10` all pass and `v2.x` does not. Report the
80
+ verified version before D1. A missing, unparseable, wrong-major, or
81
+ below-minimum version is `workflow_version_mismatch`: stop before
82
+ `get_refill_target_plan` or mutation. Do NOT require exact string equality: the
83
+ flow asset ships in the npm package while this skill is installed separately,
84
+ so an exact pin makes every additive contract change a breaking one.
81
85
  Route intent is immutable:
82
86
  workspace-wide `--yolo` uses `intent:"auto"` from first plan through terminal.
83
87
 
@@ -24,15 +24,20 @@ In `--yolo`, the coordinator may
24
24
  perform every fresh planner-ranked safe transition among existing campaigns,
25
25
  lanes, and source families. It may not create a new campaign.
26
26
 
27
- The host must load the entire asset and verify exactly `version:"v1.8"` before
28
- D1. It reports that verified version explicitly. A different or unverified
29
- version is `workflow_version_mismatch` and stops before planner or mutation.
27
+ The host must load the entire asset and verify a COMPATIBLE version before D1:
28
+ same major (`v1`) and minor at or above the minimum `v1.8`, so `v1.9` and
29
+ `v1.10` are accepted and `v2.x` is not. It reports that verified version
30
+ explicitly. A missing, unparseable, wrong-major, or below-minimum version is
31
+ `workflow_version_mismatch` and stops before planner or mutation. Exact-string
32
+ matching is forbidden here: the asset ships in the npm package while the
33
+ verifying skill installs separately, so an exact pin makes every additive
34
+ change breaking.
30
35
 
31
36
  ## Closed-loop executor
32
37
 
33
38
  ```mermaid
34
39
  flowchart TD
35
- A["Receive exact workspace, sender/action selectors, and date envelope"] --> ASSET["Verify complete flow.v1.json, workflow refill-sends-workflow, exact version v1.8"]
40
+ A["Receive exact workspace, sender/action selectors, and date envelope"] --> ASSET["Verify complete flow.v1.json, workflow refill-sends-workflow, compatible version v1 >= v1.8"]
36
41
  ASSET --> D1["Call get_refill_target_plan read-only with immutable route intent"]
37
42
  D1 --> RENDER["Render sender/campaign waterfall, coverage ledger, bounded side effects, forbidden actions, and stop condition"]
38
43
  RENDER --> D2["Call refill_sends with workspaceCoordinator true and displayed revision/action pins"]
@@ -18,6 +18,9 @@
18
18
  "validation": {
19
19
  "workflow": "refill-sends-workflow",
20
20
  "exactVersion": "v1.8",
21
+ "versionPolicy": "compatible_range",
22
+ "minimumVersion": "v1.8",
23
+ "compatibleMajor": "v1",
21
24
  "requiredTopLevelKeys": [
22
25
  "states",
23
26
  "gateOrder",