@sellable/mcp 0.1.728 → 0.1.730

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.
@@ -1313,7 +1313,29 @@ async function selectWorkspaceExactTarget(input, workspacePlanOverride, options
1313
1313
  return (!excludedTargets.some((excluded) => excluded.campaignId === candidate.campaignId &&
1314
1314
  excluded.tableId === candidate.tableId) &&
1315
1315
  !excludedExactTargetKeys.has(key) &&
1316
- !prefilterBlockedTargets.some((blocked) => coordinatorBlockedExactTargetMatches(blocked, candidate)));
1316
+ !prefilterBlockedTargets.some((blocked) => {
1317
+ if (!coordinatorBlockedExactTargetMatches(blocked, candidate)) {
1318
+ return false;
1319
+ }
1320
+ // fix(112ag): a run_scheduler_sweep is the scheduler PLACEMENT action that
1321
+ // RESOLVES a loaded_awaiting_scheduler state — the loaded blocker is set by
1322
+ // the prepare/approve fence that produced the ready rows, not by the sweep.
1323
+ // prefilterBlockedTargets excludes every blocker EXCEPT complete/capped, so
1324
+ // a loaded edge lands here and would drop its own sweep BEFORE the in-loop
1325
+ // "sweeps always bind" bypass can act (Amplify t2: cascade cmrk6nihu loaded
1326
+ // 8x, the dated 2026-07-29 sweep — required because that date is beyond the
1327
+ // 48h ambient window — was prefilter-dropped, 0 sweep dispatches, 37 ready
1328
+ // rows stranded at scheduled 0). Waive ONLY the loaded_awaiting_scheduler
1329
+ // blocker and ONLY for the sweep candidate: every other blocker still
1330
+ // excludes it, prep/approve candidates on a loaded edge are still excluded,
1331
+ // and complete/capped edges (never in prefilterBlockedTargets) still bar
1332
+ // prep re-dispatch via completeDeferredTargets in the loop below.
1333
+ if (blocked.blocker === "loaded_awaiting_scheduler" &&
1334
+ workspaceActionFamily(candidate.actionKey) === "run_scheduler_sweep") {
1335
+ return false;
1336
+ }
1337
+ return true;
1338
+ }));
1317
1339
  });
1318
1340
  if (targetCandidates.length === 0) {
1319
1341
  const pendingWaitAction = workspaceActiveWorkWaitAction(workspaceActions) ??
@@ -1436,6 +1458,18 @@ async function selectWorkspaceExactTarget(input, workspacePlanOverride, options
1436
1458
  selectedActionFamily === "continue_prospeo_source" ||
1437
1459
  selectedActionFamily === "broaden_provider_search" ||
1438
1460
  selectedActionFamily === "refresh_sender_post_engagers";
1461
+ // fix(112af-c): a prepare_messages edge suffers the same pooled-cascade
1462
+ // masking as sources/sweeps/waits — its exact scope can read scheduler-loaded
1463
+ // or complete via the shared ready buffer while the lane still holds genuine
1464
+ // never-run supply (sellable.dev 7-29: cmrcd4x4a send_invite prepare skipped
1465
+ // while 69 enrich + 1 generate never-run rows sat behind it). Unlike those
1466
+ // families a prepare is not unconditionally bindable — a genuinely-complete
1467
+ // prepare must stay deferred to avoid a re-prepare loop. So bind ONLY when the
1468
+ // LANE-SCOPED actionable census (per-sender existingRowFrontier stageCounts,
1469
+ // never the pooled coverage) proves a real frontier; an empty census keeps the
1470
+ // settled skip, and the bounded job consumes the frontier so the census drains.
1471
+ const isMaskedPrepareTarget = selectedActionFamily === "prepare_messages" &&
1472
+ exactPlanHasLaneScopedActionableFrontier(exactTargetPlan);
1439
1473
  // fix(111f, OWNER DIRECTIVE — dispatch-first): a settled preflight read
1440
1474
  // may only skip a target when its exact plan exposes NO unresolved
1441
1475
  // coordinator action — any bindable head (source supply, sweeps,
@@ -1448,6 +1482,7 @@ async function selectWorkspaceExactTarget(input, workspacePlanOverride, options
1448
1482
  const bypassSettledSkips = isSchedulerSweepTarget ||
1449
1483
  isBackgroundWaitTarget ||
1450
1484
  isSourceSupplyTarget ||
1485
+ isMaskedPrepareTarget ||
1451
1486
  yoloPlanHasUnresolvedCoordinatorAction(exactTargetPlan);
1452
1487
  if (!bypassSettledSkips && yoloPlanIsComplete(exactTargetPlan)) {
1453
1488
  completedExactTargetCount += 1;
@@ -1519,7 +1554,20 @@ async function selectWorkspaceExactTarget(input, workspacePlanOverride, options
1519
1554
  // must be enforced again after the exact binding is known.
1520
1555
  actionKey: targetConfig.approvalInputs.expectedActionKey,
1521
1556
  };
1522
- if (blockedExactTargets.some((blocked) => coordinatorBlockedExactTargetMatches(blocked, exactSelectedTarget))) {
1557
+ if (blockedExactTargets.some((blocked) => {
1558
+ if (!coordinatorBlockedExactTargetMatches(blocked, exactSelectedTarget)) {
1559
+ return false;
1560
+ }
1561
+ // fix(112ag): mirror the prefilter waiver after the exact rebind — a
1562
+ // run_scheduler_sweep is the placement action that resolves a
1563
+ // loaded_awaiting_scheduler state, so a loaded blocker on its own edge
1564
+ // must not re-skip it here. Every other blocker still excludes it.
1565
+ if (isSchedulerSweepTarget &&
1566
+ blocked.blocker === "loaded_awaiting_scheduler") {
1567
+ return false;
1568
+ }
1569
+ return true;
1570
+ })) {
1523
1571
  continue;
1524
1572
  }
1525
1573
  const selection = {
@@ -1751,6 +1799,25 @@ function classifyWorkspaceUnavailableTerminal(plan, contextNote) {
1751
1799
  }
1752
1800
  return { code: "workspace_exact_target_unavailable", note: contextNote };
1753
1801
  }
1802
+ // fix(112af-c): a prepare_messages edge on a cascade can read scheduler-loaded
1803
+ // or complete at the pooled campaign scope (the shared ready buffer routed to
1804
+ // Open/paid InMail or the connection fallback covers the aggregate gap) while a
1805
+ // specific lane still holds genuine never-run supply the pooled coverage masks
1806
+ // (sellable.dev 7-29: cmrcd4x4a send_invite prepare skipped as "complete or
1807
+ // scheduler-loaded" while 69 enrich + 1 generate never-run rows sat behind it).
1808
+ // The lane-scoped signal is the per-sender existingRowFrontier stageCounts summed
1809
+ // by workspaceActionableSupplyCensus — NEVER the pooled readyBuffer/coverage. When
1810
+ // that census is non-empty the prepare edge is a masked-gap prepare and must bind
1811
+ // so the bounded job consumes the frontier; when the census is empty the edge is
1812
+ // genuinely settled and stays deferred (no re-prepare loop).
1813
+ function exactPlanHasLaneScopedActionableFrontier(plan) {
1814
+ const census = workspaceActionableSupplyCensus(plan);
1815
+ return (census.approvalFrontier > 0 ||
1816
+ census.generateFrontier > 0 ||
1817
+ census.enrichFrontier > 0 ||
1818
+ census.rubricFrontier > 0 ||
1819
+ census.frontierHasMoreRows);
1820
+ }
1754
1821
  function yoloPlanIsComplete(plan) {
1755
1822
  const coverage = yoloCoverage(plan);
1756
1823
  return (coverage.status === "complete" ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.728",
3
+ "version": "0.1.730",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code, Codex, and Hermes campaign workflows",
6
6
  "main": "dist/index.js",