@sellable/mcp 0.1.557 → 0.1.558

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.
Files changed (63) hide show
  1. package/README.md +2 -13
  2. package/agents/registry.json +2 -2
  3. package/dist/api.js +6 -3
  4. package/dist/auth.d.ts +6 -0
  5. package/dist/auth.js +44 -2
  6. package/dist/refill-contract.d.ts +157 -0
  7. package/dist/refill-contract.js +487 -0
  8. package/dist/refill-run-client.d.ts +10 -0
  9. package/dist/refill-run-client.js +22 -0
  10. package/dist/refill-run-loop.d.ts +14 -2
  11. package/dist/refill-run-loop.js +160 -15
  12. package/dist/server.js +0 -23
  13. package/dist/tools/auth.d.ts +5 -0
  14. package/dist/tools/auth.js +49 -12
  15. package/dist/tools/campaign-message-preparation.d.ts +62 -0
  16. package/dist/tools/campaign-message-preparation.js +41 -0
  17. package/dist/tools/campaigns.js +2 -2
  18. package/dist/tools/csv-dnc.js +2 -2
  19. package/dist/tools/evergreen-refill-plan.d.ts +3 -0
  20. package/dist/tools/evergreen-refill-plan.js +29 -7
  21. package/dist/tools/leads.d.ts +32 -317
  22. package/dist/tools/leads.js +10 -171
  23. package/dist/tools/model-quality.js +6 -4
  24. package/dist/tools/prompts.d.ts +3 -3
  25. package/dist/tools/prompts.js +15 -7
  26. package/dist/tools/provider-preflight.d.ts +2 -65
  27. package/dist/tools/provider-preflight.js +10 -97
  28. package/dist/tools/readiness.d.ts +5 -89
  29. package/dist/tools/readiness.js +0 -66
  30. package/dist/tools/refill-executors.d.ts +38 -0
  31. package/dist/tools/refill-executors.js +222 -3
  32. package/dist/tools/refill-sends-v2.d.ts +118 -1
  33. package/dist/tools/refill-sends-v2.js +312 -3
  34. package/dist/tools/refill-sends.d.ts +678 -32
  35. package/dist/tools/refill-sends.js +274 -13
  36. package/dist/tools/refill-target-plan.js +486 -14
  37. package/dist/tools/registry.d.ts +115 -330
  38. package/dist/tools/registry.js +1 -7
  39. package/dist/tools/scheduler-fill-capacity.js +1 -1
  40. package/dist/tools/scheduler-run.d.ts +71 -0
  41. package/dist/tools/scheduler-run.js +203 -1
  42. package/dist/tools/setup-evergreen-campaigns.js +1 -1
  43. package/dist/tools/workspace-context.d.ts +1 -1
  44. package/dist/tools/workspace-context.js +8 -3
  45. package/dist/tools/workspace-export.js +2 -2
  46. package/dist/tools/workspaces.d.ts +48 -2
  47. package/dist/tools/workspaces.js +48 -5
  48. package/package.json +1 -1
  49. package/skills/create-campaign/SKILL.md +3 -3
  50. package/skills/create-campaign-v2/SKILL.md +1 -1
  51. package/skills/create-evergreen-campaigns/SKILL.md +16 -16
  52. package/skills/find-leads/SKILL.md +630 -48
  53. package/skills/refill-sends/SKILL.md +91 -353
  54. package/skills/refill-sends-v2/SKILL.md +6 -6
  55. package/skills/refill-sends-v2-workflow/SKILL.md +5 -5
  56. package/skills/refill-sends-v2-workflow/core/flow.v1.json +8 -8
  57. package/skills/refill-sends-workflow/SKILL.md +100 -743
  58. package/skills/refill-sends-workflow/core/contract.v2.json +543 -0
  59. package/skills/refill-sends-workflow/core/flow.v1.json +185 -1
  60. package/dist/tools/find-leads-runs.d.ts +0 -151
  61. package/dist/tools/find-leads-runs.js +0 -98
  62. package/skills/find-leads-v2/SKILL.md +0 -70
  63. package/skills/find-leads-v2/core/flow.v1.json +0 -31
@@ -58,359 +58,97 @@ allowed-tools:
58
58
 
59
59
  # Refill Sends
60
60
 
61
- Use this public command wrapper for plain operator requests such as "fill",
62
- "refill sends", "max out sends", "load everyone up", or "fill horizon sends".
63
-
64
- Host command names:
65
-
66
- - Claude Code: `/sellable:refill-sends`
67
- - Codex: `$sellable:refill-sends`
68
-
69
- Accepted invocation flags in the same user request:
70
-
71
- - `--yolo`: auto-accept the rendered bounded refill packet after the required
72
- fresh state reread.
73
- - `workspaceId: <id>`: required for scheduled automation and `--yolo`; pass it
74
- through on every refill MCP tool call instead of relying on shared config
75
- state.
76
- - `--sender <name-or-id>`: scope to a specific sender; repeat for multiple
77
- senders.
78
- - `--until <YYYY-MM-DD>`: fill through that sender-local date, inclusive,
79
- instead of the default scheduler-forward 48-hour target window.
80
- - `--target-date <YYYY-MM-DD>`: fill only that sender-local date. This means
81
- prepare rows for scheduler-fillable slots on that date, not every remaining
82
- daily-limit slot and not an inclusive through-date.
83
- - `senderIds: <id>, <id>` or `senderNames: <name>, <name>`: explicit selector
84
- alternatives when the host preserves natural-language arguments better than
85
- shell-style flags.
86
- - `untilDate: YYYY-MM-DD`: explicit date selector alternative when the host
87
- preserves natural-language arguments better than shell-style flags.
88
- - `targetDate: YYYY-MM-DD`: exact-date selector alternative when the host
89
- preserves natural-language arguments better than shell-style flags.
90
-
91
- When the host can call typed MCP tools, start with:
92
-
93
- ```text
94
- refill_sends({ yolo?: boolean, executionMode?: "manual" | "scheduled" | "yolo", requireWorkspace?: boolean, workspaceId?: string, senders?: string[], senderIds?: string[], senderNames?: string[], horizonSendDays?: number, untilDate?: "YYYY-MM-DD", targetDate?: "YYYY-MM-DD" })
95
- ```
96
-
97
- That command helper normalizes arguments and returns the execution contract. In
98
- non-yolo mode it does not mutate. In `--yolo`, it may execute exactly one safe
99
- bounded primitive from the fresh `target.globalActionQueue[0]`, then reread and
100
- return the new target plan; currently safe primitives are paid-credit refresh,
101
- existing-row message preparation, generated-message approval, receipt-proven
102
- same-source row copy, and read-only wait rereads. Same-source copy/source
103
- fallback is safe only after receipt-proven exhaustion:
104
- `hasMoreFrontierRows:false`, zero `approvalCandidates`, no `stuckActiveCells`,
105
- and no non-terminal `approvedNotDispatched` work. It does not run unbounded approval, lower
106
- paid-InMail thresholds, switch source families, create campaigns, launch, send,
107
- or write scheduler rows. Continue with the workflow below for route selection,
108
- state rereads, approval gating, source import, preparation, and bounded
109
- approval.
110
-
111
- ## Workspace Contract
112
-
113
- First resolve the target workspace id from the user's request, automation config,
114
- or install-time workspace mapping. Pass `workspaceId` on every scheduled or
115
- `--yolo` refill tool call, including setup/read calls such as
116
- `refill_sends`, `get_refill_target_plan`, `list_senders`,
117
- `get_sender_routing`, `resolve_campaign_fill_route`,
118
- `get_campaign_refill_state`, `get_scheduler_fill_capacity`,
119
- `run_scheduler_sweep`, and any later refill mutation covered by the packet.
120
- Missing `workspaceId` in scheduled or `--yolo` mode is a blocker; stop with
121
- `WORKSPACE_REQUIRED` instead of running against an implicit or guessed
122
- workspace.
123
-
124
- Do not solve scheduled or `--yolo` workspace uncertainty by changing the shared
125
- active workspace. Manual interactive workspace switching remains a separate
126
- diagnostic/setup flow, outside automation.
127
-
128
- Examples:
129
-
130
- ```text
131
- refill_sends({ yolo:true, executionMode:"yolo", requireWorkspace:true, workspaceId:"cmlq1v8ms0000jx04ang4hi7e" })
132
- get_refill_target_plan({ intent:"plain", approvalMode:"approve", workspaceId:"cmlq1v8ms0000jx04ang4hi7e" })
133
- list_senders({ workspaceId:"cmlq1v8ms0000jx04ang4hi7e" })
134
- ```
135
-
136
- Clover scheduled automation must name the Clover workspace explicitly:
61
+ This is the concise public adapter for the typed refill contract. The backend
62
+ planner, durable run, flow asset, and contract asset own allocation, retries,
63
+ circuit behavior, scheduler placement, and completion rules.
64
+
65
+ Compatibility triggers include `fill`, `refill sends`, `max out sends`,
66
+ `load everyone up`, and `fill horizon sends`. Route every one through this same
67
+ typed workflow; none authorizes a broader or legacy execution path.
68
+
69
+ Measure completion from canonical projected coverage (`sent + scheduled`). The
70
+ workflow does not lower paid-InMail thresholds; a threshold change remains a
71
+ separate operator gate.
72
+
73
+ Exact zero-shot form:
74
+
75
+ `$sellable:refill-sends in sellable.dev workspace --target-date YYYY-MM-DD --yolo`
76
+
77
+ Claude Code uses `/sellable:refill-sends`. Optional selectors are `--sender`,
78
+ `--target-date`, `--until`, and `--yolo`.
79
+
80
+ ## Bootstrap and execute
81
+
82
+ 1. Call `mcp__sellable__get_auth_status({})`. If authentication is incomplete,
83
+ use the returned login path and stop until verified.
84
+ 2. First resolve and echo the explicit workspace and date scope. In scheduled or
85
+ `--yolo` mode, a missing `workspaceId` is `WORKSPACE_REQUIRED`; never change
86
+ shared active-workspace state to guess. Echo `workspaceId`, workspace name,
87
+ `targetDate` or other date selector, sender selectors, action selectors, and
88
+ approval mode before continuing.
89
+ 3. Load
90
+ `mcp__sellable__get_subskill_prompt({ subskillName: "refill-sends-workflow" })`
91
+ until `hasMore:false`.
92
+ 4. Load
93
+ `mcp__sellable__get_subskill_asset({ subskillName: "refill-sends-workflow", assetPath: "core/flow.v1.json" })`
94
+ until `hasMore:false`.
95
+ 5. Load
96
+ `mcp__sellable__get_subskill_asset({ subskillName: "refill-sends-workflow", assetPath: "core/contract.v2.json" })`
97
+ until `hasMore:false`. Validate `contractVersion`, `cacheVersion`, and
98
+ `contractHash` against the flow and generated metadata. Stop with
99
+ `unsupported_refill_contract_major` or `refill_contract_hash_mismatch` on
100
+ incompatibility; do not emulate missing assets from repo files or memory.
101
+ 6. Invoke only the public durable entrypoint:
102
+ `mcp__sellable__refill_sends({ workspaceId, targetDate, untilDate, horizonSendDays, senderIds, senderNames, actionTypes, yolo, executionMode, requireWorkspace:true })`.
103
+ Preserve the exact scope and approval echo returned by the tool on resume.
104
+
105
+ ## Operator packet
106
+
107
+ Always render the normal bounded approval packet, even under `--yolo`. Yolo is
108
+ bounded auto-accept of that packet; it is not broader authority. Use campaign
109
+ and sender names first, with IDs secondary. Preserve these six labels exactly:
110
+
111
+ - Need to prepare
112
+ - Goal
113
+ - Already sent
114
+ - Scheduled
115
+ - Ready and waiting to be scheduled
116
+ - Still need
117
+
118
+ Show `targetShapeRevision`, `stateRevision`, action key, exact target date,
119
+ side-effect class, expected targets, placement cap, and approval expiry. The
120
+ public tool runs one packet-named primitive, records its receipt, rereads
121
+ authoritative state, and replans. Keep any existing Codex goal open through
122
+ settling; a skill cannot create `/goal` by itself.
123
+
124
+ ## Safety and terminal truth
125
+
126
+ The generated contract is authoritative. Never direct-send, raw-write scheduler
127
+ fields, create/archive/delete campaigns, lower thresholds, switch an unselected
128
+ source family, mutate sender configuration, or start an unapproved campaign.
129
+ Paused campaign start and workspace-wide scheduler placement remain separately
130
+ named, product-gated side effects. Sellable MCP receipts are the proof surface;
131
+ never use Prisma, SQL, direct database access, or production scripts as proof.
132
+
133
+ Render typed terminal truth name-first. Success is `projected_full`. Otherwise
134
+ report the concrete blocker or `deadline_reached`, `iteration_limit`, or
135
+ `operator_stopped` with target-specific evidence. A ready buffer or
136
+ `awaiting_scheduler_after_ready_buffer` is
137
+ `ready_buffer_exists_is_not_complete`, never completion.
138
+
139
+ <!-- REFILL_CONTRACT_GENERATED:START -->
140
+ ## Generated refill contract metadata
141
+
142
+ contractVersion: 2.0.0
143
+ cacheVersion: refill-contract-v1
144
+ contractHash: e54ba0f80bc534fd70fd8c10c1caab109fe9a91c205cfc423f5f6735cd53fdc1
137
145
 
138
146
  ```text
139
- refill_sends({ yolo:false, executionMode:"scheduled", requireWorkspace:true, workspaceId:"cmlq1v8ms0000jx04ang4hi7e" })
140
- get_refill_target_plan({ intent:"plain", approvalMode:"mark_ready", workspaceId:"cmlq1v8ms0000jx04ang4hi7e" })
147
+ scope: workspace_id, target_date, sender_selectors, campaign_selectors, approval_mode, contract_identity, installed_identity
148
+ gates: approval_packet, one_primitive, fresh_reread, normalized_accounting, prep_circuit
149
+ release identities (independent of semantic hash): mcpPackageVersion, installPackageVersion, codexPluginVersion
150
+ forbidden: direct_send, raw_scheduler_write, campaign_create, campaign_archive_delete, threshold_lowering, unselected_source_mutation, unapproved_campaign_start, sender_config_write
151
+ terminal: projected_full, concrete_blocker, deadline_reached, iteration_limit, operator_stopped, capped_by_scheduler, loaded_awaiting_scheduler, lanes_exhausted, not_an_evergreen_workspace, no_refillable_campaigns
152
+ ready_buffer_exists_is_not_complete
141
153
  ```
142
-
143
- First call `get_auth_status({})`. If auth is not OK, follow the returned login
144
- guidance before route resolution. Do not run refill research against an implicit
145
- or guessed workspace.
146
-
147
- Treat "refill senders", "fill senders", "load everyone up", and "max out
148
- senders" as sender-scoped requests. The target set is senders enrolled in active
149
- campaign-backed sequence campaigns, not the first active campaign returned by a
150
- resolver.
151
-
152
- Goal-mode continuation: a skill cannot create or invoke `/goal` by itself. When
153
- this command is already running inside an active Codex goal, keep that goal open
154
- until every selected sender lane is filled by projected coverage
155
- (`sent + scheduled`) for the scheduler-forward target window, Christian
156
- explicitly stops/statuses the run, or a concrete non-scheduler blocker appears.
157
- Do not call the goal complete or blocked only because the current state is
158
- `awaiting_scheduler_after_ready_buffer`; treat it as loaded, awaiting scheduler.
159
-
160
- Load the internal workflow prompt and deterministic flow asset before taking
161
- any operational step:
162
-
163
- ```text
164
- get_subskill_prompt({ subskillName: "refill-sends-workflow" })
165
- get_subskill_asset({ subskillName: "refill-sends-workflow", assetPath: "core/flow.v1.json" })
166
- ```
167
-
168
- Continue both loads until `hasMore:false`; parse the flow JSON and verify
169
- `workflow:"refill-sends-workflow"` with a `v1` version. Then follow that
170
- workflow exactly. The default path is read-only research: compute the refill
171
- target plan first, resolve the route, identify the sender-relevant campaign
172
- that most recently had scheduler-owned sends, read refill state for that target,
173
- report the next safe step using campaign names first, and stop before mutation
174
- unless the user has explicitly approved the exact workspace,
175
- campaign/table/source ids, caps/dates, approval mode, expected side effects,
176
- and stop/rollback condition.
177
-
178
- Immediately after loading the internal workflow, call
179
- `get_refill_target_plan`. The target plan is the canonical first fact receipt:
180
- eligible senders, selected sender-local days, gross target, actual sent
181
- coverage, scheduler-owned scheduled coverage across active enrolled campaigns,
182
- projected coverage (`sent + scheduled`), inferred per-sender send lane/action
183
- selections, ready buffer, remaining projected gap, paid-InMail credit/threshold
184
- feasibility, `targetShapeRevision`, and `stateRevision`. Refill target lanes are
185
- connection invites (`send_invite`), standalone paid InMails
186
- (`send_inmail_closed`), or unified Sales Nav cascades represented publicly as
187
- `send_inmail_closed` with `campaignClassification:"sales_nav_cascade"`. For a
188
- Sales Nav cascade, refill the selected campaign first; its sequence can route
189
- prospects to Open InMail, paid InMail while fresh credits are >= 5, or
190
- same-campaign connection fallback without asking for separate open/paid/
191
- connection campaigns. DMs (`send_dm`) are follow-up actions, not refill horizon
192
- target capacity, and must not be counted as refill sent, scheduled, or ready
193
- coverage. When `actionTypes` are omitted, trust the target plan's inferred lane
194
- rather than asking which campaign class to fill. If a stale target plan selects
195
- `send_dm` or `send_inmail_open` as the lane, stop and re-plan with the current
196
- planner before mutation.
197
- Short form: trust the target plan's inferred lane when it is a connection invite,
198
- paid-InMail refill lane, or unified Sales Nav cascade.
199
- Connection-only evergreen campaigns with exact `["send_invite"]` sequence proof
200
- are plain invite capacity: treat them as `selectedLane:"send_invite"` only. Do
201
- not infer DM, InMail, Sales Nav cascade, paid-credit refresh, message
202
- generation, follow-up, sequence mutation, launch/start, scheduling override, or
203
- direct-send work from a connection-only lane.
204
-
205
- Structured planner packet:
206
-
207
- - `target.eligibleSenderLedger` is the public sender eligibility ledger.
208
- - `target.senderRefillPlans[]` is the canonical sender-level packet; read and
209
- display it before mutation.
210
- - Each sender packet includes `campaignRanking.options`, `sourcePlan`,
211
- `refillReceipt`, `nextActions`, and `manualAlternates`.
212
- - `refillReceipt` is the public ladder receipt. It carries the selected
213
- campaign/sender/lane summary, skipped rungs, existing-row frontier proof, and
214
- any absolute `wait.deadlineAt`.
215
- - Preserve these coverage labels exactly: `Need to prepare`, `Goal`,
216
- `Already sent`, `Scheduled`, `Ready and waiting to be scheduled`, and
217
- `Still need`.
218
- - `target.globalActionQueue` is the only cross-sender yolo execution queue.
219
- Execute exactly one globally ranked primitive from
220
- `target.globalActionQueue[0]`, then rerun `get_refill_target_plan` with the
221
- same `workspaceId` before
222
- choosing another action.
223
- - `manualAlternates` are not yolo actions. Threshold lowering and campaign
224
- creation are manual continuations only.
225
-
226
- Refill action ladder: approve generated rows only when an explicit bounded
227
- approval gate exists, process all existing same-campaign unenriched/unprepared
228
- rows in bounded batches before any source work, then copy bounded net-new rows
229
- from the selected source (`selectedLeadListId`, provider, and source
230
- fingerprint preserved), then use provider-aligned source-more. A new source or
231
- provider switch changes the reply-rate baseline and is a manual alternate, not a
232
- `--yolo` side effect.
233
- Source/copy/fallback requires receipt-proven exhaustion of earlier rungs:
234
- `existingRowFrontier.hasMoreFrontierRows:false`, zero `approvalCandidates`, no
235
- fresh active prep, no `stuckActiveCells`, and no non-terminal
236
- `approvedNotDispatched` rows. Treat anomalies, `stuckActiveCells`, and
237
- non-terminal `approvedNotDispatched` as diagnose-and-report gates, not
238
- exhaustion. Terminal `approvedNotDispatched` blockers may be reported, then the
239
- ladder can proceed.
240
-
241
- Run-local paid-credit guard: in `--yolo`, the `refill_sends` MCP command
242
- automatically maintains a `refreshedPaidInmailSenderIds` set for the current
243
- command call. If its first target plan has stale/missing paid-InMail credit
244
- facts, it refreshes each selected sender at most once, reruns
245
- `get_refill_target_plan`, and returns the post-refresh `targetPlan` before
246
- choosing the next prep/source-copy/bounded-approval/read-only wait action. If fresh facts are still below
247
- threshold, below-threshold paid-InMail facts fall back to an existing connection
248
- lane, the same Sales Nav cascade campaign's connection branch, or a manual
249
- continuation.
250
-
251
- Freshness gate precedes scheduler wait: if any selected
252
- `target.senderRefillPlans[].paidInmail.status` is `missing_credit_facts` or
253
- `stale_credit_facts`, or the target plan contains a
254
- `refresh_paid_inmail_credits` candidate, do not enter `wait_for_scheduler` even
255
- when `remainingReadyOrProjectedGap:0`. Refresh the exact selected sender credit
256
- facts once, rerun `get_refill_target_plan`, and only then decide whether
257
- scheduler wait is the next safe action. If facts remain missing/stale after the
258
- single refresh attempt, stop with a paid-InMail freshness blocker instead of
259
- waiting on scheduler pickup.
260
- The standalone MCP refresh surface is the scoped route
261
- `/api/v3/mcp/senders/:senderId/refresh-inmail-credits` with explicit
262
- `workspaceId`; do not use active-workspace mutation as the automation control
263
- path.
264
-
265
- Compact refill lessons: sender-level target plan is final truth; trust
266
- `schedulerGate.sendable` and scheduler gate blockers, not raw
267
- `unipileAccountStatus` labels alone; use compact prep status checks for
268
- long-running jobs; reread target plans after prep or cancel; treat ready rows as
269
- intermediate; avoid huge parallel target-plan reads when output is large. If a
270
- campaign produces prepared/ready rows but sender-level projected coverage does
271
- not move after one bounded settle loop, pivot to compact prep status or a
272
- scheduler-proven lane. Do not keep waiting on campaign-level ready counts.
273
-
274
- For exact-date requests, pass `targetDate` to `get_refill_target_plan`. If you
275
- need raw proof, call the read-only `get_scheduler_fill_capacity` query for the
276
- same sender/action/date; it tells the MCP how many cells the product scheduler
277
- will try to place and does not import, approve, schedule, refresh credits, or
278
- mutate.
279
- When the refill loop has ready rows and needs scheduler pickup now, use
280
- `run_scheduler_sweep` with the same explicit `workspaceId`; it can place cells
281
- within existing scheduler gates and returns the receipt, but it never sends or
282
- bypasses limits.
283
- Scheduler-run receipt interpretation: `cellsConsidered is allocation-attempt
284
- count`, not total ready supply, while `readyCellsFound` is ready inventory found
285
- before prefilters. Inspect `campaignScopeSummary` before assuming the selected
286
- refill campaign/table was included; if absent, do not infer that target was
287
- ready-but-blocked. Interpret `prefiltered` as ready cells removed before
288
- allocation, `skipped` as considered cells blocked by scheduler gates, and
289
- `deferred` as considered cells waiting on windows/capacity/cooldown. For ready
290
- closed-InMail cells with stale paid-credit prefilter/defer reasons, refresh
291
- paid-InMail credits once through existing tools, then rerun `run_scheduler_sweep`
292
- or read `action:"status"`; `refresh_paid_inmail_credits_then_rerun` is that
293
- path. `wait_for_capacity_or_window` means report loaded/capped/waiting and do
294
- not source or prep more rows; `no_ready_cells_continue_refill_prep` means return
295
- to the refill/prep ladder. Do not treat `cellsScheduled:0` alone as failure.
296
- If the target plan is complete by projected coverage, report that the selected
297
- target is already filled and no-op without asking for approval. If the ready
298
- buffer covers the projected gap, paid InMail credit facts are fresh for every
299
- selected paid-InMail lane, but scheduled coverage is still short, keep the run
300
- open in a persistent read-only scheduler wait loop. Poll
301
- `get_refill_target_plan` every 60-120 seconds, or on the host's next continuation
302
- interval, until projected coverage fills the target, a concrete non-scheduler
303
- blocker appears, or Christian explicitly asks to stop or only receive a status
304
- report. Treat `awaiting_scheduler_after_ready_buffer` as an in-progress wait
305
- state, not a close-out condition.
306
- Wait actions are gates, not competing goals. When `wait_for_active_work` or
307
- `wait_for_scheduler` includes receipt `wait.deadlineAt`, honor that absolute
308
- deadline; if it is expired on this call, escalate to diagnostics with the
309
- receipt evidence instead of issuing another blind wait.
310
- If paid InMail credit facts are stale or missing and the first target plan
311
- contains `refresh_paid_inmail_credits`, do not present that as the operator's
312
- next action in `--yolo`. Do not present paid-credit refresh as the next operator
313
- action after `refill_sends` returns `autoPaidInmailRefresh` and the
314
- post-refresh `targetPlan`. Trust `refill_sends.autoPaidInmailRefresh`: it should
315
- show the exact sender ids refreshed once, sender-credit-cache write receipts,
316
- and a returned post-refresh `targetPlan`. Continue from that post-refresh packet.
317
- If paid InMail is below threshold after the fresh credit read, report the exact
318
- campaign/table/column threshold action or same-campaign connection fallback;
319
- `--yolo` does not lower paid-InMail thresholds or create campaigns.
320
-
321
- If the plain route's managed waterfall targets are stale, for example skipped
322
- targets show archived/completed shared slots or the returned targets do not cover
323
- the named sender, immediately run the active route refetch before declaring a
324
- sender blocked. Current dashboard-active `PAUSED` campaign-backed sequence
325
- campaigns are start-eligible refill candidates; read refill state before deciding
326
- whether to prep, approve, start, or skip. Do not treat them as archived inventory.
327
-
328
- For interactive Codex or Claude Code sessions, that approval must use the
329
- host-native structured question gate, not plain chat:
330
-
331
- - Codex: use `request_user_input`.
332
- - Claude Code: use `AskUserQuestion`.
333
-
334
- The approval question must present the final refill step with exactly two
335
- choices: `Accept` and `Decline`. Render the full operator output packet in
336
- normal chat immediately before opening the structured approval question so it
337
- can be displayed as Markdown. The chat packet must include workspace, sender
338
- scope, a campaign-by-campaign table with campaign name, sender names, action,
339
- target count/cap, source/list, and blocker/skip reason, then exact ids,
340
- expected side effects, forbidden actions, and the stop condition. The structured
341
- question body must be compact and refer back to the posted packet instead of
342
- duplicating it. Treat `Accept` as permission for only the rendered target, caps,
343
- mode, and side effects. Treat `Decline` as a hard stop with no mutation.
344
-
345
- If Christian includes `--yolo` in the same refill request, treat that flag as
346
- auto-accept for the rendered bounded refill packet after the required fresh state
347
- reread. For sender-scoped language with no named senders, `--yolo` means all
348
- eligible healthy senders enrolled in active campaign-backed sequence campaigns in
349
- the requested `workspaceId`. Without `--yolo`, if Christian did not name senders, ask
350
- which eligible enrolled senders to refill before choosing campaigns or mutating.
351
-
352
- `--yolo` only covers the exact sender set, per-sender target campaigns, caps,
353
- approval mode, and side effects in the packet. It may authorize `start_campaign`
354
- only for selected `PAUSED`, dashboard-active, campaign-backed sequence refill
355
- targets when the rendered packet names the exact campaign ids and start side
356
- effect. Starting a paused campaign can let the product scheduler schedule/send
357
- approved eligible sequence actions, so include that expected side effect in the
358
- packet. It does not authorize starting unrelated, archived, completed, draft, or
359
- direct campaigns, separate launch/send actions, archive or delete cleanup,
360
- direct scheduler writes, sender reassignment, paid-InMail threshold changes,
361
- connection campaign creation, paid-InMail credit refreshes outside the exact
362
- rendered sender packet, or campaigns outside those
363
- selected for the eligible sender set. Stop and re-plan if the route, sender set,
364
- ids, caps, blockers, paid-InMail feasibility, action class, or side-effect class
365
- drift before mutation. Sent/scheduled counts increasing toward the approved
366
- target are expected progress:
367
- they change `stateRevision`, not `targetShapeRevision`, and do not require a
368
- second approval.
369
-
370
- In `--yolo`, continue as far as the rendered packet safely allows. After each
371
- apply/prep/source-copy/bounded-approval/read-only wait result, reread state, settle processing when needed, and move to
372
- the next selected sender or start-eligible same-packet campaign instead of
373
- stopping after the first partial result. If no in-packet safe action remains,
374
- return concrete continuation options with campaign names, exact ids, which option
375
- is still covered by the current packet, and which option needs a new approval
376
- packet.
377
-
378
- For `--yolo` fill/schedule requests, completion means projected saturation
379
- (`sent + scheduled`) for the scheduler-forward target window, not merely
380
- prepared/approved/ready rows. Maintain a target-window saturation ledger per
381
- selected sender: selected send days, gross capacity, actual sent cells, future
382
- scheduler-owned scheduled cells with non-null `scheduledFor`, projected count,
383
- ready-to-schedule buffer, remaining projected gap, paid-InMail feasibility,
384
- `targetShapeRevision`, `stateRevision`, and the next MCP primitive that can
385
- reduce the gap. After every apply/prep/source-copy/bounded-approval/read-only wait result, wait for processing, reread
386
- the target plan/refill state, recompute the ledger, then keep applying safe
387
- bounded actions until projected coverage fills the target window or a concrete
388
- non-scheduler blocker is proven.
389
- If ready rows cover the projected gap but the scheduler has not picked them up
390
- yet, report loaded, awaiting scheduler and run the persistent read-only
391
- scheduler wait loop. Do not finish the refill goal, mark it complete, or mark it
392
- blocked only because it is still `awaiting_scheduler_after_ready_buffer`; keep
393
- waiting unless Christian stops the run or the host cannot continue.
394
-
395
- In `--yolo`, the default fill target is the scheduler-forward 48-hour window
396
- unless `--target-date`/`targetDate`, `--until`/`untilDate`, or an explicit
397
- compatibility `horizonSendDays` is provided. If a target date is provided,
398
- compute bounded gaps for only that sender-local date using scheduler-fillable
399
- slots. If an until date is provided, compute bounded gaps through that
400
- sender-local date inclusive, skipping no-send days and never extending beyond
401
- that date without a new packet. For each target sender, compute the bounded gap
402
- from that sender's healthy daily capacity, existing future scheduler-owned
403
- scheduled sends, and rows already ready to schedule across active campaigns
404
- enrolled with that sender. Then pick the best same-sender campaign to fill the
405
- gap: prefer recent/future scheduler-owned sends for that sender, then strongest
406
- recent result evidence, then source health. Do not stop
407
- after filling only one sender when the request was sender-scoped. If a
408
- same-source copy hits the campaign-table row cap, split the current source into
409
- a bounded LinkedIn profile source list, confirm only that smaller list into the
410
- same campaign, and operate on the copied review batch. Do not fall back to
411
- on-demand campaigns or unrelated active-campaign fills.
412
-
413
- Public concepts are regular campaign and evergreen campaign. Internal direct
414
- campaign types are unsupported refill targets. `fill_campaign_horizon` is only a
415
- legacy evergreen-only lower-level primitive after route and refill-state
416
- evidence proves an evergreen target.
154
+ <!-- REFILL_CONTRACT_GENERATED:END -->
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: refill-sends-v2
3
3
  description: Execute refill sends v2 through the fenced evergreen refill loop, with dry-run and resume support.
4
- visibility: public
4
+ visibility: internal
5
5
  allowed-tools:
6
- - mcp__sellable__refill_sends_v2
6
+ - mcp__sellable__refill_sends
7
7
  - mcp__sellable__get_refill_plan_v2
8
8
  - mcp__sellable__get_subskill_prompt
9
9
  - mcp__sellable__get_subskill_asset
@@ -24,7 +24,7 @@ Host command names:
24
24
  - Claude Code: `/sellable:refill-sends-v2`
25
25
  - Codex: `$sellable:refill-sends-v2`
26
26
 
27
- `refill_sends_v2` is the execution surface. In real-run mode it starts or
27
+ `refill_sends` is the execution surface. In real-run mode it starts or
28
28
  resumes a fenced refill run, reads a fresh packet, executes only the packet's
29
29
  named bounded work, verifies the result, and returns either a terminal report, a
30
30
  blocked report, or an in-progress resume handle. In dry-run mode it stays
@@ -40,19 +40,19 @@ with `WORKSPACE_REQUIRED`; do not switch the shared active workspace.
40
40
  For a real refill run:
41
41
 
42
42
  ```text
43
- refill_sends_v2({ workspaceId, intent:"auto", senderIds?, approvalMode? })
43
+ refill_sends({ workspaceId, intent:"auto", senderIds?, approvalMode? })
44
44
  ```
45
45
 
46
46
  For read-only inspection:
47
47
 
48
48
  ```text
49
- refill_sends_v2({ workspaceId, dryRun:true, intent:"auto", senderIds? })
49
+ refill_sends({ workspaceId, dryRun:true, intent:"auto", senderIds? })
50
50
  ```
51
51
 
52
52
  To resume an in-progress run, pass the handle back exactly:
53
53
 
54
54
  ```text
55
- refill_sends_v2({ workspaceId, runId, fence })
55
+ refill_sends({ workspaceId, runId, fence })
56
56
  ```
57
57
 
58
58
  If a stale handle loses the lease, the tool reports the holder status and the
@@ -3,7 +3,7 @@ name: refill-sends-v2-workflow
3
3
  description: Internal execution workflow for refill sends v2 fenced runs.
4
4
  visibility: internal
5
5
  allowed-tools:
6
- - mcp__sellable__refill_sends_v2
6
+ - mcp__sellable__refill_sends
7
7
  - mcp__sellable__get_refill_plan_v2
8
8
  - mcp__sellable__get_subskill_prompt
9
9
  - mcp__sellable__get_subskill_asset
@@ -16,7 +16,7 @@ allowed-tools:
16
16
  # Refill Sends V2 Workflow
17
17
 
18
18
  This internal workflow mirrors the run-record gates enforced by
19
- `refill_sends_v2`: bootstrap, plan, execute, verify, and report. Dry runs stay
19
+ `refill_sends`: bootstrap, plan, execute, verify, and report. Dry runs stay
20
20
  read-only. Real runs execute only packet-named bounded work under a fenced run
21
21
  lease and return terminal, blocked, or in-progress results.
22
22
 
@@ -25,7 +25,7 @@ Runtime flow asset: after loading this prompt, load
25
25
  through MCP, continue chunks until `hasMore:false`, parse the JSON, and verify
26
26
  `workflow:"refill-sends-v2-workflow"` with a `v1` version before driving the
27
27
  loop. If the asset cannot load or parse, stop with
28
- `blocked:refill_sends_v2_workflow_asset_unavailable`; do not emulate it from
28
+ `blocked:refill_sends_workflow_asset_unavailable`; do not emulate it from
29
29
  local files or memory.
30
30
 
31
31
  ## G0 Bootstrap
@@ -36,7 +36,7 @@ Scheduled or autonomous runs must not rely on implicit workspace state.
36
36
  Start or resume the execution loop:
37
37
 
38
38
  ```text
39
- refill_sends_v2({ workspaceId, intent:"auto", senderIds?, approvalMode?, runId?, fence? })
39
+ refill_sends({ workspaceId, intent:"auto", senderIds?, approvalMode?, runId?, fence? })
40
40
  ```
41
41
 
42
42
  Use `dryRun:true` only when the user asked for read-only inspection. A dry run
@@ -121,7 +121,7 @@ outcome, then verifies before replanning.
121
121
  - Capped scheduler capacity is complete.
122
122
 
123
123
  Scheduler wait is cross-invocation. If the tool returns `in_progress` with
124
- sweep guidance, re-invoke `refill_sends_v2` with `{runId, fence}`. The scheduler
124
+ sweep guidance, re-invoke `refill_sends` with `{runId, fence}`. The scheduler
125
125
  budget is cumulative at the run level. Zero pickup after a confirmed sweep is
126
126
  debugged from `pipelineDiagnosis`; it is not waited out forever.
127
127
  Scheduler-run receipt interpretation still applies to terminal progress:
@@ -65,7 +65,7 @@
65
65
  "purpose": "Resolve explicit workspace evidence when the request did not provide workspaceId."
66
66
  },
67
67
  {
68
- "tool": "refill_sends_v2",
68
+ "tool": "refill_sends",
69
69
  "requiredValues": {
70
70
  "workspaceId": "{workspaceId}"
71
71
  },
@@ -133,7 +133,7 @@
133
133
  "get_active_workspace",
134
134
  "list_workspaces",
135
135
  "get_workspace",
136
- "refill_sends_v2",
136
+ "refill_sends",
137
137
  "get_subskill_prompt",
138
138
  "get_subskill_asset",
139
139
  "get_refill_plan_v2"
@@ -143,7 +143,7 @@
143
143
  "tool": "get_auth_status"
144
144
  },
145
145
  {
146
- "tool": "refill_sends_v2",
146
+ "tool": "refill_sends",
147
147
  "requiredFields": ["workspaceId"]
148
148
  },
149
149
  {
@@ -281,9 +281,9 @@
281
281
  },
282
282
  {
283
283
  "id": "execute",
284
- "description": "Execute exactly the packet head action through refill_sends_v2 internals. Bounded approvals, message preparation, same-source copies, rerun_errored_cells, saved signal continuations, paid-credit refreshes, and pinned-lane starts are allowed only when named by the packet. Execute only the fingerprint captured at the last plan gate; stale packets refuse and return to plan.",
284
+ "description": "Execute exactly the packet head action through refill_sends internals. Bounded approvals, message preparation, same-source copies, rerun_errored_cells, saved signal continuations, paid-credit refreshes, and pinned-lane starts are allowed only when named by the packet. Execute only the fingerprint captured at the last plan gate; stale packets refuse and return to plan.",
285
285
  "allowedTools": [
286
- "refill_sends_v2",
286
+ "refill_sends",
287
287
  "start_campaign_message_preparation",
288
288
  "confirm_lead_list",
289
289
  "import_leads",
@@ -313,11 +313,11 @@
313
313
  },
314
314
  {
315
315
  "id": "verify",
316
- "description": "Verify whole-row outcomes before another plan read. Reattach to an own active prep job by requestSource/requestHash; never re-dispatch prep while a matching job is active. Foreign prep waits until clear or blocks foreign_prep_active. wait_for_active_work and wait_for_source_import reread the plan on bounded cadence. wait_for_scheduler is cross-invocation: each tool call polls briefly under the host guard, heartbeats the lease, and returns in_progress sweep guidance so the agent re-invokes refill_sends_v2 with {runId,fence}. The approximately five minute scheduler budget is cumulative at the run level.",
317
- "allowedTools": ["refill_sends_v2", "get_refill_plan_v2"],
316
+ "description": "Verify whole-row outcomes before another plan read. Reattach to an own active prep job by requestSource/requestHash; never re-dispatch prep while a matching job is active. Foreign prep waits until clear or blocks foreign_prep_active. wait_for_active_work and wait_for_source_import reread the plan on bounded cadence. wait_for_scheduler is cross-invocation: each tool call polls briefly under the host guard, heartbeats the lease, and returns in_progress sweep guidance so the agent re-invokes refill_sends with {runId,fence}. The approximately five minute scheduler budget is cumulative at the run level.",
317
+ "allowedTools": ["refill_sends", "get_refill_plan_v2"],
318
318
  "onEnter": [
319
319
  {
320
- "tool": "refill_sends_v2",
320
+ "tool": "refill_sends",
321
321
  "requiredFields": ["workspaceId", "runId", "fence"]
322
322
  }
323
323
  ],