@sellable/mcp 0.1.550 → 0.1.552
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/agents/registry.json +2 -2
- package/dist/index-dev.js +0 -0
- package/dist/index.js +0 -0
- package/dist/server.js +1 -1
- package/dist/tools/campaigns.d.ts +57 -8
- package/dist/tools/campaigns.js +28 -3
- package/dist/tools/leads.d.ts +22 -0
- package/dist/tools/leads.js +6 -1
- package/dist/tools/model-quality.js +6 -4
- package/dist/tools/prompts.js +6 -6
- package/dist/tools/refill-target-plan.js +2 -2
- package/dist/tools/registry.d.ts +88 -9
- package/dist/tools/scheduler-fill-capacity.js +1 -1
- package/dist/tools/sequencer.d.ts +16 -3
- package/dist/tools/sequencer.js +72 -36
- package/dist/tools/setup-evergreen-campaigns.d.ts +21 -0
- package/dist/tools/setup-evergreen-campaigns.js +23 -4
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +3 -3
- package/skills/create-campaign-v2/SKILL.md +1 -1
- package/skills/create-campaign-v2/references/tier-routing-matrix.md +5 -0
- package/skills/create-evergreen-campaigns/SKILL.md +73 -24
- package/skills/refill-sends/SKILL.md +9 -0
- package/skills/refill-sends-v2/SKILL.md +5 -0
- package/skills/refill-sends-v2-workflow/SKILL.md +7 -0
- package/skills/refill-sends-v2-workflow/core/flow.v1.json +1 -0
- package/dist/refill-date-window.d.ts +0 -34
- package/dist/refill-date-window.js +0 -210
- package/dist/tools/refill-sends-evergreen.d.ts +0 -28
- package/dist/tools/refill-sends-evergreen.js +0 -47
- package/skills/research/config.json +0 -9
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { getApi } from "../api.js";
|
|
2
|
-
async function postSetupEvergreenCampaigns(body) {
|
|
2
|
+
async function postSetupEvergreenCampaigns(body, workspaceId) {
|
|
3
3
|
const api = getApi();
|
|
4
|
-
return api.post("/api/v3/mcp/setup-evergreen-campaigns", body);
|
|
4
|
+
return api.post("/api/v3/mcp/setup-evergreen-campaigns", body, workspaceId ? { workspaceId } : undefined);
|
|
5
5
|
}
|
|
6
6
|
export const setupEvergreenCampaignsToolDefinitions = [
|
|
7
7
|
{
|
|
8
8
|
name: "setup_evergreen_campaigns",
|
|
9
|
-
description: "Evergreen campaign setup plan/verify command. Use plan mode first to inspect exact workspace/sender/campaign/table/source state and receive immutable lane packets. `selectedSenderIds` is a legacy shorthand for both scopes; prefer `postEngagerSenderIds` for the Post Engagers sender scope and `sharedSenderIds` for the shared lane sender scope when they differ. `sharedSenderIds` must include every intended shared-lane sender, not only the named Post Engagers sender; when adding other senders to existing shared evergreen campaigns, resolve those sender ids with list_senders and pass the full shared set. If a protected existing Post Engagers campaign must stay unchanged and the operator requested only shared lane execution, pass postEngagerSenderIds:[] and sharedSenderIds; do not include the protected active Post Engagers lane as a reuse packet because it can make the yolo plan non-autoExecutable. The command plans one Post Engagers lane per post-engager sender plus shared Signal Discovery and Shared Cold Fallback lanes for the shared sender set. Non-archived PAUSED/ACTIVE/DRAFT shared campaigns/tables are the reusable targets; archived campaigns, archived tables, and archived waterfall bindings are stale inventory and must not be counted as valid evergreen slots. If an existing non-archived shared campaign is already attached to additional senders, plan reporting should count those attached senders as existing shared-lane membership rather than treating them as missing or duplicate slots. yolo is only a parent-skill auto-execution hint for safe lane packets; pass yolo only in plan mode and never include yolo on mode:\"verify\" calls. This backend command remains read-only in plan mode and verifies receipts in verify mode. Package-backed prompt authority: the installed public wrapper can be the local Codex skill entrypoint, but lane workers must use get_subskill_prompt and get_subskill_asset for nested `$sellable:create-campaign`, create-campaign-v2, generate-messages, validation, and assets; nested filesystem prompt fallback is a failed UAT. Use mcp__sellable only for workspace selection and product mutations/readbacks. Do not use mcp__sellable_admin, direct DB, Prisma, SQL, built-in web search, browser search, web.run, or any external browsing/search tool as execution or research proof; if Sellable MCP research tools are insufficient, write a blocked receipt instead of browsing externally. Worker-local replans are read-only drift checks and must preserve the exact parent sender scopes, including postEngagerSenderIds:[] when intentionally empty and the exact sharedSenderIds array; if scope, planRevision, actionId, or laneKey drifts, stop with blocked:worker_plan_scope_drift before mutation. Each lane packet includes workerDispatch with preferredRuntime, runtimeFallbackOrder, acceptedRuntimes, rejectedRuntimes, requiresVisibleThreadOrDurableReceipt, receiptArtifactHint, receiptRunId, and receiptMustBeWrittenAfter; pre-existing receipts at old deterministic paths are stale and must not be used, so stop with blocked:stale_receipt_artifact if the receipt was not freshly written for the current receiptRunId. `multi_agent_v1.spawn_agent`/opaque spawn_agent is not accepted for mutating command proof unless the parent has visible thread or durable receipt proof. In local Codex, default to `workerDispatch.preferredRuntime` (`visible-codex-app-thread`): discover Codex app thread tools if needed, then call `codex_app.list_projects` and `codex_app.create_thread` with a local project target; do not create a worktree for lane execution. If Codex app thread tools are unavailable but local Codex CLI is available, use durable streaming workers with `codex -a never -s danger-full-access -c model_reasoning_effort=
|
|
9
|
+
description: "Evergreen campaign setup plan/verify command. Use plan mode first to inspect exact workspace/sender/campaign/table/source state and receive immutable lane packets. `selectedSenderIds` is a legacy shorthand for both scopes; prefer `postEngagerSenderIds` for the Post Engagers sender scope and `sharedSenderIds` for the shared lane sender scope when they differ. `sharedSenderIds` must include every intended shared-lane sender, not only the named Post Engagers sender; when adding other senders to existing shared evergreen campaigns, resolve those sender ids with list_senders and pass the full shared set. If a protected existing Post Engagers campaign must stay unchanged and the operator requested only shared lane execution, pass postEngagerSenderIds:[] and sharedSenderIds; do not include the protected active Post Engagers lane as a reuse packet because it can make the yolo plan non-autoExecutable. The command plans one Post Engagers lane per post-engager sender plus shared Signal Discovery and Shared Cold Fallback lanes for the shared sender set. Non-archived PAUSED/ACTIVE/DRAFT shared campaigns/tables are the reusable targets; archived campaigns, archived tables, and archived waterfall bindings are stale inventory and must not be counted as valid evergreen slots. If an existing non-archived shared campaign is already attached to additional senders, plan reporting should count those attached senders as existing shared-lane membership rather than treating them as missing or duplicate slots. yolo is only a parent-skill auto-execution hint for safe lane packets; pass yolo only in plan mode and never include yolo on mode:\"verify\" calls. This backend command remains read-only in plan mode and verifies receipts in verify mode. Package-backed prompt authority: the installed public wrapper can be the local Codex skill entrypoint, but lane workers must use get_subskill_prompt and get_subskill_asset for nested `$sellable:create-campaign`, create-campaign-v2, generate-messages, validation, and assets; nested filesystem prompt fallback is a failed UAT. Use mcp__sellable only for workspace selection and product mutations/readbacks. Do not use mcp__sellable_admin, direct DB, Prisma, SQL, built-in web search, browser search, web.run, or any external browsing/search tool as execution or research proof; if Sellable MCP research tools are insufficient, write a blocked receipt instead of browsing externally. Worker-local replans are read-only drift checks and must preserve the exact parent sender scopes, including postEngagerSenderIds:[] when intentionally empty and the exact sharedSenderIds array; if scope, planRevision, actionId, or laneKey drifts, stop with blocked:worker_plan_scope_drift before mutation. Each lane packet includes workerDispatch with preferredRuntime, runtimeFallbackOrder, acceptedRuntimes, rejectedRuntimes, requiresVisibleThreadOrDurableReceipt, receiptArtifactHint, receiptRunId, and receiptMustBeWrittenAfter; pre-existing receipts at old deterministic paths are stale and must not be used, so stop with blocked:stale_receipt_artifact if the receipt was not freshly written for the current receiptRunId. `multi_agent_v1.spawn_agent`/opaque spawn_agent is not accepted for mutating command proof unless the parent has visible thread or durable receipt proof. In local Codex, default to `workerDispatch.preferredRuntime` (`visible-codex-app-thread`): discover Codex app thread tools if needed, then call `codex_app.list_projects` and `codex_app.create_thread` with a local project target; do not create a worktree for lane execution. If Codex app thread tools are unavailable but local Codex CLI is available, use durable streaming workers with `codex -a never -s danger-full-access -c model_reasoning_effort=high exec --skip-git-repo-check -m <worker-model> -C <repo> -o <worker-final-file> -` and include preferredRuntimeAttempt plus fallbackReason in createCampaignWorkflowReceipt; approval, sandbox, and reasoning-effort config flags must appear before `exec`, and current customer CLI installs reject `codex exec --ask-for-approval never` and `codex exec -a never`. Do not rely on default model or default reasoning effort: copy the parent model such as `gpt-5.6-sol` into `-m` and always pass `-c model_reasoning_effort=high`; a child worker that reports GPT 5.6-Sol with reasoning below high is a launcher bug to relaunch before mutation, not a user-continue path. Plan responses include approvalSummary; render approvalSummary when asking for bounded delegated approval because it explicitly lists campaignsToCreate, campaignsToUpdate, campaignsToVerifyOnly, campaignsLeftUntouched, attachedSenders, selectedActionIds, allowedSideEffects, forbiddenSideEffects, blockers, and approvalQuestion. When safe-yolo needs normal setup work, the parent skill may ask for bounded delegated approval: one approval over the current planRevision, selected action ids, caps, allowed side-effect classes, and stop conditions lets lane workers execute without per-substep approval while staying inside that packet. In exec/automation mode, do not call request_user_input; if yolo plan autoExecutable:false and no interactive approval can be received, stop with blocked:bounded_approval_unavailable_in_exec_mode before any mutation. Lane workers must explicitly load and use the installed `$sellable:create-campaign` wrapper as the nested workflow entrypoint, then load `create-campaign-v2` and `create-campaign-v2/core/flow.v2.json`; they must execute creation, source import, create-campaign workflow steps, generate-messages, sequence attachment, pause_campaign review-state transition when the current table is still DRAFT, and review readiness through that existing create-campaign workflow/subskills, then return receipts here for verification. Customer-visible verify receipts must set status:'succeeded' or status:'completed'; status:'passed', status:'pass', and status:'passed_with_warnings' are rejected as primary success statuses. Exception: a Post Engagers lane may write status:'blocked' with blocker:'post_engagers_no_sender_posts', 'post_engagers_no_recent_sender_posts', 'post_engagers_no_sender_owned_posts', or 'post_engagers_source_author_mismatch' when Sellable MCP readback proves no usable sender-authored posts/source exists; verify returns these as acceptedLaneBlockers so the parent can report the no-op instead of retrying invalid source repair. Any other blocked receipt, including model-quality/preflight or worker model availability blockers, is not a goal-complete success condition and must not let the parent report evergreen completion. Receipts must include createCampaignStepReceipt with setupPlanCall, createCampaignWorkflowReceipt, campaignBriefReceipt, sourceDecisionReceipt, filterDecisionReceipt, messageDraftingReceipt, reviewBatchReceipt, sequenceReceipt, and verifyCall nested inside createCampaignStepReceipt; top-level-only copies of those objects are not enough and are not promoted by verify. setupPlanCall must use canonical keys: planRevision, actionId, laneKey, workspaceId, senderIds, campaignId, tableId, createIntent. Do not use laneActionId, lanePacketActionId, delegatedPlanRevision, delegatedActionId, or requestedCall text as a substitute for those canonical fields. createCampaignWorkflowReceipt must include skillCommand:'$sellable:create-campaign', skillName:'create-campaign', wrapperSkillLoaded:true, workflowPromptName:'create-campaign-v2', workflowPromptLoadedToHasMoreFalse:true, workflowAssetPath:'create-campaign-v2/core/flow.v2.json', workflowAssetLoaded:true, workerRuntime, workerThreadId or receiptArtifactPath, durableReceiptWritten when using a receipt file, and notAdHoc:true; CLI durable fallback runtimes must also include preferredRuntimeAttempt for visible-codex-app-thread and fallbackReason. messageDraftingReceipt must use exactly statusSource:'branch' or statusSource:'packaged-generate-messages-worker'; descriptive aliases such as statusSource:'package-readback-local-thread' are rejected. It must include proof that generate-messages was loaded, start_campaign_message_preparation/get_campaign_message_preparation_status ran when the packaged worker path is used, validationResult:'passed', a passed qualityReview, and at least 3 concrete sampleMessages with rowId, generatedMessageText, verdict, and issues; Do not substitute `message` for `generatedMessageText`; Do not substitute `passVerdict` for `verdict`. Before writing durable receipts, run a receipt self-check: top-level `planRevision`, `actionId`, `laneKey`, `laneType`, `workspaceId`, and `senderIds` must exist; if the self-check fails, fix the receipt before ending. Use start_campaign_message_preparation with approvalMode:\"mark_ready\" only for evergreen setup. Never call `start_campaign_message_preparation` with `approvalMode:\"approve\"`; approve exactly one semantic Approved cell through select_campaign_cells/update_cell and final proof must show approvedGeneratedMessageCount exactly 1. Shared Cold Fallback samples with a standalone name followed by 'Hey there' are rejected. This command does not launch campaigns, does not schedule sends, does not assign scheduler-owned send fields, does not raw-write campaign status, does not archive/delete cleanup targets, and does not spend paid credits.",
|
|
10
10
|
inputSchema: {
|
|
11
11
|
type: "object",
|
|
12
12
|
properties: {
|
|
@@ -15,6 +15,23 @@ export const setupEvergreenCampaignsToolDefinitions = [
|
|
|
15
15
|
enum: ["plan", "verify"],
|
|
16
16
|
description: 'Defaults to "plan". Verify only validates worker receipts.',
|
|
17
17
|
},
|
|
18
|
+
workspaceId: {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "Optional explicit workspace id. Required for connection-only evergreen setup; it is also sent as the request workspace so concurrent threads cannot drift to another active workspace.",
|
|
21
|
+
},
|
|
22
|
+
campaignSequenceOptions: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
mode: {
|
|
26
|
+
type: "string",
|
|
27
|
+
enum: ["connection_only"],
|
|
28
|
+
description: "Optional non-default sequence policy. connection_only means attach the canonical invite-only template and verify exactly send_invite, with no DM, InMail, View Profile, follow-up, launch, or send side effects.",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
required: ["mode"],
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
description: "Optional non-default evergreen sequence policy. Omit to keep the standard tier-recommended Premium/Sales Nav behavior.",
|
|
34
|
+
},
|
|
18
35
|
depth: {
|
|
19
36
|
type: "string",
|
|
20
37
|
enum: ["structure_only", "customer_visible"],
|
|
@@ -90,10 +107,12 @@ export const setupEvergreenCampaignsToolDefinitions = [
|
|
|
90
107
|
];
|
|
91
108
|
export function setupEvergreenCampaigns(input) {
|
|
92
109
|
return postSetupEvergreenCampaigns({
|
|
110
|
+
workspaceId: input.workspaceId,
|
|
93
111
|
mode: input.mode,
|
|
94
112
|
yolo: input.mode === "verify" ? undefined : input.yolo,
|
|
95
113
|
depth: input.depth,
|
|
96
114
|
handoffMode: input.mode === "verify" ? undefined : input.handoffMode,
|
|
115
|
+
campaignSequenceOptions: input.campaignSequenceOptions,
|
|
97
116
|
allConnectedSenders: input.allConnectedSenders,
|
|
98
117
|
selectedSenderIds: input.selectedSenderIds,
|
|
99
118
|
postEngagerSenderIds: input.postEngagerSenderIds,
|
|
@@ -102,5 +121,5 @@ export function setupEvergreenCampaigns(input) {
|
|
|
102
121
|
planRevision: input.planRevision,
|
|
103
122
|
selectedActionIds: input.selectedActionIds,
|
|
104
123
|
receipts: input.receipts,
|
|
105
|
-
});
|
|
124
|
+
}, input.workspaceId);
|
|
106
125
|
}
|
package/package.json
CHANGED
|
@@ -721,7 +721,7 @@ Treat host capabilities as concrete functions, not prose conventions:
|
|
|
721
721
|
import and before dispatching Message Drafting only.
|
|
722
722
|
- `launch_message_drafting`: Claude Code uses `Task` with `subagent_type`
|
|
723
723
|
`post-find-leads-message-scout` when listed; Codex uses the returned
|
|
724
|
-
compatibility agent or a generic `gpt-5.
|
|
724
|
+
compatibility agent or a generic `gpt-5.6-sol` / `high` Message Drafting agent.
|
|
725
725
|
|
|
726
726
|
If a required interactive question function or MCP loader is missing, stop and
|
|
727
727
|
explain the Sellable install/reload problem. Source work uses product-native MCP
|
|
@@ -1082,8 +1082,8 @@ updates.
|
|
|
1082
1082
|
In Codex, the filter-choice answer is the campaign-scoped go-ahead to use
|
|
1083
1083
|
this single Message Drafting background agent in step-wise and YOLO modes.
|
|
1084
1084
|
Do not ask a separate question to start it. If the named custom agent is not
|
|
1085
|
-
available, spawn a generic background agent with `model: "gpt-5.
|
|
1086
|
-
`reasoning_effort: "
|
|
1085
|
+
available, spawn a generic background agent with `model: "gpt-5.6-sol"` and
|
|
1086
|
+
`reasoning_effort: "high"` using the same lean campaign/table basis. If no
|
|
1087
1087
|
background-agent tool is callable, start the same full message branch inline
|
|
1088
1088
|
before filter drafting or skip-filter message review and record it as
|
|
1089
1089
|
`statusSource: "parent-thread-fallback"`.
|
|
@@ -291,7 +291,7 @@ in the branch read means "filters still owned by parent," not `blocked`.
|
|
|
291
291
|
|
|
292
292
|
Keep the handoff lean: `campaignId`, `workflowTableId`, concise brief/source summary, source-use rule, and 3-5 sample rows (`rowId`, name, title, company, signal). Do not paste copied row counts, hashes, full row IDs, broad row data, or local debug artifacts.
|
|
293
293
|
|
|
294
|
-
Route user copy feedback before `approve-message` back to Message Drafting; parent does not rewrite. The branch loads the full `generate-messages` prompt, every required asset, then `get_subskill_prompt({ subskillName: "create-campaign-v2-validation" })`; do not render `renderedFallbackSample`, concerns, or `qaReceipt` in the happy path. Generic fallback is `gpt-5.
|
|
294
|
+
Route user copy feedback before `approve-message` back to Message Drafting; parent does not rewrite. The branch loads the full `generate-messages` prompt, every required asset, then `get_subskill_prompt({ subskillName: "create-campaign-v2-validation" })`; do not render `renderedFallbackSample`, concerns, or `qaReceipt` in the happy path. Generic fallback is `gpt-5.6-sol` / `high` Message Drafting. Handoff is labeled Markdown, not raw JSON.
|
|
295
295
|
|
|
296
296
|
## Hard Gates
|
|
297
297
|
|
|
@@ -59,6 +59,11 @@ The tail MUST verify:
|
|
|
59
59
|
|
|
60
60
|
- `attach_recommended_sequence` is the only way to pick a template in
|
|
61
61
|
the autonomous tail. Do NOT hand-wire a sequence at Step 16.
|
|
62
|
+
- Exception: when the parent `$sellable:create-evergreen-campaigns` plan
|
|
63
|
+
explicitly carries `campaignSequenceOptions:{ mode:"connection_only" }`,
|
|
64
|
+
do not call `attach_recommended_sequence`. Use the backend-owned
|
|
65
|
+
`attach_sequence({ tableId, templateRef:"connection_only", currentStep:"send" })` path and prove
|
|
66
|
+
`sequenceReceipt.actionTypes:["send_invite"]`.
|
|
62
67
|
- Tier mismatch at attach time is an escalation, NOT a silent fallback.
|
|
63
68
|
- A Standard sender MUST NOT be attached to an INMAIL_OPEN template.
|
|
64
69
|
This would produce sends that fail at Unipile with `not_authorized`.
|
|
@@ -134,6 +134,19 @@ run without user input, or similar, run in **automation mode**:
|
|
|
134
134
|
exactly one quality-valid route-proof row when needed, and attach the
|
|
135
135
|
recommended sequence, but it still must not launch campaigns, schedule
|
|
136
136
|
sends, send messages, or spend paid InMail.
|
|
137
|
+
- **Connection-only evergreen completion is optional and non-default.** Use it
|
|
138
|
+
only when the prompt explicitly says connection-only, invite-only,
|
|
139
|
+
connection request only, no DMs, or no follow-ups. Pass the typed option
|
|
140
|
+
`campaignSequenceOptions:{ mode:"connection_only" }` plus an explicit
|
|
141
|
+
`workspaceId` to `setup_evergreen_campaigns`. Omit
|
|
142
|
+
`campaignSequenceOptions` for the standard tier-recommended Premium,
|
|
143
|
+
Sales Nav, Recruiter, and paid InMail behavior.
|
|
144
|
+
Connection-only completion still creates/reuses the same evergreen lanes,
|
|
145
|
+
source rows, and paused/unlaunched review state, but it attaches only the
|
|
146
|
+
canonical invite template and persists `currentStep:"send"` as the paused
|
|
147
|
+
review step. It does not require Message Drafting, generated messages,
|
|
148
|
+
route-proof approval, first DM, InMail, View Profile fallback, follow-up
|
|
149
|
+
branch, launch, scheduling, or sends.
|
|
137
150
|
|
|
138
151
|
If the invoking prompt explicitly asks for interactive message polish or sample
|
|
139
152
|
proof, run in **interactive polish mode** and use the confirmation/sample steps
|
|
@@ -424,7 +437,7 @@ fallback only when app thread tools are unavailable; the receipt must include
|
|
|
424
437
|
`fallbackReason`, or backend verify rejects it.
|
|
425
438
|
When visible Codex app thread tools are unavailable but local Codex CLI is
|
|
426
439
|
available, the accepted durable streaming-worker command shape is:
|
|
427
|
-
`codex -a never -s danger-full-access -c model_reasoning_effort=
|
|
440
|
+
`codex -a never -s danger-full-access -c model_reasoning_effort=high exec --skip-git-repo-check -m <worker-model> -C <repo> -o <worker-final-file> -`.
|
|
428
441
|
The approval, sandbox, and reasoning-effort config flags must come before the
|
|
429
442
|
`exec` subcommand for Codex CLI builds that expose `-a`/`-s`/`-c` only at top
|
|
430
443
|
level. `--skip-git-repo-check` belongs after `exec` because current customer and VPS Codex CLI builds expose it
|
|
@@ -434,26 +447,26 @@ forms fail on current customer CLI installs. Pipe the lane packet prompt on
|
|
|
434
447
|
stdin, require the worker to write `workerDispatch.receiptArtifactHint`, and
|
|
435
448
|
pass exactly one lane packet per worker.
|
|
436
449
|
When launching durable Codex CLI workers from an automation parent, pass an
|
|
437
|
-
explicit supported worker model and explicit `
|
|
450
|
+
explicit supported worker model and explicit `high` reasoning effort instead
|
|
438
451
|
of relying on the Codex CLI defaults. Use the parent runtime model when known,
|
|
439
452
|
for example:
|
|
440
|
-
`codex -a never -s danger-full-access -c model_reasoning_effort=
|
|
453
|
+
`codex -a never -s danger-full-access -c model_reasoning_effort=high exec --skip-git-repo-check -m <worker-model> -C <repo> -o <worker-final-file> -`.
|
|
441
454
|
In Codex CLI, the parent runtime model is visible in the run header as
|
|
442
455
|
`model: <model-name>`. Copy that exact model string into child worker launches
|
|
443
|
-
first. If the parent header says `model: gpt-5.
|
|
444
|
-
`-m gpt-5.
|
|
456
|
+
first. If the parent header says `model: gpt-5.6-sol`, launch workers with
|
|
457
|
+
`-m gpt-5.6-sol` plus `-c model_reasoning_effort=high`; do not invent or probe
|
|
445
458
|
nearby aliases such as `gpt-5.3-codex`, `gpt-5.2`, `gpt-5-codex`,
|
|
446
459
|
`codex-latest`, or `codex-mini-latest` before trying the exact parent model. A
|
|
447
|
-
one-line probe must include the same `-c model_reasoning_effort=
|
|
460
|
+
one-line probe must include the same `-c model_reasoning_effort=high` override
|
|
448
461
|
and count as supported only when it exits 0 and returns the requested output; a
|
|
449
462
|
session header followed by a `not supported` error is rejected, not accepted.
|
|
450
463
|
Do not rely on the Codex CLI default model or default reasoning effort; some
|
|
451
|
-
customer and VPS installs default to unavailable model aliases or to
|
|
452
|
-
|
|
453
|
-
with `high
|
|
454
|
-
`
|
|
464
|
+
customer and VPS installs default to unavailable model aliases or to reasoning
|
|
465
|
+
below `high`. `-m gpt-5.6-sol` alone is not enough. If a child worker reports GPT 5.6-Sol
|
|
466
|
+
with reasoning below `high`, treat that as a launcher bug, relaunch with the explicit
|
|
467
|
+
`high` config before mutation, and do not ask the user to continue through the
|
|
455
468
|
model-quality warning. If the parent cannot identify a supported worker model
|
|
456
|
-
and launch it with `
|
|
469
|
+
and launch it with `high` reasoning, stop with
|
|
457
470
|
`blocked: worker_model_unavailable` before mutation.
|
|
458
471
|
When wrapping multiple local Codex CLI workers in a shell launcher, run the
|
|
459
472
|
wrapper with `/bin/bash -lc` or another explicitly chosen portable shell. Do not
|
|
@@ -466,7 +479,7 @@ Do not embed `<<'WORKER_PROMPT'` heredocs inside a single quoted or double
|
|
|
466
479
|
quoted `/bin/bash -lc '...'` command string; nested quoting is brittle and can
|
|
467
480
|
truncate the first worker before mutation. For multi-worker launchers, write one
|
|
468
481
|
plain prompt file per lane under the current run directory, then start each
|
|
469
|
-
worker with `codex -a never -s danger-full-access -c model_reasoning_effort=
|
|
482
|
+
worker with `codex -a never -s danger-full-access -c model_reasoning_effort=high exec --skip-git-repo-check -m "$WORKER_MODEL" -C "$REPO" -o
|
|
470
483
|
"$worker_final_file" - < "$worker_prompt_file"`. Keep launcher shell variables
|
|
471
484
|
double-quoted and keep the prompt heredoc only in a standalone script/prompt-file
|
|
472
485
|
write step, not inside an already quoted shell argument. If the first launcher
|
|
@@ -572,7 +585,7 @@ launchers, write the same prompt body to `<worker-prompt-file>` and launch the
|
|
|
572
585
|
worker with stdin redirected from that file:
|
|
573
586
|
|
|
574
587
|
```
|
|
575
|
-
codex -a never -s danger-full-access -c model_reasoning_effort=
|
|
588
|
+
codex -a never -s danger-full-access -c model_reasoning_effort=high exec --skip-git-repo-check -m <worker-model> -C <repo> -o <worker-final-file> - <<'WORKER_PROMPT'
|
|
576
589
|
Use $sellable:create-campaign as the governing campaign workflow for this one lane worker.
|
|
577
590
|
Use the evergreen plan/packet below only for lane scope, source metadata,
|
|
578
591
|
postconditions, side-effect caps, and durable receipt proof.
|
|
@@ -619,10 +632,10 @@ Do not launch, start, schedule, send, or use paid InMail.
|
|
|
619
632
|
For filter proof, durable receipt status must be `filterDecisionReceipt.status:"applied"` only; never `completed`, `confirmed`, `done`, or aliases.
|
|
620
633
|
For generated messages, `update_cell` is allowed only for the semantic Approved checkbox. Never use `update_cell` for generated message text/body/sample copy. Bad copy requires `revise_message_template_and_rerun` or brief/template revision plus Generate Message rerun. Any generated-message cell override is `blocked: generated_message_cell_override`.
|
|
621
634
|
If `bootstrap_create_campaign.modelQuality.status === "warn"` because the child
|
|
622
|
-
worker reports GPT 5.
|
|
635
|
+
worker reports GPT 5.6-Sol with reasoning below `high`, that is a parent launcher
|
|
623
636
|
configuration bug, not an operator approval path inside the worker. Stop before
|
|
624
637
|
mutation, tell the parent to relaunch this lane with
|
|
625
|
-
`-c model_reasoning_effort=
|
|
638
|
+
`-c model_reasoning_effort=high`, and do not mark the worker goal complete.
|
|
626
639
|
Complete only this lane. Do not end with narration only. Before your final
|
|
627
640
|
response, run a local file-existence and JSON self-check for
|
|
628
641
|
<receiptArtifactPath>. If the lane succeeded, write the canonical success
|
|
@@ -643,7 +656,7 @@ receipt, or an accepted Post Engagers no-source blocked/no-op receipt.
|
|
|
643
656
|
WORKER_PROMPT
|
|
644
657
|
|
|
645
658
|
# Multi-worker launcher equivalent:
|
|
646
|
-
codex -a never -s danger-full-access -c model_reasoning_effort=
|
|
659
|
+
codex -a never -s danger-full-access -c model_reasoning_effort=high exec --skip-git-repo-check -m <worker-model> -C <repo> -o <worker-final-file> - < <worker-prompt-file>
|
|
647
660
|
```
|
|
648
661
|
|
|
649
662
|
If any placeholder cannot be filled from the current plan, matching
|
|
@@ -720,6 +733,9 @@ not a parent-thread summary. The receipt must include:
|
|
|
720
733
|
creation, preserve that original packet only in a separate `parentLanePacket`
|
|
721
734
|
object; do not leave `setupPlanCall.campaignId:null` or
|
|
722
735
|
`setupPlanCall.tableId:null`.
|
|
736
|
+
If the parent plan used connection-only, the receipt must also include
|
|
737
|
+
`setupPlanCall.campaignSequenceOptions:{ "mode":"connection_only" }` or
|
|
738
|
+
`setupPlanCall.sequencePolicy.mode:"connection_only"`.
|
|
723
739
|
Short form: For create lanes, `setupPlanCall.campaignId` and `setupPlanCall.tableId` must be the actual created campaign/table ids.
|
|
724
740
|
Short form: Do not leave `setupPlanCall.campaignId:null` or `setupPlanCall.tableId:null`.
|
|
725
741
|
- `createCampaignWorkflowReceipt`: proof the worker loaded the actual installed
|
|
@@ -810,22 +826,40 @@ not a parent-thread summary. The receipt must include:
|
|
|
810
826
|
them into canonical `promptLoadedToHasMoreFalse`, `requiredAssetsLoaded`,
|
|
811
827
|
`validationLoaded`, `reviewBatchRowHash`, and
|
|
812
828
|
`messageDraftRecommendation`.
|
|
829
|
+
Connection-only lanes are the exception: do not include
|
|
830
|
+
`messageDraftingReceipt` or run generated-message prep unless the operator
|
|
831
|
+
separately asked for message copy. The parent verifier expects no message
|
|
832
|
+
proof for connection-only lanes.
|
|
813
833
|
- `reviewBatchReceipt`: review-batch row ids/hash, generated row count,
|
|
814
834
|
quality-valid route-proof row id when approved, and proof that no broad
|
|
815
835
|
approve-all occurred.
|
|
836
|
+
Connection-only lanes are the exception: do not approve a route-proof row and
|
|
837
|
+
do not include a required review-batch receipt.
|
|
816
838
|
- `sequenceReceipt`: exact current workflowTableId, recommended non-paid
|
|
817
839
|
sequence attach/precheck result, and readback showing `hasSequence:true` when
|
|
818
840
|
completion is claimed. If the tool output uses
|
|
819
841
|
`attachRecommendedSequenceResult.actionTypes` or
|
|
820
842
|
`nonPaidRecommendedSequence`, copy them to canonical `actionTypes` and
|
|
821
843
|
`nonPaid`.
|
|
844
|
+
For connection-only lanes, do not call `attach_recommended_sequence`. Attach
|
|
845
|
+
with `attach_sequence({ tableId, templateRef:"connection_only", currentStep:"send" })`, then
|
|
846
|
+
include exact current-template proof:
|
|
847
|
+
`sequenceReceipt.hasSequence:true`,
|
|
848
|
+
`sequenceReceipt.actionTypes:["send_invite"]`, and
|
|
849
|
+
`sequenceReceipt.nonPaid:true`. Receipts that only say
|
|
850
|
+
`tool:"attach_recommended_sequence"` or include `send_dm`,
|
|
851
|
+
`send_inmail_open`, `send_inmail_closed`, or `view_profile` are failing
|
|
852
|
+
connection-only receipts.
|
|
822
853
|
- final paused-send proof: if the current campaign table is `DRAFT` after the
|
|
823
854
|
sequence is attached, call the product `pause_campaign({ campaignId })`
|
|
824
855
|
endpoint/tool to put the unlaunched campaign into `PAUSED` review state, then
|
|
825
856
|
reread the campaign/table. Do not raw-write `campaignStatus`, do not start or
|
|
826
857
|
launch, and do not schedule/send. Completion requires reread proof of
|
|
827
|
-
`currentStep:"send"` and `campaignStatus:"PAUSED"
|
|
828
|
-
|
|
858
|
+
`currentStep:"send"` and `campaignStatus:"PAUSED"` for standard and
|
|
859
|
+
connection-only customer-visible lanes. `send` is the product's paused
|
|
860
|
+
review step; do not use unsupported aliases such as `review` as final proof.
|
|
861
|
+
If the raw output nests this in `finalCampaignRead` or `finalTableRead`, copy
|
|
862
|
+
it to canonical
|
|
829
863
|
`finalPausedSendProof.currentStep` and
|
|
830
864
|
`finalPausedSendProof.campaignStatus`.
|
|
831
865
|
- `verifyCall`: the exact `setup_evergreen_campaigns({ mode:"verify",
|
|
@@ -1088,9 +1122,14 @@ plain row generation. The lane worker must inline the same
|
|
|
1088
1122
|
approvedGeneratedMessageCount exactly 1. Do not report completion with 2+
|
|
1089
1123
|
approved rows.
|
|
1090
1124
|
Approval shorthand: Do not report completion with 2+ approved rows.
|
|
1091
|
-
8.
|
|
1092
|
-
|
|
1093
|
-
|
|
1125
|
+
8. Standard mode: continue to
|
|
1126
|
+
`attach_recommended_sequence({ campaignId, currentStep:"send" })` and, if
|
|
1127
|
+
the campaign is still `DRAFT`, `pause_campaign({ campaignId })`. Reread the
|
|
1128
|
+
campaign/table before claiming completion.
|
|
1129
|
+
Connection-only mode: skip Message Drafting and route-proof approval, call
|
|
1130
|
+
`attach_sequence({ tableId, templateRef:"connection_only", currentStep:"send" })`, prove
|
|
1131
|
+
`sequenceReceipt.actionTypes:["send_invite"]`, and pause/reread without
|
|
1132
|
+
launching or sending.
|
|
1094
1133
|
|
|
1095
1134
|
That packaged worker path must return `messageDraftingReceipt.statusSource:
|
|
1096
1135
|
"packaged-generate-messages-worker"`. It is accepted only when the receipt
|
|
@@ -1515,11 +1554,14 @@ Message, and verify current-revision sample messages before final completion.
|
|
|
1515
1554
|
- DM lanes: add a `Delivery format:` line — either `multiline (each paragraph sends as its own DM message)` or `single message`. When multiline, the template's blank-line paragraphs ARE the message boundaries — write each one as a standalone typed message.
|
|
1516
1555
|
- **InMail lanes can never be multiline**: an InMail is one message and the recipient must reply before anything else can be sent. InMail-bound templates must read as one cohesive message — declare `Delivery format: single message (InMail — no follow-up until reply)` and never structure the copy to depend on multi-message pacing.
|
|
1517
1556
|
|
|
1518
|
-
-
|
|
1557
|
+
- In standard mode, the sequence is auto-selected by sender tier; do not hand-author sequence
|
|
1519
1558
|
templates here. Sales Nav/Recruiter senders may receive the unified Sales
|
|
1520
1559
|
Nav cascade through `attach_recommended_sequence`; attaching it does not
|
|
1521
1560
|
spend paid InMail credits by itself. Do not substitute the manual Paid
|
|
1522
1561
|
InMail Campaign template.
|
|
1562
|
+
For explicit connection-only evergreen lanes only, use the backend-owned
|
|
1563
|
+
`attach_sequence({ tableId, templateRef:"connection_only", currentStep:"send" })` path and do
|
|
1564
|
+
not call `attach_recommended_sequence`.
|
|
1523
1565
|
3. **Customer-Visible Completion Contract**: a named evergreen lane that appears
|
|
1524
1566
|
as a campaign card or campaign-backed table is not done when the shell exists.
|
|
1525
1567
|
It is done only when the customer can open the campaign and land on final
|
|
@@ -1543,7 +1585,7 @@ Message, and verify current-revision sample messages before final completion.
|
|
|
1543
1585
|
evergreen setup. Do not leave customer-visible campaigns at
|
|
1544
1586
|
`filter-choice`, `filter-rules`, or `apply-icp-rubric` and report success.
|
|
1545
1587
|
Do not proceed to Message Drafting until saved filters are applied.
|
|
1546
|
-
- Message Drafting has run from the current campaign/table basis, using the
|
|
1588
|
+
- In standard mode, Message Drafting has run from the current campaign/table basis, using the
|
|
1547
1589
|
create-campaign message prompt/assets and validation gate. Updating
|
|
1548
1590
|
`currentStep:"messages"` is not proof. Parent-thread handwritten copy is
|
|
1549
1591
|
not a substitute. The proof receipt must show
|
|
@@ -1584,6 +1626,9 @@ Message, and verify current-revision sample messages before final completion.
|
|
|
1584
1626
|
Fallback samples must still reject source/conversation hedges such as
|
|
1585
1627
|
`"hope this is relevant"`, `"might be interested"`, or `"saw you in a few
|
|
1586
1628
|
conversations"`.
|
|
1629
|
+
For explicit connection-only lanes, this whole Message Drafting and sample
|
|
1630
|
+
proof block is not required and must not be faked with parent-written
|
|
1631
|
+
messages.
|
|
1587
1632
|
- The first review batch exists and at least 3 review rows have generated
|
|
1588
1633
|
messages from the approved brief. If fewer than 3 usable rows exist, report
|
|
1589
1634
|
the actual count and why.
|
|
@@ -1596,7 +1641,7 @@ Message, and verify current-revision sample messages before final completion.
|
|
|
1596
1641
|
completion, approve exactly one quality-valid generated row. If one or more
|
|
1597
1642
|
rows are already approved, do not add more approvals during evergreen
|
|
1598
1643
|
completion. Never broad approve all rows.
|
|
1599
|
-
-
|
|
1644
|
+
- In standard mode, the recommended tier-aware sequence is attached to the current campaign
|
|
1600
1645
|
table, and the watched campaign is on Send. Use
|
|
1601
1646
|
`attach_recommended_sequence({ campaignId, currentStep:"send" })` when a
|
|
1602
1647
|
safe attach is needed. After `confirm_lead_list` or any source-list copy,
|
|
@@ -1611,6 +1656,10 @@ Message, and verify current-revision sample messages before final completion.
|
|
|
1611
1656
|
manual Paid InMail Campaign, and never attach/replace sequence outside the
|
|
1612
1657
|
current table unless the current lane packet explicitly allowed sequence
|
|
1613
1658
|
repair.
|
|
1659
|
+
For explicit connection-only lanes, the current campaign table must have
|
|
1660
|
+
exactly the canonical invite-only sequence:
|
|
1661
|
+
`sequenceReceipt.actionTypes:["send_invite"]`. Any DM, InMail, or View
|
|
1662
|
+
Profile action means the lane is not complete.
|
|
1614
1663
|
- If the current campaign table is still `DRAFT` after sequence/readiness
|
|
1615
1664
|
proof, call `pause_campaign({ campaignId })` and reread. `pause_campaign`
|
|
1616
1665
|
is the product-native review-state transition; it is not a launch and does
|
|
@@ -196,6 +196,11 @@ rather than asking which campaign class to fill. If a stale target plan selects
|
|
|
196
196
|
planner before mutation.
|
|
197
197
|
Short form: trust the target plan's inferred lane when it is a connection invite,
|
|
198
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.
|
|
199
204
|
|
|
200
205
|
Structured planner packet:
|
|
201
206
|
|
|
@@ -271,6 +276,10 @@ need raw proof, call the read-only `get_scheduler_fill_capacity` query for the
|
|
|
271
276
|
same sender/action/date; it tells the MCP how many cells the product scheduler
|
|
272
277
|
will try to place and does not import, approve, schedule, refresh credits, or
|
|
273
278
|
mutate.
|
|
279
|
+
Treat `rollingWeeklyInvite.capacityFreedDuringWindow:true` as proof that
|
|
280
|
+
rolling-weekly capacity frees later in the send window and remains schedulable;
|
|
281
|
+
use its timing fields instead of treating the window-start gate as a permanent
|
|
282
|
+
full-day blocker.
|
|
274
283
|
When the refill loop has ready rows and needs scheduler pickup now, use
|
|
275
284
|
`run_scheduler_sweep` with the same explicit `workspaceId`; it can place cells
|
|
276
285
|
within existing scheduler gates and returns the receipt, but it never sends or
|
|
@@ -62,6 +62,11 @@ for lease expiry; never guess a fence.
|
|
|
62
62
|
The default `intent:"auto"` inspects `managed_waterfall`,
|
|
63
63
|
`dashboard_evergreen`, and `active_campaign` lane sources. Report the lane
|
|
64
64
|
source and lane chain as proof for every selected sender.
|
|
65
|
+
Connection-only evergreen lanes are invite-only refill targets. When the packet
|
|
66
|
+
or campaign proof shows exactly `["send_invite"]`, report and execute only
|
|
67
|
+
`selectedLane:"send_invite"` work; do not infer DM, InMail, Sales Nav cascade,
|
|
68
|
+
paid-credit refresh, message generation, follow-up, sequence mutation,
|
|
69
|
+
launch/start beyond packet authority, scheduler writes, or direct sends.
|
|
65
70
|
|
|
66
71
|
If membership blocks a workspace read, report the structured
|
|
67
72
|
`workspace_access` blocker instead of retrying auth or switching workspaces.
|
|
@@ -61,6 +61,13 @@ the repair rung, such as re-run errored enrichment/message cells
|
|
|
61
61
|
(`start_campaign`). The loop bounds and refuses repair loops; it never invents
|
|
62
62
|
a fix list.
|
|
63
63
|
|
|
64
|
+
Connection-only evergreen packets are invite-only. If the selected lane or
|
|
65
|
+
campaign proof is exactly `["send_invite"]`, the workflow may refill only
|
|
66
|
+
`selectedLane:"send_invite"` capacity. Do not treat that lane as a DM, InMail,
|
|
67
|
+
Sales Nav cascade, paid-credit refresh, generated-message requirement,
|
|
68
|
+
follow-up branch, sequence-repair task, scheduler write, launch/send, or
|
|
69
|
+
provider-family continuation.
|
|
70
|
+
|
|
64
71
|
Use plain-language labels first and tokens second, for example "copy leads
|
|
65
72
|
already found into the campaign table (`reconcile_source_copy`)".
|
|
66
73
|
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"awaiting scheduler is not an end state; window-closed reports name remaining-ready, expected pickup time, and resume handle",
|
|
53
53
|
"honest-rubric-fail means a human updates the rubric or changes lead source",
|
|
54
54
|
"source replenishment beyond same-source-automatic is a scoped create-campaign handoff, never refill-owned provider search",
|
|
55
|
+
"connection-only evergreen lanes with exact [\"send_invite\"] proof are invite-only refill capacity; never infer DM, InMail, Sales Nav cascade, paid-credit refresh, message generation, follow-up, sequence mutation, scheduler writes, launch, or send work from them",
|
|
55
56
|
"no campaign creation, provider-family switch, threshold lowering, scheduler writes, sends, archives, deletes, or brief/filter/message/sequence/sender mutation without a separate approval packet"
|
|
56
57
|
],
|
|
57
58
|
"requiredBootstrap": [
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
export type RefillDateWindowSource = "default_scheduler_forward" | "horizon_send_days" | "until_date" | "target_date";
|
|
2
|
-
export type NormalizedRefillDateSelector = {
|
|
3
|
-
source: RefillDateWindowSource;
|
|
4
|
-
targetDate: string | null;
|
|
5
|
-
untilDate: string | null;
|
|
6
|
-
horizonSendDays: number | null;
|
|
7
|
-
};
|
|
8
|
-
export type RefillRunDateWindow = NormalizedRefillDateSelector & {
|
|
9
|
-
version: 1;
|
|
10
|
-
selectedDates: string[];
|
|
11
|
-
senderWindows?: Array<{
|
|
12
|
-
senderId: string | null;
|
|
13
|
-
timeZone: string | null;
|
|
14
|
-
selectedDates: string[];
|
|
15
|
-
}>;
|
|
16
|
-
};
|
|
17
|
-
type DateSelectorInput = {
|
|
18
|
-
targetDate?: unknown;
|
|
19
|
-
untilDate?: unknown;
|
|
20
|
-
horizonSendDays?: unknown;
|
|
21
|
-
};
|
|
22
|
-
export declare function normalizeRefillDateSelector(input: DateSelectorInput): NormalizedRefillDateSelector;
|
|
23
|
-
export declare function refillDateSelectorBody(selector: NormalizedRefillDateSelector): {
|
|
24
|
-
targetDate?: string;
|
|
25
|
-
untilDate?: string;
|
|
26
|
-
horizonSendDays?: number;
|
|
27
|
-
};
|
|
28
|
-
export declare function dateWindowFromSelector(selector: NormalizedRefillDateSelector): RefillRunDateWindow;
|
|
29
|
-
export declare function dateWindowFromPlan(plan: Record<string, unknown>, selector: NormalizedRefillDateSelector): RefillRunDateWindow;
|
|
30
|
-
export declare function dateWindowFromRunState(runState: unknown): RefillRunDateWindow | null;
|
|
31
|
-
export declare function selectorFromDateWindow(window: RefillRunDateWindow): NormalizedRefillDateSelector;
|
|
32
|
-
export declare function dateSelectorMatchesWindow(selector: NormalizedRefillDateSelector, window: RefillRunDateWindow): boolean;
|
|
33
|
-
export declare function schedulerSweepTargetDates(window: RefillRunDateWindow): string[];
|
|
34
|
-
export {};
|