@sellable/mcp 0.1.908 → 0.1.909
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.
|
@@ -135,19 +135,9 @@ export function normalizeRefillV3SourceOwnerReceipt(params) {
|
|
|
135
135
|
const signalExcludedPostIds = stringArray(rawRecord.excludedPostIds);
|
|
136
136
|
const signalImportResult = recordValue(rawRecord.importResult);
|
|
137
137
|
const signalImportJobId = stringValue(signalImportResult?.jobId);
|
|
138
|
-
|
|
138
|
+
const signalImportPending = isSignalOwner &&
|
|
139
139
|
rawRecord.rowsGainedPending === true &&
|
|
140
|
-
signalImportJobId
|
|
141
|
-
// Signal import is asynchronous. Starting its scrape is not a zero-row
|
|
142
|
-
// terminal: return a retained effect identity so the coordinator reobserves
|
|
143
|
-
// the live source job instead of recording a dry round and spending the
|
|
144
|
-
// keyword avenue before any rows can arrive.
|
|
145
|
-
return {
|
|
146
|
-
kind: "pending",
|
|
147
|
-
effectIdentity: signalImportJobId,
|
|
148
|
-
detail: `Signal import ${signalImportJobId} started and rows are pending; reobserve the source job before classifying yield.`,
|
|
149
|
-
};
|
|
150
|
-
}
|
|
140
|
+
signalImportJobId !== null;
|
|
151
141
|
const signalRowsGained = Math.max(0, numberValue(rawRecord.rowsGained) ?? 0);
|
|
152
142
|
const signalProjection = recordValue(rawRecord.yieldProjection);
|
|
153
143
|
const signalYieldRecord = recordValue(rawRecord.yieldEvidence);
|
|
@@ -266,6 +256,19 @@ export function normalizeRefillV3SourceOwnerReceipt(params) {
|
|
|
266
256
|
}
|
|
267
257
|
: null,
|
|
268
258
|
};
|
|
259
|
+
if (signalImportPending) {
|
|
260
|
+
// Search and per-post qualification have already completed at this point;
|
|
261
|
+
// only row materialization is asynchronous. Preserve that completed search
|
|
262
|
+
// receipt while returning the retained import identity. Otherwise the live
|
|
263
|
+
// job disappears after settlement with no negative-set entry and the outer
|
|
264
|
+
// coordinator offers the identical broadening round again.
|
|
265
|
+
return {
|
|
266
|
+
kind: "pending",
|
|
267
|
+
effectIdentity: signalImportJobId,
|
|
268
|
+
detail: `Signal import ${signalImportJobId} started and rows are pending; reobserve the source job before classifying yield.`,
|
|
269
|
+
receipt,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
269
272
|
return importedCount > 0
|
|
270
273
|
? { kind: "receipt", receipt }
|
|
271
274
|
: { kind: "no_effect", receipt };
|
|
@@ -860,6 +860,36 @@ export async function runRefillV3CampaignWorkWithProductionOwners(input, owners
|
|
|
860
860
|
after: sourceOutcome.receipt,
|
|
861
861
|
});
|
|
862
862
|
}
|
|
863
|
+
if (sourceOutcome.kind === "scoped_failure" &&
|
|
864
|
+
sourceOutcome.pendingReceipt &&
|
|
865
|
+
owners.recordSourceCycle) {
|
|
866
|
+
// A Signal search has completed once the bounded posts were sampled
|
|
867
|
+
// and its async import was launched. Record that round before
|
|
868
|
+
// returning the retained job wait. Previously the pending branch
|
|
869
|
+
// wrote nothing, so the job could settle and disappear while the
|
|
870
|
+
// next advance still advertised the identical round as untried.
|
|
871
|
+
await owners.recordSourceCycle({
|
|
872
|
+
...sourceCycleScope,
|
|
873
|
+
...sourceCycleRunFact,
|
|
874
|
+
receipt: {
|
|
875
|
+
schemaVersion: 1,
|
|
876
|
+
kind: "search",
|
|
877
|
+
campaignId: request.scope.campaignId,
|
|
878
|
+
family: request.sourceCommand.family,
|
|
879
|
+
protectedFitDigest,
|
|
880
|
+
requestFingerprint: sourceOutcome.pendingReceipt.requestFingerprint,
|
|
881
|
+
sourceFingerprint: sourceOutcome.pendingReceipt.sourceAfterFingerprint,
|
|
882
|
+
keywordBatch: request.sourceCommand.keywordBatch,
|
|
883
|
+
postIds: request.sourceCommand.selectedPostIds,
|
|
884
|
+
// Row materialization is still pending. Zero here describes the
|
|
885
|
+
// completed search receipt, not the eventual import yield; the
|
|
886
|
+
// live job and fresh campaign/source observations own that.
|
|
887
|
+
importedCount: 0,
|
|
888
|
+
yieldEvidence: sourceOutcome.pendingReceipt.yieldEvidence,
|
|
889
|
+
observedAt: request.scope.date,
|
|
890
|
+
},
|
|
891
|
+
});
|
|
892
|
+
}
|
|
863
893
|
const closedProviderFrontierSpent = sourceOutcome.kind === "source_terminal";
|
|
864
894
|
const qualitySafeProviderFrontierSpent = request.action === "broaden_source_family" &&
|
|
865
895
|
request.sourceCommand.family === "cold" &&
|
|
@@ -1323,12 +1353,18 @@ async function executeRefillV3Continuation(input, dependencies) {
|
|
|
1323
1353
|
scopeFingerprint,
|
|
1324
1354
|
}),
|
|
1325
1355
|
});
|
|
1326
|
-
|
|
1356
|
+
// Source-owner refusals are valid, reobserved no-effect receipts. Their one
|
|
1357
|
+
// correction still belongs to this exact packet and must return before the
|
|
1358
|
+
// ordinary completed-work path releases the retained campaign.
|
|
1359
|
+
const correctiveContext = outcome.ok
|
|
1360
|
+
? outcome.receipt?.correctiveContext
|
|
1361
|
+
: outcome.correctiveContext;
|
|
1362
|
+
if (correctiveContext !== undefined) {
|
|
1327
1363
|
return {
|
|
1328
1364
|
kind: "attention_correction_required",
|
|
1329
1365
|
runToken,
|
|
1330
1366
|
packet: advanceResult.packet,
|
|
1331
|
-
correction:
|
|
1367
|
+
correction: correctiveContext,
|
|
1332
1368
|
outcome,
|
|
1333
1369
|
};
|
|
1334
1370
|
}
|
|
@@ -144,10 +144,16 @@ export type RefillV3SourceOwnerOutcome = {
|
|
|
144
144
|
kind: "no_effect";
|
|
145
145
|
receipt: RefillV3SourceOwnerReceipt;
|
|
146
146
|
} | {
|
|
147
|
-
/**
|
|
147
|
+
/**
|
|
148
|
+
* The search completed and the source mutation started an asynchronous
|
|
149
|
+
* import that has not settled. The completed-search receipt must be
|
|
150
|
+
* recorded before waiting so the same keyword/post round cannot reopen
|
|
151
|
+
* after the import job disappears from world state.
|
|
152
|
+
*/
|
|
148
153
|
kind: "pending";
|
|
149
154
|
effectIdentity: string;
|
|
150
155
|
detail: string;
|
|
156
|
+
receipt: RefillV3SourceOwnerReceipt;
|
|
151
157
|
} | {
|
|
152
158
|
/** A closed provider-source business terminal, never infrastructure. */
|
|
153
159
|
kind: "source_terminal";
|
|
@@ -220,6 +226,8 @@ export type RefillV3SourceDispatchResult = {
|
|
|
220
226
|
failureClass: RefillV3SourceFailureClass | "uncertain";
|
|
221
227
|
retryable: true;
|
|
222
228
|
effectIdentity: string | null;
|
|
229
|
+
/** Completed search evidence retained while its async import settles. */
|
|
230
|
+
pendingReceipt?: RefillV3SourceOwnerReceipt;
|
|
223
231
|
detail: string;
|
|
224
232
|
correctiveContext?: RefillV3AttentionCorrection;
|
|
225
233
|
exhausted: false;
|
|
@@ -457,6 +457,7 @@ export async function dispatchRefillV3SourceFamily(input) {
|
|
|
457
457
|
failureClass: "uncertain",
|
|
458
458
|
retryable: true,
|
|
459
459
|
effectIdentity: outcome.effectIdentity,
|
|
460
|
+
pendingReceipt: outcome.receipt,
|
|
460
461
|
detail: `${ownerKey}: ${outcome.detail}`,
|
|
461
462
|
exhausted: false,
|
|
462
463
|
reobserveRequired: true,
|