@sellable/mcp 0.1.742 → 0.1.744
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,7 +214,7 @@ export type SchedulerChangedCounts = {
|
|
|
214
214
|
}>;
|
|
215
215
|
};
|
|
216
216
|
export declare function normalizeSchedulerChangedCounts(value: unknown): SchedulerChangedCounts | null;
|
|
217
|
-
export declare function schedulerEnvelopeIsTerminal(schedulerStatus: string): boolean;
|
|
217
|
+
export declare function schedulerEnvelopeIsTerminal(schedulerStatus: string, receipt?: Record<string, unknown> | null): boolean;
|
|
218
218
|
export declare function normalizeSchedulerPrimitiveResult(value: unknown, expected?: {
|
|
219
219
|
expectedTargets: SchedulerExpectedTargetInput[];
|
|
220
220
|
expectedTargetsHash: string;
|
|
@@ -223,7 +223,7 @@ export declare function normalizeSchedulerPrimitiveResult(value: unknown, expect
|
|
|
223
223
|
retryAfterMs: number;
|
|
224
224
|
changedCounts: null;
|
|
225
225
|
auditComplete: false;
|
|
226
|
-
|
|
226
|
+
unsettledReceipt?: Record<string, unknown> | undefined;
|
|
227
227
|
status: "matching_scheduler_active";
|
|
228
228
|
schedulerStatus: string;
|
|
229
229
|
terminal: false;
|
|
@@ -274,50 +274,71 @@ function completeExpectedTargetSummary(value, expectedTargets, maxPlacements) {
|
|
|
274
274
|
JSON.stringify(accounted) === JSON.stringify(target?.senderIds));
|
|
275
275
|
});
|
|
276
276
|
}
|
|
277
|
-
// fix(112ao-2): the scheduler's
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
-
const
|
|
281
|
-
// The envelope statuses that report
|
|
282
|
-
// therefore eligible for the receipt audit below.
|
|
277
|
+
// fix(112ao-2): the scheduler's ATTACHING envelope statuses. These describe a
|
|
278
|
+
// dispatch that joined an existing run rather than producing its own outcome.
|
|
279
|
+
// They are terminal ONLY when the attach actually yielded a terminal receipt.
|
|
280
|
+
const SCHEDULER_ATTACHING_ENVELOPE_STATUSES = new Set(["accepted", "attached"]);
|
|
281
|
+
// The envelope statuses that report an outcome of this dispatch directly.
|
|
283
282
|
const SCHEDULER_TERMINAL_ENVELOPE_STATUSES = new Set([
|
|
284
283
|
"ran",
|
|
285
284
|
"window_closed_noop",
|
|
286
285
|
]);
|
|
287
|
-
|
|
288
|
-
|
|
286
|
+
// The only receipt statuses that constitute a settled outcome. A receipt
|
|
287
|
+
// without one of these is not evidence that anything finished.
|
|
288
|
+
const SCHEDULER_TERMINAL_RECEIPT_STATUSES = new Set([
|
|
289
|
+
"ran",
|
|
290
|
+
"window_closed_noop",
|
|
291
|
+
"failed",
|
|
292
|
+
]);
|
|
293
|
+
function hasTerminalSchedulerReceipt(receipt) {
|
|
294
|
+
const status = receipt ? stringValue(receipt.status) : null;
|
|
295
|
+
return Boolean(status && SCHEDULER_TERMINAL_RECEIPT_STATUSES.has(status));
|
|
296
|
+
}
|
|
297
|
+
export function schedulerEnvelopeIsTerminal(schedulerStatus, receipt = null) {
|
|
298
|
+
if (SCHEDULER_TERMINAL_ENVELOPE_STATUSES.has(schedulerStatus))
|
|
299
|
+
return true;
|
|
300
|
+
return (SCHEDULER_ATTACHING_ENVELOPE_STATUSES.has(schedulerStatus) &&
|
|
301
|
+
hasTerminalSchedulerReceipt(receipt));
|
|
289
302
|
}
|
|
290
303
|
export function normalizeSchedulerPrimitiveResult(value, expected) {
|
|
291
304
|
const response = recordValue(value);
|
|
292
305
|
const receipt = recordValue(response?.receipt);
|
|
293
306
|
const schedulerStatus = stringValue(response?.status) ?? stringValue(receipt?.status) ?? "unknown";
|
|
294
307
|
const errorCode = stringValue(recordValue(response?.error)?.code);
|
|
295
|
-
// fix(112ao-2): whether this dispatch finished is
|
|
296
|
-
//
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
//
|
|
302
|
-
// that
|
|
303
|
-
//
|
|
304
|
-
// (Dotwork 2026-07-29: 21 exact runs,
|
|
308
|
+
// fix(112ao-2): whether this dispatch finished is decided explicitly from the
|
|
309
|
+
// envelope status plus the RECEIPT'S OWN STATUS — never from the bare
|
|
310
|
+
// presence of a receipt field.
|
|
311
|
+
//
|
|
312
|
+
// The previous guard was `!receipt && (accepted || attached)`. Truthiness is
|
|
313
|
+
// the wrong test: an attach that carries a receipt with no terminal status is
|
|
314
|
+
// not evidence that anything settled, yet it skipped this branch, ran the v3
|
|
315
|
+
// audit on that non-evidence, and could return auditComplete: true — a
|
|
316
|
+
// completion claim for a run still in flight, which the coordinator then
|
|
317
|
+
// treats as done rather than awaiting (Dotwork 2026-07-29: 21 exact runs,
|
|
318
|
+
// coverage frozen at sent:0/scheduled:0).
|
|
319
|
+
//
|
|
320
|
+
// The attach is NOT always in flight, and this deliberately does not treat it
|
|
321
|
+
// so: scheduler-run.ts:466-483 only returns a receipt from
|
|
322
|
+
// waitForSchedulerRunReceipt when it is scope-matched to THIS request, so an
|
|
323
|
+
// attach carrying a terminal receipt is a legitimate idempotent completion of
|
|
324
|
+
// this exact operation and must keep its counters. Discarding it would report
|
|
325
|
+
// zero placements for a sweep that really placed cells.
|
|
305
326
|
//
|
|
306
|
-
// `
|
|
307
|
-
// TERMINAL and continue to the audit below. `backoff` and `failed` keep their
|
|
327
|
+
// `ran`/`window_closed_noop` remain terminal. `backoff`/`failed` keep their
|
|
308
328
|
// existing handling — the run loop already unwraps a backoff envelope's
|
|
309
329
|
// replayed receipt deliberately (schedulerRunReceiptIsFreshZeroScheduled).
|
|
310
|
-
if (
|
|
330
|
+
if (SCHEDULER_ATTACHING_ENVELOPE_STATUSES.has(schedulerStatus) &&
|
|
331
|
+
!hasTerminalSchedulerReceipt(receipt)) {
|
|
311
332
|
return {
|
|
312
333
|
status: "matching_scheduler_active",
|
|
313
334
|
schedulerStatus,
|
|
314
335
|
terminal: false,
|
|
315
336
|
disposition: "bounded_reread_wait",
|
|
316
337
|
receipt: null,
|
|
317
|
-
// A
|
|
318
|
-
//
|
|
319
|
-
//
|
|
320
|
-
...(receipt ? {
|
|
338
|
+
// A non-terminal receipt is not this dispatch's effect. Surfaced under a
|
|
339
|
+
// distinct name so it stays readable for diagnostics but can never be
|
|
340
|
+
// mistaken for a settled outcome.
|
|
341
|
+
...(receipt ? { unsettledReceipt: receipt } : {}),
|
|
321
342
|
retryAfterMs: numberValue(response?.retryAfterMs) ?? 30_000,
|
|
322
343
|
changedCounts: null,
|
|
323
344
|
auditComplete: false,
|
|
@@ -363,7 +384,7 @@ export function normalizeSchedulerPrimitiveResult(value, expected) {
|
|
|
363
384
|
status: schedulerStatus,
|
|
364
385
|
// fix(112ao-2): the completion decision, carried explicitly instead of
|
|
365
386
|
// leaving each consumer to re-infer it from the status string.
|
|
366
|
-
terminal: schedulerEnvelopeIsTerminal(schedulerStatus),
|
|
387
|
+
terminal: schedulerEnvelopeIsTerminal(schedulerStatus, receipt),
|
|
367
388
|
receipt: response?.receipt ?? null,
|
|
368
389
|
retryAfterMs: numberValue(response?.retryAfterMs),
|
|
369
390
|
changedCounts,
|
|
@@ -2967,11 +2988,26 @@ export async function executeOneYoloPrimitive(action, workspaceId) {
|
|
|
2967
2988
|
refusalReason: "run_scheduler_sweep action is missing exact workspace/date/revision scope or complete receipt requirements",
|
|
2968
2989
|
};
|
|
2969
2990
|
}
|
|
2991
|
+
// fix(112ao-1): poll by RUN IDENTITY. requestKey is already unique per
|
|
2992
|
+
// sweep, so requestKey + targetDate names this exact dispatch. Sending
|
|
2993
|
+
// targetShapeRevision/expectedTargetsHash/maxPlacements here made the
|
|
2994
|
+
// probe assert that the PLANNER's revision had not moved — but it is
|
|
2995
|
+
// state-fresh by design (112q D2), so it always had, scopeMatches came
|
|
2996
|
+
// back false, and every wait branch below fell through to the
|
|
2997
|
+
// action:"run" redispatch at the end of this block. The dispatch below
|
|
2998
|
+
// still carries the full write scope.
|
|
2970
2999
|
const statusResult = recordValue(await runSchedulerSweep({
|
|
2971
3000
|
workspaceId,
|
|
2972
3001
|
action: "status",
|
|
2973
3002
|
targetDate,
|
|
2974
3003
|
requestKey,
|
|
3004
|
+
// fix(112ao-1-revert): the identity-only probe REQUIRES the FIX 1
|
|
3005
|
+
// server half (route isStatusReadScope). It shipped in 0.1.743 while
|
|
3006
|
+
// the deployed route still demanded the full triple, so every probe
|
|
3007
|
+
// 400'd invalid_scheduler_scope, api.ts threw, and the sweep primitive
|
|
3008
|
+
// died before its action:"run" dispatch — no sweep could place in ANY
|
|
3009
|
+
// workspace. Restored to the full scope until the server half is
|
|
3010
|
+
// deployed. Re-remove these three ONLY after that deploy is live.
|
|
2975
3011
|
targetShapeRevision,
|
|
2976
3012
|
expectedTargetsHash,
|
|
2977
3013
|
maxPlacements,
|