@sellable/mcp 0.1.730 → 0.1.732
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tools/refill-sends.d.ts +384 -0
- package/dist/tools/refill-sends.js +356 -32
- package/package.json +1 -1
|
@@ -3232,6 +3232,123 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
|
|
|
3232
3232
|
workspaceId: string | null;
|
|
3233
3233
|
workspaceResolution: string;
|
|
3234
3234
|
intent: RefillSendsIntent;
|
|
3235
|
+
} | {
|
|
3236
|
+
ok: boolean;
|
|
3237
|
+
status: string;
|
|
3238
|
+
blocker: string;
|
|
3239
|
+
note: string;
|
|
3240
|
+
coordinator: {
|
|
3241
|
+
scope: "workspace";
|
|
3242
|
+
status: "blocked";
|
|
3243
|
+
backgroundJob?: undefined;
|
|
3244
|
+
workspaceTargetPlan?: undefined;
|
|
3245
|
+
selectedTarget?: undefined;
|
|
3246
|
+
waitAction?: undefined;
|
|
3247
|
+
exactTargetPlan?: undefined;
|
|
3248
|
+
note?: undefined;
|
|
3249
|
+
completedTarget?: undefined;
|
|
3250
|
+
exactRunResult?: undefined;
|
|
3251
|
+
handBack?: undefined;
|
|
3252
|
+
};
|
|
3253
|
+
continuation: {
|
|
3254
|
+
required: boolean;
|
|
3255
|
+
userActionRequired: boolean;
|
|
3256
|
+
renderBeforeInvoke?: undefined;
|
|
3257
|
+
kind?: undefined;
|
|
3258
|
+
tool?: undefined;
|
|
3259
|
+
arguments?: undefined;
|
|
3260
|
+
owner?: undefined;
|
|
3261
|
+
retryAfterMs?: undefined;
|
|
3262
|
+
stopCondition?: undefined;
|
|
3263
|
+
};
|
|
3264
|
+
targetDate: string | null;
|
|
3265
|
+
untilDate: string | null;
|
|
3266
|
+
horizonSendDays: number | null;
|
|
3267
|
+
fillWindow: {
|
|
3268
|
+
mode: string;
|
|
3269
|
+
targetDate: string;
|
|
3270
|
+
description: string;
|
|
3271
|
+
untilDate?: undefined;
|
|
3272
|
+
horizonSendDays?: undefined;
|
|
3273
|
+
horizonHours?: undefined;
|
|
3274
|
+
} | {
|
|
3275
|
+
mode: string;
|
|
3276
|
+
untilDate: string;
|
|
3277
|
+
description: string;
|
|
3278
|
+
targetDate?: undefined;
|
|
3279
|
+
horizonSendDays?: undefined;
|
|
3280
|
+
horizonHours?: undefined;
|
|
3281
|
+
} | {
|
|
3282
|
+
mode: string;
|
|
3283
|
+
horizonSendDays: number | null;
|
|
3284
|
+
horizonHours: number | null;
|
|
3285
|
+
description: string;
|
|
3286
|
+
targetDate?: undefined;
|
|
3287
|
+
untilDate?: undefined;
|
|
3288
|
+
};
|
|
3289
|
+
approvalMode: RefillSendsApprovalMode;
|
|
3290
|
+
campaignId: string | null;
|
|
3291
|
+
tableId: string | null;
|
|
3292
|
+
targetConfig: RefillTargetConfigV1 | null;
|
|
3293
|
+
runHandle: RefillRunHandleV1 | null;
|
|
3294
|
+
reportingContext: RefillReportingContextV2 | null;
|
|
3295
|
+
messageTemplateRevision: MessageTemplateRevisionV1 | null;
|
|
3296
|
+
senderScope: string;
|
|
3297
|
+
senderSelectors: {
|
|
3298
|
+
senders: string[];
|
|
3299
|
+
senderIds: string[];
|
|
3300
|
+
senderNames: string[];
|
|
3301
|
+
};
|
|
3302
|
+
firstOperationalSteps: string[];
|
|
3303
|
+
approvalContract: string;
|
|
3304
|
+
forbiddenActions: string[];
|
|
3305
|
+
hostExamples: {
|
|
3306
|
+
claude: string[];
|
|
3307
|
+
codex: string[];
|
|
3308
|
+
mcpTool: {
|
|
3309
|
+
name: string;
|
|
3310
|
+
arguments: {
|
|
3311
|
+
workspaceRunState?: Record<string, unknown> | undefined;
|
|
3312
|
+
workspaceCoordinator?: boolean | undefined;
|
|
3313
|
+
messageTemplateRevision?: MessageTemplateRevisionV1 | undefined;
|
|
3314
|
+
reportingContext?: RefillReportingContextV2 | undefined;
|
|
3315
|
+
targetConfig?: RefillTargetConfigV1 | undefined;
|
|
3316
|
+
runHandle?: RefillRunHandleV1 | undefined;
|
|
3317
|
+
fence?: number | undefined;
|
|
3318
|
+
runId?: string | undefined;
|
|
3319
|
+
expectedActionKey?: string | undefined;
|
|
3320
|
+
expectedTargetShapeRevision?: string | undefined;
|
|
3321
|
+
targetDate: string | null;
|
|
3322
|
+
untilDate: string | null;
|
|
3323
|
+
horizonSendDays: number | null;
|
|
3324
|
+
campaignId: string | undefined;
|
|
3325
|
+
tableId: string | undefined;
|
|
3326
|
+
intent: RefillSendsIntent;
|
|
3327
|
+
approvalMode: RefillSendsApprovalMode;
|
|
3328
|
+
workspaceId: string | null;
|
|
3329
|
+
actionTypes?: ("send_invite" | "send_inmail_closed")[] | undefined;
|
|
3330
|
+
yolo: boolean;
|
|
3331
|
+
senders: string[];
|
|
3332
|
+
senderIds: string[];
|
|
3333
|
+
senderNames: string[];
|
|
3334
|
+
};
|
|
3335
|
+
};
|
|
3336
|
+
};
|
|
3337
|
+
actionTypes?: ("send_invite" | "send_inmail_closed")[] | undefined;
|
|
3338
|
+
command: string;
|
|
3339
|
+
tool: string;
|
|
3340
|
+
promptName: string;
|
|
3341
|
+
workflowPromptName: string;
|
|
3342
|
+
workflowAsset: {
|
|
3343
|
+
subskillName: string;
|
|
3344
|
+
assetPath: string;
|
|
3345
|
+
expectedVersion: string;
|
|
3346
|
+
};
|
|
3347
|
+
yolo: boolean;
|
|
3348
|
+
executionMode: RefillSendsExecutionMode;
|
|
3349
|
+
workspaceId: string | null;
|
|
3350
|
+
workspaceResolution: string;
|
|
3351
|
+
intent: RefillSendsIntent;
|
|
3235
3352
|
} | {
|
|
3236
3353
|
targetPlan: unknown;
|
|
3237
3354
|
orchestration: {
|
|
@@ -8397,6 +8514,273 @@ export declare function executeRefillSendsCommand(input?: RefillSendsCommandInpu
|
|
|
8397
8514
|
workspaceId: string | null;
|
|
8398
8515
|
workspaceResolution: string;
|
|
8399
8516
|
intent: RefillSendsIntent;
|
|
8517
|
+
} | {
|
|
8518
|
+
status: "in_progress";
|
|
8519
|
+
note: string;
|
|
8520
|
+
targetPlan: unknown;
|
|
8521
|
+
exactTargetPlan: {} | null;
|
|
8522
|
+
orchestration: {
|
|
8523
|
+
mode: string;
|
|
8524
|
+
scope: string;
|
|
8525
|
+
phase: string;
|
|
8526
|
+
checkpointedFields?: undefined;
|
|
8527
|
+
transportBudgetMs?: undefined;
|
|
8528
|
+
};
|
|
8529
|
+
coordinator: {
|
|
8530
|
+
scope: string;
|
|
8531
|
+
status: string;
|
|
8532
|
+
completedTarget: WorkspaceExactTarget;
|
|
8533
|
+
selectedTarget: WorkspaceExactTarget;
|
|
8534
|
+
workspaceTargetPlan: unknown;
|
|
8535
|
+
exactRunResult: {
|
|
8536
|
+
status: "blocked";
|
|
8537
|
+
blocker: string;
|
|
8538
|
+
guidance: string;
|
|
8539
|
+
conflicts: string[];
|
|
8540
|
+
runId: string | undefined;
|
|
8541
|
+
readOnly: boolean;
|
|
8542
|
+
forbiddenActions: string[];
|
|
8543
|
+
boundedAuthority: string;
|
|
8544
|
+
} | {
|
|
8545
|
+
readOnly: boolean;
|
|
8546
|
+
mode: string;
|
|
8547
|
+
forbiddenActions: string[];
|
|
8548
|
+
boundedAuthority: string;
|
|
8549
|
+
blocker: string;
|
|
8550
|
+
workspaceId: string;
|
|
8551
|
+
guidance: string;
|
|
8552
|
+
warnings: string[];
|
|
8553
|
+
journalPath: string | null;
|
|
8554
|
+
text: string;
|
|
8555
|
+
workspaceResolution: string;
|
|
8556
|
+
status?: undefined;
|
|
8557
|
+
conflicts?: undefined;
|
|
8558
|
+
runId?: undefined;
|
|
8559
|
+
} | {
|
|
8560
|
+
readOnly: boolean;
|
|
8561
|
+
mode: string;
|
|
8562
|
+
forbiddenActions: string[];
|
|
8563
|
+
boundedAuthority: string;
|
|
8564
|
+
warnings: any[];
|
|
8565
|
+
journalPath: string | null;
|
|
8566
|
+
text: string;
|
|
8567
|
+
workspaceId: string;
|
|
8568
|
+
workspaceResolution: string;
|
|
8569
|
+
blocker?: undefined;
|
|
8570
|
+
guidance?: undefined;
|
|
8571
|
+
status?: undefined;
|
|
8572
|
+
conflicts?: undefined;
|
|
8573
|
+
runId?: undefined;
|
|
8574
|
+
} | {
|
|
8575
|
+
runSnapshot: unknown;
|
|
8576
|
+
readOnly: boolean;
|
|
8577
|
+
forbiddenActions: string[];
|
|
8578
|
+
boundedAuthority: string;
|
|
8579
|
+
status: "dry_run";
|
|
8580
|
+
plan: Record<string, unknown>;
|
|
8581
|
+
blocker?: undefined;
|
|
8582
|
+
guidance?: undefined;
|
|
8583
|
+
conflicts?: undefined;
|
|
8584
|
+
runId?: undefined;
|
|
8585
|
+
} | {
|
|
8586
|
+
runSnapshot: unknown;
|
|
8587
|
+
readOnly: boolean;
|
|
8588
|
+
forbiddenActions: string[];
|
|
8589
|
+
boundedAuthority: string;
|
|
8590
|
+
status: "in_progress";
|
|
8591
|
+
runId: string;
|
|
8592
|
+
fence: number;
|
|
8593
|
+
gate: import("../refill-run-loop.js").RefillLoopGate;
|
|
8594
|
+
guidance: string;
|
|
8595
|
+
journalPath?: string | null;
|
|
8596
|
+
targetConfig?: RefillTargetConfigV1;
|
|
8597
|
+
runHandle?: RefillRunHandleV1;
|
|
8598
|
+
refillReporting?: Record<string, unknown>;
|
|
8599
|
+
blocker?: undefined;
|
|
8600
|
+
conflicts?: undefined;
|
|
8601
|
+
} | {
|
|
8602
|
+
runSnapshot: unknown;
|
|
8603
|
+
readOnly: boolean;
|
|
8604
|
+
forbiddenActions: string[];
|
|
8605
|
+
boundedAuthority: string;
|
|
8606
|
+
status: "blocked";
|
|
8607
|
+
blocker: string;
|
|
8608
|
+
runId?: string;
|
|
8609
|
+
fence?: number;
|
|
8610
|
+
gate?: import("../refill-run-loop.js").RefillLoopGate;
|
|
8611
|
+
guidance: string;
|
|
8612
|
+
holderRunId?: string;
|
|
8613
|
+
report?: Record<string, unknown>;
|
|
8614
|
+
journalPath?: string | null;
|
|
8615
|
+
targetConfig?: RefillTargetConfigV1;
|
|
8616
|
+
runHandle?: RefillRunHandleV1;
|
|
8617
|
+
refillReporting?: Record<string, unknown>;
|
|
8618
|
+
conflicts?: undefined;
|
|
8619
|
+
} | {
|
|
8620
|
+
runSnapshot: unknown;
|
|
8621
|
+
readOnly: boolean;
|
|
8622
|
+
forbiddenActions: string[];
|
|
8623
|
+
boundedAuthority: string;
|
|
8624
|
+
status: "terminal";
|
|
8625
|
+
doneReason: string;
|
|
8626
|
+
report: Record<string, unknown>;
|
|
8627
|
+
runId: string;
|
|
8628
|
+
guidance?: string;
|
|
8629
|
+
journalPath?: string | null;
|
|
8630
|
+
targetConfig?: RefillTargetConfigV1;
|
|
8631
|
+
runHandle?: RefillRunHandleV1;
|
|
8632
|
+
refillReporting?: Record<string, unknown>;
|
|
8633
|
+
runState?: Record<string, unknown>;
|
|
8634
|
+
blocker?: undefined;
|
|
8635
|
+
conflicts?: undefined;
|
|
8636
|
+
};
|
|
8637
|
+
backgroundJob: {
|
|
8638
|
+
jobId: string;
|
|
8639
|
+
status?: undefined;
|
|
8640
|
+
activityState?: undefined;
|
|
8641
|
+
checkedRows?: undefined;
|
|
8642
|
+
preparedMessages?: undefined;
|
|
8643
|
+
activeCellCount?: undefined;
|
|
8644
|
+
};
|
|
8645
|
+
waitAction?: undefined;
|
|
8646
|
+
exactTargetPlan?: undefined;
|
|
8647
|
+
note?: undefined;
|
|
8648
|
+
handBack?: undefined;
|
|
8649
|
+
};
|
|
8650
|
+
continuation: {
|
|
8651
|
+
required: boolean;
|
|
8652
|
+
kind: string;
|
|
8653
|
+
owner: string;
|
|
8654
|
+
userActionRequired: boolean;
|
|
8655
|
+
tool: string;
|
|
8656
|
+
retryAfterMs: number;
|
|
8657
|
+
arguments: {
|
|
8658
|
+
workspaceRunState?: Record<string, unknown> | {
|
|
8659
|
+
coordinatorBlockedExactTargets: (Record<string, unknown> | null)[];
|
|
8660
|
+
} | undefined;
|
|
8661
|
+
yolo: boolean;
|
|
8662
|
+
executionMode: "yolo";
|
|
8663
|
+
requireWorkspace: boolean;
|
|
8664
|
+
workspaceId: string;
|
|
8665
|
+
workspaceCoordinator: boolean;
|
|
8666
|
+
backgroundWait: {
|
|
8667
|
+
jobId: string;
|
|
8668
|
+
campaignId: string;
|
|
8669
|
+
tableId: string;
|
|
8670
|
+
deadlineAt: string;
|
|
8671
|
+
};
|
|
8672
|
+
senders?: string[];
|
|
8673
|
+
senderIds?: string[];
|
|
8674
|
+
senderNames?: string[];
|
|
8675
|
+
horizonSendDays?: number;
|
|
8676
|
+
untilDate?: string;
|
|
8677
|
+
targetDate?: string;
|
|
8678
|
+
campaignId?: string;
|
|
8679
|
+
tableId?: string;
|
|
8680
|
+
intent?: RefillSendsIntent;
|
|
8681
|
+
approvalMode?: RefillSendsApprovalMode;
|
|
8682
|
+
actionTypes?: RefillSendsActionType[];
|
|
8683
|
+
expectedTargetShapeRevision?: string;
|
|
8684
|
+
expectedActionKey?: string;
|
|
8685
|
+
runId?: string;
|
|
8686
|
+
fence?: number;
|
|
8687
|
+
runHandle?: RefillRunHandleV1;
|
|
8688
|
+
targetConfig?: RefillTargetConfigV1;
|
|
8689
|
+
reportingContext?: RefillReportingContextV2;
|
|
8690
|
+
messageTemplateRevision?: MessageTemplateRevisionV1;
|
|
8691
|
+
agentKeywords?: string[];
|
|
8692
|
+
};
|
|
8693
|
+
stopCondition: string;
|
|
8694
|
+
renderBeforeInvoke?: undefined;
|
|
8695
|
+
};
|
|
8696
|
+
targetDate: string | null;
|
|
8697
|
+
untilDate: string | null;
|
|
8698
|
+
horizonSendDays: number | null;
|
|
8699
|
+
fillWindow: {
|
|
8700
|
+
mode: string;
|
|
8701
|
+
targetDate: string;
|
|
8702
|
+
description: string;
|
|
8703
|
+
untilDate?: undefined;
|
|
8704
|
+
horizonSendDays?: undefined;
|
|
8705
|
+
horizonHours?: undefined;
|
|
8706
|
+
} | {
|
|
8707
|
+
mode: string;
|
|
8708
|
+
untilDate: string;
|
|
8709
|
+
description: string;
|
|
8710
|
+
targetDate?: undefined;
|
|
8711
|
+
horizonSendDays?: undefined;
|
|
8712
|
+
horizonHours?: undefined;
|
|
8713
|
+
} | {
|
|
8714
|
+
mode: string;
|
|
8715
|
+
horizonSendDays: number | null;
|
|
8716
|
+
horizonHours: number | null;
|
|
8717
|
+
description: string;
|
|
8718
|
+
targetDate?: undefined;
|
|
8719
|
+
untilDate?: undefined;
|
|
8720
|
+
};
|
|
8721
|
+
approvalMode: RefillSendsApprovalMode;
|
|
8722
|
+
campaignId: string | null;
|
|
8723
|
+
tableId: string | null;
|
|
8724
|
+
targetConfig: RefillTargetConfigV1 | null;
|
|
8725
|
+
runHandle: RefillRunHandleV1 | null;
|
|
8726
|
+
reportingContext: RefillReportingContextV2 | null;
|
|
8727
|
+
messageTemplateRevision: MessageTemplateRevisionV1 | null;
|
|
8728
|
+
senderScope: string;
|
|
8729
|
+
senderSelectors: {
|
|
8730
|
+
senders: string[];
|
|
8731
|
+
senderIds: string[];
|
|
8732
|
+
senderNames: string[];
|
|
8733
|
+
};
|
|
8734
|
+
firstOperationalSteps: string[];
|
|
8735
|
+
approvalContract: string;
|
|
8736
|
+
forbiddenActions: string[];
|
|
8737
|
+
hostExamples: {
|
|
8738
|
+
claude: string[];
|
|
8739
|
+
codex: string[];
|
|
8740
|
+
mcpTool: {
|
|
8741
|
+
name: string;
|
|
8742
|
+
arguments: {
|
|
8743
|
+
workspaceRunState?: Record<string, unknown> | undefined;
|
|
8744
|
+
workspaceCoordinator?: boolean | undefined;
|
|
8745
|
+
messageTemplateRevision?: MessageTemplateRevisionV1 | undefined;
|
|
8746
|
+
reportingContext?: RefillReportingContextV2 | undefined;
|
|
8747
|
+
targetConfig?: RefillTargetConfigV1 | undefined;
|
|
8748
|
+
runHandle?: RefillRunHandleV1 | undefined;
|
|
8749
|
+
fence?: number | undefined;
|
|
8750
|
+
runId?: string | undefined;
|
|
8751
|
+
expectedActionKey?: string | undefined;
|
|
8752
|
+
expectedTargetShapeRevision?: string | undefined;
|
|
8753
|
+
targetDate: string | null;
|
|
8754
|
+
untilDate: string | null;
|
|
8755
|
+
horizonSendDays: number | null;
|
|
8756
|
+
campaignId: string | undefined;
|
|
8757
|
+
tableId: string | undefined;
|
|
8758
|
+
intent: RefillSendsIntent;
|
|
8759
|
+
approvalMode: RefillSendsApprovalMode;
|
|
8760
|
+
workspaceId: string | null;
|
|
8761
|
+
actionTypes?: ("send_invite" | "send_inmail_closed")[] | undefined;
|
|
8762
|
+
yolo: boolean;
|
|
8763
|
+
senders: string[];
|
|
8764
|
+
senderIds: string[];
|
|
8765
|
+
senderNames: string[];
|
|
8766
|
+
};
|
|
8767
|
+
};
|
|
8768
|
+
};
|
|
8769
|
+
actionTypes?: ("send_invite" | "send_inmail_closed")[] | undefined;
|
|
8770
|
+
command: string;
|
|
8771
|
+
tool: string;
|
|
8772
|
+
promptName: string;
|
|
8773
|
+
workflowPromptName: string;
|
|
8774
|
+
workflowAsset: {
|
|
8775
|
+
subskillName: string;
|
|
8776
|
+
assetPath: string;
|
|
8777
|
+
expectedVersion: string;
|
|
8778
|
+
};
|
|
8779
|
+
yolo: boolean;
|
|
8780
|
+
executionMode: RefillSendsExecutionMode;
|
|
8781
|
+
workspaceId: string | null;
|
|
8782
|
+
workspaceResolution: string;
|
|
8783
|
+
intent: RefillSendsIntent;
|
|
8400
8784
|
} | {
|
|
8401
8785
|
status: "terminal";
|
|
8402
8786
|
doneReason: "loaded_awaiting_scheduler";
|
|
@@ -219,6 +219,13 @@ function normalizeWorkspaceRunState(value) {
|
|
|
219
219
|
if (entries.length > 0)
|
|
220
220
|
attemptLedgers[key] = entries;
|
|
221
221
|
}
|
|
222
|
+
// fix(112aj): preserve the continuation-level progress-or-settle counter across
|
|
223
|
+
// coordinator calls. Like the attempt ledgers above, stripping it here would
|
|
224
|
+
// reset the identical-active_exact_run replay count to 1 on every resume and the
|
|
225
|
+
// cap could never trip.
|
|
226
|
+
const activeExactRunProgress = recordValue(root.activeExactRunProgress);
|
|
227
|
+
const activeExactRunFingerprint = stringValue(activeExactRunProgress?.fingerprint);
|
|
228
|
+
const activeExactRunCount = numberValue(activeExactRunProgress?.count);
|
|
222
229
|
return {
|
|
223
230
|
version: 1,
|
|
224
231
|
senderCursors,
|
|
@@ -226,6 +233,14 @@ function normalizeWorkspaceRunState(value) {
|
|
|
226
233
|
passRates: [],
|
|
227
234
|
coordinatorBlockedExactTargets,
|
|
228
235
|
...attemptLedgers,
|
|
236
|
+
...(activeExactRunFingerprint && typeof activeExactRunCount === "number"
|
|
237
|
+
? {
|
|
238
|
+
activeExactRunProgress: {
|
|
239
|
+
fingerprint: activeExactRunFingerprint,
|
|
240
|
+
count: activeExactRunCount,
|
|
241
|
+
},
|
|
242
|
+
}
|
|
243
|
+
: {}),
|
|
229
244
|
};
|
|
230
245
|
}
|
|
231
246
|
const WORKSPACE_ATTEMPT_LEDGER_KEYS = [
|
|
@@ -813,6 +828,36 @@ function withKeywordsHandoffScope(result, scopedInput) {
|
|
|
813
828
|
}
|
|
814
829
|
const BACKGROUND_WAIT_FAST_PATH_TTL_MS = 10 * 60 * 1000;
|
|
815
830
|
const BACKGROUND_WAIT_MIN_RETRY_MS = 5_000;
|
|
831
|
+
// fix(112aj): the continuation-level progress-or-settle contract (the same
|
|
832
|
+
// principle as the ag/af-c bypasses, applied one layer up). An identical
|
|
833
|
+
// active_exact_run continuation — the SAME fence resumed at the same gate /
|
|
834
|
+
// gateSeq / state / plan / shape revision with no observable coverage or effect
|
|
835
|
+
// advance — may not be re-invoked unboundedly. Clover t4 (fence 109, run
|
|
836
|
+
// cmrz49lii) resumed a broaden fence stuck at g2_execute 20× with a byte-stable
|
|
837
|
+
// runSnapshot (gate g2_execute, gateSeq 2, stateRev 36a1de45) — no product effect,
|
|
838
|
+
// no fresh handoff, no no_forward_progress — because the broaden's own attempt
|
|
839
|
+
// bookkeeping wobbles the run-loop's mortality signature. This coordinator bound
|
|
840
|
+
// counts identical active_exact_run resumes and, past the cap, returns an honest
|
|
841
|
+
// no_forward_progress terminal and settles the fence (no continuation, not
|
|
842
|
+
// re-spawned). A fence that IS advancing (any fingerprint field changes) resets
|
|
843
|
+
// the counter and resumes normally, unbounded.
|
|
844
|
+
const ACTIVE_EXACT_RUN_REPLAY_CAP = 3;
|
|
845
|
+
function activeExactRunProgressFingerprint(result) {
|
|
846
|
+
const snapshot = recordValue(result.runSnapshot);
|
|
847
|
+
const runId = stringValue(result.runId) ?? stringValue(snapshot?.runId);
|
|
848
|
+
const fence = numberValue(result.fence);
|
|
849
|
+
if (!runId || typeof fence !== "number" || !snapshot)
|
|
850
|
+
return null;
|
|
851
|
+
return [
|
|
852
|
+
runId,
|
|
853
|
+
String(fence),
|
|
854
|
+
stringValue(snapshot.gate) ?? "",
|
|
855
|
+
String(numberValue(snapshot.gateSeq) ?? ""),
|
|
856
|
+
stringValue(snapshot.stateRevision) ?? "",
|
|
857
|
+
stringValue(snapshot.planRevision) ?? "",
|
|
858
|
+
stringValue(snapshot.targetShapeRevision) ?? "",
|
|
859
|
+
].join("|");
|
|
860
|
+
}
|
|
816
861
|
// Action families whose successful exact terminal means NEW ROWS landed on
|
|
817
862
|
// the campaign — invalidating any earlier complete/capped defer for it.
|
|
818
863
|
const WORKSPACE_SUPPLY_ACTION_FAMILIES = new Set([
|
|
@@ -895,6 +940,51 @@ function backgroundWaitFromSelection(selection, now) {
|
|
|
895
940
|
retryAfterMs,
|
|
896
941
|
};
|
|
897
942
|
}
|
|
943
|
+
// fix(112ai): extract a still-running bounded prep/approve job receipt from a
|
|
944
|
+
// just-completed exact run. When the census bypass admits a masked prepare/
|
|
945
|
+
// approve edge, the coordinator dispatches a bounded job and the exact run
|
|
946
|
+
// returns exact_action_complete with a preparationReceipt that is still RUNNING
|
|
947
|
+
// (terminal:false) — the job drains the lane ASYNC, so the actionable census is
|
|
948
|
+
// non-empty only because scanning has not finished. That in-flight job IS the
|
|
949
|
+
// queued supply behind a non-empty census, so the coordinator must wait on it
|
|
950
|
+
// (self-heal) rather than false-terminal actionable_supply_not_queued
|
|
951
|
+
// (sellable-t4 7-29: prepare_messages:7fc0766d dispatched job cmrz555uc scanning
|
|
952
|
+
// while 681 enrich rows sat in the census). A terminal:true receipt means the
|
|
953
|
+
// job already drained; that is NOT a wait case, and the normal terminal logic
|
|
954
|
+
// (which may legitimately block on residual, correctly-named conditions) runs.
|
|
955
|
+
function dispatchedRunningPrepReceipt(result, completedFamily) {
|
|
956
|
+
if (completedFamily !== "prepare_messages" &&
|
|
957
|
+
completedFamily !== "approve_messages") {
|
|
958
|
+
return null;
|
|
959
|
+
}
|
|
960
|
+
const r = recordValue(result);
|
|
961
|
+
if (stringValue(r?.status) !== "terminal")
|
|
962
|
+
return null;
|
|
963
|
+
if (stringValue(r?.doneReason) !== "exact_action_complete")
|
|
964
|
+
return null;
|
|
965
|
+
const receipt = recordValue(recordValue(r?.report)?.preparationReceipt);
|
|
966
|
+
if (!receipt)
|
|
967
|
+
return null;
|
|
968
|
+
// Only a still-running durable receipt is draining work. terminal:true means
|
|
969
|
+
// the job finished (residual census is a different, correctly-named case); a
|
|
970
|
+
// failed/blocked/errored receipt is a real condition the terminal must surface.
|
|
971
|
+
if (receipt.terminal === true)
|
|
972
|
+
return null;
|
|
973
|
+
const status = stringValue(receipt.status);
|
|
974
|
+
if (status === "failed" ||
|
|
975
|
+
status === "error" ||
|
|
976
|
+
status === "blocked" ||
|
|
977
|
+
status === "cancelled") {
|
|
978
|
+
return null;
|
|
979
|
+
}
|
|
980
|
+
const jobId = stringValue(receipt.jobId);
|
|
981
|
+
if (!jobId)
|
|
982
|
+
return null;
|
|
983
|
+
return {
|
|
984
|
+
jobId,
|
|
985
|
+
retryAfterMs: Math.max(BACKGROUND_WAIT_MIN_RETRY_MS, numberValue(receipt.retryAfterMs) ?? 15_000),
|
|
986
|
+
};
|
|
987
|
+
}
|
|
898
988
|
function workspaceExactTargetsFromAction(action) {
|
|
899
989
|
if (!Array.isArray(action.exactTargets) || action.exactTargets.length === 0) {
|
|
900
990
|
return [];
|
|
@@ -1394,6 +1484,12 @@ async function selectWorkspaceExactTarget(input, workspacePlanOverride, options
|
|
|
1394
1484
|
workspacePlan,
|
|
1395
1485
|
};
|
|
1396
1486
|
}
|
|
1487
|
+
// fix(112ak): empty-candidate terminal path — a ready-surplus gap resolves to
|
|
1488
|
+
// the truthful loaded terminal instead of the actionable_supply_not_queued
|
|
1489
|
+
// defect class (see readySurplusLoadedSelection).
|
|
1490
|
+
const readyLoadedSelection = readySurplusLoadedSelection(workspacePlan);
|
|
1491
|
+
if (readyLoadedSelection)
|
|
1492
|
+
return readyLoadedSelection;
|
|
1397
1493
|
return {
|
|
1398
1494
|
status: "blocked",
|
|
1399
1495
|
...classifyWorkspaceUnavailableTerminal(workspacePlan, (excludedTargets.length > 0 ||
|
|
@@ -1458,17 +1554,23 @@ async function selectWorkspaceExactTarget(input, workspacePlanOverride, options
|
|
|
1458
1554
|
selectedActionFamily === "continue_prospeo_source" ||
|
|
1459
1555
|
selectedActionFamily === "broaden_provider_search" ||
|
|
1460
1556
|
selectedActionFamily === "refresh_sender_post_engagers";
|
|
1461
|
-
// fix(112af-c): a prepare_messages edge suffers the
|
|
1462
|
-
// masking as sources/sweeps/waits — its exact scope can
|
|
1463
|
-
// or complete via the shared ready buffer while the lane
|
|
1464
|
-
//
|
|
1465
|
-
// while 69 enrich + 1 generate never-run rows sat
|
|
1466
|
-
//
|
|
1467
|
-
//
|
|
1468
|
-
//
|
|
1469
|
-
//
|
|
1470
|
-
//
|
|
1471
|
-
|
|
1557
|
+
// fix(112af-c/112ai): a prepare_messages OR approve_messages edge suffers the
|
|
1558
|
+
// same pooled-cascade masking as sources/sweeps/waits — its exact scope can
|
|
1559
|
+
// read scheduler-loaded or complete via the shared ready buffer while the lane
|
|
1560
|
+
// still holds genuine actionable supply (sellable.dev 7-29: cmrcd4x4a
|
|
1561
|
+
// send_invite prepare skipped while 69 enrich + 1 generate never-run rows sat
|
|
1562
|
+
// behind it; Amplify t3 Sadhna + Dotwork cmqbt8b8: approve_messages skipped
|
|
1563
|
+
// while a real approval frontier — needsApproval > 0 — sat behind it). This
|
|
1564
|
+
// closes the masked-supply family (sweep→112ag, prepare→112af-c, approve→112ai)
|
|
1565
|
+
// with ONE census-conditional bypass. Unlike sources/sweeps/waits these are not
|
|
1566
|
+
// unconditionally bindable — a genuinely-complete prepare/approve must stay
|
|
1567
|
+
// deferred to avoid a re-prepare loop. So bind ONLY when the LANE-SCOPED
|
|
1568
|
+
// actionable census (per-sender existingRowFrontier stageCounts —
|
|
1569
|
+
// needsApproval/needsGenerate/needsEnrich/needsRubric, never the pooled
|
|
1570
|
+
// coverage) proves a real frontier; an empty census keeps the settled skip, and
|
|
1571
|
+
// the bounded job consumes the frontier so the census drains.
|
|
1572
|
+
const isMaskedSupplyTarget = (selectedActionFamily === "prepare_messages" ||
|
|
1573
|
+
selectedActionFamily === "approve_messages") &&
|
|
1472
1574
|
exactPlanHasLaneScopedActionableFrontier(exactTargetPlan);
|
|
1473
1575
|
// fix(111f, OWNER DIRECTIVE — dispatch-first): a settled preflight read
|
|
1474
1576
|
// may only skip a target when its exact plan exposes NO unresolved
|
|
@@ -1482,7 +1584,7 @@ async function selectWorkspaceExactTarget(input, workspacePlanOverride, options
|
|
|
1482
1584
|
const bypassSettledSkips = isSchedulerSweepTarget ||
|
|
1483
1585
|
isBackgroundWaitTarget ||
|
|
1484
1586
|
isSourceSupplyTarget ||
|
|
1485
|
-
|
|
1587
|
+
isMaskedSupplyTarget ||
|
|
1486
1588
|
yoloPlanHasUnresolvedCoordinatorAction(exactTargetPlan);
|
|
1487
1589
|
if (!bypassSettledSkips && yoloPlanIsComplete(exactTargetPlan)) {
|
|
1488
1590
|
completedExactTargetCount += 1;
|
|
@@ -1678,6 +1780,12 @@ async function selectWorkspaceExactTarget(input, workspacePlanOverride, options
|
|
|
1678
1780
|
workspacePlan,
|
|
1679
1781
|
};
|
|
1680
1782
|
}
|
|
1783
|
+
// fix(112ak): filtered-candidate terminal path — a ready-surplus gap resolves to
|
|
1784
|
+
// the truthful loaded terminal instead of the actionable_supply_not_queued defect
|
|
1785
|
+
// class (see readySurplusLoadedSelection).
|
|
1786
|
+
const readyLoadedSelection = readySurplusLoadedSelection(workspacePlan);
|
|
1787
|
+
if (readyLoadedSelection)
|
|
1788
|
+
return readyLoadedSelection;
|
|
1681
1789
|
return {
|
|
1682
1790
|
status: "blocked",
|
|
1683
1791
|
...classifyWorkspaceUnavailableTerminal(workspacePlan, (workspaceCoverage.remainingReadyOrProjectedGap !== 0
|
|
@@ -1763,18 +1871,115 @@ function workspaceActionableSupplyCensus(plan) {
|
|
|
1763
1871
|
senderPlanCount: senderPlans.length,
|
|
1764
1872
|
};
|
|
1765
1873
|
}
|
|
1874
|
+
// fix(112ak, OWNER closing invariant): the workspace terminal classifier must
|
|
1875
|
+
// only count actionable supply / frontier signal from senders that still OWE
|
|
1876
|
+
// coverage. A COVERED sender (remainingProjectedGap 0) can carry surplus
|
|
1877
|
+
// hasMoreFrontierRows or surplus stage rows; that surplus must never be read as
|
|
1878
|
+
// "unexposed actionable supply" for a DIFFERENT sender's gap (Amplify t5:
|
|
1879
|
+
// Ali/Victor gap 0 but hasMoreFrontierRows true masked Sadhna's gap-10 lane
|
|
1880
|
+
// whose own stage census was empty and whose 10 rows were paid-InMail
|
|
1881
|
+
// ready_to_schedule surplus — so the workspace false-terminaled
|
|
1882
|
+
// actionable_supply_not_queued while every gap-bearing lane was actually
|
|
1883
|
+
// scheduler/pacing-bound). This re-derives the census over ONLY gap-bearing
|
|
1884
|
+
// senders and buckets each gap lane: real actionable supply, ready-surplus
|
|
1885
|
+
// (prepared rows awaiting the scheduler), or opaque (no ready/actionable/frontier
|
|
1886
|
+
// residue). A missing gap is treated as gap-bearing (conservative) so plans
|
|
1887
|
+
// without gap accounting keep the loud actionable classification.
|
|
1888
|
+
function workspaceGapBearingActionableSupply(plan) {
|
|
1889
|
+
const target = yoloTarget(plan);
|
|
1890
|
+
const senderPlansRaw = target?.senderPlans;
|
|
1891
|
+
const senderPlans = Array.isArray(senderPlansRaw) ? senderPlansRaw : [];
|
|
1892
|
+
let approvalFrontier = 0;
|
|
1893
|
+
let generateFrontier = 0;
|
|
1894
|
+
let enrichFrontier = 0;
|
|
1895
|
+
let rubricFrontier = 0;
|
|
1896
|
+
let frontierHasMoreRows = false;
|
|
1897
|
+
let gapSenderCount = 0;
|
|
1898
|
+
let readySurplusGapSenders = 0;
|
|
1899
|
+
let opaqueGapSenders = 0;
|
|
1900
|
+
for (const senderPlan of senderPlans) {
|
|
1901
|
+
const rec = recordValue(senderPlan);
|
|
1902
|
+
const gap = numberValue(rec?.remainingProjectedGap);
|
|
1903
|
+
// Only lanes that still owe coverage classify the workspace gap. A gap-0
|
|
1904
|
+
// (covered) sender's surplus never contributes; a missing gap is included.
|
|
1905
|
+
if (typeof gap === "number" && gap <= 0)
|
|
1906
|
+
continue;
|
|
1907
|
+
gapSenderCount += 1;
|
|
1908
|
+
const receipt = recordValue(rec?.refillReceipt);
|
|
1909
|
+
const frontier = recordValue(receipt?.existingRowFrontier);
|
|
1910
|
+
const stageCounts = recordValue(frontier?.stageCounts);
|
|
1911
|
+
const approval = Math.max(numberValue(receipt?.approvalCandidates) ?? 0, numberValue(stageCounts?.needsApproval) ?? 0);
|
|
1912
|
+
const generate = numberValue(stageCounts?.needsGenerate) ?? 0;
|
|
1913
|
+
const enrich = numberValue(stageCounts?.needsEnrich) ?? 0;
|
|
1914
|
+
const rubric = numberValue(stageCounts?.needsRubric) ?? 0;
|
|
1915
|
+
const laneActionable = approval + generate + enrich + rubric;
|
|
1916
|
+
const laneFrontier = frontier?.hasMoreFrontierRows === true;
|
|
1917
|
+
const laneReady = numberValue(stageCounts?.ready) ?? 0;
|
|
1918
|
+
approvalFrontier += approval;
|
|
1919
|
+
generateFrontier += generate;
|
|
1920
|
+
enrichFrontier += enrich;
|
|
1921
|
+
rubricFrontier += rubric;
|
|
1922
|
+
if (laneFrontier)
|
|
1923
|
+
frontierHasMoreRows = true;
|
|
1924
|
+
if (laneActionable === 0 && !laneFrontier) {
|
|
1925
|
+
if (laneReady > 0)
|
|
1926
|
+
readySurplusGapSenders += 1;
|
|
1927
|
+
else
|
|
1928
|
+
opaqueGapSenders += 1;
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
const actionableRows = approvalFrontier + generateFrontier + enrichFrontier + rubricFrontier;
|
|
1932
|
+
return {
|
|
1933
|
+
approvalFrontier,
|
|
1934
|
+
generateFrontier,
|
|
1935
|
+
enrichFrontier,
|
|
1936
|
+
rubricFrontier,
|
|
1937
|
+
frontierHasMoreRows,
|
|
1938
|
+
actionableRows,
|
|
1939
|
+
gapSenderCount,
|
|
1940
|
+
readySurplusGapSenders,
|
|
1941
|
+
opaqueGapSenders,
|
|
1942
|
+
};
|
|
1943
|
+
}
|
|
1944
|
+
// fix(112ak): when the workspace gap is owed entirely by gap-bearing lanes whose
|
|
1945
|
+
// residue is ready-surplus (prepared rows in stageCounts.ready, zero actionable
|
|
1946
|
+
// stage supply, no own frontier), the gap is scheduler/pacing-bound — the rows
|
|
1947
|
+
// are ready and the scheduler places them as capacity frees — NOT a
|
|
1948
|
+
// planner-exposure defect. Return the truthful loaded terminal instead of
|
|
1949
|
+
// actionable_supply_not_queued (Amplify t5: Sadhna's gap-10 lane was 10 paid-InMail
|
|
1950
|
+
// ready_to_schedule rows on a fully-scheduled day while COVERED senders carried
|
|
1951
|
+
// the only frontier signal). Gated on the gap-bearing census being empty-actionable
|
|
1952
|
+
// AND every gap lane ready-surplus (no opaque residue), so a genuinely-stuck or
|
|
1953
|
+
// genuinely-actionable gap still classifies honestly. Applied at BOTH selection
|
|
1954
|
+
// terminal sites (empty-candidate early path and the filtered-candidate path).
|
|
1955
|
+
function readySurplusLoadedSelection(workspacePlan) {
|
|
1956
|
+
const gapSupply = workspaceGapBearingActionableSupply(workspacePlan);
|
|
1957
|
+
if (gapSupply.gapSenderCount > 0 &&
|
|
1958
|
+
gapSupply.actionableRows === 0 &&
|
|
1959
|
+
!gapSupply.frontierHasMoreRows &&
|
|
1960
|
+
gapSupply.opaqueGapSenders === 0 &&
|
|
1961
|
+
gapSupply.readySurplusGapSenders > 0) {
|
|
1962
|
+
return {
|
|
1963
|
+
status: "loaded_awaiting_scheduler",
|
|
1964
|
+
note: "Every gap-bearing sender lane is already prepared and ready to schedule; the remaining workspace gap is scheduler/pacing-bound (ready rows awaiting placement), not unexposed actionable supply. No refill run or mutation was started." +
|
|
1965
|
+
workspaceTypedBlockersNote(workspacePlan),
|
|
1966
|
+
workspacePlan,
|
|
1967
|
+
};
|
|
1968
|
+
}
|
|
1969
|
+
return null;
|
|
1970
|
+
}
|
|
1766
1971
|
function classifyWorkspaceUnavailableTerminal(plan, contextNote) {
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1972
|
+
// fix(112ak): gap-gate the actionable_supply signal — only supply behind a
|
|
1973
|
+
// gap-bearing lane proves the planner failed to expose actionable work. A
|
|
1974
|
+
// covered sender's surplus frontier/stage rows do NOT justify the defect class.
|
|
1975
|
+
const census = workspaceGapBearingActionableSupply(plan);
|
|
1976
|
+
const actionableRows = census.actionableRows;
|
|
1772
1977
|
if (actionableRows > 0 || census.frontierHasMoreRows) {
|
|
1773
1978
|
return {
|
|
1774
1979
|
code: "actionable_supply_not_queued",
|
|
1775
1980
|
note: `Actionable existing-row supply remains (${census.approvalFrontier} approval, ` +
|
|
1776
1981
|
`${census.generateFrontier} generate, ${census.enrichFrontier} enrich, ` +
|
|
1777
|
-
`${census.rubricFrontier} rubric candidates across sender lanes` +
|
|
1982
|
+
`${census.rubricFrontier} rubric candidates across gap-bearing sender lanes` +
|
|
1778
1983
|
`${census.frontierHasMoreRows ? ", plus unprocessed frontier rows" : ""}) ` +
|
|
1779
1984
|
"but the fresh workspace queue exposed no executable exact edge for it. " +
|
|
1780
1985
|
"This is retryable: re-run refill_sends with a fresh command; if it repeats, " +
|
|
@@ -1786,7 +1991,8 @@ function classifyWorkspaceUnavailableTerminal(plan, contextNote) {
|
|
|
1786
1991
|
const gap = coverage.remainingReadyOrProjectedGap ?? coverage.remainingProjectedGap;
|
|
1787
1992
|
// Claim receipt-proven exhaustion only when sender receipts were actually
|
|
1788
1993
|
// present in the plan; a plan without senderPlans keeps the generic code.
|
|
1789
|
-
|
|
1994
|
+
const senderPlanCount = workspaceActionableSupplyCensus(plan).senderPlanCount;
|
|
1995
|
+
if (senderPlanCount > 0 && typeof gap === "number" && gap > 0) {
|
|
1790
1996
|
return {
|
|
1791
1997
|
code: "new_campaign_required",
|
|
1792
1998
|
note: `Receipts prove every existing planner-ranked campaign/lane/source family is ` +
|
|
@@ -1799,17 +2005,19 @@ function classifyWorkspaceUnavailableTerminal(plan, contextNote) {
|
|
|
1799
2005
|
}
|
|
1800
2006
|
return { code: "workspace_exact_target_unavailable", note: contextNote };
|
|
1801
2007
|
}
|
|
1802
|
-
// fix(112af-c): a prepare_messages edge on a cascade can
|
|
1803
|
-
// or complete at the pooled campaign scope (the shared ready
|
|
1804
|
-
// Open/paid InMail or the connection fallback covers the aggregate
|
|
1805
|
-
// specific lane still holds genuine
|
|
1806
|
-
// (sellable.dev 7-29: cmrcd4x4a send_invite prepare skipped as
|
|
1807
|
-
// scheduler-loaded" while 69 enrich + 1 generate never-run rows sat
|
|
1808
|
-
//
|
|
1809
|
-
//
|
|
1810
|
-
//
|
|
1811
|
-
//
|
|
1812
|
-
//
|
|
2008
|
+
// fix(112af-c/112ai): a prepare_messages OR approve_messages edge on a cascade can
|
|
2009
|
+
// read scheduler-loaded or complete at the pooled campaign scope (the shared ready
|
|
2010
|
+
// buffer routed to Open/paid InMail or the connection fallback covers the aggregate
|
|
2011
|
+
// gap) while a specific lane still holds genuine actionable supply the pooled
|
|
2012
|
+
// coverage masks (sellable.dev 7-29: cmrcd4x4a send_invite prepare skipped as
|
|
2013
|
+
// "complete or scheduler-loaded" while 69 enrich + 1 generate never-run rows sat
|
|
2014
|
+
// behind it; Dotwork cmqbt8b8 + Amplify t3 Sadhna: approve skipped while a real
|
|
2015
|
+
// needsApproval frontier sat behind it). The lane-scoped signal is the per-sender
|
|
2016
|
+
// existingRowFrontier stageCounts summed by workspaceActionableSupplyCensus — NEVER
|
|
2017
|
+
// the pooled readyBuffer/coverage. When that census is non-empty the edge is a
|
|
2018
|
+
// masked-gap prep/approve and must bind so the bounded job consumes the frontier;
|
|
2019
|
+
// when the census is empty the edge is genuinely settled and stays deferred (no
|
|
2020
|
+
// re-prepare / re-approve loop).
|
|
1813
2021
|
function exactPlanHasLaneScopedActionableFrontier(plan) {
|
|
1814
2022
|
const census = workspaceActionableSupplyCensus(plan);
|
|
1815
2023
|
return (census.approvalFrontier > 0 ||
|
|
@@ -3413,6 +3621,49 @@ export async function executeRefillSendsCommand(input = {}) {
|
|
|
3413
3621
|
: supplyLandedOnCampaign
|
|
3414
3622
|
? clearCompleteDefersForCampaign(deferredCoordinatorWorkspaceRunState, selectedCoordinatorTarget?.campaignId ?? null)
|
|
3415
3623
|
: deferredCoordinatorWorkspaceRunState;
|
|
3624
|
+
// fix(112aj): continuation-level progress-or-settle. When this dispatch is an
|
|
3625
|
+
// active_exact_run resume (continuationHandle set, in_progress), fingerprint
|
|
3626
|
+
// the fence's observable state; if the SAME fence has been re-invoked
|
|
3627
|
+
// ACTIVE_EXACT_RUN_REPLAY_CAP times with a byte-identical fingerprint (no
|
|
3628
|
+
// coverage/effect advance), settle it honestly instead of re-inviting an
|
|
3629
|
+
// identical continuation. A fence that advanced (any fingerprint field moved)
|
|
3630
|
+
// resets the counter and resumes normally.
|
|
3631
|
+
let progressBoundedWorkspaceRunState = coordinatorWorkspaceRunState;
|
|
3632
|
+
if (yolo && continuationHandle) {
|
|
3633
|
+
const fingerprint = activeExactRunProgressFingerprint(result);
|
|
3634
|
+
const priorProgress = recordValue(recordValue(scopedInput.workspaceRunState)?.activeExactRunProgress);
|
|
3635
|
+
const replayCount = fingerprint && stringValue(priorProgress?.fingerprint) === fingerprint
|
|
3636
|
+
? (numberValue(priorProgress?.count) ?? 0) + 1
|
|
3637
|
+
: 1;
|
|
3638
|
+
if (fingerprint && replayCount >= ACTIVE_EXACT_RUN_REPLAY_CAP) {
|
|
3639
|
+
return {
|
|
3640
|
+
...command,
|
|
3641
|
+
ok: false,
|
|
3642
|
+
status: "blocked",
|
|
3643
|
+
blocker: "no_forward_progress",
|
|
3644
|
+
note: `The active exact run (${continuationHandle.runId} fence ${continuationHandle.fence}) was resumed ${replayCount} times with no observable coverage or effect advance ` +
|
|
3645
|
+
"(identical gate/state fingerprint). Settling the fence instead of re-inviting an identical continuation; a fresh refill_sends command reconciles it. No run or mutation was started.",
|
|
3646
|
+
coordinator: {
|
|
3647
|
+
scope: "workspace",
|
|
3648
|
+
status: "blocked",
|
|
3649
|
+
},
|
|
3650
|
+
continuation: { required: false, userActionRequired: false },
|
|
3651
|
+
};
|
|
3652
|
+
}
|
|
3653
|
+
progressBoundedWorkspaceRunState = fingerprint
|
|
3654
|
+
? {
|
|
3655
|
+
...(recordValue(coordinatorWorkspaceRunState) ?? {}),
|
|
3656
|
+
activeExactRunProgress: { fingerprint, count: replayCount },
|
|
3657
|
+
}
|
|
3658
|
+
: coordinatorWorkspaceRunState;
|
|
3659
|
+
}
|
|
3660
|
+
else {
|
|
3661
|
+
const base = recordValue(coordinatorWorkspaceRunState);
|
|
3662
|
+
if (base && "activeExactRunProgress" in base) {
|
|
3663
|
+
const { activeExactRunProgress: _cleared, ...rest } = base;
|
|
3664
|
+
progressBoundedWorkspaceRunState = rest;
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3416
3667
|
const workspaceContinuationArguments = {
|
|
3417
3668
|
yolo: true,
|
|
3418
3669
|
executionMode: "yolo",
|
|
@@ -3432,8 +3683,8 @@ export async function executeRefillSendsCommand(input = {}) {
|
|
|
3432
3683
|
: {}),
|
|
3433
3684
|
approvalMode: scopedInput.approvalMode ?? "approve",
|
|
3434
3685
|
...(isWorkspaceCoordinator ? { workspaceCoordinator: true } : {}),
|
|
3435
|
-
...(
|
|
3436
|
-
? { workspaceRunState:
|
|
3686
|
+
...(progressBoundedWorkspaceRunState
|
|
3687
|
+
? { workspaceRunState: progressBoundedWorkspaceRunState }
|
|
3437
3688
|
: {}),
|
|
3438
3689
|
};
|
|
3439
3690
|
if (isWorkspaceCoordinator &&
|
|
@@ -3659,6 +3910,79 @@ export async function executeRefillSendsCommand(input = {}) {
|
|
|
3659
3910
|
};
|
|
3660
3911
|
}
|
|
3661
3912
|
if (nextSelection.status === "blocked") {
|
|
3913
|
+
// fix(112ai, OWNER closing invariant): actionable_supply_not_queued is a
|
|
3914
|
+
// planner-exposure DEFECT terminal and is legal ONLY when no bounded
|
|
3915
|
+
// prep/approve job dispatched THIS command is still draining the census.
|
|
3916
|
+
// The af-c/ai census bypass admits the masked prepare/approve edge and
|
|
3917
|
+
// the coordinator dispatches a bounded job, but that job drains ASYNC:
|
|
3918
|
+
// the exact run returns exact_action_complete with a still-running
|
|
3919
|
+
// receipt (terminal:false) while the census still shows the un-drained
|
|
3920
|
+
// rows. Emitting actionable_supply_not_queued here (continuation
|
|
3921
|
+
// required:false) HALTS the yolo loop before the job drains — the exact
|
|
3922
|
+
// false-terminal the owner ruled unacceptable on sellable-t4
|
|
3923
|
+
// (prepare_messages:7fc0766d dispatched job cmrz555uc scanning while 681
|
|
3924
|
+
// enrich rows sat in the census). Recognize the in-flight job as the
|
|
3925
|
+
// queued supply: emit a healthy background-wait so the loop re-invokes,
|
|
3926
|
+
// the fast path probes the job by id (sidestepping the planner-exposure
|
|
3927
|
+
// gap that starved the reread), and the census drains (self-heal). This
|
|
3928
|
+
// makes "non-empty census + dispatched running job + halting defect
|
|
3929
|
+
// terminal" unrepresentable.
|
|
3930
|
+
const runningPrepReceipt = dispatchedRunningPrepReceipt(result, completedPrepFamily);
|
|
3931
|
+
if (nextSelection.code === "actionable_supply_not_queued" &&
|
|
3932
|
+
runningPrepReceipt &&
|
|
3933
|
+
selectedCoordinatorTarget) {
|
|
3934
|
+
const backgroundContinuationInput = workspaceCoordinatorInput(scopedInput);
|
|
3935
|
+
delete backgroundContinuationInput.expectedTargetShapeRevision;
|
|
3936
|
+
delete backgroundContinuationInput.expectedActionKey;
|
|
3937
|
+
const backgroundWait = {
|
|
3938
|
+
jobId: runningPrepReceipt.jobId,
|
|
3939
|
+
campaignId: selectedCoordinatorTarget.campaignId ?? null,
|
|
3940
|
+
tableId: selectedCoordinatorTarget.tableId ?? null,
|
|
3941
|
+
deadlineAt: new Date(Date.now() + BACKGROUND_WAIT_FAST_PATH_TTL_MS).toISOString(),
|
|
3942
|
+
};
|
|
3943
|
+
return {
|
|
3944
|
+
...command,
|
|
3945
|
+
status: "in_progress",
|
|
3946
|
+
note: `The exact ${completedPrepFamily} edge dispatched a bounded preparation job (${runningPrepReceipt.jobId}) that is still draining the lane; the actionable census remains non-empty only because that job has not finished scanning. Waiting on the in-flight job instead of false-terminaling actionable_supply_not_queued — the loop re-invokes, the job drains the frontier, and coverage advances.`,
|
|
3947
|
+
targetPlan: nextSelection.workspacePlan,
|
|
3948
|
+
exactTargetPlan: nextSelection.exactTargetPlan ?? null,
|
|
3949
|
+
orchestration: {
|
|
3950
|
+
mode: "fenced_bounded_yolo",
|
|
3951
|
+
scope: "workspace_exact_target_coordinator",
|
|
3952
|
+
phase: "read_only_background_wait",
|
|
3953
|
+
},
|
|
3954
|
+
coordinator: {
|
|
3955
|
+
scope: "workspace",
|
|
3956
|
+
status: "waiting_background",
|
|
3957
|
+
completedTarget: selectedCoordinatorTarget,
|
|
3958
|
+
selectedTarget: selectedCoordinatorTarget,
|
|
3959
|
+
workspaceTargetPlan: nextSelection.workspacePlan,
|
|
3960
|
+
exactRunResult: result,
|
|
3961
|
+
backgroundJob: { jobId: runningPrepReceipt.jobId },
|
|
3962
|
+
},
|
|
3963
|
+
continuation: {
|
|
3964
|
+
required: true,
|
|
3965
|
+
kind: "workspace_background_wait",
|
|
3966
|
+
owner: "packaged_workflow",
|
|
3967
|
+
userActionRequired: false,
|
|
3968
|
+
tool: "refill_sends",
|
|
3969
|
+
retryAfterMs: runningPrepReceipt.retryAfterMs,
|
|
3970
|
+
arguments: {
|
|
3971
|
+
...backgroundContinuationInput,
|
|
3972
|
+
yolo: true,
|
|
3973
|
+
executionMode: "yolo",
|
|
3974
|
+
requireWorkspace: true,
|
|
3975
|
+
workspaceId,
|
|
3976
|
+
workspaceCoordinator: true,
|
|
3977
|
+
backgroundWait,
|
|
3978
|
+
...(coordinatorWorkspaceRunState
|
|
3979
|
+
? { workspaceRunState: coordinatorWorkspaceRunState }
|
|
3980
|
+
: {}),
|
|
3981
|
+
},
|
|
3982
|
+
stopCondition: "A bounded preparation job dispatched this command is still draining the actionable census. After the bounded wait, replan the whole workspace; do not open or resume an exact fence solely to poll background work.",
|
|
3983
|
+
},
|
|
3984
|
+
};
|
|
3985
|
+
}
|
|
3662
3986
|
const persistedDeferredBlocker = coordinatorDeferredBlocker(coordinatorWorkspaceRunState);
|
|
3663
3987
|
const workspaceCoverage = yoloCoverage(nextSelection.workspacePlan);
|
|
3664
3988
|
if (persistedDeferredBlocker === "loaded_awaiting_scheduler" &&
|